. **/ namespace Widgets\Graph\Actions; use API, CArrayHelper, CControllerDashboardWidgetView, CControllerResponseData, CGraphDraw, CMacrosResolverHelper, CRoleHelper, CUrl, CWebUser; class WidgetView extends CControllerDashboardWidgetView { protected function init(): void { parent::init(); $this->addValidationRules([ 'edit_mode' => 'in 0,1', 'dashboardid' => 'db dashboard.dashboardid', 'contents_width' => 'int32', 'contents_height' => 'int32', 'has_custom_time_period' => 'in 1' ]); } protected function doAction(): void { $width = (int) $this->getInput('contents_width', 100); $height = (int) $this->getInput('contents_height', 100); $resourceid = null; $host = []; $graph = []; $profileIdx = 'web.dashboard.filter'; $profileIdx2 = $this->getInput('dashboardid', 0); $is_resource_available = true; $header_name = $this->widget->getDefaultName(); if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH && $this->fields_values['graphid']) { $resource_type = SCREEN_RESOURCE_GRAPH; $resourceid = reset($this->fields_values['graphid']); $graph_dims = getGraphDims($resourceid); $graph_dims['graphHeight'] = $height; $graph_dims['width'] = $width; } elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH && $this->fields_values['itemid']) { $resource_type = SCREEN_RESOURCE_SIMPLE_GRAPH; $resourceid = $this->fields_values['itemid'][0]; $graph_dims = getGraphDims(); $graph_dims['graphHeight'] = $height; $graph_dims['width'] = $width; } else { $resource_type = null; $graph_dims = getGraphDims(); } $graph_dims['shiftYtop'] = CGraphDraw::DEFAULT_TOP_BOTTOM_PADDING; $time_control_data = [ 'id' => '', 'containerid' => '', 'objDims' => $graph_dims, 'loadSBox' => 0, 'loadImage' => 1, 'reloadOnAdd' => 1, 'useCustomEvents' => 1 ]; $flickerfreescreen_data = [ 'id' => '', 'interval' => CWebUser::getRefresh(), 'timeline' => [], 'resourcetype' => $resource_type, 'profileIdx' => $profileIdx, 'profileIdx2' => $profileIdx2, 'useCustomEvents' => 1 ]; // Replace graph item by particular host item if the host has been overridden. if ($this->fields_values['override_hostid'] && $resourceid) { // Find same simple-graph item in the overridden host. if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) { $options = [ 'output' => ['itemid', 'name_resolved'], 'selectHosts' => ['name'], 'hostids' => $this->fields_values['override_hostid'], 'filter' => [ 'value_type' => [ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64] ], 'webitems' => true ]; $src_items = []; if ($this->isTemplateDashboard()) { $options['itemids'] = $resourceid; } else { $src_items = API::Item()->get([ 'output' => ['key_'], 'itemids' => $resourceid, 'webitems' => true ]); if ($src_items) { $options['filter']['key_'] = $src_items[0]['key_']; } } if ($this->isTemplateDashboard() || $src_items) { $items = API::Item()->get($options); $item = reset($items); if ($item) { $resourceid = $item['itemid']; $item = CArrayHelper::renameKeys($item, ['name_resolved' => 'name']); } else { $resourceid = null; $is_resource_available = false; } } else { $resourceid = null; $is_resource_available = false; } } // Find requested host and change graph details. elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) { // get host $hosts = API::Host()->get([ 'output' => ['hostid', 'host', 'name'], 'hostids' => $this->fields_values['override_hostid'] ]); $host = reset($hosts); // get graph $graph = API::Graph()->get([ 'output' => API_OUTPUT_EXTEND, 'selectGraphItems' => API_OUTPUT_EXTEND, 'selectHosts' => [], 'graphids' => $resourceid ]); $graph = reset($graph); if ($graph && count($graph['hosts']) == 1) { $graph = $this->setAxisItem($graph, 'ymax'); $graph = $this->setAxisItem($graph, 'ymin'); } if ($graph) { $graph['hosts'] = $hosts; $items = $graph['gitems']; if (!$this->isTemplateDashboard()) { $items = getSameGraphItemsForHost($items, $this->fields_values['override_hostid'][0], false); } if ($items) { foreach ($items as &$item) { $item['host'] = $host['host']; } unset($item); $graph['name'] = CMacrosResolverHelper::resolveGraphName($graph['name'], $items); } else { $is_resource_available = false; } } else { $is_resource_available = false; } } } else { if (!$resourceid) { $is_resource_available = false; } elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) { $items = API::Item()->get([ 'output' => [!$this->isTemplateDashboard() ? 'name_resolved' : 'name', 'key_', 'delay', 'hostid'], 'selectHosts' => ['name'], 'itemids' => $resourceid, 'filter' => ['value_type' => [ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64]], 'webitems' => true ]); $item = reset($items); if (!$item) { $is_resource_available = false; } elseif (!$this->isTemplateDashboard()) { $item = CArrayHelper::renameKeys($item, ['name_resolved' => 'name']); } } elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) { // get graph, used below $graph = API::Graph()->get([ 'output' => API_OUTPUT_EXTEND, 'selectHosts' => ['hostid', 'name'], 'graphids' => $resourceid, 'expandName' => true ]); $graph = reset($graph); if (!$graph) { $is_resource_available = false; } } } if ($is_resource_available) { // Build graph action and data source links. if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_SIMPLE_GRAPH) { if ((!$this->isTemplateDashboard() || $this->fields_values['override_hostid']) && !$this->hasInput('has_custom_time_period')) { $time_control_data['loadSBox'] = 1; } if ($resourceid) { $graph_src = (new CUrl('chart.php')) ->setArgument('itemids', [$resourceid]) ->setArgument('width', $width) ->setArgument('height', $height) ->setArgument('legend', $this->fields_values['show_legend']); } else { $graph_src = new CUrl('chart3.php'); } $graph_src ->setArgument('from') ->setArgument('to'); $header_name = $this->isTemplateDashboard() ? $item['name'] : $item['hosts'][0]['name'].NAME_DELIMITER.$item['name']; } elseif ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) { $graph_src = ''; $prepend_host_name = $this->isTemplateDashboard() ? false : count($graph['hosts']) == 1 || $this->fields_values['override_hostid']; $header_name = $prepend_host_name ? $graph['hosts'][0]['name'].NAME_DELIMITER.$graph['name'] : $graph['name']; if ($this->fields_values['override_hostid'] && $resourceid && array_key_exists('name', $host) && $graph) { $graph_src = $this->prepareGraphSrc($graph, $host); } if ($graph_dims['graphtype'] == GRAPH_TYPE_PIE || $graph_dims['graphtype'] == GRAPH_TYPE_EXPLODED) { if (!$this->fields_values['override_hostid'] || $graph_src === '') { $graph_src = (new CUrl('chart6.php')) ->setArgument('graphid', $resourceid) ->setArgument('graph3d', $graph['show_3d']); } } else { if (!$this->fields_values['override_hostid'] || $graph_src === '') { $graph_src = (new CUrl('chart2.php'))->setArgument('graphid', $resourceid); } if ((!$this->isTemplateDashboard() || $this->fields_values['override_hostid']) && !$this->hasInput('has_custom_time_period')) { $time_control_data['loadSBox'] = 1; } } $graph_src ->setArgument('width', $width) ->setArgument('height', $height) ->setArgument('legend', $this->fields_values['show_legend'] && $graph['show_legend'] ? 1 : 0) ->setArgument('from') ->setArgument('to'); } if (!$this->isTemplateDashboard() || $this->fields_values['override_hostid']) { $graph_src->setArgument('resolve_macros', 1); } $graph_src ->setArgument('profileIdx', $profileIdx) ->setArgument('profileIdx2', $profileIdx2); if ($graph_dims['graphtype'] != GRAPH_TYPE_PIE && $graph_dims['graphtype'] != GRAPH_TYPE_EXPLODED) { $graph_src->setArgument('outer', '1'); } $graph_src->setArgument('widget_view', '1'); $time_control_data['src'] = $graph_src->getUrl(); $graph_url = $this->prepareGraphUrl($graph, $resourceid); } $response = [ 'name' => $this->getInput('name', $header_name), 'is_resource_available' => $is_resource_available, 'widget' => [ 'graph_url' => ($is_resource_available && $graph_url !== null) ? $graph_url->getUrl() : null, 'time_control_data' => $time_control_data, 'flickerfreescreen_data' => $flickerfreescreen_data ], 'info' => $this->makeWidgetInfo(), 'user' => [ 'debug_mode' => $this->getDebugMode() ] ]; $this->setResponse(new CControllerResponseData($response)); } /** * Make widget specific info to show in widget's header. */ private function makeWidgetInfo(): array { $info = []; if ($this->hasInput('has_custom_time_period')) { $info[] = [ 'icon' => ZBX_ICON_TIME_PERIOD, 'hint' => relativeDateToText($this->fields_values['time_period']['from'], $this->fields_values['time_period']['to'] ) ]; } return $info; } private function setAxisItem(array $graph, string $axis): array { $type_key = $axis.'_type'; $itemid_key = $axis.'_itemid'; if ($graph[$type_key] == GRAPH_YAXIS_TYPE_ITEM_VALUE && $graph[$itemid_key]) { $item = ['itemid' => $graph[$itemid_key]]; if (!$this->isTemplateDashboard()) { $items = getSameGraphItemsForHost([$item], $this->fields_values['override_hostid'][0], false ); $item = reset($items); } if ($item && $item['itemid'] > 0) { $graph[$itemid_key] = $item['itemid']; } else { $graph[$type_key] = GRAPH_YAXIS_TYPE_CALCULATED; } } return $graph; } private function prepareGraphSrc(array $graph, array $host): CUrl { if ($graph['graphtype'] == GRAPH_TYPE_PIE || $graph['graphtype'] == GRAPH_TYPE_EXPLODED) { $graph_src = (new CUrl('chart7.php')) ->setArgument('name', $host['name'].NAME_DELIMITER.$graph['name']) ->setArgument('graphtype', $graph['graphtype']) ->setArgument('graph3d', $graph['show_3d']); } else { $graph_src = (new CUrl('chart3.php')) ->setArgument('name', $host['name'].NAME_DELIMITER.$graph['name']) ->setArgument('ymin_type', $graph['ymin_type']) ->setArgument('ymax_type', $graph['ymax_type']) ->setArgument('ymin_itemid', $graph['ymin_itemid']) ->setArgument('ymax_itemid', $graph['ymax_itemid']) ->setArgument('showworkperiod', $graph['show_work_period']) ->setArgument('showtriggers', $graph['show_triggers']) ->setArgument('graphtype', $graph['graphtype']) ->setArgument('yaxismin', $graph['yaxismin']) ->setArgument('yaxismax', $graph['yaxismax']) ->setArgument('percent_left', $graph['percent_left']) ->setArgument('percent_right', $graph['percent_right']); } $new_graph_items = getSameGraphItemsForHost($graph['gitems'], $this->fields_values['override_hostid'][0], false ); foreach ($new_graph_items as &$new_graph_item) { unset($new_graph_item['gitemid'], $new_graph_item['graphid']); } unset($new_graph_item); $graph_src->setArgument('items', $new_graph_items); return $graph_src; } private function prepareGraphUrl(array $graph, ?string $resourceid = null): ?CUrl { if ($this->isEditMode() || !$graph || ($this->isTemplateDashboard() && !$this->fields_values['override_hostid'])) { return null; } if ($this->fields_values['source_type'] == ZBX_WIDGET_FIELD_RESOURCE_GRAPH) { $has_host_graph = $this->fields_values['override_hostid'] ? (bool) API::Graph()->get([ 'output' => [], 'hostids' => $this->fields_values['override_hostid'], 'filter' => [ 'name' => $graph['name'] ] ]) : true; if ($has_host_graph && $this->checkAccess(CRoleHelper::UI_MONITORING_HOSTS)) { return (new CUrl('zabbix.php')) ->setArgument('action', 'charts.view') ->setArgument('filter_hostids', [$graph['hosts'][0]['hostid']]) ->setArgument('filter_name', $graph['name']) ->setArgument('filter_show', GRAPH_FILTER_HOST) ->setArgument('filter_set', '1') ->setArgument('from') ->setArgument('to'); } else { return null; } } return $this->checkAccess(CRoleHelper::UI_MONITORING_LATEST_DATA) ? (new CUrl('history.php')) ->setArgument('itemids', [$resourceid]) ->setArgument('from') ->setArgument('to') : null; } private function isEditMode(): bool { return (bool) $this->getInput('edit_mode', 0); } }