You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
9.3 KiB

<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
namespace Widgets\Problems\Actions;
use CControllerDashboardWidgetView,
CControllerResponseData,
CRoleHelper,
CScreenProblem,
CSettingsHelper,
API;
class WidgetView extends CControllerDashboardWidgetView {
protected function init(): void {
parent::init();
$this->addValidationRules([
'initial_load' => 'in 0,1',
'dynamic_hostid' => 'db hosts.hostid'
]);
}
protected function doAction(): void {
// Editing template dashboard?
if ($this->isTemplateDashboard() && !$this->hasInput('dynamic_hostid')) {
$this->setResponse(new CControllerResponseData([
'name' => $this->getInput('name', $this->widget->getDefaultName()),
'error' => _('No data.'),
'user' => [
'debug_mode' => $this->getDebugMode()
]
]));
}
else {
$search_limit = CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT);
$data = CScreenProblem::getData([
'show' => $this->fields_values['show'],
'groupids' => !$this->isTemplateDashboard() ? $this->fields_values['groupids'] : null,
'exclude_groupids' => !$this->isTemplateDashboard() ? $this->fields_values['exclude_groupids'] : null,
'hostids' => !$this->isTemplateDashboard()
? $this->fields_values['hostids']
: [$this->getInput('dynamic_hostid')],
'name' => $this->fields_values['problem'],
'severities' => $this->fields_values['severities'],
'evaltype' => $this->fields_values['evaltype'],
'tags' => $this->fields_values['tags'],
'show_symptoms' => $this->fields_values['show_symptoms'],
'show_suppressed' => $this->fields_values['show_suppressed'],
'acknowledgement_status' => $this->fields_values['acknowledgement_status'],
'acknowledged_by_me' => $this->fields_values['acknowledgement_status'] == ZBX_ACK_STATUS_ACK
? $this->fields_values['acknowledged_by_me']
: 0,
'show_opdata' => $this->fields_values['show_opdata']
], $search_limit);
[$sortfield, $sortorder] = self::getSorting($this->fields_values['sort_triggers']);
$data = CScreenProblem::sortData($data, $search_limit, $sortfield, $sortorder);
if (count($data['problems']) > $this->fields_values['show_lines']) {
$info = _n('%1$d of %3$d%2$s problem is shown', '%1$d of %3$d%2$s problems are shown',
min($this->fields_values['show_lines'], count($data['problems'])),
(count($data['problems']) > $search_limit) ? '+' : '',
min($search_limit, count($data['problems']))
);
}
else {
$info = '';
}
$data['problems'] = array_slice($data['problems'], 0, $this->fields_values['show_lines'], true);
$data = CScreenProblem::makeData($data, [
'show' => $this->fields_values['show'],
'details' => 0,
'show_opdata' => $this->fields_values['show_opdata']
]);
$data += [
'show_three_columns' => false,
'show_two_columns' => false
];
$cause_eventids_with_symptoms = [];
$symptom_data['problems'] = [];
if ($data['problems']) {
$data['triggers_hosts'] = getTriggersHostsList($data['triggers']);
foreach ($data['problems'] as &$problem) {
$problem['symptom_count'] = 0;
$problem['symptoms'] = [];
if ($problem['cause_eventid'] == 0) {
$options = [
'output' => ['objectid'],
'filter' => ['cause_eventid' => $problem['eventid']]
];
$symptom_events = $this->fields_values['show'] == TRIGGERS_OPTION_ALL
? API::Event()->get($options)
: API::Problem()->get($options + ['recent' => true]);
if ($symptom_events) {
$enabled_triggers = API::Trigger()->get([
'output' => [],
'triggerids' => array_column($symptom_events, 'objectid'),
'filter' => ['status' => TRIGGER_STATUS_ENABLED],
'preservekeys' => true
]);
$symptom_events = array_filter($symptom_events,
static fn($event) => array_key_exists($event['objectid'], $enabled_triggers)
);
$problem['symptom_count'] = count($symptom_events);
}
if ($problem['symptom_count'] > 0) {
$data['show_three_columns'] = true;
$cause_eventids_with_symptoms[] = $problem['eventid'];
}
}
// There is at least one independent symptom event.
if ($problem['cause_eventid'] != 0) {
$data['show_two_columns'] = true;
}
}
unset($problem);
if ($cause_eventids_with_symptoms) {
// Get all symptoms for given cause event IDs.
$symptom_data = CScreenProblem::getData([
'show_symptoms' => true,
'show_suppressed' => true,
'cause_eventid' => $cause_eventids_with_symptoms,
'show' => $this->fields_values['show'],
'show_opdata' => $this->fields_values['show_opdata']
], ZBX_PROBLEM_SYMPTOM_LIMIT, true);
if ($symptom_data['problems']) {
$symptom_data = CScreenProblem::sortData($symptom_data, ZBX_PROBLEM_SYMPTOM_LIMIT, $sortfield,
$sortorder
);
// Filter does not matter.
$symptom_data = CScreenProblem::makeData($symptom_data, [
'show' => $this->fields_values['show'],
'show_opdata' => $this->fields_values['show_opdata'],
'details' => 0
], true);
$data['users'] += $symptom_data['users'];
$data['correlations'] += $symptom_data['correlations'];
foreach ($symptom_data['actions'] as $key => $actions) {
$data['actions'][$key] += $actions;
}
if ($symptom_data['triggers']) {
// Add hosts from symptoms to the list.
$data['triggers_hosts'] += getTriggersHostsList($symptom_data['triggers']);
// Store all known triggers in one place.
$data['triggers'] += $symptom_data['triggers'];
}
foreach ($data['problems'] as &$problem) {
foreach ($symptom_data['problems'] as $symptom) {
if (bccomp($symptom['cause_eventid'], $problem['eventid']) == 0) {
$problem['symptoms'][] = $symptom;
}
}
}
unset($problem);
}
}
}
if ($this->fields_values['show_tags']) {
$data['tags'] = makeTags($data['problems'] + $symptom_data['problems'], true, 'eventid',
$this->fields_values['show_tags'], $this->fields_values['tags'], null,
$this->fields_values['tag_name_format'], $this->fields_values['tag_priority']
);
}
$this->setResponse(new CControllerResponseData($data + [
'name' => $this->getInput('name', $this->widget->getDefaultName()),
'error' => null,
'initial_load' => (bool) $this->getInput('initial_load', 0),
'fields' => [
'show' => $this->fields_values['show'],
'show_lines' => $this->fields_values['show_lines'],
'show_tags' => $this->fields_values['show_tags'],
'show_timeline' => $this->fields_values['show_timeline'],
'tags' => $this->fields_values['tags'],
'tag_name_format' => $this->fields_values['tag_name_format'],
'tag_priority' => $this->fields_values['tag_priority'],
'show_opdata' => $this->fields_values['show_opdata']
],
'info' => $info,
'sortfield' => $sortfield,
'sortorder' => $sortorder,
'user' => [
'debug_mode' => $this->getDebugMode()
],
'config' => [
'problem_ack_style' => CSettingsHelper::get(CSettingsHelper::PROBLEM_ACK_STYLE),
'problem_unack_style' => CSettingsHelper::get(CSettingsHelper::PROBLEM_UNACK_STYLE),
'blink_period' => CSettingsHelper::get(CSettingsHelper::BLINK_PERIOD)
],
'allowed' => [
'ui_problems' => $this->checkAccess(CRoleHelper::UI_MONITORING_PROBLEMS),
'add_comments' => $this->checkAccess(CRoleHelper::ACTIONS_ADD_PROBLEM_COMMENTS),
'change_severity' => $this->checkAccess(CRoleHelper::ACTIONS_CHANGE_SEVERITY),
'acknowledge' => $this->checkAccess(CRoleHelper::ACTIONS_ACKNOWLEDGE_PROBLEMS),
'close' => $this->checkAccess(CRoleHelper::ACTIONS_CLOSE_PROBLEMS),
'suppress_problems' => $this->checkAccess(CRoleHelper::ACTIONS_SUPPRESS_PROBLEMS),
'rank_change' => $this->checkAccess(CRoleHelper::ACTIONS_CHANGE_PROBLEM_RANKING)
]
]));
}
}
private static function getSorting(int $sort_triggers): array {
switch ($sort_triggers) {
case SCREEN_SORT_TRIGGERS_TIME_ASC:
return ['clock', ZBX_SORT_UP];
case SCREEN_SORT_TRIGGERS_TIME_DESC:
default:
return ['clock', ZBX_SORT_DOWN];
case SCREEN_SORT_TRIGGERS_SEVERITY_ASC:
return ['severity', ZBX_SORT_UP];
case SCREEN_SORT_TRIGGERS_SEVERITY_DESC:
return ['severity', ZBX_SORT_DOWN];
case SCREEN_SORT_TRIGGERS_HOST_NAME_ASC:
return ['host', ZBX_SORT_UP];
case SCREEN_SORT_TRIGGERS_HOST_NAME_DESC:
return ['host', ZBX_SORT_DOWN];
case SCREEN_SORT_TRIGGERS_NAME_ASC:
return ['name', ZBX_SORT_UP];
case SCREEN_SORT_TRIGGERS_NAME_DESC:
return ['name', ZBX_SORT_DOWN];
}
}
}