addCssFile('modules/WecomCenter/assets/wecom.center.css'); $e = function ($v) { return htmlspecialchars((string) ($v ?? ''), ENT_QUOTES, 'UTF-8'); }; $t = function (string $k, array $a = []) use ($e) { return $e(I18n::t($k, $a)); }; // Zabbix CTag escapes plain strings; wrap trusted, self-built markup so it renders as HTML. $raw = function (string $h) { return new class($h) { private $h; public function __construct(string $h) { $this->h = $h; } public function toString($destroy = true): string { return $this->h; } public function __toString(): string { return $this->h; } }; }; $save = $e((new CUrl('zabbix.php'))->setArgument('action', 'wecom.center.save')->getUrl()); $view_url = (new CUrl('zabbix.php'))->setArgument('action', 'wecom.center.view')->getUrl(); $mtid = $e($data['mediatypeid']); $active_tab = (string) ($_REQUEST['tab'] ?? 'alert'); if (!in_array($active_tab, ['alert', 'opt', 'maint', 'l2'], true)) { $active_tab = 'alert'; } $tabHref = function (string $id) use ($data) { return htmlspecialchars((new CUrl('zabbix.php')) ->setArgument('action', 'wecom.center.view') ->setArgument('mediatypeid', $data['mediatypeid']) ->setArgument('tab', $id) ->getUrl(), ENT_QUOTES, 'UTF-8'); }; $html_page = (new CHtmlPage())->setTitle(I18n::t('page.title')); if (!$data['mediatype']) { $initBody = '
'.$t('init.sub').'
' .'
' .'
' .'
' .'
' .'
'; $initCard = '
⚡' .''.$t('init.title').'
' .'
'.$initBody.'
'; $heroI = '
'.$t('page.title').'
' .'
'.$t('init.sub').'
'; $html_page->addItem($raw('
'.$heroI.$initCard.'
')); $html_page->show(); return; } $mask = (int) $data['severity']; $enabled = ((int) $data['active'] === 0); /* helper to build a card */ $card = function (string $ico, string $title, string $body, string $extra = '', string $sub = '') { return '
'.$ico.'' .''.$title.'' .($sub !== '' ? ''.$sub.'' : '') .'
'.$body.'
'; }; /* ============================ TAB 1: ALERT ============================ */ // -- robot -- $robotBody = '
' .'' .'' .'
' .'
' .'
' .'' .'' .'
'; $robotCard = $card('🤖', $t('sec.robot'), $robotBody, '', $e($data['mediatype']['name'] ?? '')); // -- threshold -- $sevChecks = ''; for ($i = 1; $i <= 6; $i++) { $bit = 1 << ($i - 1); $chk = (($mask & $bit) !== 0) ? ' checked' : ''; $sevChecks .= ''; } $thresholdBody = '
'.$t('lbl.threshold_hint').'
' .'
' .'' .'' .'
' .'
'.$sevChecks.'
' .'
' .'
'; $thresholdCard = $card('⚙️', $t('sec.threshold'), $thresholdBody); // -- strategy presets -- $presetRows = ''; foreach ($data['presets'] as $key => $p) { $is_cur = ((string) $data['current_strategy'] === (string) $key); $name = $t($p['label']).($is_cur ? ' '.$t('preset.current').'' : ''); $prevUrl = $e((new CUrl('zabbix.php')) ->setArgument('action', 'wecom.center.view') ->setArgument('mediatypeid', $data['mediatypeid']) ->setArgument('tab', 'alert') ->setArgument('preview_preset', $key) ->getUrl()); $presetRows .= '
' .'
'.$name.'
' .'
'.$t($p['desc']).'
' .'
' .''.$t('btn.preview').'' .'
' .'
' .'
'; } $strategyBody = '
'.$t('lbl.strategy_hint').'
'.$presetRows; $strategyCard = $card('🚨', $t('sec.strategy'), $strategyBody, ' wc-card--wide'); // -- preview -- $previewCard = ''; if ($data['preview'] !== null) { $pv = $data['preview']; $pkey = $data['preview_key']; $rows = ''; foreach ($pv['classes'] as $ck => $c) { $label = $t($data['classes'][$ck]['label'] ?? $ck); $rows .= ''.$label.''.$t('sev.'.($c['target'] + 1)).'' .''.$e($c['count']).''.$e($c['changes']).''; } $rows .= ''.$t('cls.total').'' .''.$e($pv['total']).''.$e($pv['changes']).''; $tbl = '' .''.$rows.'
'.$t('cls.col.class').''.$t('cls.col.target').''.$t('cls.col.count').''.$t('cls.col.changes').'
'; $body = '
'.$t('preview.hint').'
'.$tbl; $previewCard = $card('🔍', $t('preview.title', [I18n::t($data['presets'][$pkey]['label'] ?? $pkey)]), $body, ' wc-card--wide'); } $tab_alert = '
'.$robotCard.$thresholdCard.$strategyCard.$previewCard.'
'; /* ======================== TAB 2: OPTIMIZATION ========================= */ // -- tuning -- $tuneOpts = ''; foreach (['small', 'medium', 'large'] as $pk) { $tuneOpts .= ''; } $tuneBody = '
'.$t('lbl.tuning_hint').'
' .'
' .'' .'
' .'
' .'
' .'
'.$t('tuning.env').'
' .'
'.$e($data['tuning']['env']).'
' .'
'.$t('tuning.cmd').'
' .'
'.$e($data['tuning']['cmd']).'
'; $tuningCard = $card('⚙️', $t('sec.tuning'), $tuneBody, ' wc-card--wide'); // -- template import -- $tplOpts = ''; if (!$data['templates']) { $tplOpts = ''; } foreach ($data['templates'] as $tf) { $tplOpts .= ''; } $importBody = '
'.$t('lbl.template_hint').'
' .'
' .'
' .'' .'
' .'
'; $importCard = $card('📦', $t('sec.template'), $importBody); // -- map -- if ($data['server_host']) { $mapBody = '
'.$t('map.hint').'
' .'
' .'' .'' .'
'.$e($data['server_host']['name']).'
' .'
' .'
' .'
' .'
' .'
' .'
'; } else { $mapBody = '
'.$t('msg.no_server_host').'
'; } $mapCard = $card('🗺️', $t('sec.map'), $mapBody); // -- template switch -- $srcOpts = ''; $dstOpts = ''; foreach ($data['huawei_tpls'] as $tp) { $selS = ((string) $data['switch_src'] === (string) $tp['templateid']) ? ' selected' : ''; $selD = ((string) $data['switch_dst'] === (string) $tp['templateid']) ? ' selected' : ''; $srcOpts .= ''; $dstOpts .= ''; } $switchBody = '
'.$t('lbl.switch_hint').'
' .'
' .'' .'
' .'
' .'
' .'' .'
'; if ($data['switch_preview'] !== null) { $sp = $data['switch_preview']; if ((int) $sp['count'] === 0) { $switchBody .= '
'.$t('switch.none', [$sp['src_name']]).'
'; } else { $chips = ''; foreach ($sp['hosts'] as $hn) { $chips .= ''.$e($hn).''; } $switchBody .= '
' .'
'.$t('switch.result', [$sp['count'], $sp['src_name'], $sp['dst_name']]).'
' .'
'.$chips.'
' .'
' .'' .'' .'' .'' .'
'; } } $switchCard = $card('🔁', $t('sec.switch'), $switchBody, ' wc-card--wide'); $initBody2 = '
'.$t('lbl.init_hint').'
' .'
' .'' .'
' .'
' .'
' .'
'; $initCard2 = $card('⚡', $t('sec.init'), $initBody2); $tab_opt = '
'.$tuningCard.$importCard.$mapCard.$initCard2.$switchCard.'
'; /* ======================== TAB 3: MAINTENANCE ========================== */ // -- by class: pick a class + a severity, apply to every trigger in that class -- $classOpts = ''; foreach ($data['classes'] as $ck => $c) { if ($ck === 'other') { continue; } $classOpts .= ''; } $prioOpts = ''; for ($p = 0; $p <= 5; $p++) { $prioOpts .= ''; } $classBody = '
'.$t('lbl.class_sev_hint').'
' .'
' .'
' .'
' .'
' .'
' .'
' .'
'; $classCard = $card('🏷️', $t('sec.class_sev'), $classBody, ' wc-card--wide'); // -- by single trigger: search, then adjust severity / enable per row -- $searchBody = '
'.$t('lbl.trig_hint', [$data['trigger_count']]).'
' .'
' .'' .'
' .'
'; $maintBody = $searchBody; if ($data['trig_search'] !== '') { if ($data['triggers']) { $ids = []; $rows = ''; foreach ($data['triggers'] as $tg) { $ids[] = $tg['triggerid']; $host = !empty($tg['hosts']) ? $tg['hosts'][0]['host'] : ''; $chk = ((int) $tg['status'] === 0) ? ' checked' : ''; $sevSel = ''; for ($p = 0; $p <= 5; $p++) { $sevSel .= ''; } $rows .= '
' .'' .'' .'
'; } $maintBody .= '
' .'
' .'' .'' .'' .'
'.$t('lbl.trig_edit_hint').'
' .'
'.$rows.'
' .'
' .'
'; } else { $maintBody .= '
'.$t('msg.no_trig_search').'
'; } } $trigCard = $card('🔧', $t('sec.triggers'), $maintBody, ' wc-card--wide'); $tab_maint = '
'.$classCard.$trigCard.'
'; /* ======================== TAB 4: L2 TOPOLOGY CONFIG ================== */ $l2 = $data['l2']; // templates multi-select $tplSel = ''; foreach ($data['l2_templates'] as $tn) { $sel = in_array($tn, (array) $l2['templates'], true) ? ' selected' : ''; $tplSel .= ''; } $collectBody = '
'.$t('lbl.l2_templates_hint').'
' .'
' .'
' .'
' .'
' .'
' .'
'; $collectCard = $card('📡', $t('sec.l2_collect'), $collectBody, ' wc-card--wide'); $displayBody = '
' .'
' .'
' .'
' .'
'; $displayCard = $card('🖥️', $t('sec.l2_display'), $displayBody); $netLines = ''; foreach ((array) ($l2['networks'] ?? []) as $nw) { $netLines .= ($nw['key'] ?? '').' | '.($nw['label'] ?? '').' | '.implode(',', (array) ($nw['keywords'] ?? [])).' | '.($nw['color'] ?? '#607D8B')."\n"; } $networkBody = '
'.$t('lbl.l2_networks_hint').'
' .'
' .'
'; $networkCard = $card('🌐', $t('sec.l2_networks'), $networkBody, ' wc-card--wide'); $coreRowHtml = function (array $r) use ($e, $t, $l2) { $netSel = ''; $isRegex = (($r['match'] ?? 'contains') === 'regex'); return '
'.$netSel .'' .'' .'
'; }; $coreRows = ''; foreach ((array) ($l2['core_rules'] ?? []) as $r) { $coreRows .= $coreRowHtml($r); } $coreBody = '
'.$t('lbl.l2_cores_hint').'
' .'
'.$coreRows.'
' .'
' .''; $coreCard = $card('🔑', $t('sec.l2_cores'), $coreBody, ' wc-card--wide'); $colorFields = ''; foreach (['100' => 'lbl.color_100', '1000' => 'lbl.color_1000', '10000' => 'lbl.color_10000', '20000' => 'lbl.color_20000', 'unknown' => 'lbl.color_unknown', 'down' => 'lbl.color_down'] as $ck => $lab) { $colorFields .= '
' .'
'; } $colorCard = $card('🎨', $t('sec.l2_colors'), '
'.$colorFields.'
', ' wc-card--wide'); $latBody = '
' .'
' .'
' .'
'; $latCard = $card('⏱️', $t('sec.l2_latency'), $latBody); $ruleRowHtml = function (array $r) use ($e, $t) { $isRegex = (($r['match'] ?? 'contains') === 'regex'); $big = !empty($r['big']); return '
' .'' .'' .'' .'' .'' .'
'; }; $ruleRows = ''; foreach ((array) $l2['group_rules'] as $r) { $ruleRows .= $ruleRowHtml($r); } $groupBody = '
'.$t('lbl.rule_hint').'
' .'
'.$ruleRows.'
' .'
' .''; $groupCard = $card('📁', $t('sec.l2_group'), $groupBody, ' wc-card--wide'); $tab_l2 = '
' .'' .'' .'
'.$collectCard.$displayCard.$networkCard.$coreCard.$colorCard.$latCard.$groupCard.'
' .'
' .'
' .''; /* ============================ assemble =============================== */ $hero = '
'.$t('page.title').'
' .'
'.$t('hero.sub').'
'; $tabbar = '
' .''.$t('tab.alert').'' .''.$t('tab.opt').'' .''.$t('tab.maint').'' .''.$t('tab.l2').'' .'
'; $content = ($active_tab === 'opt') ? $tab_opt : (($active_tab === 'maint') ? $tab_maint : (($active_tab === 'l2') ? $tab_l2 : $tab_alert)); $html_page->addItem($raw('
'.$hero.$tabbar.$content.'
')); $html_page->show();