function get_macro($hostid, $macro_name, $force = false) { $macros = API::UserMacro()->get(array("output" => API_OUTPUT_EXTEND, "hostids" => array($hostid), "nopermissions" => $force)); foreach ($macros as $macro) { if ($macro['macro'] === $macro_name) { return $macro['value']; } } return null; }
/** * Update Host. * * @param array $hosts multidimensional array with Hosts data * @param string $hosts ['host'] Host name. * @param int $hosts ['port'] Port. OPTIONAL * @param int $hosts ['status'] Host Status. OPTIONAL * @param int $hosts ['useip'] Use IP. OPTIONAL * @param string $hosts ['dns'] DNS. OPTIONAL * @param string $hosts ['ip'] IP. OPTIONAL * @param int $hosts ['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts ['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts ['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts ['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts ['ipmi_password'] IPMI password. OPTIONAL * @param string $hosts ['groups'] groups * * @return boolean */ public function update($hosts) { $hosts = zbx_toArray($hosts); $hostids = zbx_objectValues($hosts, 'hostid'); $this->checkInput($hosts, __FUNCTION__); // fetch fields required to update host inventory $inventories = array(); foreach ($hosts as $host) { if (isset($host['inventory'])) { $inventory = $host['inventory']; $inventory['hostid'] = $host['hostid']; $inventories[] = $inventory; } } $inventories = $this->extendObjects('host_inventory', $inventories, array('inventory_mode')); $inventories = zbx_toHash($inventories, 'hostid'); $macros = array(); foreach ($hosts as &$host) { if (isset($host['macros'])) { $macros[$host['hostid']] = $host['macros']; unset($host['macros']); } } unset($host); if ($macros) { API::UserMacro()->replaceMacros($macros); } foreach ($hosts as $host) { // extend host inventory with the required data if (isset($host['inventory']) && $host['inventory']) { $inventory = $inventories[$host['hostid']]; // if no host inventory record exists in the DB, it's disabled if (!isset($inventory['inventory_mode'])) { $inventory['inventory_mode'] = HOST_INVENTORY_DISABLED; } $host['inventory'] = $inventory; } API::HostInterface()->replaceHostInterfaces($host); unset($host['interfaces']); $data = $host; $data['hosts'] = $host; $result = $this->massUpdate($data); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Host update failed.')); } } return array('hostids' => $hostids); }
/** * Update Host. * * @param array $hosts multidimensional array with Hosts data * @param string $hosts ['host'] Host name. * @param int $hosts ['port'] Port. OPTIONAL * @param int $hosts ['status'] Host Status. OPTIONAL * @param int $hosts ['useip'] Use IP. OPTIONAL * @param string $hosts ['dns'] DNS. OPTIONAL * @param string $hosts ['ip'] IP. OPTIONAL * @param int $hosts ['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts ['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts ['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts ['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts ['ipmi_password'] IPMI password. OPTIONAL * @param string $hosts ['groups'] groups * * @return boolean */ public function update($hosts) { $hosts = zbx_toArray($hosts); $hostids = zbx_objectValues($hosts, 'hostid'); $this->checkInput($hosts, __FUNCTION__); $macros = array(); foreach ($hosts as $host) { API::HostInterface()->replaceHostInterfaces($host); unset($host['interfaces']); if (isset($host['macros'])) { $macros[$host['hostid']] = $host['macros']; unset($host['macros']); } $data = $host; $data['hosts'] = $host; $result = $this->massUpdate($data); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Host update failed.')); } } if ($macros) { API::UserMacro()->replaceMacros($macros); } return array('hostids' => $hostids); }
/** * Update Template * * @param array $templates multidimensional array with templates data * @return boolean */ public function update($templates) { $templates = zbx_toArray($templates); $templateids = zbx_objectValues($templates, 'templateid'); $updTemplates = $this->get(array('templateids' => $templateids, 'editable' => 1, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => 1)); foreach ($templates as $template) { if (!isset($updTemplates[$template['templateid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } $macros = array(); foreach ($templates as $template) { // if visible name is not given or empty it should be set to host name if (!isset($template['name']) || isset($template['name']) && zbx_empty(trim($template['name']))) { if (isset($template['host'])) { $template['name'] = $template['host']; } } $tplTmp = $template; $template['templates_link'] = isset($template['templates']) ? $template['templates'] : null; if (isset($template['macros'])) { $macros[$template['templateid']] = $template['macros']; unset($template['macros']); } unset($template['templates']); unset($template['templateid']); unset($tplTmp['templates']); $template['templates'] = array($tplTmp); $result = $this->massUpdate($template); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Failed to update template')); } } if ($macros) { API::UserMacro()->replaceMacros($macros); } return array('templateids' => $templateids); }
protected function calcTriggers() { $this->triggers = array(); if ($this->m_showTriggers != 1) { return; } $max = 3; $cnt = 0; foreach ($this->items as $inum => $item) { $db_triggers = DBselect('SELECT DISTINCT h.host,tr.description,tr.triggerid,tr.expression,tr.priority,tr.value' . ' FROM triggers tr,functions f,items i,hosts h' . ' WHERE tr.triggerid=f.triggerid' . " AND f.function IN ('last','min','avg','max')" . ' AND tr.status=' . TRIGGER_STATUS_ENABLED . ' AND i.itemid=f.itemid' . ' AND h.hostid=i.hostid' . ' AND f.itemid=' . $item['itemid'] . ' ORDER BY tr.priority'); while (($trigger = DBfetch($db_triggers)) && $cnt < $max) { $db_fnc_cnt = DBselect('SELECT COUNT(*) AS cnt FROM functions f WHERE f.triggerid=' . $trigger['triggerid']); $fnc_cnt = DBfetch($db_fnc_cnt); if ($fnc_cnt['cnt'] != 1) { continue; } $trigger = API::UserMacro()->resolveTrigger($trigger); if (!preg_match('/^\\{([0-9]+)\\}\\s*?([\\<\\>\\=]{1})\\s*?([\\-0-9\\.]+)([TGMKsmhdw]?)$/', $trigger['expression'], $arr)) { continue; } $val = convert($arr[3] . $arr[4]); $minY = $this->m_minY[$this->items[$inum]['axisside']]; $maxY = $this->m_maxY[$this->items[$inum]['axisside']]; $this->triggers[] = array('skipdraw' => $val <= $minY || $val >= $maxY, 'y' => $this->sizeY - ($val - $minY) / ($maxY - $minY) * $this->sizeY + $this->shiftY, 'color' => getSeverityColor($trigger['priority']), 'description' => _('Trigger') . ': ' . CTriggerHelper::expandDescription($trigger), 'constant' => '[' . $arr[2] . ' ' . $arr[3] . $arr[4] . ']'); ++$cnt; } } }
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $hostids = array_keys($result); // adding groups if ($options['selectGroups'] !== null) { $relationMap = $this->createRelationMap($result, 'hostid', 'groupid', 'hosts_groups'); $groups = API::HostGroup()->get(array('output' => $options['selectGroups'], 'groupids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $groups, 'groups'); } // adding templates if ($options['selectParentTemplates'] !== null) { if ($options['selectParentTemplates'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'hostid', 'templateid', 'hosts_templates'); $templates = API::Template()->get(array('output' => $options['selectParentTemplates'], 'templateids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($templates, 'host'); } $result = $relationMap->mapMany($result, $templates, 'parentTemplates', $options['limitSelects']); } else { $templates = API::Template()->get(array('hostids' => $hostids, 'countOutput' => true, 'groupCount' => true)); $templates = zbx_toHash($templates, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['parentTemplates'] = isset($templates[$hostid]) ? $templates[$hostid]['rowscount'] : 0; } } } // adding items if ($options['selectItems'] !== null) { if ($options['selectItems'] != API_OUTPUT_COUNT) { $items = API::Item()->get(array('output' => $this->outputExtend($options['selectItems'], array('hostid', 'itemid')), 'hostids' => $hostids, 'nopermissions' => true, 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($items, 'name'); } $relationMap = $this->createRelationMap($items, 'hostid', 'itemid'); $items = $this->unsetExtraFields($items, array('hostid', 'itemid'), $options['selectItems']); $result = $relationMap->mapMany($result, $items, 'items', $options['limitSelects']); } else { $items = API::Item()->get(array('hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $items = zbx_toHash($items, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['items'] = isset($items[$hostid]) ? $items[$hostid]['rowscount'] : 0; } } } // adding discoveries if ($options['selectDiscoveries'] !== null) { if ($options['selectDiscoveries'] != API_OUTPUT_COUNT) { $items = API::DiscoveryRule()->get(array('output' => $this->outputExtend($options['selectDiscoveries'], array('hostid', 'itemid')), 'hostids' => $hostids, 'nopermissions' => true, 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($items, 'name'); } $relationMap = $this->createRelationMap($items, 'hostid', 'itemid'); $items = $this->unsetExtraFields($items, array('hostid', 'itemid'), $options['selectDiscoveries']); $result = $relationMap->mapMany($result, $items, 'discoveries', $options['limitSelects']); } else { $items = API::DiscoveryRule()->get(array('hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $items = zbx_toHash($items, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['discoveries'] = isset($items[$hostid]) ? $items[$hostid]['rowscount'] : 0; } } } // adding triggers if ($options['selectTriggers'] !== null) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { // discovered items $res = DBselect('SELECT i.hostid,f.triggerid' . ' FROM items i,functions f' . ' WHERE ' . dbConditionInt('i.hostid', $hostids) . ' AND i.itemid=f.itemid'); $relationMap = new CRelationMap(); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['hostid'], $relation['triggerid']); } $triggers = API::Trigger()->get(array('output' => $options['selectTriggers'], 'triggerids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($triggers, 'description'); } $result = $relationMap->mapMany($result, $triggers, 'triggers', $options['limitSelects']); } else { $triggers = API::Trigger()->get(array('hostids' => $hostids, 'countOutput' => true, 'groupCount' => true)); $triggers = zbx_toHash($triggers, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['triggers'] = isset($triggers[$hostid]) ? $triggers[$hostid]['rowscount'] : 0; } } } // adding graphs if ($options['selectGraphs'] !== null) { if ($options['selectGraphs'] != API_OUTPUT_COUNT) { // discovered items $res = DBselect('SELECT i.hostid,gi.graphid' . ' FROM items i,graphs_items gi' . ' WHERE ' . dbConditionInt('i.hostid', $hostids) . ' AND i.itemid=gi.itemid'); $relationMap = new CRelationMap(); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['hostid'], $relation['graphid']); } $graphs = API::Graph()->get(array('output' => $options['selectGraphs'], 'graphids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($graphs, 'name'); } $result = $relationMap->mapMany($result, $graphs, 'graphs', $options['limitSelects']); } else { $graphs = API::Graph()->get(array('hostids' => $hostids, 'countOutput' => true, 'groupCount' => true)); $graphs = zbx_toHash($graphs, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['graphs'] = isset($graphs[$hostid]) ? $graphs[$hostid]['rowscount'] : 0; } } } // adding http tests if ($options['selectHttpTests'] !== null) { if ($options['selectHttpTests'] != API_OUTPUT_COUNT) { $httpTests = API::HttpTest()->get(array('output' => $this->outputExtend($options['selectHttpTests'], array('hostid', 'httptestid')), 'hostids' => $hostids, 'nopermissions' => true, 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($httpTests, 'name'); } $relationMap = $this->createRelationMap($httpTests, 'hostid', 'httptestid'); $httpTests = $this->unsetExtraFields($httpTests, array('hostid', 'httptestid'), $options['selectHttpTests']); $result = $relationMap->mapMany($result, $httpTests, 'httpTests', $options['limitSelects']); } else { $httpTests = API::HttpTest()->get(array('hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $httpTests = zbx_toHash($httpTests, 'hostid'); foreach ($result as $hostId => $host) { $result[$hostId]['httpTests'] = isset($httpTests[$hostId]) ? $httpTests[$hostId]['rowscount'] : 0; } } } // adding applications if ($options['selectApplications'] !== null) { if ($options['selectApplications'] != API_OUTPUT_COUNT) { $applications = API::Application()->get(array('output' => $this->outputExtend($options['selectApplications'], array('hostid', 'applicationid')), 'hostids' => $hostids, 'nopermissions' => true, 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($applications, 'name'); } $relationMap = $this->createRelationMap($applications, 'hostid', 'applicationid'); $applications = $this->unsetExtraFields($applications, array('hostid', 'applicationid'), $options['selectApplications']); $result = $relationMap->mapMany($result, $applications, 'applications', $options['limitSelects']); } else { $applications = API::Application()->get(array('output' => $options['selectApplications'], 'hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $applications = zbx_toHash($applications, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['applications'] = isset($applications[$hostid]) ? $applications[$hostid]['rowscount'] : 0; } } } // adding macros if ($options['selectMacros'] !== null && $options['selectMacros'] != API_OUTPUT_COUNT) { $macros = API::UserMacro()->get(array('output' => $this->outputExtend($options['selectMacros'], array('hostid', 'hostmacroid')), 'hostids' => $hostids, 'preservekeys' => true)); $relationMap = $this->createRelationMap($macros, 'hostid', 'hostmacroid'); $macros = $this->unsetExtraFields($macros, array('hostid', 'hostmacroid'), $options['selectMacros']); $result = $relationMap->mapMany($result, $macros, 'macros', $options['limitSelects']); } return $result; }
/** * Get macros with values. * * @param array $data * @param array $data[<id>] any identificator * @param array $data['hostids'] the list of host ids; [<hostid1>, ...] * @param array $data['macros'] the list of user macros to resolve, ['<usermacro1>' => null, ...] * * @return array */ protected function getUserMacros(array $data) { // User macros. $hostids = []; foreach ($data as $element) { foreach ($element['hostids'] as $hostid) { $hostids[$hostid] = true; } } if (!$hostids) { return $data; } /* * @var array $host_templates * @var array $host_templates[<hostid>] array of templates */ $host_templates = []; /* * @var array $host_macros * @var array $host_macros[<hostid>] * @var array $host_macros[<hostid>][<macro>] macro base without curly braces * @var string $host_macros[<hostid>][<macro>]['value'] base macro value (without context); can be null * @var array $host_macros[<hostid>][<macro>]['contexts'] context values; ['<context1>' => '<value1>', ...] */ $host_macros = []; $user_macro_parser = new CUserMacroParser(); do { $db_hosts = API::Host()->get(['hostids' => array_keys($hostids), 'templated_hosts' => true, 'output' => ['hostid'], 'selectParentTemplates' => ['templateid'], 'selectMacros' => ['macro', 'value']]); $hostids = []; foreach ($db_hosts as $db_host) { $host_templates[$db_host['hostid']] = zbx_objectValues($db_host['parentTemplates'], 'templateid'); foreach ($db_host['macros'] as $db_macro) { if ($user_macro_parser->parse($db_macro['macro']) != CParser::PARSE_SUCCESS) { continue; } $macro = $user_macro_parser->getMacro(); $context = $user_macro_parser->getContext(); if (!array_key_exists($db_host['hostid'], $host_macros)) { $host_macros[$db_host['hostid']] = []; } if (!array_key_exists($macro, $host_macros[$db_host['hostid']])) { $host_macros[$db_host['hostid']][$macro] = ['value' => null, 'contexts' => []]; } if ($context === null) { $host_macros[$db_host['hostid']][$macro]['value'] = $db_macro['value']; } else { $host_macros[$db_host['hostid']][$macro]['contexts'][$context] = $db_macro['value']; } } } foreach ($db_hosts as $db_host) { // Only unprocessed templates will be populated. foreach ($host_templates[$db_host['hostid']] as $templateid) { if (!array_key_exists($templateid, $host_templates)) { $hostids[$templateid] = true; } } } } while ($hostids); $all_macros_resolved = true; $user_macro_parser = new CUserMacroParser(); foreach ($data as &$element) { $hostids = []; foreach ($element['hostids'] as $hostid) { $hostids[$hostid] = true; } $hostids = array_keys($hostids); natsort($hostids); foreach ($element['macros'] as $usermacro => &$value) { if ($user_macro_parser->parse($usermacro) == CParser::PARSE_SUCCESS) { $value = $this->getHostUserMacros($hostids, $user_macro_parser->getMacro(), $user_macro_parser->getContext(), $host_templates, $host_macros); if ($value['value'] === null) { $all_macros_resolved = false; } } else { // This macro cannot be resolved. $value = ['value' => $usermacro, 'value_default' => null]; } } unset($value); } unset($element); if (!$all_macros_resolved) { // Global macros. $db_global_macros = API::UserMacro()->get(['output' => ['macro', 'value'], 'globalmacro' => true]); /* * @var array $global_macros * @var array $global_macros[<macro>] macro base without curly braces * @var string $global_macros[<macro>]['value'] base macro value (without context); can be null * @var array $global_macros[<macro>]['contexts'] context values; ['<context1>' => '<value1>', ...] */ $global_macros = []; foreach ($db_global_macros as $db_global_macro) { if ($user_macro_parser->parse($db_global_macro['macro']) == CParser::PARSE_SUCCESS) { $macro = $user_macro_parser->getMacro(); $context = $user_macro_parser->getContext(); if (!array_key_exists($macro, $global_macros)) { $global_macros[$macro] = ['value' => null, 'contexts' => []]; } if ($context === null) { $global_macros[$macro]['value'] = $db_global_macro['value']; } else { $global_macros[$macro]['contexts'][$context] = $db_global_macro['value']; } } } foreach ($data as &$element) { foreach ($element['macros'] as $usermacro => &$value) { if ($value['value'] === null && $user_macro_parser->parse($usermacro) == CParser::PARSE_SUCCESS) { $macro = $user_macro_parser->getMacro(); $context = $user_macro_parser->getContext(); if (array_key_exists($macro, $global_macros)) { if ($context !== null && array_key_exists($context, $global_macros[$macro]['contexts'])) { $value['value'] = $global_macros[$macro]['contexts'][$context]; } elseif ($global_macros[$macro]['value'] !== null) { if ($context === null) { $value['value'] = $global_macros[$macro]['value']; } elseif ($value['value_default'] === null) { $value['value_default'] = $global_macros[$macro]['value']; } } } } } unset($value); } unset($element); } foreach ($data as &$element) { foreach ($element['macros'] as $usermacro => &$value) { if ($value['value'] !== null) { $value = $value['value']; } elseif ($value['value_default'] !== null) { $value = $value['value_default']; } else { // Unresolved macro. $value = $usermacro; } } unset($value); } unset($element); return $data; }
show_error_message(_('Cannot update macros')); } } /* * Display */ $form = new CForm(); $form->cleanItems(); $cmbConf = new CComboBox('configDropDown', 'adm.macros.php', 'redirect(this.options[this.selectedIndex].value);'); $cmbConf->addItems(array('adm.gui.php' => _('GUI'), 'adm.housekeeper.php' => _('Housekeeping'), 'adm.images.php' => _('Images'), 'adm.iconmapping.php' => _('Icon mapping'), 'adm.regexps.php' => _('Regular expressions'), 'adm.macros.php' => _('Macros'), 'adm.valuemapping.php' => _('Value mapping'), 'adm.workingtime.php' => _('Working time'), 'adm.triggerseverities.php' => _('Trigger severities'), 'adm.triggerdisplayoptions.php' => _('Trigger displaying options'), 'adm.other.php' => _('Other'))); $form->addItem($cmbConf); $cnf_wdgt = new CWidget(); $cnf_wdgt->addPageHeader(_('CONFIGURATION OF MACROS'), $form); $data = array(); $data['form_refresh'] = get_request('form_refresh', 0); $data['macros'] = array(); if ($data['form_refresh']) { $data['macros'] = get_request('macros', array()); } else { $data['macros'] = API::UserMacro()->get(array('output' => API_OUTPUT_EXTEND, 'globalmacro' => 1)); } if (empty($data['macros'])) { $data['macros'] = array(0 => array('macro' => '', 'value' => '')); } if ($result) { $data['macros'] = order_macros($data['macros'], 'macro'); } $macrosForm = new CView('administration.general.macros.edit', $data); $cnf_wdgt->addItem($macrosForm->render()); $cnf_wdgt->show(); require_once dirname(__FILE__) . '/include/page_footer.php';
/** * Get macros with values. * * @param array $data Macros to resolve (array(hostids => array(hostid), macros => array(macro => null))) * * @return array */ protected function getUserMacros(array $data) { /* * User macros */ $hostIds = array(); foreach ($data as $element) { foreach ($element['hostids'] as $hostId) { $hostIds[$hostId] = $hostId; } } if (!$hostIds) { return $data; } // hostid => array(templateid) $hostTemplates = array(); // hostid => array(macro => value) $hostMacros = array(); do { $dbHosts = API::Host()->get(array('hostids' => $hostIds, 'templated_hosts' => true, 'output' => array('hostid'), 'selectParentTemplates' => array('templateid'), 'selectMacros' => array('macro', 'value'))); $hostIds = array(); if ($dbHosts) { foreach ($dbHosts as $dbHost) { $hostTemplates[$dbHost['hostid']] = zbx_objectValues($dbHost['parentTemplates'], 'templateid'); foreach ($dbHost['macros'] as $dbMacro) { if (!isset($hostMacros[$dbHost['hostid']])) { $hostMacros[$dbHost['hostid']] = array(); } $hostMacros[$dbHost['hostid']][$dbMacro['macro']] = $dbMacro['value']; } } foreach ($dbHosts as $dbHost) { // only unprocessed templates will be populated foreach ($hostTemplates[$dbHost['hostid']] as $templateId) { if (!isset($hostTemplates[$templateId])) { $hostIds[$templateId] = $templateId; } } } } } while ($hostIds); $allMacrosResolved = true; foreach ($data as &$element) { $hostIds = array(); foreach ($element['hostids'] as $hostId) { $hostIds[$hostId] = $hostId; } natsort($hostIds); foreach ($element['macros'] as $macro => &$value) { $value = $this->getHostUserMacros($hostIds, $macro, $hostTemplates, $hostMacros); if ($value === null) { $allMacrosResolved = false; } } unset($value); } unset($element); if ($allMacrosResolved) { // there are no more hosts with unresolved macros return $data; } /* * Global macros */ $dbGlobalMacros = API::UserMacro()->get(array('output' => array('macro', 'value'), 'globalmacro' => true)); if ($dbGlobalMacros) { $dbGlobalMacros = zbx_toHash($dbGlobalMacros, 'macro'); $allMacrosResolved = true; foreach ($data as &$element) { foreach ($element['macros'] as $macro => &$value) { if ($value === null) { if (isset($dbGlobalMacros[$macro])) { $value = $dbGlobalMacros[$macro]['value']; } else { $allMacrosResolved = false; } } } unset($value); } unset($element); if ($allMacrosResolved) { // there are no more hosts with unresolved macros return $data; } } /* * Unresolved macros stay as is */ foreach ($data as &$element) { foreach ($element['macros'] as $macro => &$value) { if ($value === null) { $value = $macro; } } unset($value); } unset($element); return $data; }
/** * Get list of inherited macros by host ids. * * Returns an array like: * array( * '{$MACRO}' => array( * 'macro' => '{$MACRO}', * 'template' => array( <- optional * 'value' => 'template-level value' * 'templateid' => 10001, * 'name' => 'Template OS Linux' * ), * 'global' => array( <- optional * 'value' => 'global-level value' * ) * ) * ) * * @param array $hostids * * @return array */ function getInheritedMacros(array $hostids) { $user_macro_parser = new CUserMacroParser(); $all_macros = []; $global_macros = []; $db_global_macros = API::UserMacro()->get(['output' => ['macro', 'value'], 'globalmacro' => true]); foreach ($db_global_macros as $db_global_macro) { $all_macros[$db_global_macro['macro']] = true; $global_macros[$db_global_macro['macro']] = $db_global_macro['value']; } // hostid => array('name' => name, 'macros' => array(macro => value), 'templateids' => array(templateid)) $hosts = []; $templateids = $hostids; do { $db_templates = API::Template()->get(['output' => ['name'], 'selectParentTemplates' => ['templateid'], 'selectMacros' => ['macro', 'value'], 'templateids' => $templateids, 'preservekeys' => true]); $templateids = []; foreach ($db_templates as $hostid => $db_template) { $hosts[$hostid] = ['templateid' => $hostid, 'name' => $db_template['name'], 'templateids' => zbx_objectValues($db_template['parentTemplates'], 'templateid'), 'macros' => []]; /* * Global macros are overwritten by template macros and template macros are overwritten by host macros. * Macros with contexts require additional checking for contexts, since {$MACRO:} is the same as * {$MACRO:""}. */ foreach ($db_template['macros'] as $dbMacro) { if (array_key_exists($dbMacro['macro'], $all_macros)) { $hosts[$hostid]['macros'][$dbMacro['macro']] = $dbMacro['value']; $all_macros[$dbMacro['macro']] = true; } else { $user_macro_parser->parse($dbMacro['macro']); $tpl_macro = $user_macro_parser->getMacro(); $tpl_context = $user_macro_parser->getContext(); if ($tpl_context === null) { $hosts[$hostid]['macros'][$dbMacro['macro']] = $dbMacro['value']; $all_macros[$dbMacro['macro']] = true; } else { $match_found = false; foreach ($global_macros as $global_macro => $global_value) { $user_macro_parser->parse($global_macro); $gbl_macro = $user_macro_parser->getMacro(); $gbl_context = $user_macro_parser->getContext(); if ($tpl_macro === $gbl_macro && $tpl_context === $gbl_context) { $match_found = true; unset($global_macros[$global_macro], $hosts[$hostid][$global_macro], $all_macros[$global_macro]); $hosts[$hostid]['macros'][$dbMacro['macro']] = $dbMacro['value']; $all_macros[$dbMacro['macro']] = true; $global_macros[$dbMacro['macro']] = $global_value; break; } } if (!$match_found) { $hosts[$hostid]['macros'][$dbMacro['macro']] = $dbMacro['value']; $all_macros[$dbMacro['macro']] = true; } } } } } foreach ($db_templates as $db_template) { // only unprocessed templates will be populated foreach ($db_template['parentTemplates'] as $template) { if (!array_key_exists($template['templateid'], $hosts)) { $templateids[$template['templateid']] = $template['templateid']; } } } } while ($templateids); $all_macros = array_keys($all_macros); $all_templates = []; $inherited_macros = []; // resolving foreach ($all_macros as $macro) { $inherited_macro = ['macro' => $macro]; if (array_key_exists($macro, $global_macros)) { $inherited_macro['global'] = ['value' => $global_macros[$macro]]; } $templateids = $hostids; do { natsort($templateids); foreach ($templateids as $templateid) { if (array_key_exists($templateid, $hosts) && array_key_exists($macro, $hosts[$templateid]['macros'])) { $inherited_macro['template'] = ['value' => $hosts[$templateid]['macros'][$macro], 'templateid' => $hosts[$templateid]['templateid'], 'name' => $hosts[$templateid]['name'], 'rights' => PERM_READ]; if (!array_key_exists($hosts[$templateid]['templateid'], $all_templates)) { $all_templates[$hosts[$templateid]['templateid']] = []; } $all_templates[$hosts[$templateid]['templateid']][] =& $inherited_macro['template']; break 2; } } $parent_templateids = []; foreach ($templateids as $templateid) { if (array_key_exists($templateid, $hosts)) { foreach ($hosts[$templateid]['templateids'] as $templateid) { $parent_templateids[$templateid] = $templateid; } } } $templateids = $parent_templateids; } while ($templateids); $inherited_macros[$macro] = $inherited_macro; } // checking permissions if ($all_templates) { $db_templates = API::Template()->get(['output' => ['templateid'], 'templateids' => array_keys($all_templates), 'editable' => true]); foreach ($db_templates as $db_template) { foreach ($all_templates[$db_template['templateid']] as &$template) { $template['rights'] = PERM_READ_WRITE; } unset($template); } } return $inherited_macros; }
/** * Find user macros and store found ones with value to replace to $macroValues property. * * @param array $trigger * * @return mixed */ protected function expandUserMacros(array $trigger) { $macros = array(); if (preg_match_all('/' . ZBX_PREG_EXPRESSION_USER_MACROS . '/', $trigger['description'], $matches)) { $macros = API::UserMacro()->getMacros(array('macros' => $matches[1], 'triggerid' => $trigger['triggerid'])); } return $macros; }
/** * Get user macros. * * @param array $texts * @param array $options * @param int $options['hostid'] * @param int $options['triggerid'] * * @return array */ private function getUserMacros(array $texts, array $options = array()) { $matches = $this->findMacros(ZBX_PREG_EXPRESSION_USER_MACROS, $texts); if (empty($matches)) { return array(); } $options['macros'] = $matches; return API::UserMacro()->getMacros($options); }
function get_global_macro($name) { $macros = API::UserMacro()->get(array('output' => API_OUTPUT_EXTEND, 'globalmacro' => true)); $macros = zbx_toHash($macros, 'macro'); return $macros[$name]['value']; }
} // deletehe if ($dbMacros) { $result = $result && (bool) API::UserMacro()->deleteGlobal(array_keys($dbMacros)); } // create if ($macros) { $result = $result && (bool) API::UserMacro()->createGlobal(array_values($macros)); } $result = DBend($result); } show_messages($result, _('Macros updated'), _('Cannot update macros')); if ($result) { unset($_REQUEST['form_refresh']); } } /* * Display */ $data = []; if (hasRequest('form_refresh')) { $data['macros'] = getRequest('macros', []); } else { $data['macros'] = API::UserMacro()->get(['output' => ['globalmacroid', 'macro', 'value'], 'globalmacro' => true]); $data['macros'] = array_values(order_macros($data['macros'], 'macro')); } if (!$data['macros']) { $data['macros'][] = ['macro' => '', 'value' => '']; } (new CView('administration.general.macros.edit', $data))->render()->show(); require_once dirname(__FILE__) . '/include/page_footer.php';
/** * Allows to: * - remove hosts from groups; * - unlink and clear templates from hosts; * - remove macros from hosts. * * Supported $data parameters are: * - hostids - an array of host IDs to be updated * - templateids - an array of template IDs to be updated * - groupids - an array of host group IDs the hosts should be removed from * - templateids_link - an array of template IDs to unlink from the hosts * - templateids_clear - an array of template IDs to unlink and clear from the hosts * - macros - an array of macros to delete from the hosts * * @param array $data * * @return array */ public function massRemove(array $data) { $allHostIds = array_merge($data['hostids'], $data['templateids']); if (isset($data['groupids'])) { API::HostGroup()->massRemove(array('hostids' => $data['hostids'], 'templateids' => $data['templateids'], 'groupids' => zbx_toArray($data['groupids']))); } if (!empty($data['templateids_link'])) { $this->unlink(zbx_toArray($data['templateids_link']), $allHostIds); } if (isset($data['templateids_clear'])) { $this->unlink(zbx_toArray($data['templateids_clear']), $allHostIds, true); } if (isset($data['macros'])) { $hostMacros = API::UserMacro()->get(array('hostids' => $allHostIds, 'filter' => array('macro' => $data['macros']))); $hostMacroIds = zbx_objectValues($hostMacros, 'hostmacroid'); API::UserMacro()->delete($hostMacroIds); } return array($this->pkOption() => $data[$this->pkOption()]); }
/** * Update host. * * @param array $hosts An array with hosts data. * @param string $hosts[]['hostid'] Host ID. * @param string $hosts[]['host'] Host technical name (optional). * @param string $hosts[]['name'] Host visible name (optional). * @param array $hosts[]['groups'] An array of host group objects with IDs that host will be replaced to. * @param int $hosts[]['status'] Status of the host (optional). * @param array $hosts[]['interfaces'] An array of host interfaces data to be replaced. * @param int $hosts[]['interfaces']['type'] Interface type. * @param int $hosts[]['interfaces']['main'] Is this the default interface to use. * @param string $hosts[]['interfaces']['ip'] Interface IP (optional). * @param int $hosts[]['interfaces']['port'] Interface port (optional). * @param int $hosts[]['interfaces']['useip'] Interface shoud use IP (optional). * @param string $hosts[]['interfaces']['dns'] Interface shoud use DNS (optional). * @param int $hosts[]['interfaces']['bulk'] Use bulk requests for interface (optional). * @param int $hosts[]['proxy_hostid'] ID of the proxy that is used to monitor the host (optional). * @param int $hosts[]['ipmi_authtype'] IPMI authentication type (optional). * @param int $hosts[]['ipmi_privilege'] IPMI privilege (optional). * @param string $hosts[]['ipmi_username'] IPMI username (optional). * @param string $hosts[]['ipmi_password'] IPMI password (optional). * @param array $hosts[]['inventory'] An array of host inventory data (optional). * @param array $hosts[]['macros'] An array of host macros (optional). * @param string $hosts[]['macros'][]['macro'] Host macro (required if "macros" is set). * @param array $hosts[]['templates'] An array of template objects with IDs that will be linked to host (optional). * @param string $hosts[]['templates'][]['templateid'] Template ID (required if "templates" is set). * @param array $hosts[]['templates_clear'] Templates to unlink and clear from the host (optional). * @param string $hosts[]['templates_clear'][]['templateid'] Template ID (required if "templates" is set). * @param string $hosts[]['tls_connect'] Connections to host (optional). * @param string $hosts[]['tls_accept'] Connections from host (optional). * @param string $hosts[]['tls_psk_identity'] PSK identity (required if "PSK" type is set). * @param string $hosts[]['tls_psk'] PSK (required if "PSK" type is set). * @param string $hosts[]['tls_issuer'] Certificate issuer (optional). * @param string $hosts[]['tls_subject'] Certificate subject (optional). * * @return array */ public function update($hosts) { $hosts = zbx_toArray($hosts); $hostids = zbx_objectValues($hosts, 'hostid'); $db_hosts = $this->get(['output' => ['hostid', 'host', 'flags', 'tls_connect', 'tls_accept', 'tls_issuer', 'tls_subject', 'tls_psk_identity', 'tls_psk'], 'hostids' => $hostids, 'editable' => true, 'preservekeys' => true]); $this->validateUpdate($hosts, $db_hosts); $inventories = []; foreach ($hosts as &$host) { // If visible name is not given or empty it should be set to host name. if (array_key_exists('host', $host) && (!array_key_exists('name', $host) || !trim($host['name']))) { $host['name'] = $host['host']; } $host['tls_connect'] = array_key_exists('tls_connect', $host) ? $host['tls_connect'] : $db_hosts[$host['hostid']]['tls_connect']; $host['tls_accept'] = array_key_exists('tls_accept', $host) ? $host['tls_accept'] : $db_hosts[$host['hostid']]['tls_accept']; // Clean PSK fields. if ($host['tls_connect'] != HOST_ENCRYPTION_PSK && ($host['tls_accept'] & HOST_ENCRYPTION_PSK) != HOST_ENCRYPTION_PSK) { $host['tls_psk_identity'] = ''; $host['tls_psk'] = ''; } // Clean certificate fields. if ($host['tls_connect'] != HOST_ENCRYPTION_CERTIFICATE && ($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) != HOST_ENCRYPTION_CERTIFICATE) { $host['tls_issuer'] = ''; $host['tls_subject'] = ''; } // Fetch fields required to update host inventory. if (array_key_exists('inventory', $host)) { $inventory = $host['inventory']; $inventory['hostid'] = $host['hostid']; $inventories[] = $inventory; } } unset($host); $inventories = $this->extendObjects('host_inventory', $inventories, ['inventory_mode']); $inventories = zbx_toHash($inventories, 'hostid'); $macros = []; foreach ($hosts as &$host) { if (isset($host['macros'])) { $macros[$host['hostid']] = $host['macros']; unset($host['macros']); } } unset($host); if ($macros) { API::UserMacro()->replaceMacros($macros); } foreach ($hosts as $host) { // extend host inventory with the required data if (isset($host['inventory']) && $host['inventory']) { $inventory = $inventories[$host['hostid']]; // if no host inventory record exists in the DB, it's disabled if (!isset($inventory['inventory_mode'])) { $inventory['inventory_mode'] = HOST_INVENTORY_DISABLED; } $host['inventory'] = $inventory; } $data = $host; $data['hosts'] = $host; $result = $this->massUpdate($data); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Host update failed.')); } } return ['hostids' => $hostids]; }
function explode_exp($expression, $html = false, $resolve_macro = false, $src_host = null, $dst_host = null) { $exp = !$html ? '' : array(); $trigger = array(); for ($i = 0, $state = '', $max = zbx_strlen($expression); $i < $max; $i++) { if ($expression[$i] == '{') { if ($expression[$i + 1] == '$') { $usermacro = ''; $state = 'USERMACRO'; } elseif ($expression[$i + 1] == '#') { $lldmacro = ''; $state = 'LLDMACRO'; } else { $functionid = ''; $state = 'FUNCTIONID'; continue; } } elseif ($expression[$i] == '}') { if ($state == 'USERMACRO') { $usermacro .= '}'; if ($resolve_macro) { $function_data['expression'] = $usermacro; $function_data = API::UserMacro()->resolveTrigger($function_data); $usermacro = $function_data['expression']; } if ($html) { array_push($exp, $usermacro); } else { $exp .= $usermacro; } $state = ''; continue; } elseif ($state == 'LLDMACRO') { $lldmacro .= '}'; if ($html) { array_push($exp, $lldmacro); } else { $exp .= $lldmacro; } $state = ''; continue; } elseif ($functionid == 'TRIGGER.VALUE') { if ($html) { array_push($exp, '{' . $functionid . '}'); } else { $exp .= '{' . $functionid . '}'; } $state = ''; continue; } $sql = 'SELECT h.host,i.itemid,i.key_,f.function,f.triggerid,f.parameter,i.itemid,i.status,i.type,i.flags' . ' FROM items i,functions f,hosts h' . ' WHERE f.functionid=' . $functionid . ' AND i.itemid=f.itemid' . ' AND h.hostid=i.hostid'; if (is_numeric($functionid) && ($function_data = DBfetch(DBselect($sql)))) { if ($resolve_macro) { $trigger = $function_data; $function_data = API::UserMacro()->resolveItem($function_data); $function_data['expression'] = $function_data['parameter']; $function_data = API::UserMacro()->resolveTrigger($function_data); $function_data['parameter'] = $function_data['expression']; } if (!is_null($src_host) && !is_null($dst_host) && strcmp($src_host, $function_data['host']) == 0) { $function_data['host'] = $dst_host; } if ($html) { $style = $function_data['status'] == ITEM_STATUS_DISABLED ? 'disabled' : 'unknown'; if ($function_data['status'] == ITEM_STATUS_ACTIVE) { $style = 'enabled'; } if ($function_data['flags'] == ZBX_FLAG_DISCOVERY_CREATED || $function_data['type'] == ITEM_TYPE_HTTPTEST) { $link = new CSpan($function_data['host'] . ':' . $function_data['key_'], $style); } elseif ($function_data['flags'] == ZBX_FLAG_DISCOVERY_PROTOTYPE) { $link = new CLink($function_data['host'] . ':' . $function_data['key_'], 'disc_prototypes.php?form=update&itemid=' . $function_data['itemid'] . '&parent_discoveryid=' . $trigger['discoveryRuleid'] . '&switch_node=' . id2nodeid($function_data['itemid']), $style); } else { $link = new CLink($function_data['host'] . ':' . $function_data['key_'], 'items.php?form=update&itemid=' . $function_data['itemid'] . '&switch_node=' . id2nodeid($function_data['itemid']), $style); } array_push($exp, array('{', $link, '.', bold($function_data['function'] . '('), $function_data['parameter'], bold(')'), '}')); } else { $exp .= '{' . $function_data['host'] . ':' . $function_data['key_'] . '.' . $function_data['function'] . '(' . $function_data['parameter'] . ')}'; } } else { if ($html) { array_push($exp, new CSpan('*ERROR*', 'on')); } else { $exp .= '*ERROR*'; } } $state = ''; continue; } switch ($state) { case 'FUNCTIONID': $functionid .= $expression[$i]; break; case 'USERMACRO': $usermacro .= $expression[$i]; break; case 'LLDMACRO': $lldmacro .= $expression[$i]; break; default: if ($html) { array_push($exp, $expression[$i]); } else { $exp .= $expression[$i]; } } } return $exp; }
/** * Update template. * * @param array $templates * * @return array */ public function update(array $templates) { $templates = zbx_toArray($templates); $this->validateUpdate($templates); $macros = array(); foreach ($templates as $template) { // if visible name is not given or empty it should be set to host name if ((!isset($template['name']) || zbx_empty(trim($template['name']))) && isset($template['host'])) { $template['name'] = $template['host']; } $templateCopy = $template; $template['templates_link'] = isset($template['templates']) ? $template['templates'] : null; if (isset($template['macros'])) { $macros[$template['templateid']] = $template['macros']; unset($template['macros']); } unset($template['templates'], $template['templateid'], $templateCopy['templates']); $template['templates'] = array($templateCopy); if (!$this->massUpdate($template)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Failed to update template.')); } } if ($macros) { API::UserMacro()->replaceMacros($macros); } return array('templateids' => zbx_objectValues($templates, 'templateid')); }
/** * Process screen. * * @return CDiv (screen inside container) */ public function get() { $this->dataId = 'discovery'; $sort_field = $this->data['sort']; $sort_order = $this->data['sortorder']; $druleid = $this->data['druleid']; // discovery rules $options = ['output' => ['druleid', 'name'], 'selectDHosts' => ['dhostid', 'status', 'lastup', 'lastdown'], 'filter' => ['status' => DRULE_STATUS_ACTIVE]]; if ($druleid > 0) { $options['druleids'] = $druleid; // set selected discovery rule id } $drules = API::DRule()->get($options); if ($drules) { order_result($drules, 'name'); } // discovery services $options = ['selectHosts' => ['hostid', 'name', 'status'], 'output' => ['dserviceid', 'type', 'key_', 'port', 'status', 'lastup', 'lastdown', 'ip', 'dns'], 'sortfield' => $sort_field, 'sortorder' => $sort_order, 'limitSelects' => 1]; if ($druleid > 0) { $options['druleids'] = $druleid; } else { $options['druleids'] = zbx_objectValues($drules, 'druleid'); } $dservices = API::DService()->get($options); // user macros $macros = API::UserMacro()->get(['output' => ['macro', 'value'], 'globalmacro' => true]); $macros = zbx_toHash($macros, 'macro'); // services $services = []; foreach ($dservices as $dservice) { $key_ = $dservice['key_']; if ($key_ !== '') { if (array_key_exists($key_, $macros)) { $key_ = $macros[$key_]['value']; } $key_ = ': ' . $key_; } $service_name = discovery_check_type2str($dservice['type']) . discovery_port2str($dservice['type'], $dservice['port']) . $key_; $services[$service_name] = 1; } ksort($services); // discovery services to hash $dservices = zbx_toHash($dservices, 'dserviceid'); // discovery hosts $dhosts = API::DHost()->get(['druleids' => zbx_objectValues($drules, 'druleid'), 'selectDServices' => ['dserviceid', 'ip', 'dns', 'type', 'status', 'key_'], 'output' => ['dhostid', 'lastdown', 'lastup', 'druleid']]); $dhosts = zbx_toHash($dhosts, 'dhostid'); $header = [make_sorting_header(_('Discovered device'), 'ip', $sort_field, $sort_order, 'zabbix.php?action=discovery.view'), _('Monitored host'), _('Uptime') . '/' . _('Downtime')]; foreach ($services as $name => $foo) { $header[] = (new CColHeader($name))->addClass('vertical_rotation'); } // create table $table = (new CTableInfo())->makeVerticalRotation()->setHeader($header); foreach ($drules as $drule) { $discovery_info = []; foreach ($drule['dhosts'] as $dhost) { if ($dhost['status'] == DHOST_STATUS_DISABLED) { $hclass = 'disabled'; $htime = $dhost['lastdown']; } else { $hclass = 'enabled'; $htime = $dhost['lastup']; } // $primary_ip stores the primary host ip of the dhost $primary_ip = ''; foreach ($dhosts[$dhost['dhostid']]['dservices'] as $dservice) { $dservice = $dservices[$dservice['dserviceid']]; $hostName = ''; $host = reset($dservices[$dservice['dserviceid']]['hosts']); if (!is_null($host)) { $hostName = $host['name']; } if ($primary_ip !== '') { if ($primary_ip === $dservice['ip']) { $htype = 'primary'; } else { $htype = 'slave'; } } else { $primary_ip = $dservice['ip']; $htype = 'primary'; } if (!array_key_exists($dservice['ip'], $discovery_info)) { $discovery_info[$dservice['ip']] = ['ip' => $dservice['ip'], 'dns' => $dservice['dns'], 'type' => $htype, 'class' => $hclass, 'host' => $hostName, 'time' => $htime]; } if ($dservice['status'] == DSVC_STATUS_DISABLED) { $class = ZBX_STYLE_INACTIVE_BG; $time = 'lastdown'; } else { $class = ZBX_STYLE_ACTIVE_BG; $time = 'lastup'; } $key_ = $dservice['key_']; if ($key_ !== '') { if (array_key_exists($key_, $macros)) { $key_ = $macros[$key_]['value']; } $key_ = NAME_DELIMITER . $key_; } $service_name = discovery_check_type2str($dservice['type']) . discovery_port2str($dservice['type'], $dservice['port']) . $key_; $discovery_info[$dservice['ip']]['services'][$service_name] = ['class' => $class, 'time' => $dservice[$time]]; } } if ($druleid == 0 && $discovery_info) { $col = new CCol([bold($drule['name']), SPACE . '(' . _n('%d device', '%d devices', count($discovery_info)) . ')']); $col->setColSpan(count($services) + 3); $table->addRow($col); } order_result($discovery_info, $sort_field, $sort_order); foreach ($discovery_info as $ip => $h_data) { $dns = $h_data['dns'] == '' ? '' : ' (' . $h_data['dns'] . ')'; $row = [$h_data['type'] == 'primary' ? (new CSpan($ip . $dns))->addClass($h_data['class']) : new CSpan(SPACE . SPACE . $ip . $dns), new CSpan(array_key_exists('host', $h_data) ? $h_data['host'] : ''), (new CSpan($h_data['time'] == 0 || $h_data['type'] === 'slave' ? '' : convert_units(['value' => time() - $h_data['time'], 'units' => 'uptime'])))->addClass($h_data['class'])]; foreach ($services as $name => $foo) { $class = null; $time = SPACE; $hint = (new CDiv(SPACE))->addClass($class); $hint_table = null; if (array_key_exists($name, $h_data['services'])) { $class = $h_data['services'][$name]['class']; $time = $h_data['services'][$name]['time']; $hint_table = (new CTableInfo())->setAttribute('style', 'width: auto;'); if ($class == ZBX_STYLE_ACTIVE_BG) { $hint_table->setHeader(_('Uptime')); } else { $hint_table->setHeader(_('Downtime')); } $hint_table->addRow((new CCol(zbx_date2age($h_data['services'][$name]['time'])))->addClass($class)); } $column = (new CCol($hint))->addClass($class); if (!is_null($hint_table)) { $column->setHint($hint_table); } $row[] = $column; } $table->addRow($row); } } return $this->getOutput($table, true, $this->data); }
/** * Expand macros inside key name and return it * Example: * key: 'test.key[a, b, "{HOSTNAME}"]' * name: 'Test item $1, $2, $3' * result: 'Test item a, b, Zabbix-server' * * @param array $item * @param string $item['key_'] * @param string $item['itemid'] * @param string $item['name'] * * @return string */ function itemName($item) { $name = $item['name']; // if item name contains $1..$9 macros, we need to expand them if (preg_match('/\\$[1-9]/', $name)) { $key = resolveItemKeyMacros($item); // parsing key to get the parameters out of it $ItemKey = new CItemKey($key); if ($ItemKey->isValid()) { $keyParameters = $ItemKey->getParameters(); $searchOffset = 0; while (preg_match('/\\$[1-9]/', $name, $matches, PREG_OFFSET_CAPTURE, $searchOffset)) { // matches[0][0] - matched param, [1] - second character of it $paramNumber = $matches[0][0][1] - 1; $replaceString = isset($keyParameters[$paramNumber]) ? $keyParameters[$paramNumber] : ''; $name = substr_replace($name, $replaceString, $matches[0][1], 2); $searchOffset = $matches[0][1] + strlen($replaceString); } } } if (preg_match_all('/' . ZBX_PREG_EXPRESSION_USER_MACROS . '/', $name, $arr)) { $macros = API::UserMacro()->getMacros(array('macros' => $arr[1], 'itemid' => $item['itemid'])); $name = str_replace(array_keys($macros), array_values($macros), $name); } return $name; }