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.
303 lines
8.6 KiB
303 lines
8.6 KiB
1 year ago
|
<?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;
|
||
|
}
|
||
|
}
|