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 22// indicator of sort field 23$sort_div = (new CSpan())->addClass(($data['sortorder'] === ZBX_SORT_DOWN) ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP); 24 25$backurl = (new CUrl('zabbix.php')) 26 ->setArgument('action', 'dashboard.view') 27 ->getUrl(); 28 29$url_details = (new CUrl('tr_events.php')) 30 ->setArgument('triggerid', '') 31 ->setArgument('eventid', ''); 32 33$show_timeline = ($data['sortfield'] === 'clock' && $data['fields']['show_timeline']); 34$show_recovery_data = in_array($data['fields']['show'], [TRIGGERS_OPTION_RECENT_PROBLEM, TRIGGERS_OPTION_ALL]); 35 36$header_time = new CColHeader(($data['sortfield'] === 'clock') ? [_('Time'), $sort_div] : _('Time')); 37 38if ($show_timeline) { 39 $header = [ 40 $header_time->addClass(ZBX_STYLE_RIGHT), 41 (new CColHeader())->addClass(ZBX_STYLE_TIMELINE_TH), 42 (new CColHeader())->addClass(ZBX_STYLE_TIMELINE_TH) 43 ]; 44} 45else { 46 $header = [$header_time]; 47} 48 49$table = (new CTableInfo()) 50 ->setHeader(array_merge($header, [ 51 $show_recovery_data ? _('Recovery time') : null, 52 $show_recovery_data ? _('Status') : null, 53 _('Info'), 54 ($data['sortfield'] === 'host') ? [_('Host'), $sort_div] : _('Host'), 55 [ 56 ($data['sortfield'] === 'name') ? [_('Problem'), $sort_div] : _('Problem'), 57 ' • ', 58 ($data['sortfield'] === 'severity') ? [_('Severity'), $sort_div] : _('Severity') 59 ], 60 $data['fields']['show_latest_values'] ? _('Latest values') : null, 61 _('Duration'), 62 _('Ack'), 63 _('Actions'), 64 $data['fields']['show_tags'] ? _('Tags') : null 65 ])); 66 67$today = strtotime('today'); 68$last_clock = 0; 69 70if ($data['data']['problems']) { 71 $triggers_hosts = makeTriggersHostsList($data['data']['triggers_hosts']); 72} 73 74foreach ($data['data']['problems'] as $eventid => $problem) { 75 $trigger = $data['data']['triggers'][$problem['objectid']]; 76 77 if ($problem['r_eventid'] != 0) { 78 $value = TRIGGER_VALUE_FALSE; 79 $value_str = _('RESOLVED'); 80 $value_clock = $problem['r_clock']; 81 } 82 else { 83 $in_closing = false; 84 85 foreach ($problem['acknowledges'] as $acknowledge) { 86 if (($acknowledge['action'] & ZBX_PROBLEM_UPDATE_CLOSE) == ZBX_PROBLEM_UPDATE_CLOSE) { 87 $in_closing = true; 88 break; 89 } 90 } 91 92 $value = $in_closing ? TRIGGER_VALUE_FALSE : TRIGGER_VALUE_TRUE; 93 $value_str = $in_closing ? _('CLOSING') : _('PROBLEM'); 94 $value_clock = $in_closing ? time() : $problem['clock']; 95 } 96 97 $url_details 98 ->setArgument('triggerid', $problem['objectid']) 99 ->setArgument('eventid', $problem['eventid']); 100 101 $cell_clock = ($problem['clock'] >= $today) 102 ? zbx_date2str(TIME_FORMAT_SECONDS, $problem['clock']) 103 : zbx_date2str(DATE_TIME_FORMAT_SECONDS, $problem['clock']); 104 $cell_clock = new CCol(new CLink($cell_clock, $url_details)); 105 106 $is_acknowledged = $problem['acknowledged'] == EVENT_ACKNOWLEDGED; 107 108 if ($show_recovery_data) { 109 if ($problem['r_eventid'] != 0) { 110 $cell_r_clock = ($problem['r_clock'] >= $today) 111 ? zbx_date2str(TIME_FORMAT_SECONDS, $problem['r_clock']) 112 : zbx_date2str(DATE_TIME_FORMAT_SECONDS, $problem['r_clock']); 113 $cell_r_clock = (new CCol(new CLink($cell_r_clock, $url_details))) 114 ->addClass(ZBX_STYLE_NOWRAP) 115 ->addClass(ZBX_STYLE_RIGHT); 116 } 117 else { 118 $cell_r_clock = ''; 119 } 120 121 $cell_status = new CSpan($value_str); 122 123 // Add colors and blinking to span depending on configuration and trigger parameters. 124 addTriggerValueStyle($cell_status, $value, $value_clock, $is_acknowledged); 125 } 126 127 // Info. 128 $info_icons = []; 129 if ($problem['r_eventid'] != 0) { 130 if ($problem['correlationid'] != 0) { 131 $info_icons[] = makeInformationIcon( 132 array_key_exists($problem['correlationid'], $data['data']['correlations']) 133 ? _s('Resolved by correlation rule "%1$s".', 134 $data['data']['correlations'][$problem['correlationid']]['name'] 135 ) 136 : _('Resolved by correlation rule.') 137 ); 138 } 139 elseif ($problem['userid'] != 0) { 140 $info_icons[] = makeInformationIcon( 141 array_key_exists($problem['userid'], $data['data']['users']) 142 ? _s('Resolved by user "%1$s".', getUserFullname($data['data']['users'][$problem['userid']])) 143 : _('Resolved by inaccessible user.') 144 ); 145 } 146 } 147 148 if (array_key_exists('suppression_data', $problem) && $problem['suppression_data']) { 149 $info_icons[] = makeSuppressedProblemIcon($problem['suppression_data']); 150 } 151 152 $description = (new CCol([ 153 (new CLinkAction($problem['name'])) 154 ->setAjaxHint(CHintBoxHelper::getEventList($trigger['triggerid'], $eventid, $backurl, $show_timeline, 155 $data['fields']['show_tags'], $data['fields']['tags'], $data['fields']['tag_name_format'], 156 $data['fields']['tag_priority'] 157 )) 158 ->setAttribute('aria-label', _xs('%1$s, Severity, %2$s', 'screen reader', 159 $problem['name'], getSeverityName($problem['severity'], $data['config']) 160 )) 161 ])); 162 163 $description_style = getSeverityStyle($problem['severity']); 164 165 if ($value == TRIGGER_VALUE_TRUE) { 166 $description->addClass($description_style); 167 } 168 169 if (!$show_recovery_data && $data['config'][$is_acknowledged ? 'problem_ack_style' : 'problem_unack_style']) { 170 // blinking 171 $duration = time() - $problem['clock']; 172 173 if ($data['config']['blink_period'] != 0 && $duration < $data['config']['blink_period']) { 174 $description 175 ->addClass('blink') 176 ->setAttribute('data-time-to-blink', $data['config']['blink_period'] - $duration) 177 ->setAttribute('data-toggle-class', ZBX_STYLE_BLINK_HIDDEN); 178 } 179 } 180 181 if ($show_timeline) { 182 if ($last_clock != 0) { 183 CScreenProblem::addTimelineBreakpoint($table, $last_clock, $problem['clock'], $data['sortorder']); 184 } 185 $last_clock = $problem['clock']; 186 187 $row = [ 188 $cell_clock->addClass(ZBX_STYLE_TIMELINE_DATE), 189 (new CCol()) 190 ->addClass(ZBX_STYLE_TIMELINE_AXIS) 191 ->addClass(ZBX_STYLE_TIMELINE_DOT), 192 (new CCol())->addClass(ZBX_STYLE_TIMELINE_TD) 193 ]; 194 } 195 else { 196 $row = [ 197 $cell_clock 198 ->addClass(ZBX_STYLE_NOWRAP) 199 ->addClass(ZBX_STYLE_RIGHT) 200 ]; 201 } 202 203 // Create acknowledge url. 204 $problem_update_url = (new CUrl('zabbix.php')) 205 ->setArgument('action', 'acknowledge.edit') 206 ->setArgument('eventids', [$problem['eventid']]) 207 ->setArgument('backurl', $backurl) 208 ->getUrl(); 209 210 $table->addRow(array_merge($row, [ 211 $show_recovery_data ? $cell_r_clock : null, 212 $show_recovery_data ? $cell_status : null, 213 makeInformationList($info_icons), 214 $triggers_hosts[$trigger['triggerid']], 215 $description, 216 $data['fields']['show_latest_values'] ? CScreenProblem::getLatestValues($trigger['items']) : null, 217 (new CCol(zbx_date2age($problem['clock'], ($problem['r_eventid'] != 0) ? $problem['r_clock'] : 0))) 218 ->addClass(ZBX_STYLE_NOWRAP), 219 (new CLink($problem['acknowledged'] == EVENT_ACKNOWLEDGED ? _('Yes') : _('No'), $problem_update_url)) 220 ->addClass($problem['acknowledged'] == EVENT_ACKNOWLEDGED ? ZBX_STYLE_GREEN : ZBX_STYLE_RED) 221 ->addClass(ZBX_STYLE_LINK_ALT), 222 makeEventActionsIcons($problem['eventid'], $data['data']['actions'], $data['data']['mediatypes'], 223 $data['data']['users'], $data['config'] 224 ), 225 $data['fields']['show_tags'] ? $data['data']['tags'][$problem['eventid']] : null 226 ])); 227} 228 229if ($data['info'] !== '') { 230 $table->setFooter([ 231 (new CCol($data['info'])) 232 ->setColSpan($table->getNumCols()) 233 ->addClass(ZBX_STYLE_LIST_TABLE_FOOTER) 234 ]); 235} 236 237$output = [ 238 'aria_label' => _xs('%1$s widget', 'screen reader', $data['name']).', '.$data['info'], 239 'header' => $data['name'], 240 'body' => $table->toString() 241]; 242 243if (($messages = getMessages()) !== null) { 244 $output['messages'] = $messages->toString(); 245} 246 247if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) { 248 CProfiler::getInstance()->stop(); 249 $output['debug'] = CProfiler::getInstance()->make()->toString(); 250} 251 252echo (new CJson())->encode($output); 253