protected function doAction() { $script = []; $this->getInputs($script, ['scriptid', 'name', 'type', 'execute_on', 'command', 'description', 'usrgrpid', 'groupid', 'host_access']); $script['confirmation'] = $this->getInput('confirmation', ''); if ($this->getInput('type', ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) == ZBX_SCRIPT_TYPE_IPMI && $this->hasInput('commandipmi')) { $script['command'] = $this->getInput('commandipmi'); } if ($this->getInput('hgstype', 1) == 0) { $script['groupid'] = 0; } DBstart(); $result = API::Script()->update($script); if ($result) { $scriptId = reset($result['scriptids']); add_audit(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_SCRIPT, 'Name [' . $this->getInput('name', '') . '] id [' . $scriptId . ']'); } $result = DBend($result); if ($result) { $response = new CControllerResponseRedirect('zabbix.php?action=script.list&uncheck=1'); $response->setMessageOk(_('Script updated')); } else { $response = new CControllerResponseRedirect('zabbix.php?action=script.edit&scriptid=' . $this->getInput('scriptid')); $response->setFormData($this->getInputAll()); $response->setMessageError(_('Cannot update script')); } $this->setResponse($response); }
protected function doAction() { $sortField = $this->getInput('sort', CProfile::get('web.scripts.php.sort', 'name')); $sortOrder = $this->getInput('sortorder', CProfile::get('web.scripts.php.sortorder', ZBX_SORT_UP)); CProfile::update('web.scripts.php.sort', $sortField, PROFILE_TYPE_STR); CProfile::update('web.scripts.php.sortorder', $sortOrder, PROFILE_TYPE_STR); $config = select_config(); $data = ['uncheck' => $this->hasInput('uncheck'), 'sort' => $sortField, 'sortorder' => $sortOrder]; // list of scripts $data['scripts'] = API::Script()->get(['output' => ['scriptid', 'name', 'command', 'host_access', 'usrgrpid', 'groupid', 'type', 'execute_on'], 'editable' => true, 'limit' => $config['search_limit'] + 1]); // sorting & paging order_result($data['scripts'], $sortField, $sortOrder); $url = (new CUrl('zabbix.php'))->setArgument('action', 'script.list'); $data['paging'] = getPagingLine($data['scripts'], $sortOrder, $url); // find script host group name and user group name. set to '' if all host/user groups used. $usrgrpids = []; $groupids = []; foreach ($data['scripts'] as &$script) { $script['userGroupName'] = null; // all user groups $script['hostGroupName'] = null; // all host groups if ($script['usrgrpid'] != 0) { $usrgrpids[] = $script['usrgrpid']; } if ($script['groupid'] != 0) { $groupids[] = $script['groupid']; } } unset($script); if ($usrgrpids) { $userGroups = API::UserGroup()->get(['output' => ['name'], 'usrgrpids' => $usrgrpids, 'preservekeys' => true]); foreach ($data['scripts'] as &$script) { if ($script['usrgrpid'] != 0 && array_key_exists($script['usrgrpid'], $userGroups)) { $script['userGroupName'] = $userGroups[$script['usrgrpid']]['name']; } unset($script['usrgrpid']); } unset($script); } if ($groupids) { $hostGroups = API::HostGroup()->get(['output' => ['name'], 'groupids' => $groupids, 'preservekeys' => true]); foreach ($data['scripts'] as &$script) { if ($script['groupid'] != 0 && array_key_exists($script['groupid'], $hostGroups)) { $script['hostGroupName'] = $hostGroups[$script['groupid']]['name']; } unset($script['groupid']); } unset($script); } $response = new CControllerResponseData($data); $response->setTitle(_('Configuration of scripts')); $this->setResponse($response); }
function getActionMapBySysmap($sysmap) { $action_map = new CAreaMap('links' . $sysmap['sysmapid']); $areas = populateFromMapAreas($sysmap); $map_info = getSelementsInfo($sysmap); processAreasCoordinates($sysmap, $areas, $map_info); $hostids = array(); foreach ($sysmap['selements'] as $sid => &$selement) { if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) { $hostids[$selement['elementid']] = $selement['elementid']; // expanding hosts url macros again as some hosts were added from hostgroup areeas // and automatic expanding only happens for elements that are defined for map in db foreach ($selement['urls'] as $urlid => $url) { $selement['urls'][$urlid]['url'] = str_replace('{HOST.ID}', $selement['elementid'], $url['url']); } } if ($selement['elementsubtype'] == SYSMAP_ELEMENT_SUBTYPE_HOST_GROUP_ELEMENTS) { unset($sysmap['selements'][$sid]); } } unset($selement); if (count($hostids)) { $scripts_by_hosts = API::Script()->getScriptsByHosts($hostids); } $hosts = API::Host()->get(array('nodeids' => get_current_nodeid(true), 'hostids' => $hostids, 'output' => array('status'), 'nopermissions' => true, 'preservekeys' => true, 'selectScreens' => API_OUTPUT_COUNT)); foreach ($sysmap['selements'] as $elem) { $back = get_png_by_selement($map_info[$elem['selementid']]); $area = new CArea(array($elem['x'], $elem['y'], $elem['x'] + imagesx($back), $elem['y'] + imagesy($back)), '', '', 'rect'); $area->addClass('menu-map'); // pop up menu order_result($elem['urls'], 'name'); $menuData = array('urls' => array_values($elem['urls']), 'elementId' => $elem['elementid'], 'elementType' => $elem['elementtype'], 'scripts' => array(), 'hasScreens' => false, 'isMonitored' => false); if ($elem['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) { $host = $hosts[$elem['elementid']]; $menuData['scripts'] = $scripts_by_hosts[$elem['elementid']]; $menuData['hasScreens'] = (bool) $host['screens']; $menuData['isMonitored'] = $hosts[$elem['elementid']]['status'] == HOST_STATUS_MONITORED; } $area->setAttribute('data-menu', $menuData); $action_map->addItem($area); } return $action_map; }
protected function doAction() { $scriptids = $this->getInput('scriptids'); DBstart(); $result = API::Script()->delete($scriptids); if ($result) { foreach ($scriptids as $scriptid) { add_audit(AUDIT_ACTION_DELETE, AUDIT_RESOURCE_SCRIPT, _('Script') . ' [' . $scriptid . ']'); } } $result = DBend($result); $deleted = count($scriptids); $response = new CControllerResponseRedirect('zabbix.php?action=script.list&uncheck=1'); if ($result) { $response->setMessageOk(_n('Script deleted', 'Scripts deleted', $deleted)); } else { $response->setMessageError(_n('Cannot delete script', 'Cannot delete scripts', $deleted)); } $this->setResponse($response); }
protected function doAction() { // default values $data = ['sid' => $this->getUserSID(), 'scriptid' => 0, 'name' => '', 'type' => ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT, 'execute_on' => ZBX_SCRIPT_EXECUTE_ON_AGENT, 'command' => '', 'commandipmi' => '', 'description' => '', 'usrgrpid' => 0, 'groupid' => 0, 'host_access' => 0, 'confirmation' => '', 'enable_confirmation' => 0, 'hgstype' => 0]; // get values from the dabatase if ($this->hasInput('scriptid')) { $scripts = API::Script()->get(['output' => ['scriptid', 'name', 'type', 'execute_on', 'command', 'description', 'usrgrpid', 'groupid', 'host_access', 'confirmation'], 'scriptids' => $this->getInput('scriptid')]); $script = $scripts[0]; $data['scriptid'] = $script['scriptid']; $data['name'] = $script['name']; $data['type'] = $script['type']; $data['execute_on'] = $script['execute_on']; $data['command'] = $script['type'] == ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT ? $script['command'] : ''; $data['commandipmi'] = $script['type'] == ZBX_SCRIPT_TYPE_IPMI ? $script['command'] : ''; $data['description'] = $script['description']; $data['usrgrpid'] = $script['usrgrpid']; $data['groupid'] = $script['groupid']; $data['host_access'] = $script['host_access']; $data['confirmation'] = $script['confirmation']; $data['enable_confirmation'] = $script['confirmation'] !== ''; $data['hgstype'] = $script['groupid'] != 0 ? 1 : 0; } // overwrite with input variables $this->getInputs($data, ['name', 'type', 'execute_on', 'command', 'commandipmi', 'description', 'usrgrpid', 'groupid', 'host_access', 'confirmation', 'enable_confirmation', 'hgstype']); // get host group if ($data['groupid'] == 0) { $data['hostgroup'] = null; } else { $hostgroups = API::HostGroup()->get(['groupids' => [$data['groupid']], 'output' => ['groupid', 'name']]); $hostgroup = $hostgroups[0]; $data['hostgroup'][] = ['id' => $hostgroup['groupid'], 'name' => $hostgroup['name']]; } // get list of user groups $usergroups = API::UserGroup()->get(['output' => ['usrgrpid', 'name']]); order_result($usergroups, 'name'); $data['usergroups'] = $usergroups; $response = new CControllerResponseData($data); $response->setTitle(_('Configuration of scripts')); $this->setResponse($response); }
/** * Generates array with HTML items representing operation with description * * @param int $type short or long description, use const. SHORT_DESCRIPTION and LONG_DESCRIPTION * @param array $data * @param int $data['operationtype'] type of operation: OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND, ... * @param int $data['opmessage']['mediatypeid'] type id of message media * @param bool $data['opmessage']['default_msg'] should default message be used * @param bool $data['opmessage']['operationid'] if true $data['operationid'] will be used to retrieve default messages from DB * @param string $data['opmessage']['subject'] subject of message * @param string $data['opmessage']['message'] message it self * @param array $data['opmessage_usr'] list of user ids if OPERATION_TYPE_MESSAGE * @param array $data['opmessage_grp'] list of group ids if OPERATION_TYPE_MESSAGE * @param array $data['opcommand_grp'] list of group ids if OPERATION_TYPE_COMMAND * @param array $data['opcommand_hst'] list of host ids if OPERATION_TYPE_COMMAND * @param array $data['opgroup'] list of group ids if OPERATION_TYPE_GROUP_ADD or OPERATION_TYPE_GROUP_REMOVE * @param array $data['optemplate'] list of template ids if OPERATION_TYPE_TEMPLATE_ADD or OPERATION_TYPE_TEMPLATE_REMOVE * @param int $data['operationid'] id of operation * @param int $data['opcommand']['type'] type of command: ZBX_SCRIPT_TYPE_IPMI, ZBX_SCRIPT_TYPE_SSH, ... * @param string $data['opcommand']['command'] actual command * @param int $data['opcommand']['scriptid'] script id used if $data['opcommand']['type'] is ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT * * @return array */ function get_operation_descr($type, $data) { $result = array(); if ($type == SHORT_DESCRIPTION) { switch ($data['operationtype']) { case OPERATION_TYPE_MESSAGE: $mediaTypes = API::Mediatype()->get(array('mediatypeids' => $data['opmessage']['mediatypeid'], 'output' => array('description'))); if (empty($mediaTypes)) { $mediatype = _('all media'); } else { $mediatype = reset($mediaTypes); $mediatype = $mediatype['description']; } if (!empty($data['opmessage_usr'])) { $users = API::User()->get(array('userids' => zbx_objectValues($data['opmessage_usr'], 'userid'), 'output' => array('userid', 'alias', 'name', 'surname'))); order_result($users, 'alias'); foreach ($users as $user) { $fullnames[] = getUserFullname($user); } $result[] = bold(_('Send message to users') . NAME_DELIMITER); $result[] = array(implode(', ', $fullnames), SPACE, _('via'), SPACE, $mediatype); $result[] = BR(); } if (!empty($data['opmessage_grp'])) { $usrgrps = API::UserGroup()->get(array('usrgrpids' => zbx_objectValues($data['opmessage_grp'], 'usrgrpid'), 'output' => API_OUTPUT_EXTEND)); order_result($usrgrps, 'name'); $result[] = bold(_('Send message to user groups') . NAME_DELIMITER); $result[] = array(implode(', ', zbx_objectValues($usrgrps, 'name')), SPACE, _('via'), SPACE, $mediatype); $result[] = BR(); } break; case OPERATION_TYPE_COMMAND: if (!isset($data['opcommand_grp'])) { $data['opcommand_grp'] = array(); } if (!isset($data['opcommand_hst'])) { $data['opcommand_hst'] = array(); } $hosts = API::Host()->get(array('hostids' => zbx_objectValues($data['opcommand_hst'], 'hostid'), 'output' => array('hostid', 'name'))); foreach ($data['opcommand_hst'] as $cmd) { if ($cmd['hostid'] != 0) { continue; } $result[] = array(bold(_('Run remote commands on current host')), BR()); break; } if (!empty($hosts)) { order_result($hosts, 'name'); $result[] = bold(_('Run remote commands on hosts') . NAME_DELIMITER); $result[] = array(implode(', ', zbx_objectValues($hosts, 'name')), BR()); } $groups = API::HostGroup()->get(array('groupids' => zbx_objectValues($data['opcommand_grp'], 'groupid'), 'output' => array('groupid', 'name'))); if (!empty($groups)) { order_result($groups, 'name'); $result[] = bold(_('Run remote commands on host groups') . NAME_DELIMITER); $result[] = array(implode(', ', zbx_objectValues($groups, 'name')), BR()); } break; case OPERATION_TYPE_HOST_ADD: $result[] = array(bold(_('Add host')), BR()); break; case OPERATION_TYPE_HOST_REMOVE: $result[] = array(bold(_('Remove host')), BR()); break; case OPERATION_TYPE_HOST_ENABLE: $result[] = array(bold(_('Enable host')), BR()); break; case OPERATION_TYPE_HOST_DISABLE: $result[] = array(bold(_('Disable host')), BR()); break; case OPERATION_TYPE_GROUP_ADD: case OPERATION_TYPE_GROUP_REMOVE: if (!isset($data['opgroup'])) { $data['opgroup'] = array(); } $groups = API::HostGroup()->get(array('groupids' => zbx_objectValues($data['opgroup'], 'groupid'), 'output' => array('groupid', 'name'))); if (!empty($groups)) { order_result($groups, 'name'); if (OPERATION_TYPE_GROUP_ADD == $data['operationtype']) { $result[] = bold(_('Add to host groups') . NAME_DELIMITER); } else { $result[] = bold(_('Remove from host groups') . NAME_DELIMITER); } $result[] = array(implode(', ', zbx_objectValues($groups, 'name')), BR()); } break; case OPERATION_TYPE_TEMPLATE_ADD: case OPERATION_TYPE_TEMPLATE_REMOVE: if (!isset($data['optemplate'])) { $data['optemplate'] = array(); } $templates = API::Template()->get(array('templateids' => zbx_objectValues($data['optemplate'], 'templateid'), 'output' => array('hostid', 'name'))); if (!empty($templates)) { order_result($templates, 'name'); if (OPERATION_TYPE_TEMPLATE_ADD == $data['operationtype']) { $result[] = bold(_('Link to templates') . NAME_DELIMITER); } else { $result[] = bold(_('Unlink from templates') . NAME_DELIMITER); } $result[] = array(implode(', ', zbx_objectValues($templates, 'name')), BR()); } break; default: } } else { switch ($data['operationtype']) { case OPERATION_TYPE_MESSAGE: if (isset($data['opmessage']['default_msg']) && !empty($data['opmessage']['default_msg'])) { if (isset($_REQUEST['def_shortdata']) && isset($_REQUEST['def_longdata'])) { $result[] = array(bold(_('Subject') . NAME_DELIMITER), BR(), zbx_nl2br($_REQUEST['def_shortdata'])); $result[] = array(bold(_('Message') . NAME_DELIMITER), BR(), zbx_nl2br($_REQUEST['def_longdata'])); } elseif (isset($data['opmessage']['operationid'])) { $sql = 'SELECT a.def_shortdata,a.def_longdata ' . ' FROM actions a,operations o ' . ' WHERE a.actionid=o.actionid ' . ' AND o.operationid=' . zbx_dbstr($data['operationid']); if ($rows = DBfetch(DBselect($sql, 1))) { $result[] = array(bold(_('Subject') . NAME_DELIMITER), BR(), zbx_nl2br($rows['def_shortdata'])); $result[] = array(bold(_('Message') . NAME_DELIMITER), BR(), zbx_nl2br($rows['def_longdata'])); } } } else { $result[] = array(bold(_('Subject') . NAME_DELIMITER), BR(), zbx_nl2br($data['opmessage']['subject'])); $result[] = array(bold(_('Message') . NAME_DELIMITER), BR(), zbx_nl2br($data['opmessage']['message'])); } break; case OPERATION_TYPE_COMMAND: switch ($data['opcommand']['type']) { case ZBX_SCRIPT_TYPE_IPMI: $result[] = array(bold(_('Run IPMI command') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); break; case ZBX_SCRIPT_TYPE_SSH: $result[] = array(bold(_('Run SSH commands') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); break; case ZBX_SCRIPT_TYPE_TELNET: $result[] = array(bold(_('Run TELNET commands') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); break; case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT: if ($data['opcommand']['execute_on'] == ZBX_SCRIPT_EXECUTE_ON_AGENT) { $result[] = array(bold(_('Run custom commands on Zabbix agent') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); } else { $result[] = array(bold(_('Run custom commands on Zabbix server') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); } break; case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT: $userScripts = API::Script()->get(array('scriptids' => $data['opcommand']['scriptid'], 'output' => API_OUTPUT_EXTEND)); $userScript = reset($userScripts); $result[] = array(bold(_('Run global script') . NAME_DELIMITER), italic($userScript['name'])); break; default: $result[] = array(bold(_('Run commands') . NAME_DELIMITER), BR(), italic(zbx_nl2br($data['opcommand']['command']))); } break; default: } } return $result; }
/** * Delete UserGroups. * * @param array $usrgrpids * @return boolean */ public function delete($usrgrpids) { $usrgrpids = zbx_toArray($usrgrpids); $dbUsrgrps = $this->get(array('output' => array('usrgrpid', 'name'), 'usrgrpids' => $usrgrpids, 'preservekeys' => true)); if (empty($usrgrpids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } if (USER_TYPE_SUPER_ADMIN != self::$userData['type']) { // GETTEXT: API exception self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can delete user groups.')); } // check, if this user group is used in one of the scripts. If so, it cannot be deleted $dbScripts = API::Script()->get(array('output' => array('scriptid', 'name', 'usrgrpid'), 'usrgrpids' => $usrgrpids, 'nopermissions' => true)); if (!empty($dbScripts)) { foreach ($dbScripts as $snum => $script) { if ($script['usrgrpid'] == 0) { continue; } self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group "%1$s" is used in script "%2$s".', $dbUsrgrps[$script['usrgrpid']]['name'], $script['name'])); } } // check, if this user group is used in the config. If so, it cannot be deleted $config = select_config(); if (isset($dbUsrgrps[$config['alert_usrgrpid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group [%s] is used in configuration for database down messages.', $dbUsrgrps[$config['alert_usrgrpid']]['name'])); } // delete action operation msg $operationids = array(); $sql = 'SELECT DISTINCT om.operationid' . ' FROM opmessage_grp om' . ' WHERE ' . dbConditionInt('om.usrgrpid', $usrgrpids); $dbOperations = DBselect($sql); while ($dbOperation = DBfetch($dbOperations)) { $operationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('opmessage_grp', array('usrgrpid' => $usrgrpids)); // delete empty operations $delOperationids = array(); $sql = 'SELECT DISTINCT o.operationid' . ' FROM operations o' . ' WHERE ' . dbConditionInt('o.operationid', $operationids) . ' AND NOT EXISTS(SELECT om.opmessage_grpid FROM opmessage_grp om WHERE om.operationid=o.operationid)'; $dbOperations = DBselect($sql); while ($dbOperation = DBfetch($dbOperations)) { $delOperationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('operations', array('operationid' => $delOperationids)); DB::delete('rights', array('groupid' => $usrgrpids)); DB::delete('users_groups', array('usrgrpid' => $usrgrpids)); DB::delete('usrgrp', array('usrgrpid' => $usrgrpids)); return array('usrgrpids' => $usrgrpids); }
/** * Retrieve overview table object for items. * * @param array $hostIds * @param string $application name of application to filter * @param int $viewMode * * @return CTableInfo */ function getItemsDataOverview($hostIds, $application, $viewMode) { $sqlFrom = ''; $sqlWhere = ''; if ($application !== '') { $sqlFrom = 'applications a,items_applications ia,'; $sqlWhere = ' AND i.itemid=ia.itemid AND a.applicationid=ia.applicationid AND a.name=' . zbx_dbstr($application); } $dbItems = DBfetchArray(DBselect('SELECT DISTINCT h.hostid,h.name AS hostname,i.itemid,i.key_,i.value_type,i.units,' . 'i.name,t.priority,i.valuemapid,t.value AS tr_value,t.triggerid' . ' FROM hosts h,' . $sqlFrom . 'items i' . ' LEFT JOIN functions f ON f.itemid=i.itemid' . ' LEFT JOIN triggers t ON t.triggerid=f.triggerid AND t.status=' . TRIGGER_STATUS_ENABLED . ' WHERE ' . dbConditionInt('h.hostid', $hostIds) . ' AND h.status=' . HOST_STATUS_MONITORED . ' AND h.hostid=i.hostid' . ' AND i.status=' . ITEM_STATUS_ACTIVE . ' AND ' . dbConditionInt('i.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)) . $sqlWhere)); $dbItems = CMacrosResolverHelper::resolveItemNames($dbItems); CArrayHelper::sort($dbItems, array(array('field' => 'name_expanded', 'order' => ZBX_SORT_UP), array('field' => 'itemid', 'order' => ZBX_SORT_UP))); // fetch latest values $history = Manager::History()->getLast(zbx_toHash($dbItems, 'itemid'), 1, ZBX_HISTORY_PERIOD); // fetch data for the host JS menu $hosts = API::Host()->get(array('output' => array('name', 'hostid', 'status'), 'monitored_hosts' => true, 'hostids' => $hostIds, 'with_monitored_items' => true, 'preservekeys' => true, 'selectScreens' => $viewMode == STYLE_LEFT ? API_OUTPUT_COUNT : null)); $items = array(); foreach ($dbItems as $dbItem) { $name = $dbItem['name_expanded']; $dbItem['hostname'] = get_node_name_by_elid($dbItem['hostid'], null, NAME_DELIMITER) . $dbItem['hostname']; $hostNames[$dbItem['hostid']] = $dbItem['hostname']; // a little tricky check for attempt to overwrite active trigger (value=1) with // inactive or active trigger with lower priority. if (!isset($items[$name][$dbItem['hostname']]) || ($items[$name][$dbItem['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE && $dbItem['tr_value'] == TRIGGER_VALUE_TRUE || ($items[$name][$dbItem['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE || $dbItem['tr_value'] == TRIGGER_VALUE_TRUE) && $dbItem['priority'] > $items[$name][$dbItem['hostname']]['severity'])) { $items[$name][$dbItem['hostname']] = array('itemid' => $dbItem['itemid'], 'value_type' => $dbItem['value_type'], 'value' => isset($history[$dbItem['itemid']]) ? $history[$dbItem['itemid']][0]['value'] : null, 'units' => $dbItem['units'], 'name' => $name, 'valuemapid' => $dbItem['valuemapid'], 'severity' => $dbItem['priority'], 'tr_value' => $dbItem['tr_value'], 'triggerid' => $dbItem['triggerid']); } } $table = new CTableInfo(_('No items found.')); if (empty($hostNames)) { return $table; } $table->makeVerticalRotation(); order_result($hostNames); if ($viewMode == STYLE_TOP) { $header = array(new CCol(_('Items'), 'center')); foreach ($hostNames as $hostName) { $header[] = new CCol($hostName, 'vertical_rotation'); } $table->setHeader($header, 'vertical_header'); foreach ($items as $descr => $ithosts) { $tableRow = array(nbsp($descr)); foreach ($hostNames as $hostName) { $tableRow = getItemDataOverviewCells($tableRow, $ithosts, $hostName); } $table->addRow($tableRow); } } else { $scripts = API::Script()->getScriptsByHosts(zbx_objectValues($hosts, 'hostid')); $header = array(new CCol(_('Hosts'), 'center')); foreach ($items as $descr => $ithosts) { $header[] = new CCol($descr, 'vertical_rotation'); } $table->setHeader($header, 'vertical_header'); foreach ($hostNames as $hostId => $hostName) { $host = $hosts[$hostId]; $name = new CSpan($host['name'], 'link_menu'); $name->setMenuPopup(getMenuPopupHost($host, $scripts[$hostId])); $tableRow = array(new CCol($name)); foreach ($items as $ithosts) { $tableRow = getItemDataOverviewCells($tableRow, $ithosts, $hostName); } $table->addRow($tableRow); } } return $table; }
function make_trigger_details($trigger) { $table = new CTableInfo(); if (is_show_all_nodes()) { $table->addRow(array(_('Node'), get_node_name_by_elid($trigger['triggerid']))); } $expression = explode_exp($trigger['expression'], true, true); $host = API::Host()->get(array('output' => array('name', 'hostid'), 'hostids' => $trigger['hosts'][0]['hostid'], 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => array('hostid'), 'preservekeys' => true)); $host = reset($host); $hostScripts = API::Script()->getScriptsByHosts($host['hostid']); // host js link $hostSpan = new CSpan($host['name'], 'link_menu menu-host'); $scripts = $hostScripts[$host['hostid']]; $hostSpan->attr('data-menu', hostMenuData($host, $scripts)); // get visible name of the first host $table->addRow(array(_('Host'), $hostSpan)); $table->addRow(array(_('Trigger'), CTriggerHelper::expandDescription($trigger))); $table->addRow(array(_('Severity'), getSeverityCell($trigger['priority']))); $table->addRow(array(_('Expression'), $expression)); $table->addRow(array(_('Event generation'), _('Normal') . (TRIGGER_MULT_EVENT_ENABLED == $trigger['type'] ? SPACE . '+' . SPACE . _('Multiple PROBLEM events') : ''))); $table->addRow(array(_('Disabled'), TRIGGER_STATUS_ENABLED == $trigger['status'] ? new CCol(_('No'), 'off') : new CCol(_('Yes'), 'on'))); return $table; }
/** * Create map area with submenu for sysmap elements. * In submenu gathered information about urls, scripts and submaps. * * @param array $sysmap * @param array $options * @param int $options['severity_min'] * * @return CAreaMap */ function getActionMapBySysmap($sysmap, array $options = array()) { $sysmap['selements'] = zbx_toHash($sysmap['selements'], 'selementid'); $sysmap['links'] = zbx_toHash($sysmap['links'], 'linkid'); $actionMap = new CAreaMap('links' . $sysmap['sysmapid']); $areas = populateFromMapAreas($sysmap); $mapInfo = getSelementsInfo($sysmap, $options); processAreasCoordinates($sysmap, $areas, $mapInfo); $hostIds = array(); $triggerIds = array(); foreach ($sysmap['selements'] as $id => &$selement) { if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) { $hostIds[$selement['elementid']] = $selement['elementid']; // expanding host URL macros again as some hosts were added from hostgroup areas // and automatic expanding only happens for elements that are defined for map in db foreach ($selement['urls'] as $urlId => $url) { $selement['urls'][$urlId]['url'] = str_replace('{HOST.ID}', $selement['elementid'], $url['url']); } } elseif ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { $triggerIds[$selement['elementid']] = $selement['elementid']; } if ($selement['elementsubtype'] == SYSMAP_ELEMENT_SUBTYPE_HOST_GROUP_ELEMENTS) { unset($sysmap['selements'][$id]); } } unset($selement); $hostScripts = API::Script()->getScriptsByHosts($hostIds); $hosts = API::Host()->get(array('hostids' => $hostIds, 'output' => array('hostid', 'status'), 'nopermissions' => true, 'preservekeys' => true, 'selectGraphs' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT)); $triggers = API::Trigger()->get(array('output' => array('triggerid'), 'triggerids' => $triggerIds, 'selectHosts' => array('status'), 'preservekeys' => true, 'nopermissions' => true)); foreach ($sysmap['selements'] as $elem) { $back = get_png_by_selement($mapInfo[$elem['selementid']]); $area = new CArea(array($elem['x'], $elem['y'], $elem['x'] + imagesx($back), $elem['y'] + imagesy($back)), '', '', 'rect'); $area->addClass('menu-map'); $hostId = null; $scripts = null; $gotos = null; switch ($elem['elementtype']) { case SYSMAP_ELEMENT_TYPE_HOST: $host = $hosts[$elem['elementid']]; if ($hostScripts[$elem['elementid']]) { $hostId = $elem['elementid']; $scripts = $hostScripts[$elem['elementid']]; } $gotos['triggerStatus'] = array('hostid' => $elem['elementid'], 'show_severity' => isset($options['severity_min']) ? $options['severity_min'] : null); $gotos['showTriggers'] = $hosts[$elem['elementid']]['status'] == HOST_STATUS_MONITORED; $gotos['graphs'] = array('hostid' => $host['hostid']); $gotos['showGraphs'] = (bool) $host['graphs']; $gotos['screens'] = array('hostid' => $host['hostid']); $gotos['showScreens'] = (bool) $host['screens']; $gotos['inventory'] = array('hostid' => $host['hostid']); $gotos['latestData'] = array('hostids' => array($host['hostid'])); break; case SYSMAP_ELEMENT_TYPE_MAP: $gotos['submap'] = array('sysmapid' => $elem['elementid'], 'severity_min' => isset($options['severity_min']) ? $options['severity_min'] : null); break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $gotos['events'] = array('triggerid' => $elem['elementid'], 'stime' => date(TIMESTAMP_FORMAT, time() - SEC_PER_WEEK), 'period' => SEC_PER_WEEK); $gotos['showEvents'] = false; if (isset($triggers[$elem['elementid']])) { foreach ($triggers[$elem['elementid']]['hosts'] as $host) { if ($host['status'] == HOST_STATUS_MONITORED) { $gotos['showEvents'] = true; break; } } } break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $gotos['triggerStatus'] = array('groupid' => $elem['elementid'], 'hostid' => 0, 'show_severity' => isset($options['severity_min']) ? $options['severity_min'] : null); // always show active trigger link for host group map elements $gotos['showTriggers'] = true; break; } order_result($elem['urls'], 'name'); $area->setMenuPopup(CMenuPopupHelper::getMap($hostId, $scripts, $gotos, $elem['urls'])); $actionMap->addItem($area); } return $actionMap; }
**/ require_once dirname(__FILE__) . '/include/config.inc.php'; require_once dirname(__FILE__) . '/include/hosts.inc.php'; require_once dirname(__FILE__) . '/include/forms.inc.php'; $page['title'] = _('Scripts'); $page['file'] = 'scripts_exec.php'; define('ZBX_PAGE_NO_MENU', 1); require_once dirname(__FILE__) . '/include/page_header.php'; // VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION $fields = array('hostid' => array(T_ZBX_INT, O_OPT, P_SYS, DB_ID, 'isset({execute})'), 'scriptid' => array(T_ZBX_INT, O_OPT, P_SYS, DB_ID, 'isset({execute})'), 'execute' => array(T_ZBX_INT, O_OPT, P_ACT, IN('0,1'), null)); check_fields($fields); if (isset($_REQUEST['execute'])) { $scriptid = get_request('scriptid'); $hostid = get_request('hostid'); $data = array('message' => '', 'info' => DBfetch(DBselect('SELECT s.name FROM scripts s WHERE s.scriptid=' . zbx_dbstr($scriptid)))); $result = API::Script()->execute(array('hostid' => $hostid, 'scriptid' => $scriptid)); $isErrorExist = false; if (empty($result)) { $isErrorExist = true; } elseif ($result['response'] == 'failed') { error($result['value']); $isErrorExist = true; } else { $data['message'] = $result['value']; } if ($isErrorExist) { show_error_message(_('Cannot connect to the trapper port of zabbix server daemon, but it should be available to run the script.')); } // render view $scriptView = new CView('general.script.execute', $data); $scriptView->render();
$triggersEventCount[$row['objectid']] = $row['cnt_event']; } $triggers = API::Trigger()->get(array('triggerids' => array_keys($triggersEventCount), 'output' => array('triggerid', 'description', 'expression', 'priority', 'flags', 'lastchange'), 'selectItems' => array('hostid', 'name', 'value_type', 'key_'), 'expandDescription' => true, 'expandData' => true, 'preservekeys' => true, 'nopermissions' => true)); $hosts = array(); foreach ($triggers as $tid => $trigger) { $hosts[$trigger['hostid']] = $trigger['hostid']; $trigger['cnt_event'] = $triggersEventCount[$tid]; $items = $trigger['items']; $trigger['items'] = array(); foreach ($items as $item) { $trigger['items'][$item['itemid']] = array('itemid' => $item['itemid'], 'action' => str_in_array($item['value_type'], array(ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64)) ? 'showgraph' : 'showvalues', 'name' => itemName($item), 'value_type' => $item['value_type']); } $triggers[$tid] = $trigger; } CArrayHelper::sort($triggers, array(array('field' => 'cnt_event', 'order' => ZBX_SORT_DOWN), 'host', 'description', 'priority')); $scripts_by_hosts = API::Script()->getScriptsByHosts($hosts); foreach ($triggers as $trigger) { $menus = ''; $host_nodeid = id2nodeid($trigger['hostid']); foreach ($scripts_by_hosts[$trigger['hostid']] as $script) { $script_nodeid = id2nodeid($script['scriptid']); if (bccomp($host_nodeid, $script_nodeid) == 0) { $menus .= "['" . $script['name'] . "',\"javascript: openWinCentered('scripts_exec.php?execute=1&hostid=" . $trigger['hostid'] . "&scriptid=" . $script['scriptid'] . "','Global script',760,540,'titlebar=no, resizable=yes, scrollbars=yes, dialog=no');\", null,{'outer' : ['pum_o_item'],'inner' : ['pum_i_item']}],"; } } $menus .= "['" . _('URLs') . "',null,null,{'outer' : ['pum_oheader'],'inner' : ['pum_iheader']}],"; $menus .= "['" . _('Latest data') . "',\"javascript: redirect('latest.php?hostid=" . $trigger['hostid'] . "')\", null,{'outer' : ['pum_o_item'],'inner' : ['pum_i_item']}]"; $menus = "show_popup_menu(event,[['" . _('Scripts') . "',null,null,{'outer' : ['pum_oheader'],'inner' : ['pum_iheader']}]," . $menus . "],180);"; $hostSpan = new CSpan($trigger['hostname'], 'link_menu'); $hostSpan->setAttribute('onclick', $menus); $tr_conf_link = 'null';
$scriptView->set('hostGroup', $hostGroup); // get list of user groups $usergroups = API::UserGroup()->get(array('output' => array('usrgrpid', 'name'))); order_result($usergroups, 'name'); $scriptView->set('usergroups', $usergroups); // render view $scriptView->render(); $scriptView->show(); } else { $sortField = getRequest('sort', CProfile::get('web.' . $page['file'] . '.sort', 'name')); $sortOrder = getRequest('sortorder', CProfile::get('web.' . $page['file'] . '.sortorder', ZBX_SORT_UP)); CProfile::update('web.' . $page['file'] . '.sort', $sortField, PROFILE_TYPE_STR); CProfile::update('web.' . $page['file'] . '.sortorder', $sortOrder, PROFILE_TYPE_STR); $data = array('sort' => $sortField, 'sortorder' => $sortOrder); // list of scripts $data['scripts'] = API::Script()->get(array('output' => array('scriptid', 'name', 'command', 'host_access', 'usrgrpid', 'groupid', 'type', 'execute_on'), 'editable' => true, 'selectGroups' => API_OUTPUT_EXTEND)); // find script host group name and user group name. set to '' if all host/user groups used. foreach ($data['scripts'] as $key => $script) { $scriptId = $script['scriptid']; if ($script['usrgrpid'] > 0) { $userGroup = API::UserGroup()->get(array('usrgrpids' => $script['usrgrpid'], 'output' => API_OUTPUT_EXTEND)); $userGroup = reset($userGroup); $data['scripts'][$key]['userGroupName'] = $userGroup['name']; } else { $data['scripts'][$key]['userGroupName'] = ''; // all user groups } if ($script['groupid'] > 0) { $group = array_pop($script['groups']); $data['scripts'][$key]['hostGroupName'] = $group['name']; } else {
public function validateOperations($operations) { $operations = zbx_toArray($operations); foreach ($operations as $operation) { if ((isset($operation['esc_step_from']) || isset($operation['esc_step_to'])) && !isset($operation['esc_step_from'], $operation['esc_step_to'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('esc_step_from and esc_step_to must be set together.')); } if (isset($operation['esc_step_from'], $operation['esc_step_to'])) { if ($operation['esc_step_from'] < 1 || $operation['esc_step_to'] < 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation escalation step values.')); } if ($operation['esc_step_from'] > $operation['esc_step_to'] && $operation['esc_step_to'] != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation escalation step values.')); } } if (isset($operation['esc_period'])) { if (isset($operation['esc_period']) && $operation['esc_period'] != 0 && $operation['esc_period'] < SEC_PER_MIN) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation step duration.')); } } $hostIdsAll = $hostGroupIdsAll = $useridsAll = $userGroupidsAll = array(); switch ($operation['operationtype']) { case OPERATION_TYPE_MESSAGE: $userids = isset($operation['opmessage_usr']) ? zbx_objectValues($operation['opmessage_usr'], 'userid') : array(); $usergroupids = isset($operation['opmessage_grp']) ? zbx_objectValues($operation['opmessage_grp'], 'usrgrpid') : array(); if (empty($userids) && empty($usergroupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No recipients for action operation message.')); } $useridsAll = array_merge($useridsAll, $userids); $userGroupidsAll = array_merge($userGroupidsAll, $usergroupids); break; case OPERATION_TYPE_COMMAND: if (!isset($operation['opcommand']['type'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No command type specified for action operation.')); } if ((!isset($operation['opcommand']['command']) || zbx_empty(trim($operation['opcommand']['command']))) && $operation['opcommand']['type'] != ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No command specified for action operation.')); } switch ($operation['opcommand']['type']) { case ZBX_SCRIPT_TYPE_IPMI: break; case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT: if (!isset($operation['opcommand']['execute_on'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No execution target specified for action operation command "%s".', $operation['opcommand']['command'])); } break; case ZBX_SCRIPT_TYPE_SSH: if (!isset($operation['opcommand']['authtype']) || zbx_empty($operation['opcommand']['authtype'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No authentication type specified for action operation command "%s".', $operation['opcommand']['command'])); } if (!isset($operation['opcommand']['username']) || zbx_empty($operation['opcommand']['username'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No authentication user name specified for action operation command "%s".', $operation['opcommand']['command'])); } if ($operation['opcommand']['authtype'] == ITEM_AUTHTYPE_PUBLICKEY) { if (!isset($operation['opcommand']['publickey']) || zbx_empty($operation['opcommand']['publickey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No public key file specified for action operation command "%s".', $operation['opcommand']['command'])); } if (!isset($operation['opcommand']['privatekey']) || zbx_empty($operation['opcommand']['privatekey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No private key file specified for action operation command "%s".', $operation['opcommand']['command'])); } } break; case ZBX_SCRIPT_TYPE_TELNET: if (!isset($operation['opcommand']['username']) || zbx_empty($operation['opcommand']['username'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No authentication user name specified for action operation command "%s".', $operation['opcommand']['command'])); } break; case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT: if (!isset($operation['opcommand']['scriptid']) || zbx_empty($operation['opcommand']['scriptid'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No script specified for action operation command.')); } $scripts = API::Script()->get(array('output' => array('scriptid', 'name'), 'scriptids' => $operation['opcommand']['scriptid'], 'preservekeys' => true)); if (!isset($scripts[$operation['opcommand']['scriptid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Specified script does not exist or you do not have rights on it for action operation command.')); } break; default: self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation command type.')); } if (isset($operation['opcommand']['port']) && !zbx_empty($operation['opcommand']['port'])) { if (zbx_ctype_digit($operation['opcommand']['port'])) { if ($operation['opcommand']['port'] > 65535 || $operation['opcommand']['port'] < 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect action operation port "%s".', $operation['opcommand']['port'])); } } elseif (!preg_match('/^' . ZBX_PREG_EXPRESSION_USER_MACROS . '$/', $operation['opcommand']['port'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect action operation port "%s".', $operation['opcommand']['port'])); } } $groupids = array(); if (isset($operation['opcommand_grp'])) { $groupids = zbx_objectValues($operation['opcommand_grp'], 'groupid'); } $hostids = array(); $withoutCurrent = true; if (isset($operation['opcommand_hst'])) { foreach ($operation['opcommand_hst'] as $hstCommand) { if ($hstCommand['hostid'] == 0) { $withoutCurrent = false; } else { $hostids[$hstCommand['hostid']] = $hstCommand['hostid']; } } } if (empty($groupids) && empty($hostids) && $withoutCurrent) { if ($operation['opcommand']['type'] == ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('You did not specify targets for action operation global script "%s".', $scripts[$operation['opcommand']['scriptid']]['name'])); } else { self::exception(ZBX_API_ERROR_PARAMETERS, _s('You did not specify targets for action operation command "%s".', $operation['opcommand']['command'])); } } $hostIdsAll = array_merge($hostIdsAll, $hostids); $hostGroupIdsAll = array_merge($hostGroupIdsAll, $groupids); break; case OPERATION_TYPE_GROUP_ADD: case OPERATION_TYPE_GROUP_REMOVE: $groupids = isset($operation['opgroup']) ? zbx_objectValues($operation['opgroup'], 'groupid') : array(); if (empty($groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Operation has no group to operate.')); } $hostGroupIdsAll = array_merge($hostGroupIdsAll, $groupids); break; case OPERATION_TYPE_TEMPLATE_ADD: case OPERATION_TYPE_TEMPLATE_REMOVE: $templateids = isset($operation['optemplate']) ? zbx_objectValues($operation['optemplate'], 'templateid') : array(); if (empty($templateids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Operation has no template to operate.')); } $hostIdsAll = array_merge($hostIdsAll, $templateids); break; case OPERATION_TYPE_HOST_ADD: case OPERATION_TYPE_HOST_REMOVE: case OPERATION_TYPE_HOST_ENABLE: case OPERATION_TYPE_HOST_DISABLE: break; default: self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation type.')); } } if (!API::HostGroup()->isWritable($hostGroupIdsAll)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation host group. Host group does not exist or you have no access to this host group.')); } if (!API::Host()->isWritable($hostIdsAll)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation host. Host does not exist or you have no access to this host.')); } if (!API::User()->isReadable($useridsAll)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation user. User does not exist or you have no access to this user.')); } if (!API::UserGroup()->isReadable($userGroupidsAll)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect action operation user group. User group does not exist or you have no access to this user group.')); } return true; }
/** * Delete host groups. * * @param array $groupids * * @return boolean */ public function delete($groupids) { if (empty($groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $groupids = zbx_toArray($groupids); $options = array('groupids' => $groupids, 'editable' => true, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true); $delGroups = $this->get($options); foreach ($groupids as $groupid) { if (!isset($delGroups[$groupid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } if ($delGroups[$groupid]['internal'] == ZBX_INTERNAL_GROUP) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Group "%1$s" is internal and can not be deleted.', $delGroups[$groupid]['name'])); } } $dltGroupids = getDeletableHostGroups($groupids); if (count($groupids) != count($dltGroupids)) { foreach ($groupids as $groupid) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Group "%s" cannot be deleted, because some hosts depend on it.', $delGroups[$groupid]['name'])); } } $dbScripts = API::Script()->get(array('groupids' => $groupids, 'output' => array('scriptid', 'groupid'), 'nopermissions' => true)); if (!empty($dbScripts)) { foreach ($dbScripts as $script) { if ($script['groupid'] == 0) { continue; } self::exception(ZBX_API_ERROR_PARAMETERS, _s('Group "%s" cannot be deleted, because it is used in a global script.', $delGroups[$script['groupid']]['name'])); } } // delete screens items $resources = array(SCREEN_RESOURCE_HOSTGROUP_TRIGGERS, SCREEN_RESOURCE_HOSTS_INFO, SCREEN_RESOURCE_TRIGGERS_INFO, SCREEN_RESOURCE_TRIGGERS_OVERVIEW, SCREEN_RESOURCE_DATA_OVERVIEW); DB::delete('screens_items', array('resourceid' => $groupids, 'resourcetype' => $resources)); // delete sysmap element if (!empty($groupids)) { DB::delete('sysmaps_elements', array('elementtype' => SYSMAP_ELEMENT_TYPE_HOST_GROUP, 'elementid' => $groupids)); } // disable actions // actions from conditions $actionids = array(); $dbActions = DBselect('SELECT DISTINCT c.actionid' . ' FROM conditions c' . ' WHERE c.conditiontype=' . CONDITION_TYPE_HOST_GROUP . ' AND ' . dbConditionString('c.value', $groupids)); while ($dbAction = DBfetch($dbActions)) { $actionids[$dbAction['actionid']] = $dbAction['actionid']; } // actions from operations $dbActions = DBselect('SELECT DISTINCT o.actionid' . ' FROM operations o,opgroup og' . ' WHERE o.operationid=og.operationid' . ' AND ' . dbConditionInt('og.groupid', $groupids)); while ($dbAction = DBfetch($dbActions)) { $actionids[$dbAction['actionid']] = $dbAction['actionid']; } if (!empty($actionids)) { $update = array(); $update[] = array('values' => array('status' => ACTION_STATUS_DISABLED), 'where' => array('actionid' => $actionids)); DB::update('actions', $update); } // delete action conditions DB::delete('conditions', array('conditiontype' => CONDITION_TYPE_HOST_GROUP, 'value' => $groupids)); // delete action operation commands $operationids = array(); $dbOperations = DBselect('SELECT DISTINCT og.operationid' . ' FROM opgroup og' . ' WHERE ' . dbConditionInt('og.groupid', $groupids)); while ($dbOperation = DBfetch($dbOperations)) { $operationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('opgroup', array('groupid' => $groupids)); // delete empty operations $delOperationids = array(); $dbOperations = DBselect('SELECT DISTINCT o.operationid' . ' FROM operations o' . ' WHERE ' . dbConditionInt('o.operationid', $operationids) . ' AND NOT EXISTS (SELECT NULL FROM opgroup og WHERE o.operationid=og.operationid)'); while ($dbOperation = DBfetch($dbOperations)) { $delOperationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('operations', array('operationid' => $delOperationids)); // host groups DB::delete('groups', array('groupid' => $groupids)); // TODO: remove audit foreach ($groupids as $groupid) { add_audit_ext(AUDIT_ACTION_DELETE, AUDIT_RESOURCE_HOST_GROUP, $groupid, $delGroups[$groupid]['name'], 'groups', null, null); } return array('groupids' => $groupids); }
function make_hint_row($type, $instance) { $state = $instance['state']; if ($type == "other" && $instance["stuck_state"] == 1) { $state = "stuck"; } $r = new CRow(); if (in_array($type, array("poweron", "poweroff", "suspend"))) { $r->addItem(new CCheckBox("hostids[]", null, null, $instance['hostid'])); } $hostScripts = API::Script()->getScriptsByHosts(zbx_objectValues(array($instance['host']), 'hostid')); $hostSpan = new CSpan(nbsp($instance['name']), 'link_menu menu-host'); $hostSpan->setAttribute('data-menu', hostMenuData($instance['host'], $hostScripts[$instance['hostid']])); $r->addItem($hostSpan); $r->addItem(new CCol($state, get_item_level($state))); $r->addItem($instance['cpu']); $r->addItem($instance['memory']); $r->addItem($instance['main_interface']); if ($type == "other" && $instance["stuck_state"] == 1) { $question = $instance['stuck_question']; $json = new CJSON(); $choiceinfos = $json->decode($instance['stuck_choices'], true); $answer_form = new CForm(); $answer_form->setAction('#'); $answer_form->setAttribute('id', "answer"); $answer_form->addVar("driver", "vsphere"); $answer_form->addVar("hostids[]", $instance['hostid']); $instancename = $instance['host']['host']; $answer_button = new CButton('answer', _('Answer'), "return checkAnswer('answer', 'choice', '{$instancename}', 'Execute');"); $choice_table = new CTableInfo(); foreach ($choiceinfos as $choice) { $radio = new CRadioButton('choice', $choice['key']); $label = new CLabel($choice['label']); $choice_table->addRow(new CRow(array($radio, $label))); } $answer_form->addItem($choice_table); $answer_form->addItem($answer_button); $question_span = new CSpan($question); $question_span->setHint($answer_form); $question_col = new CCol($question_span, 'warning'); $r->addItem($question_col); } else { if ($type == "poweron") { $ssh_link = new CLink(_('connect'), "gateone.php?hostid={$instance['hostid']}"); $ssh_link->setTarget("_blank"); $r->addItem($ssh_link); } } return $r; }
/** * Gathers action operation script details and returns the HTML items representing action operation with hint. * * @param array $operations array of action operations * @param string $operation['operationtype'] action operation type. * Possible values: OPERATION_TYPE_MESSAGE and OPERATION_TYPE_COMMAND * @param string $operation['opcommand']['type'] action operation command type. * Possible values: ZBX_SCRIPT_TYPE_IPMI, ZBX_SCRIPT_TYPE_SSH, * ZBX_SCRIPT_TYPE_TELNET, ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT * and ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT * @param string $operation['opmessage']['default_msg'] '1' to show default message (optional) * @param array $defaultMessage array containing default subject and message set via action * @param string $defaultMessage['subject'] default subject * @param string $defaultMessage['message'] default message text * * @return array returns an array of action operation hints */ function getActionOperationHints(array $operations, array $defaultMessage) { $result = []; $scriptids = []; $scripts = []; foreach ($operations as $operation) { if ($operation['operationtype'] == OPERATION_TYPE_COMMAND && $operation['opcommand']['type'] == ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT) { $scriptids[$operation['opcommand']['scriptid']] = true; } } if ($scriptids) { $scripts = API::Script()->get(['output' => ['name'], 'scriptids' => array_keys($scriptids), 'preservekeys' => true]); } foreach ($operations as $key => $operation) { $result[$key] = []; switch ($operation['operationtype']) { case OPERATION_TYPE_MESSAGE: // show default entered action subject and message or show custom subject and message for each operation $subject = isset($operation['opmessage']['default_msg']) && $operation['opmessage']['default_msg'] ? $defaultMessage['subject'] : $operation['opmessage']['subject']; $message = isset($operation['opmessage']['default_msg']) && $operation['opmessage']['default_msg'] ? $defaultMessage['message'] : $operation['opmessage']['message']; $result[$key][] = [bold($subject), BR(), BR(), zbx_nl2br($message)]; break; case OPERATION_TYPE_COMMAND: switch ($operation['opcommand']['type']) { case ZBX_SCRIPT_TYPE_IPMI: $result[$key][] = [bold(_('Run IPMI command') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; break; case ZBX_SCRIPT_TYPE_SSH: $result[$key][] = [bold(_('Run SSH commands') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; break; case ZBX_SCRIPT_TYPE_TELNET: $result[$key][] = [bold(_('Run TELNET commands') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; break; case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT: if ($operation['opcommand']['execute_on'] == ZBX_SCRIPT_EXECUTE_ON_AGENT) { $result[$key][] = [bold(_('Run custom commands on Zabbix agent') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; } else { $result[$key][] = [bold(_('Run custom commands on Zabbix server') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; } break; case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT: $scriptId = $operation['opcommand']['scriptid']; if (isset($scripts[$scriptId])) { $result[$key][] = [bold(_('Run global script') . ': '), italic($scripts[$scriptId]['name'])]; } break; default: $result[$key][] = [bold(_('Run commands') . ': '), BR(), italic(zbx_nl2br($operation['opcommand']['command']))]; } } } return $result; }
$form->attr('id', 'scripts'); $table = new CTableInfo(_('No scripts found.')); if ($multiselect) { $header = array(array(new CCheckBox('all_scripts', null, "javascript: checkAll('" . $form->getName() . "', 'all_scripts', 'scripts');"), _('Name')), _('Execute on'), _('Commands')); } else { $header = array(_('Name'), _('Execute on'), _('Commands')); } $table->setHeader($header); $options = array('nodeids' => $nodeId, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true); if (is_null($hostid)) { $options['groupids'] = $groupid; } if (!is_null($writeonly)) { $options['editable'] = true; } $scripts = API::Script()->get($options); order_result($scripts, 'name'); foreach ($scripts as $script) { $description = new CLink($script['name'], '#'); if ($multiselect) { $js_action = 'javascript: addValue(' . zbx_jsvalue($reference) . ', ' . zbx_jsvalue($script['scriptid']) . ');'; } else { $values = array($dstfld1 => $script[$srcfld1], $dstfld2 => $script[$srcfld2]); $js_action = 'javascript: addValues(' . zbx_jsvalue($dstfrm) . ', ' . zbx_jsvalue($values) . '); close_window(); return false;'; } $description->setAttribute('onclick', $js_action . ' jQuery(this).removeAttr("onclick");'); if ($multiselect) { $description = new CCol(array(new CCheckBox('scripts[' . zbx_jsValue($script[$srcfld1]) . ']', null, null, $script['scriptid']), $description)); } if ($script['type'] == ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) { switch ($script['execute_on']) {
/** * Validates the input parameters for the delete() method. * * @throws APIException * * @param array $userGroupIds */ protected function validateDelete(array $userGroupIds) { if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can delete user groups.')); } if (!$userGroupIds) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $dbUserGroups = $this->get(array('output' => array('usrgrpid', 'name'), 'usrgrpids' => $userGroupIds, 'preservekeys' => true)); // check if user group is used in scripts $dbScripts = API::Script()->get(array('output' => array('scriptid', 'name', 'usrgrpid'), 'usrgrpids' => $userGroupIds, 'nopermissions' => true)); foreach ($dbScripts as $dbScript) { if ($dbScript['usrgrpid'] == 0) { continue; } self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group "%1$s" is used in script "%2$s".', $dbUserGroups[$dbScript['usrgrpid']]['name'], $dbScript['name'])); } // check if user group is used in config $config = select_config(); if (isset($dbUserGroups[$config['alert_usrgrpid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group "%1$s" is used in configuration for database down messages.', $dbUserGroups[$config['alert_usrgrpid']]['name'])); } // check if user group is used in users with 1 user group $dbUsers = API::User()->get(array('output' => array('userid', 'usrgrpid', 'alias'), 'usrgrpids' => $userGroupIds, 'selectUsrgrps' => array('usrgrpid'))); foreach ($dbUsers as $dbUser) { if (count($dbUser['usrgrps']) == 1) { $dbGroup = reset($dbUser['usrgrps']); self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group "%1$s" is the only group that user "%2$s" belongs to.', $dbUserGroups[$dbGroup['usrgrpid']]['name'], $dbUser['alias'])); } } }
} if (getRequest('hostid') && !API::Host()->isReadable([getRequest('hostid')])) { access_deny(); } $sortField = getRequest('sort', CProfile::get('web.' . $page['file'] . '.sort', 'name')); $sortOrder = getRequest('sortorder', CProfile::get('web.' . $page['file'] . '.sortorder', ZBX_SORT_UP)); CProfile::update('web.' . $page['file'] . '.sort', $sortField, PROFILE_TYPE_STR); CProfile::update('web.' . $page['file'] . '.sortorder', $sortOrder, PROFILE_TYPE_STR); $hostId = getRequest('hostid', 0); /* * Display */ if ($hostId > 0) { $data = []; // host scripts $data['hostScripts'] = API::Script()->getScriptsByHosts([$hostId]); // inventory info $data['tableTitles'] = getHostInventories(); $data['tableTitles'] = zbx_toHash($data['tableTitles'], 'db_field'); $inventoryFields = array_keys($data['tableTitles']); // overview tab $data['host'] = API::Host()->get(['output' => ['hostid', 'host', 'name', 'status', 'maintenance_status', 'maintenanceid', 'maintenance_type', 'description'], 'selectInterfaces' => API_OUTPUT_EXTEND, 'selectItems' => API_OUTPUT_COUNT, 'selectTriggers' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => $inventoryFields, 'selectGraphs' => API_OUTPUT_COUNT, 'selectApplications' => API_OUTPUT_COUNT, 'selectDiscoveries' => API_OUTPUT_COUNT, 'selectHttpTests' => API_OUTPUT_COUNT, 'hostids' => $hostId, 'preservekeys' => true]); $data['host'] = reset($data['host']); unset($data['host']['inventory']['hostid']); // resolve macros $data['host']['interfaces'] = CMacrosResolverHelper::resolveHostInterfaces($data['host']['interfaces']); if ($data['host']['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $data['maintenances'] = API::Maintenance()->get(['maintenanceids' => [$data['host']['maintenanceid']], 'output' => ['name', 'description'], 'preservekeys' => true]); } // get permissions $userType = CWebUser::getType();
$options = array('output' => array('name', 'hostid'), 'hostids' => $available_hosts, 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => array('hostid'), 'preservekeys' => true); $sql_from = ''; $sql_where = ''; if ($_REQUEST['groupid'] > 0) { $sql_from .= ',hosts_groups hg '; $sql_where .= ' AND hg.hostid=h.hostid AND hg.groupid=' . $_REQUEST['groupid']; $options['groupid'] = $_REQUEST['groupid']; } if ($_REQUEST['hostid'] > 0) { $sql_where .= ' AND h.hostid=' . $_REQUEST['hostid']; $options['hostids'] = $_REQUEST['hostid']; } $hosts = API::Host()->get($options); // fetch scripts for the host JS menu if ($_REQUEST['hostid'] == 0) { $hostScripts = API::Script()->getScriptsByHosts($options['hostids']); } // select hosts $sql = 'SELECT DISTINCT h.name as hostname,h.hostid, a.* ' . ' FROM applications a, hosts h ' . $sql_from . ' WHERE a.hostid=h.hostid' . $sql_where . ' AND ' . dbConditionInt('h.hostid', $available_hosts) . order_by('h.name,h.hostid', 'a.name,a.applicationid'); $db_app_res = DBselect($sql); while ($db_app = DBfetch($db_app_res)) { $db_app['item_cnt'] = 0; $db_apps[$db_app['applicationid']] = $db_app; $db_appids[$db_app['applicationid']] = $db_app['applicationid']; } $tab_rows = array(); // select items $sql = 'SELECT DISTINCT i.*, ia.applicationid ' . ' FROM items i,items_applications ia' . ' WHERE ' . dbConditionInt('ia.applicationid', $db_appids) . ' AND i.itemid=ia.itemid' . ($_REQUEST['show_without_data'] ? '' : ' AND i.lastvalue IS NOT NULL') . ' AND (i.status=' . ITEM_STATUS_ACTIVE . ' OR i.status=' . ITEM_STATUS_NOTSUPPORTED . ')' . ' AND ' . dbConditionInt('i.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)) . order_by('i.name,i.itemid,i.lastclock'); $db_items = DBselect($sql); while ($db_item = DBfetch($db_items)) { $description = itemName($db_item);
function make_trigger_details($trigger) { $hostNames = array(); $hostIds = zbx_objectValues($trigger['hosts'], 'hostid'); $hosts = API::Host()->get(array('output' => array('name', 'hostid', 'status'), 'hostids' => $hostIds, 'selectScreens' => API_OUTPUT_COUNT, 'selectGraphs' => API_OUTPUT_COUNT)); if (count($hosts) > 1) { order_result($hosts, 'name', ZBX_SORT_UP); } $scripts = API::Script()->getScriptsByHosts($hostIds); foreach ($hosts as $host) { $hostName = new CSpan($host['name'], 'link_menu'); $hostName->setMenuPopup(CMenuPopupHelper::getHost($host, $scripts[$host['hostid']])); $hostNames[] = $hostName; $hostNames[] = ', '; } array_pop($hostNames); $table = new CTableInfo(); $table->addRow(array(new CCol(_n('Host', 'Hosts', count($hosts))), new CCol($hostNames, 'wraptext'))); $table->addRow(array(new CCol(_('Trigger')), new CCol(CMacrosResolverHelper::resolveTriggerName($trigger), 'wraptext'))); $table->addRow(array(_('Severity'), getSeverityCell($trigger['priority']))); $table->addRow(array(new CCol(_('Expression')), new CCol(explode_exp($trigger['expression'], true, true), 'trigger-expression'))); $table->addRow(array(_('Event generation'), _('Normal') . (TRIGGER_MULT_EVENT_ENABLED == $trigger['type'] ? SPACE . '+' . SPACE . _('Multiple PROBLEM events') : ''))); $table->addRow(array(_('Disabled'), TRIGGER_STATUS_ENABLED == $trigger['status'] ? new CCol(_('No'), 'off') : new CCol(_('Yes'), 'on'))); return $table; }
if (!isset($this->data['new_operation']['opcommand'])) { $this->data['new_operation']['opcommand'] = array(); } $this->data['new_operation']['opcommand']['type'] = isset($this->data['new_operation']['opcommand']['type']) ? $this->data['new_operation']['opcommand']['type'] : ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT; $this->data['new_operation']['opcommand']['scriptid'] = isset($this->data['new_operation']['opcommand']['scriptid']) ? $this->data['new_operation']['opcommand']['scriptid'] : ''; $this->data['new_operation']['opcommand']['execute_on'] = isset($this->data['new_operation']['opcommand']['execute_on']) ? $this->data['new_operation']['opcommand']['execute_on'] : ZBX_SCRIPT_EXECUTE_ON_AGENT; $this->data['new_operation']['opcommand']['publickey'] = isset($this->data['new_operation']['opcommand']['publickey']) ? $this->data['new_operation']['opcommand']['publickey'] : ''; $this->data['new_operation']['opcommand']['privatekey'] = isset($this->data['new_operation']['opcommand']['privatekey']) ? $this->data['new_operation']['opcommand']['privatekey'] : ''; $this->data['new_operation']['opcommand']['authtype'] = isset($this->data['new_operation']['opcommand']['authtype']) ? $this->data['new_operation']['opcommand']['authtype'] : ITEM_AUTHTYPE_PASSWORD; $this->data['new_operation']['opcommand']['username'] = isset($this->data['new_operation']['opcommand']['username']) ? $this->data['new_operation']['opcommand']['username'] : ''; $this->data['new_operation']['opcommand']['password'] = isset($this->data['new_operation']['opcommand']['password']) ? $this->data['new_operation']['opcommand']['password'] : ''; $this->data['new_operation']['opcommand']['port'] = isset($this->data['new_operation']['opcommand']['port']) ? $this->data['new_operation']['opcommand']['port'] : ''; $this->data['new_operation']['opcommand']['command'] = isset($this->data['new_operation']['opcommand']['command']) ? $this->data['new_operation']['opcommand']['command'] : ''; $this->data['new_operation']['opcommand']['script'] = ''; if (!zbx_empty($this->data['new_operation']['opcommand']['scriptid'])) { $userScripts = API::Script()->get(array('scriptids' => $this->data['new_operation']['opcommand']['scriptid'], 'output' => API_OUTPUT_EXTEND)); if ($userScript = reset($userScripts)) { $this->data['new_operation']['opcommand']['script'] = $userScript['name']; } } $cmdList = new CTable(null, 'formElementTable'); $cmdList->attr('style', 'min-width: 310px;'); $cmdList->setHeader(array(_('Target'), _('Action'))); $addCmdBtn = new CButton('add', _('New'), 'javascript: showOpCmdForm(0, "new");', 'link_menu'); $cmdList->addRow(new CRow(new CCol($addCmdBtn, null, 3), null, 'opCmdListFooter')); // add participations if (!isset($this->data['new_operation']['opcommand_grp'])) { $this->data['new_operation']['opcommand_grp'] = array(); } if (!isset($this->data['new_operation']['opcommand_hst'])) { $this->data['new_operation']['opcommand_hst'] = array();
/** * Retrieve overview table object for items. * * @param $hostids * @param null $view_style * * @return CTableInfo */ function get_items_data_overview($hostids, $view_style) { global $USER_DETAILS; $db_items = DBselect('SELECT DISTINCT h.hostid,h.name AS hostname,i.itemid,i.key_,i.value_type,i.lastvalue,i.units,i.lastclock,' . 'i.name,t.priority,i.valuemapid,t.value AS tr_value,t.triggerid' . ' FROM hosts h,items i' . ' LEFT JOIN functions f ON f.itemid=i.itemid' . ' LEFT JOIN triggers t ON t.triggerid=f.triggerid AND t.status=' . TRIGGER_STATUS_ENABLED . ' WHERE ' . dbConditionInt('h.hostid', $hostids) . ' AND h.status=' . HOST_STATUS_MONITORED . ' AND h.hostid=i.hostid' . ' AND i.status=' . ITEM_STATUS_ACTIVE . ' AND ' . dbConditionInt('i.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)) . ' ORDER BY i.name,i.itemid'); $options = array('output' => array('name', 'hostid'), 'monitored_hosts' => true, 'hostids' => $hostids, 'with_monitored_items' => true, 'preservekeys' => true); if ($view_style == STYLE_LEFT) { $options['selectScreens'] = API_OUTPUT_COUNT; $options['selectInventory'] = array('hostid'); } // fetch data for the host JS menu $hosts = API::Host()->get($options); $items = array(); while ($row = DBfetch($db_items)) { $descr = itemName($row); $row['hostname'] = get_node_name_by_elid($row['hostid'], null, ': ') . $row['hostname']; $hostnames[$row['hostid']] = $row['hostname']; // a little tricky check for attempt to overwrite active trigger (value=1) with // inactive or active trigger with lower priority. if (!isset($items[$descr][$row['hostname']]) || ($items[$descr][$row['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE && $row['tr_value'] == TRIGGER_VALUE_TRUE || ($items[$descr][$row['hostname']]['tr_value'] == TRIGGER_VALUE_FALSE || $row['tr_value'] == TRIGGER_VALUE_TRUE) && $row['priority'] > $items[$descr][$row['hostname']]['severity'])) { $items[$descr][$row['hostname']] = array('itemid' => $row['itemid'], 'value_type' => $row['value_type'], 'lastvalue' => $row['lastvalue'], 'lastclock' => $row['lastclock'], 'units' => $row['units'], 'name' => $row['name'], 'valuemapid' => $row['valuemapid'], 'severity' => $row['priority'], 'tr_value' => $row['tr_value'], 'triggerid' => $row['triggerid']); } } $table = new CTableInfo(_('No items defined.')); if (empty($hostnames)) { return $table; } $table->makeVerticalRotation(); order_result($hostnames); if ($view_style == STYLE_TOP) { $header = array(new CCol(_('Items'), 'center')); foreach ($hostnames as $hostname) { $header[] = new CCol($hostname, 'vertical_rotation'); } $table->setHeader($header, 'vertical_header'); foreach ($items as $descr => $ithosts) { $tableRow = array(nbsp($descr)); foreach ($hostnames as $hostname) { $tableRow = get_item_data_overview_cells($tableRow, $ithosts, $hostname); } $table->addRow($tableRow); } } else { $hostScripts = API::Script()->getScriptsByHosts(zbx_objectValues($hosts, 'hostid')); foreach ($hostScripts as $hostid => $scripts) { $hosts[$hostid]['scripts'] = $scripts; } $header = array(new CCol(_('Hosts'), 'center')); foreach ($items as $descr => $ithosts) { $header[] = new CCol($descr, 'vertical_rotation'); } $table->setHeader($header, 'vertical_header'); foreach ($hostnames as $hostid => $hostname) { $host = $hosts[$hostid]; // host js menu link $hostSpan = new CSpan(nbsp($host['name']), 'link_menu menu-host'); $hostSpan->setAttribute('data-menu', hostMenuData($host, $hostScripts[$host['hostid']])); $tableRow = array(new CCol($hostSpan)); foreach ($items as $ithosts) { $tableRow = get_item_data_overview_cells($tableRow, $ithosts, $hostname); } $table->addRow($tableRow); } } return $table; }
function make_trigger_details($trigger) { $hosts = reset($trigger['hosts']); $hostId = $hosts['hostid']; $hosts = API::Host()->get(array('output' => array('name', 'hostid', 'status'), 'hostids' => $hostId, 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true)); $host = reset($hosts); $scripts = API::Script()->getScriptsByHosts($hostId); $hostName = new CSpan($host['name'], 'link_menu'); $hostName->setMenuPopup(getMenuPopupHost($host, $scripts ? reset($scripts) : null)); $table = new CTableInfo(); if (is_show_all_nodes()) { $table->addRow(array(_('Node'), get_node_name_by_elid($trigger['triggerid']))); } $table->addRow(array(_('Host'), $hostName)); $table->addRow(array(_('Trigger'), CMacrosResolverHelper::resolveTriggerName($trigger))); $table->addRow(array(_('Severity'), getSeverityCell($trigger['priority']))); $table->addRow(array(_('Expression'), explode_exp($trigger['expression'], true, true))); $table->addRow(array(_('Event generation'), _('Normal') . (TRIGGER_MULT_EVENT_ENABLED == $trigger['type'] ? SPACE . '+' . SPACE . _('Multiple PROBLEM events') : ''))); $table->addRow(array(_('Disabled'), TRIGGER_STATUS_ENABLED == $trigger['status'] ? new CCol(_('No'), 'off') : new CCol(_('Yes'), 'on'))); return $table; }
CProfile::update('web.' . $page['file'] . '.sortorder', $sortOrder, PROFILE_TYPE_STR); if (hasRequest('filterState')) { CProfile::update('web.hostinventories.filter.state', getRequest('filterState'), PROFILE_TYPE_INT); } if (PAGE_TYPE_JS == $page['type'] || PAGE_TYPE_HTML_BLOCK == $page['type']) { require_once dirname(__FILE__) . '/include/page_footer.php'; exit; } $hostId = getRequest('hostid', 0); /* * Display */ if ($hostId > 0) { $data = array(); // host scripts $data['hostScripts'] = API::Script()->getScriptsByHosts(array($hostId)); // inventory info $data['tableTitles'] = getHostInventories(); $data['tableTitles'] = zbx_toHash($data['tableTitles'], 'db_field'); $inventoryFields = array_keys($data['tableTitles']); // overview tab $data['host'] = API::Host()->get(array('output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 'selectInterfaces' => API_OUTPUT_EXTEND, 'selectItems' => API_OUTPUT_COUNT, 'selectTriggers' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => $inventoryFields, 'selectGraphs' => API_OUTPUT_COUNT, 'selectApplications' => API_OUTPUT_COUNT, 'selectDiscoveries' => API_OUTPUT_COUNT, 'selectHttpTests' => API_OUTPUT_COUNT, 'hostids' => $hostId, 'preservekeys' => true)); $data['host'] = reset($data['host']); unset($data['host']['inventory']['hostid']); // resolve macros $data['host']['interfaces'] = CMacrosResolverHelper::resolveHostInterfaces($data['host']['interfaces']); // get permissions $userType = CWebUser::getType(); if ($userType == USER_TYPE_SUPER_ADMIN) { $data['rwHost'] = true; } elseif ($userType == USER_TYPE_ZABBIX_ADMIN) {
$sql .= ' AND EXISTS (' . 'SELECT NULL' . ' FROM functions f,items i,hosts_groups hgg' . ' JOIN rights r' . ' ON r.id=hgg.groupid' . ' AND ' . dbConditionInt('r.groupid', $userGroups) . ' WHERE t.triggerid=f.triggerid' . ' AND f.itemid=i.itemid' . ' AND i.hostid=hgg.hostid' . ' GROUP BY f.triggerid' . ' HAVING MIN(r.permission)>' . PERM_DENY . ')'; } $sql .= ' AND ' . dbConditionInt('t.flags', array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED)) . ' GROUP BY e.objectid' . ' ORDER BY cnt_event desc'; $result = DBselect($sql, 100); while ($row = DBfetch($result)) { $triggersEventCount[$row['objectid']] = $row['cnt_event']; } $triggers = API::Trigger()->get(array('triggerids' => array_keys($triggersEventCount), 'output' => array('triggerid', 'description', 'expression', 'priority', 'flags', 'url', 'lastchange'), 'selectHosts' => array('hostid', 'status', 'name'), 'selectItems' => array('itemid', 'hostid', 'name', 'key_', 'value_type'), 'expandDescription' => true, 'preservekeys' => true, 'nopermissions' => true)); $hostIds = array(); foreach ($triggers as $triggerId => $trigger) { $hostIds[$trigger['hosts'][0]['hostid']] = $trigger['hosts'][0]['hostid']; $triggers[$triggerId]['cnt_event'] = $triggersEventCount[$triggerId]; } CArrayHelper::sort($triggers, array(array('field' => 'cnt_event', 'order' => ZBX_SORT_DOWN), 'host', 'description', 'priority')); $hosts = API::Host()->get(array('output' => array('hostid', 'status'), 'hostids' => $hostIds, 'selectGraphs' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true)); $scripts = API::Script()->getScriptsByHosts($hostIds); $monitoredHostIds = array(); foreach ($triggers as $trigger) { foreach ($trigger['hosts'] as $host) { if ($host['status'] == HOST_STATUS_MONITORED) { $monitoredHostIds[$host['hostid']] = true; } } } if ($monitoredHostIds) { $monitoredHosts = API::Host()->get(array('output' => array('hostid'), 'selectGroups' => array('groupid'), 'hostids' => array_keys($monitoredHostIds), 'preservekeys' => true)); } foreach ($triggers as $trigger) { foreach ($trigger['hosts'] as $host) { if ($host['status'] == HOST_STATUS_MONITORED) { // Pass a monitored 'hostid' and corresponding first 'groupid' to menu pop-up "Events" link.
/** * Create DIV with latest problem triggers. * * If no sortfield and sortorder are defined, the sort indicater in the column name will not be displayed. * * @param array $filter['groupids'] * @param array $filter['hostids'] * @param array $filter['maintenance'] * @param int $filter['extAck'] * @param int $filter['severity'] * @param int $filter['limit'] * @param string $filter['sortfield'] * @param string $filter['sortorder'] * @param string $backurl * * @return CDiv */ function make_latest_issues(array $filter = [], $backurl) { // hide the sort indicator if no sortfield and sortorder are given $show_sort_indicator = isset($filter['sortfield']) || isset($filter['sortorder']); if (isset($filter['sortfield']) && $filter['sortfield'] !== 'lastchange') { $sort_field = [$filter['sortfield'], 'lastchange']; $sort_order = [$filter['sortorder'], ZBX_SORT_DOWN]; } else { $sort_field = ['lastchange']; $sort_order = [ZBX_SORT_DOWN]; } $options = ['groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'search' => $filter['trigger_name'] !== '' ? ['description' => $filter['trigger_name']] : null, 'filter' => ['priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE]]; $triggers = API::Trigger()->get(array_merge($options, ['output' => ['triggerid', 'expression', 'description', 'url', 'priority', 'lastchange', 'comments', 'error', 'state'], 'selectHosts' => ['hostid'], 'selectLastEvent' => ['eventid', 'acknowledged', 'objectid', 'clock', 'ns'], 'withLastEventUnacknowledged' => isset($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'sortfield' => $sort_field, 'sortorder' => $sort_order, 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT, 'preservekeys' => true, 'expandComment' => true])); $triggers = CMacrosResolverHelper::resolveTriggerUrls($triggers); // don't use withLastEventUnacknowledged and skipDependent because of performance issues $triggers_total_count = API::Trigger()->get(array_merge($options, ['countOutput' => true])); // get acknowledges $hostids = []; $eventids = []; foreach ($triggers as $trigger) { foreach ($trigger['hosts'] as $host) { $hostids[$host['hostid']] = true; } if ($trigger['lastEvent']) { $eventids[] = $trigger['lastEvent']['eventid']; } } $config = select_config(); if ($config['event_ack_enable'] && $eventids) { $event_acknowledges = API::Event()->get(['output' => ['eventid'], 'eventids' => $eventids, 'select_acknowledges' => API_OUTPUT_EXTEND, 'preservekeys' => true]); } // actions $actions = makeEventsActions($eventids); // indicator of sort field if ($show_sort_indicator) { $sort_div = (new CDiv())->addClass($filter['sortorder'] === ZBX_SORT_DOWN ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP); } $table = (new CTableInfo())->setHeader([$show_sort_indicator && $filter['sortfield'] === 'hostname' ? [_('Host'), $sort_div] : _('Host'), $show_sort_indicator && $filter['sortfield'] === 'priority' ? [_('Issue'), $sort_div] : _('Issue'), $show_sort_indicator && $filter['sortfield'] === 'lastchange' ? [_('Last change'), $sort_div] : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions')]); $hostids = array_keys($hostids); $scripts = API::Script()->getScriptsByHosts($hostids); // get hosts $hosts = API::Host()->get(['hostids' => $hostids, 'output' => ['hostid', 'name', 'status', 'maintenance_status', 'maintenance_type', 'maintenanceid'], 'selectGraphs' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true]); $maintenanceids = []; foreach ($hosts as $host) { if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $maintenanceids[$host['maintenanceid']] = true; } } if ($maintenanceids) { $maintenances = API::Maintenance()->get(['maintenanceids' => array_keys($maintenanceids), 'output' => ['name', 'description'], 'preservekeys' => true]); } // triggers foreach ($triggers as $trigger) { $host_list = []; foreach ($trigger['hosts'] as $trigger_host) { $host = $hosts[$trigger_host['hostid']]; $host_name = (new CSpan($host['name']))->addClass(ZBX_STYLE_LINK_ACTION)->setMenuPopup(CMenuPopupHelper::getHost($host, $scripts[$host['hostid']])); if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $maintenance_icon = (new CSpan())->addClass(ZBX_STYLE_ICON_MAINT)->addClass(ZBX_STYLE_CURSOR_POINTER); if (array_key_exists($host['maintenanceid'], $maintenances)) { $maintenance = $maintenances[$host['maintenanceid']]; $hint = $maintenance['name'] . ' [' . ($host['maintenance_type'] ? _('Maintenance without data collection') : _('Maintenance with data collection')) . ']'; if ($maintenance['description']) { $hint .= "\n" . $maintenance['description']; } $maintenance_icon->setHint($hint); } $host_name = (new CSpan([$host_name, $maintenance_icon]))->addClass(ZBX_STYLE_REL_CONTAINER); } $host_list[] = $host_name; $host_list[] = ', '; } array_pop($host_list); // unknown triggers $unknown = ''; if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) { $unknown = makeUnknownIcon($trigger['error']); } // trigger has events if ($trigger['lastEvent']) { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, ['clock' => $trigger['lastEvent']['clock'], 'ns' => $trigger['lastEvent']['ns']])); } else { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, ['clock' => $trigger['lastchange'], 'ns' => '999999999'])); } if ($config['event_ack_enable']) { if ($trigger['lastEvent']) { $trigger['lastEvent']['acknowledges'] = $event_acknowledges[$trigger['lastEvent']['eventid']]['acknowledges']; $ack = getEventAckState($trigger['lastEvent'], $backurl); } else { $ack = (new CSpan(_('No events')))->addClass(ZBX_STYLE_GREY); } } else { $ack = null; } // description if ($trigger['lastEvent'] || $trigger['comments'] !== '' || $trigger['url'] !== '') { $description = (new CSpan($description))->setHint(make_popup_eventlist($trigger, $backurl), '', true, 'max-width: 500px')->addClass(ZBX_STYLE_LINK_ACTION); } $description = (new CCol($description))->addClass(getSeverityStyle($trigger['priority'])); // clock $clock = new CLink(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $trigger['lastchange']), 'events.php?filter_set=1&triggerid=' . $trigger['triggerid'] . '&period=' . ZBX_PERIOD_DEFAULT . '&stime=' . date(TIMESTAMP_FORMAT, $trigger['lastchange'])); // actions $action_hint = $trigger['lastEvent'] && isset($actions[$trigger['lastEvent']['eventid']]) ? $actions[$trigger['lastEvent']['eventid']] : SPACE; $table->addRow([new CCol($host_list), $description, $clock, zbx_date2age($trigger['lastchange']), $unknown, $ack, (new CCol($action_hint))->addClass(ZBX_STYLE_NOWRAP)]); } // initialize blinking zbx_add_post_js('jqBlink.blink();'); $info = _n('%1$d of %2$d issue is shown', '%1$d of %2$d issues are shown', count($triggers), $triggers_total_count); return [$table, $info]; }
/** * Create DIV with latest problem triggers. * * If no sortfield and sortorder are defined, the sort indicater in the column name will not be displayed. * * @param array $filter['screenid'] * @param array $filter['groupids'] * @param array $filter['hostids'] * @param array $filter['maintenance'] * @param int $filter['extAck'] * @param int $filter['severity'] * @param int $filter['limit'] * @param string $filter['sortfield'] * @param string $filter['sortorder'] * @param string $filter['backUrl'] * * @return CDiv */ function make_latest_issues(array $filter = array()) { // hide the sort indicator if no sortfield and sortorder are given $showSortIndicator = isset($filter['sortfield']) || isset($filter['sortorder']); if (!isset($filter['sortfield'])) { $filter['sortfield'] = 'lastchange'; } if (!isset($filter['sortorder'])) { $filter['sortorder'] = ZBX_SORT_DOWN; } $options = array('groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'filter' => array('priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE)); $triggers = API::Trigger()->get(array_merge($options, array('withLastEventUnacknowledged' => isset($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'output' => array('triggerid', 'state', 'error', 'url', 'expression', 'description', 'priority', 'lastchange'), 'selectHosts' => array('hostid', 'name'), 'selectLastEvent' => array('eventid', 'acknowledged', 'objectid', 'clock', 'ns'), 'sortfield' => $filter['sortfield'], 'sortorder' => $filter['sortorder'], 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT))); // don't use withLastEventUnacknowledged and skipDependent because of performance issues $triggersTotalCount = API::Trigger()->get(array_merge($options, array('countOutput' => true))); // get acknowledges $eventIds = array(); foreach ($triggers as $trigger) { if ($trigger['lastEvent']) { $eventIds[] = $trigger['lastEvent']['eventid']; } } if ($eventIds) { $eventAcknowledges = API::Event()->get(array('eventids' => $eventIds, 'select_acknowledges' => API_OUTPUT_EXTEND, 'preservekeys' => true)); } foreach ($triggers as $tnum => $trigger) { // if trigger is lost (broken expression) we skip it if (empty($trigger['hosts'])) { unset($triggers[$tnum]); continue; } $host = reset($trigger['hosts']); $trigger['hostid'] = $host['hostid']; $trigger['hostname'] = $host['name']; if ($trigger['lastEvent']) { $trigger['lastEvent']['acknowledges'] = isset($eventAcknowledges[$trigger['lastEvent']['eventid']]) ? $eventAcknowledges[$trigger['lastEvent']['eventid']]['acknowledges'] : null; } $triggers[$tnum] = $trigger; } $hostIds = zbx_objectValues($triggers, 'hostid'); // get hosts $hosts = API::Host()->get(array('hostids' => $hostIds, 'output' => array('hostid', 'name', 'status', 'maintenance_status', 'maintenance_type', 'maintenanceid'), 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true)); // actions $actions = getEventActionsStatHints($eventIds); // ack params $ackParams = isset($filter['screenid']) ? array('screenid' => $filter['screenid']) : array(); $config = select_config(); // indicator of sort field if ($showSortIndicator) { $sortDiv = new CDiv(SPACE, $filter['sortorder'] === ZBX_SORT_DOWN ? 'icon_sortdown default_cursor' : 'icon_sortup default_cursor'); $sortDiv->addStyle('float: left'); $hostHeaderDiv = new CDiv(array(_('Host'), SPACE)); $hostHeaderDiv->addStyle('float: left'); $issueHeaderDiv = new CDiv(array(_('Issue'), SPACE)); $issueHeaderDiv->addStyle('float: left'); $lastChangeHeaderDiv = new CDiv(array(_('Time'), SPACE)); $lastChangeHeaderDiv->addStyle('float: left'); } $table = new CTableInfo(_('No events found.')); $table->setHeader(array(is_show_all_nodes() ? _('Node') : null, $showSortIndicator && $filter['sortfield'] === 'hostname' ? array($hostHeaderDiv, $sortDiv) : _('Host'), $showSortIndicator && $filter['sortfield'] === 'priority' ? array($issueHeaderDiv, $sortDiv) : _('Issue'), $showSortIndicator && $filter['sortfield'] === 'lastchange' ? array($lastChangeHeaderDiv, $sortDiv) : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions'))); $scripts = API::Script()->getScriptsByHosts($hostIds); // triggers foreach ($triggers as $trigger) { $host = $hosts[$trigger['hostid']]; $hostName = new CSpan($host['name'], 'link_menu'); $hostName->setMenuPopup(getMenuPopupHost($host, $scripts[$host['hostid']])); // add maintenance icon with hint if host is in maintenance $maintenanceIcon = null; if ($host['maintenance_status']) { $maintenanceIcon = new CDiv(null, 'icon-maintenance-abs'); // get maintenance $maintenances = API::Maintenance()->get(array('maintenanceids' => $host['maintenanceid'], 'output' => API_OUTPUT_EXTEND, 'limit' => 1)); if ($maintenance = reset($maintenances)) { $hint = $maintenance['name'] . ' [' . ($host['maintenance_type'] ? _('Maintenance without data collection') : _('Maintenance with data collection')) . ']'; if (isset($maintenance['description'])) { // double quotes mandatory $hint .= "\n" . $maintenance['description']; } $maintenanceIcon->setHint($hint); $maintenanceIcon->addClass('pointer'); } $hostName->addClass('left-to-icon-maintenance-abs'); } $hostDiv = new CDiv(array($hostName, $maintenanceIcon), 'maintenance-abs-cont'); // unknown triggers $unknown = SPACE; if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) { $unknown = new CDiv(SPACE, 'status_icon iconunknown'); $unknown->setHint($trigger['error'], '', 'on'); } // trigger has events if ($trigger['lastEvent']) { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastEvent']['clock'], 'ns' => $trigger['lastEvent']['ns']))); // ack $ack = getEventAckState($trigger['lastEvent'], empty($filter['backUrl']) ? true : $filter['backUrl'], true, $ackParams); } else { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastchange'], 'ns' => '999999999'))); // ack $ack = new CSpan(_('No events'), 'unknown'); } // description if (!zbx_empty($trigger['url'])) { $description = new CLink($description, resolveTriggerUrl($trigger), null, null, true); } else { $description = new CSpan($description, 'pointer'); } $description = new CCol($description, getSeverityStyle($trigger['priority'])); if ($trigger['lastEvent']) { $description->setHint(make_popup_eventlist($trigger['triggerid'], $trigger['lastEvent']['eventid']), '', '', false); } // clock $clock = new CLink(zbx_date2str(_('d M Y H:i:s'), $trigger['lastchange']), 'events.php?triggerid=' . $trigger['triggerid'] . '&source=0&show_unknown=1&nav_time=' . $trigger['lastchange']); // actions $actionHint = $trigger['lastEvent'] && isset($actions[$trigger['lastEvent']['eventid']]) ? $actions[$trigger['lastEvent']['eventid']] : SPACE; $table->addRow(array(get_node_name_by_elid($trigger['triggerid']), $hostDiv, $description, $clock, zbx_date2age($trigger['lastchange']), $unknown, $ack, $actionHint)); } // initialize blinking zbx_add_post_js('jqBlink.blink();'); $script = new CJSScript(get_js("jQuery('#hat_lastiss_footer').html('" . _s('Updated: %s', zbx_date2str(_('H:i:s'))) . "')")); $infoDiv = new CDiv(_n('%1$d of %2$d issue is shown', '%1$d of %2$d issues are shown', count($triggers), $triggersTotalCount)); $infoDiv->addStyle('text-align: right; padding-right: 3px;'); return new CDiv(array($table, $infoDiv, $script)); }
foreach ($triggers as $tnum => $trigger) { if (!isset($trigger['hasEvents'])) { $triggers[$tnum]['hasEvents'] = isset($allEventCounts[$trigger['triggerid']]); } } } } $tr_hostids = array(); foreach ($triggers as $tnum => $trigger) { $triggers[$tnum]['events'] = array(); //getting all host ids and names foreach ($trigger['hosts'] as $tr_hosts) { $tr_hostids[$tr_hosts['hostid']] = $tr_hosts['hostid']; } } $scripts_by_hosts = API::Script()->getScriptsByHosts($tr_hostids); // fetch all hosts $hosts = API::Host()->get(array('hostids' => $tr_hostids, 'preservekeys' => true, 'selectScreens' => API_OUTPUT_COUNT, 'selectInventory' => array('hostid'))); if ($show_events != EVENTS_OPTION_NOEVENT) { $ev_options = array('nodeids' => get_current_nodeid(), 'triggerids' => zbx_objectValues($triggers, 'triggerid'), 'filter' => array('value_changed' => TRIGGER_VALUE_CHANGED_YES), 'output' => API_OUTPUT_EXTEND, 'select_acknowledges' => API_OUTPUT_COUNT, 'time_from' => time() - $config['event_expire'] * SEC_PER_DAY, 'time_till' => time(), 'nopermissions' => true); switch ($show_events) { case EVENTS_OPTION_ALL: break; case EVENTS_OPTION_NOT_ACK: $ev_options['acknowledged'] = false; $ev_options['value'] = TRIGGER_VALUE_TRUE; break; } $events = API::Event()->get($ev_options); $sortFields = array(array('field' => 'clock', 'order' => ZBX_SORT_DOWN), array('field' => 'eventid', 'order' => ZBX_SORT_DOWN)); CArrayHelper::sort($events, $sortFields);