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 22class CControllerDashboardView extends CController { 23 24 protected function init() { 25 $this->disableSIDValidation(); 26 } 27 28 protected function checkInput() { 29 $fields = [ 30 'dashboardid' => 'db dashboard.dashboardid', 31 'source_dashboardid' => 'db dashboard.dashboardid', 32 'hostid' => 'db hosts.hostid', 33 'new' => 'in 1', 34 'cancel' => 'in 1', 35 'from' => 'range_time', 36 'to' => 'range_time', 37 'slideshow' => 'in 1' 38 ]; 39 40 $ret = $this->validateInput($fields) && $this->validateTimeSelectorPeriod(); 41 42 if (!$ret) { 43 $this->setResponse(new CControllerResponseFatal()); 44 } 45 46 return $ret; 47 } 48 49 protected function checkPermissions() { 50 if (!$this->checkAccess(CRoleHelper::UI_MONITORING_DASHBOARD)) { 51 return false; 52 } 53 54 if ($this->hasInput('new') || $this->hasInput('source_dashboardid')) { 55 return $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS); 56 } 57 58 if ($this->hasInput('hostid')) { 59 $hosts = API::Host()->get([ 60 'output' => [], 61 'hostids' => [$this->getInput('hostid')] 62 ]); 63 64 if (!$hosts) { 65 return false; 66 } 67 } 68 69 return true; 70 } 71 72 protected function doAction() { 73 [$dashboard, $error] = $this->getDashboard(); 74 75 if ($error !== null) { 76 $this->setResponse(new CControllerResponseData(['error' => $error])); 77 78 return; 79 } 80 81 if ($dashboard === null) { 82 $this->setResponse(new CControllerResponseRedirect((new CUrl('zabbix.php')) 83 ->setArgument('action', 'dashboard.list') 84 ->setArgument('page', $this->hasInput('cancel') ? CPagerHelper::loadPage('dashboard.list', null) : null) 85 )); 86 87 return; 88 } 89 90 if ($this->hasInput('slideshow')) { 91 $dashboard['auto_start'] = '1'; 92 } 93 94 $dashboard['can_edit_dashboards'] = $this->checkAccess(CRoleHelper::ACTIONS_EDIT_DASHBOARDS); 95 $dashboard['can_view_reports'] = $this->checkAccess(CRoleHelper::UI_REPORTS_SCHEDULED_REPORTS); 96 $dashboard['can_create_reports'] = $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_SCHEDULED_REPORTS); 97 98 $time_selector_options = [ 99 'profileIdx' => 'web.dashboard.filter', 100 'profileIdx2' => ($dashboard['dashboardid'] !== null) ? $dashboard['dashboardid'] : 0, 101 'from' => $this->hasInput('from') ? $this->getInput('from') : null, 102 'to' => $this->hasInput('to') ? $this->getInput('to') : null 103 ]; 104 105 updateTimeSelectorPeriod($time_selector_options); 106 107 $data = [ 108 'dashboard' => $dashboard, 109 'widget_defaults' => CWidgetConfig::getDefaults(CWidgetConfig::CONTEXT_DASHBOARD), 110 'has_time_selector' => CDashboardHelper::hasTimeSelector($dashboard['pages']), 111 'time_period' => getTimeSelectorPeriod($time_selector_options), 112 'active_tab' => CProfile::get('web.dashboard.filter.active', 1) 113 ]; 114 115 if (self::hasDynamicWidgets($dashboard['pages'])) { 116 $hostid = $this->getInput('hostid', CProfile::get('web.dashboard.hostid', 0)); 117 118 $hosts = ($hostid != 0) 119 ? CArrayHelper::renameObjectsKeys(API::Host()->get([ 120 'output' => ['hostid', 'name'], 121 'hostids' => [$hostid] 122 ]), ['hostid' => 'id']) 123 : []; 124 125 $data['dynamic'] = [ 126 'has_dynamic_widgets' => true, 127 'host' => $hosts ? $hosts[0] : null 128 ]; 129 } 130 else { 131 $data['dynamic'] = [ 132 'has_dynamic_widgets' => false, 133 'host' => null 134 ]; 135 } 136 137 $response = new CControllerResponseData($data); 138 $response->setTitle(_('Dashboard')); 139 $this->setResponse($response); 140 } 141 142 /** 143 * Get dashboard data from API. 144 * 145 * @return array 146 */ 147 private function getDashboard() { 148 $dashboard = null; 149 $error = null; 150 151 if ($this->hasInput('new')) { 152 $dashboard = [ 153 'dashboardid' => null, 154 'name' => _('New dashboard'), 155 'display_period' => DB::getDefault('dashboard', 'display_period'), 156 'auto_start' => DB::getDefault('dashboard', 'auto_start'), 157 'editable' => true, 158 'pages' => [ 159 [ 160 'dashboard_pageid' => null, 161 'name' => '', 162 'display_period' => 0, 163 'widgets' => [] 164 ] 165 ], 166 'owner' => [ 167 'id' => CWebUser::$data['userid'], 168 'name' => CDashboardHelper::getOwnerName(CWebUser::$data['userid']) 169 ], 170 'has_related_reports' => false 171 ]; 172 } 173 elseif ($this->hasInput('source_dashboardid')) { 174 // Clone dashboard and show as new. 175 $dashboards = API::Dashboard()->get([ 176 'output' => ['name', 'private', 'display_period', 'auto_start'], 177 'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'], 178 'selectUsers' => ['userid', 'permission'], 179 'selectUserGroups' => ['usrgrpid', 'permission'], 180 'dashboardids' => [$this->getInput('source_dashboardid')] 181 ]); 182 183 if ($dashboards) { 184 $dashboard = [ 185 'dashboardid' => null, 186 'name' => $dashboards[0]['name'], 187 'display_period' => $dashboards[0]['display_period'], 188 'auto_start' => $dashboards[0]['auto_start'], 189 'editable' => true, 190 'pages' => CDashboardHelper::preparePagesForGrid( 191 CDashboardHelper::unsetInaccessibleFields($dashboards[0]['pages']), null, true 192 ), 193 'owner' => [ 194 'id' => CWebUser::$data['userid'], 195 'name' => CDashboardHelper::getOwnerName(CWebUser::$data['userid']) 196 ], 197 'sharing' => [ 198 'private' => $dashboards[0]['private'], 199 'users' => $dashboards[0]['users'], 200 'userGroups' => $dashboards[0]['userGroups'] 201 ], 202 'has_related_reports' => false 203 ]; 204 } 205 else { 206 $error = _('No permissions to referred object or it does not exist!'); 207 } 208 } 209 else { 210 // Getting existing dashboard. 211 $dashboardid = $this->hasInput('dashboardid') 212 ? $this->getInput('dashboardid') 213 : CProfile::get('web.dashboard.dashboardid'); 214 215 if ($dashboardid === null && CProfile::get('web.dashboard.list_was_opened') != 1) { 216 // Get first available dashboard that user has read permissions. 217 $dashboards = API::Dashboard()->get([ 218 'output' => ['dashboardid'], 219 'sortfield' => 'name', 220 'limit' => 1 221 ]); 222 223 if ($dashboards) { 224 $dashboardid = $dashboards[0]['dashboardid']; 225 } 226 } 227 228 if ($dashboardid !== null) { 229 $dashboards = API::Dashboard()->get([ 230 'output' => ['dashboardid', 'name', 'userid', 'display_period', 'auto_start'], 231 'selectPages' => ['dashboard_pageid', 'name', 'display_period', 'widgets'], 232 'dashboardids' => [$dashboardid], 233 'preservekeys' => true 234 ]); 235 236 if ($dashboards) { 237 CDashboardHelper::updateEditableFlag($dashboards); 238 239 $dashboard = array_shift($dashboards); 240 $dashboard['pages'] = CDashboardHelper::preparePagesForGrid($dashboard['pages'], null, true); 241 $dashboard['owner'] = [ 242 'id' => $dashboard['userid'], 243 'name' => CDashboardHelper::getOwnerName($dashboard['userid']) 244 ]; 245 $dashboard['has_related_reports'] = (bool) API::Report()->get([ 246 'output' => [], 247 'filter' => ['dashboardid' => $dashboard['dashboardid']], 248 'limit' => 1 249 ]); 250 251 CProfile::update('web.dashboard.dashboardid', $dashboardid, PROFILE_TYPE_ID); 252 } 253 elseif ($this->hasInput('dashboardid')) { 254 $error = _('No permissions to referred object or it does not exist!'); 255 } 256 else { 257 // In case if previous dashboard is deleted, show dashboard list. 258 } 259 } 260 } 261 262 return [$dashboard, $error]; 263 } 264 265 /** 266 * Checks, if any of widgets has checked dynamic field. 267 * 268 * @param array $grid_pages 269 * 270 * @static 271 * 272 * @return bool 273 */ 274 private static function hasDynamicWidgets($grid_pages) { 275 foreach ($grid_pages as $page) { 276 foreach ($page['widgets'] as $widget) { 277 if (array_key_exists('dynamic', $widget['fields']) && $widget['fields']['dynamic'] == 1) { 278 return true; 279 } 280 } 281 } 282 283 return false; 284 } 285} 286