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.
zabbix/ui/app/controllers/CControllerDashboardView.php

303 lines
8.6 KiB

<?php
/*
** 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.
**/
class CControllerDashboardView extends CController {
protected function init() {
$this->disableCsrfValidation();
}
protected function checkInput() {
$fields = [
'dashboardid' => 'db dashboard.dashboardid',
'hostid' => 'db hosts.hostid',
'new' => 'in 1',
'cancel' => 'in 1',
'clone' => 'in 1',
'from' => 'range_time',
'to' => 'range_time',
'slideshow' => 'in 1'
];
$ret = $this->validateInput($fields) && $this->validateTimeSelectorPeriod();
if ($ret && $this->hasInput('clone')) {
$validator = new CNewValidator($this->getInputAll(), [
'dashboardid' => 'required'
]);
foreach ($validator->getAllErrors() as $error) {
info($error);
}
if ($validator->isErrorFatal() || $validator->isError()) {
$ret = false;
}
}
if (!$ret) {
$this->setResponse(new CControllerResponseFatal());
}
return $ret;
}
protected function checkPermissions() {
if (!$this->checkAccess(CRoleHelper::UI_MONITORING_DASHBOARD)) {
return false;
}
if ($this->hasInput('new') || $this->hasInput('clone')) {
return $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS);
}
if ($this->hasInput('hostid')) {
$hosts = API::Host()->get([
'output' => [],
'hostids' => [$this->getInput('hostid')]
]);
if (!$hosts) {
return false;
}
}
return true;
}
/**
* @throws JsonException
*/
protected function doAction() {
[$dashboard, $error] = $this->getDashboard();
if ($error !== null) {
$response = new CControllerResponseData(['error' => $error]);
$response->setTitle(_('Dashboard'));
$this->setResponse($response);
return;
}
if ($dashboard === null) {
$this->setResponse(new CControllerResponseRedirect((new CUrl('zabbix.php'))
->setArgument('action', 'dashboard.list')
->setArgument('page', $this->hasInput('cancel') ? CPagerHelper::loadPage('dashboard.list', null) : null)
));
return;
}
if ($this->hasInput('slideshow')) {
$dashboard['auto_start'] = '1';
}
$dashboard['can_edit_dashboards'] = $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS);
$dashboard['can_view_reports'] = $this->checkAccess(CRoleHelper::UI_REPORTS_SCHEDULED_REPORTS);
$dashboard['can_create_reports'] = $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_SCHEDULED_REPORTS);
$time_selector_options = [
'profileIdx' => 'web.dashboard.filter',
'profileIdx2' => $dashboard['dashboardid'] ?? 0,
'from' => $this->hasInput('from') ? $this->getInput('from') : null,
'to' => $this->hasInput('to') ? $this->getInput('to') : null
];
updateTimeSelectorPeriod($time_selector_options);
$widget_defaults = APP::ModuleManager()->getWidgetsDefaults();
$data = [
'dashboard' => $dashboard,
'widget_defaults' => $widget_defaults,
'widget_last_type' => CDashboardHelper::getWidgetLastType(),
'configuration_hash' => $dashboard['dashboardid'] !== null
? CDashboardHelper::getConfigurationHash($dashboard, $widget_defaults)
: null,
'has_time_selector' => CDashboardHelper::hasTimeSelector($dashboard['pages']),
'time_period' => getTimeSelectorPeriod($time_selector_options),
'clone' => $this->hasInput('clone'),
'active_tab' => CProfile::get('web.dashboard.filter.active', 1)
];
if (self::hasDynamicWidgets($dashboard['pages'])) {
$hostid = $this->getInput('hostid', CProfile::get('web.dashboard.hostid', 0));
$hosts = ($hostid != 0)
? CArrayHelper::renameObjectsKeys(API::Host()->get([
'output' => ['hostid', 'name'],
'hostids' => [$hostid]
]), ['hostid' => 'id'])
: [];
$data['dynamic'] = [
'has_dynamic_widgets' => true,
'host' => $hosts ? $hosts[0] : null
];
}
else {
$data['dynamic'] = [
'has_dynamic_widgets' => false,
'host' => null
];
}
$response = new CControllerResponseData($data);
$response->setTitle(_('Dashboard'));
$this->setResponse($response);
}
/**
* Get dashboard data from API.
*/
private function getDashboard(): array {
$dashboard = null;
$error = null;
if ($this->hasInput('new')) {
$dashboard = [
'dashboardid' => null,
'name' => _('New dashboard'),
'display_period' => DB::getDefault('dashboard', 'display_period'),
'auto_start' => DB::getDefault('dashboard', 'auto_start'),
'editable' => true,
'pages' => [
[
'dashboard_pageid' => null,
'name' => '',
'display_period' => 0,
'widgets' => []
]
],
'owner' => [
'id' => CWebUser::$data['userid'],
'name' => CDashboardHelper::getOwnerName(CWebUser::$data['userid'])
],
'has_related_reports' => false
];
}
elseif ($this->hasInput('clone')) {
$dashboards = API::Dashboard()->get([
'output' => ['dashboardid', 'name', 'private', 'display_period', 'auto_start'],
'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
'selectUsers' => ['userid', 'permission'],
'selectUserGroups' => ['usrgrpid', 'permission'],
'dashboardids' => $this->getInput('dashboardid')
]);
if ($dashboards) {
$dashboard = [
'dashboardid' => $dashboards[0]['dashboardid'],
'name' => $dashboards[0]['name'],
'display_period' => $dashboards[0]['display_period'],
'auto_start' => $dashboards[0]['auto_start'],
'editable' => true,
'pages' => CDashboardHelper::preparePagesForGrid(
CDashboardHelper::unsetInaccessibleFields($dashboards[0]['pages']), null, true
),
'owner' => [
'id' => CWebUser::$data['userid'],
'name' => CDashboardHelper::getOwnerName(CWebUser::$data['userid'])
],
'sharing' => [
'private' => $dashboards[0]['private'],
'users' => $dashboards[0]['users'],
'userGroups' => $dashboards[0]['userGroups']
],
'has_related_reports' => false
];
}
else {
$error = _('No permissions to referred object or it does not exist!');
}
}
else {
// Getting existing dashboard.
$dashboardid = $this->hasInput('dashboardid')
? $this->getInput('dashboardid')
: CProfile::get('web.dashboard.dashboardid');
if ($dashboardid === null && CProfile::get('web.dashboard.list_was_opened') != 1) {
// Get first available dashboard that user has read permissions.
$dashboards = API::Dashboard()->get([
'output' => ['dashboardid'],
'sortfield' => 'name',
'limit' => 1
]);
if ($dashboards) {
$dashboardid = $dashboards[0]['dashboardid'];
}
}
if ($dashboardid !== null) {
$dashboards = API::Dashboard()->get([
'output' => ['dashboardid', 'name', 'userid', 'display_period', 'auto_start'],
'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'],
'dashboardids' => $dashboardid,
'preservekeys' => true
]);
if ($dashboards) {
CDashboardHelper::updateEditableFlag($dashboards);
$dashboard = array_shift($dashboards);
$dashboard['pages'] = CDashboardHelper::preparePagesForGrid($dashboard['pages'], null, true);
$dashboard['owner'] = [
'id' => $dashboard['userid'],
'name' => CDashboardHelper::getOwnerName($dashboard['userid'])
];
$dashboard['has_related_reports'] = (bool) API::Report()->get([
'output' => [],
'filter' => ['dashboardid' => $dashboard['dashboardid']],
'limit' => 1
]);
CProfile::update('web.dashboard.dashboardid', $dashboardid, PROFILE_TYPE_ID);
}
elseif ($this->hasInput('dashboardid')) {
$error = _('No permissions to referred object or it does not exist!');
}
else {
// In case if previous dashboard is deleted, show dashboard list.
}
}
}
return [$dashboard, $error];
}
/**
* Checks, if any of widgets has checked dynamic field.
*/
private static function hasDynamicWidgets($grid_pages): bool {
foreach ($grid_pages as $page) {
foreach ($page['widgets'] as $widget) {
if (array_key_exists('dynamic', $widget['fields']) && $widget['fields']['dynamic'] == 1) {
return true;
}
}
}
return false;
}
}