1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22require_once dirname(__FILE__).'/../../blocks.inc.php'; 23 24class CScreenHostTriggers extends CScreenBase { 25 26 /** 27 * Process screen. 28 * 29 * @return CDiv (screen inside container) 30 */ 31 public function get() { 32 $params = [ 33 'groupids' => null, 34 'hostids' => null, 35 'maintenance' => null, 36 'trigger_name' => '', 37 'severity' => null, 38 'limit' => $this->screenitem['elements'] 39 ]; 40 41 // by default triggers are sorted by date desc, do we need to override this? 42 switch ($this->screenitem['sort_triggers']) { 43 case SCREEN_SORT_TRIGGERS_DATE_DESC: 44 $params['sortfield'] = 'lastchange'; 45 $params['sortorder'] = ZBX_SORT_DOWN; 46 break; 47 case SCREEN_SORT_TRIGGERS_SEVERITY_DESC: 48 $params['sortfield'] = 'severity'; 49 $params['sortorder'] = ZBX_SORT_DOWN; 50 break; 51 case SCREEN_SORT_TRIGGERS_HOST_NAME_ASC: 52 // a little black magic here - there is no such field 'hostname' in 'triggers', 53 // but API has a special case for sorting by hostname 54 $params['sortfield'] = 'hostname'; 55 $params['sortorder'] = ZBX_SORT_UP; 56 break; 57 } 58 59 if ($this->screenitem['resourceid'] != 0) { 60 $hosts = API::Host()->get([ 61 'output' => ['name'], 62 'hostids' => [$this->screenitem['resourceid']] 63 ]); 64 65 $header = (new CDiv([ 66 new CTag('h4', true, _('Host issues')), 67 (new CList())->addItem([_('Host'), ':', SPACE, $hosts[0]['name']]) 68 ]))->addClass(ZBX_STYLE_DASHBRD_WIDGET_HEAD); 69 70 $params['hostids'] = $this->screenitem['resourceid']; 71 } 72 else { 73 $groupid = getRequest('tr_groupid', CProfile::get('web.screens.tr_groupid', 0)); 74 $hostid = getRequest('tr_hostid', CProfile::get('web.screens.tr_hostid', 0)); 75 76 CProfile::update('web.screens.tr_groupid', $groupid, PROFILE_TYPE_ID); 77 CProfile::update('web.screens.tr_hostid', $hostid, PROFILE_TYPE_ID); 78 79 // get groups 80 $groups = API::HostGroup()->get([ 81 'output' => ['name'], 82 'monitored_hosts' => true, 83 'preservekeys' => true 84 ]); 85 order_result($groups, 'name'); 86 87 foreach ($groups as &$group) { 88 $group = $group['name']; 89 } 90 unset($group); 91 92 // get hsots 93 $options = [ 94 'output' => ['name'], 95 'monitored_hosts' => true, 96 'preservekeys' => true 97 ]; 98 if ($groupid != 0) { 99 $options['groupids'] = [$groupid]; 100 } 101 $hosts = API::Host()->get($options); 102 order_result($hosts, 'name'); 103 104 foreach ($hosts as &$host) { 105 $host = $host['name']; 106 } 107 unset($host); 108 109 $groups = [0 => _('all')] + $groups; 110 $hosts = [0 => _('all')] + $hosts; 111 112 if (!array_key_exists($hostid, $hosts)) { 113 $hostid = 0; 114 } 115 116 if ($groupid != 0) { 117 $params['groupids'] = $groupid; 118 } 119 if ($hostid != 0) { 120 $params['hostids'] = $hostid; 121 } 122 123 $groups_cb = (new CComboBox('tr_groupid', $groupid, 'submit()', $groups)) 124 ->setEnabled($this->mode != SCREEN_MODE_EDIT); 125 $hosts_cb = (new CComboBox('tr_hostid', $hostid, 'submit()', $hosts)) 126 ->setEnabled($this->mode != SCREEN_MODE_EDIT); 127 128 $header = (new CDiv([ 129 new CTag('h4', true, _('Host issues')), 130 (new CForm('get', $this->pageFile)) 131 ->addItem( 132 (new CList()) 133 ->addItem([_('Group'), ' ', $groups_cb]) 134 ->addItem(' ') 135 ->addItem([_('Host'), ' ', $hosts_cb]) 136 ) 137 ]))->addClass(ZBX_STYLE_DASHBRD_WIDGET_HEAD); 138 } 139 140 list($table, $info) = $this->getProblemsListTable($params, 141 (new CUrl($this->pageFile)) 142 ->setArgument('screenid', $this->screenid) 143 ->getUrl() 144 ); 145 146 $footer = (new CList()) 147 ->addItem($info) 148 ->addItem(_s('Updated: %s', zbx_date2str(TIME_FORMAT_SECONDS))) 149 ->addClass(ZBX_STYLE_DASHBRD_WIDGET_FOOT); 150 151 return $this->getOutput(new CUiWidget('hat_trstatus', [$header, $table, $footer])); 152 } 153 154 /** 155 * Render table with host or host group problems. 156 * 157 * @param array $filter Array of filter options. 158 * @param int $filter['limit'] Table rows count. 159 * @param array $filter['groupids'] Host group ids. 160 * @param array $filter['hostids'] Host ids. 161 * @param string $filter['sortfield'] Sort field name. 162 * @param string $filter['sortorder'] Sort order. 163 * @param string $back_url URL used by acknowledgment page. 164 */ 165 protected function getProblemsListTable($filter, $back_url) { 166 $config = select_config(); 167 168 $filter = $filter + [ 169 'show' => TRIGGERS_OPTION_IN_PROBLEM, 170 'show_timeline' => 0, 171 'details' => 1, 172 'show_latest_values' => 0, 173 'sort_field' => '', 174 'sort_order' => ZBX_SORT_DOWN 175 ]; 176 177 $data = CScreenProblem::getData($filter, $config); 178 179 $header = [ 180 'hostname' => _('Host'), 181 'severity' => _('Issue'), 182 'lastchange' => _('Last change') 183 ]; 184 185 if (array_key_exists('sortfield', $filter)) { 186 $sort_field = $filter['sortfield']; 187 $sort_order = ($sort_field !== 'lastchange') ? $filter['sortorder'] : ZBX_SORT_DOWN; 188 189 $header[$sort_field] = [ 190 $header[$sort_field], 191 (new CDiv())->addClass(($sort_order === ZBX_SORT_DOWN) ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP) 192 ]; 193 194 $data = CScreenProblem::sortData($data, $config, $sort_field === 'hostname' ? 'host' : $sort_field, 195 $sort_order 196 ); 197 } 198 199 $info = _n('%1$d of %3$d%2$s problem is shown', '%1$d of %3$d%2$s problems are shown', 200 min($filter['limit'], count($data['problems'])), 201 (count($data['problems']) > $config['search_limit']) ? '+' : '', 202 min($config['search_limit'], count($data['problems'])) 203 ); 204 $data['problems'] = array_slice($data['problems'], 0, $filter['limit'], true); 205 $data = CScreenProblem::makeData($data, $filter); 206 207 $hostids = []; 208 foreach ($data['triggers'] as $trigger) { 209 $hostids += $trigger['hosts'] ? array_fill_keys(zbx_objectValues($trigger['hosts'], 'hostid'), '') : []; 210 } 211 212 $hosts = API::Host()->get([ 213 'output' => ['hostid', 'name', 'status'], 214 'hostids' => array_keys($hostids), 215 'preservekeys' => true 216 ]); 217 218 $table = (new CTableInfo())->setHeader($header + [_('Age'), _('Info'), _('Ack'), _('Actions')]); 219 220 foreach ($data['problems'] as $problem) { 221 $trigger = $data['triggers'][$problem['objectid']]; 222 223 // Host name with hint box. 224 $host = reset($trigger['hosts']); 225 $host = $hosts[$host['hostid']]; 226 $host_name = (new CLinkAction($host['name']))->setMenuPopup(CMenuPopupHelper::getHost($host['hostid'])); 227 228 // Info. 229 $info_icons = []; 230 if ($problem['r_eventid'] != 0) { 231 if ($problem['correlationid'] != 0) { 232 $info_icons[] = makeInformationIcon( 233 array_key_exists($problem['correlationid'], $data['correlations']) 234 ? _s('Resolved by correlation rule "%1$s".', 235 $data['correlations'][$problem['correlationid']]['name'] 236 ) 237 : _('Resolved by correlation rule.') 238 ); 239 } 240 elseif ($problem['userid'] != 0) { 241 $info_icons[] = makeInformationIcon( 242 array_key_exists($problem['userid'], $data['users']) 243 ? _s('Resolved by user "%1$s".', getUserFullname($data['users'][$problem['userid']])) 244 : _('Resolved by inaccessible user.') 245 ); 246 } 247 } 248 249 // Clock. 250 $clock = new CLink(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $problem['clock']), 251 (new CUrl('zabbix.php')) 252 ->setArgument('action', 'problem.view') 253 ->setArgument('filter_triggerids[]', $trigger['triggerid']) 254 ->setArgument('filter_set', '1') 255 ); 256 257 $table->addRow([ 258 $host_name, 259 (new CCol([ 260 (new CLinkAction($problem['name'])) 261 ->setAjaxHint( 262 CHintBoxHelper::getEventList($trigger['triggerid'], $problem['eventid'], $back_url) 263 ) 264 ]))->addClass(getSeverityStyle($problem['severity'])), 265 $clock, 266 zbx_date2age($problem['clock']), 267 makeInformationList($info_icons), 268 (new CLink($problem['acknowledged'] ? _('Yes') : _('No'), 269 (new CUrl('zabbix.php')) 270 ->setArgument('action', 'acknowledge.edit') 271 ->setArgument('eventids', [$problem['eventid']]) 272 ->setArgument('backurl', $back_url) 273 ->getUrl()) 274 ) 275 ->addClass($problem['acknowledged'] ? ZBX_STYLE_GREEN : ZBX_STYLE_RED) 276 ->addClass(ZBX_STYLE_LINK_ALT), 277 makeEventActionsIcons($problem['eventid'], $data['actions'], $data['mediatypes'], $data['users'], 278 $config 279 ) 280 ]); 281 } 282 283 return [$table, $info]; 284 } 285} 286