<?php declare(strict_types = 1); /* ** Zabbix ** Copyright (C) 2001-2022 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 CWidgetConfig { /** * Array of deprecated widgets constants. */ public const DEPRECATED_WIDGETS = [ WIDGET_DATA_OVER ]; /** * Classifier for non-template dashboards. */ public const CONTEXT_DASHBOARD = 'dashboard'; /** * Classifier for template and host dashboards. */ public const CONTEXT_TEMPLATE_DASHBOARD = 'template_dashboard'; /** * Get default names for all widget types. * * @static * * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD * * @return array */ public static function getKnownWidgetTypes(string $context): array { $types = [ WIDGET_ACTION_LOG => _('Action log'), WIDGET_CLOCK => _('Clock'), WIDGET_DATA_OVER => _('Data overview'), WIDGET_DISCOVERY => _('Discovery status'), WIDGET_FAV_GRAPHS => _('Favorite graphs'), WIDGET_FAV_MAPS => _('Favorite maps'), WIDGET_GEOMAP => _('Geomap'), WIDGET_ITEM => _('Item value'), WIDGET_GRAPH => _('Graph (classic)'), WIDGET_GRAPH_PROTOTYPE => _('Graph prototype'), WIDGET_HOST_AVAIL => _('Host availability'), WIDGET_MAP => _('Map'), WIDGET_NAV_TREE => _('Map navigation tree'), WIDGET_PLAIN_TEXT => _('Plain text'), WIDGET_PROBLEM_HOSTS => _('Problem hosts'), WIDGET_PROBLEMS => _('Problems'), WIDGET_PROBLEMS_BY_SV => _('Problems by severity'), WIDGET_SLA_REPORT => _('SLA report'), WIDGET_SVG_GRAPH => _('Graph'), WIDGET_SYSTEM_INFO => _('System information'), WIDGET_TRIG_OVER => _('Trigger overview'), WIDGET_URL => _('URL'), WIDGET_WEB => _('Web monitoring'), WIDGET_TOP_HOSTS => _('Top hosts') ]; $types = array_filter($types, function(string $type) use ($context): bool { return self::isWidgetTypeSupportedInContext($type, $context); }, ARRAY_FILTER_USE_KEY ); return $types; } /** * Get JavaScript classes for all widget types. * * @static * * @return array */ public static function getJSClasses(): array { return [ WIDGET_ACTION_LOG => 'CWidget', WIDGET_CLOCK => 'CWidgetClock', WIDGET_DATA_OVER => 'CWidget', WIDGET_DISCOVERY => 'CWidget', WIDGET_FAV_GRAPHS => 'CWidget', WIDGET_FAV_MAPS => 'CWidget', WIDGET_GEOMAP => 'CWidgetGeoMap', WIDGET_ITEM => 'CWidgetItem', WIDGET_GRAPH => 'CWidgetGraph', WIDGET_GRAPH_PROTOTYPE => 'CWidgetGraphPrototype', WIDGET_HOST_AVAIL => 'CWidget', WIDGET_MAP => 'CWidgetMap', WIDGET_NAV_TREE => 'CWidgetNavTree', WIDGET_PLAIN_TEXT => 'CWidget', WIDGET_PROBLEM_HOSTS => 'CWidget', WIDGET_PROBLEMS => 'CWidgetProblems', WIDGET_PROBLEMS_BY_SV => 'CWidgetProblemsBySv', WIDGET_SLA_REPORT => 'CWidget', WIDGET_SVG_GRAPH => 'CWidgetSvgGraph', WIDGET_SYSTEM_INFO => 'CWidget', WIDGET_TRIG_OVER => 'CWidgetTrigerOver', WIDGET_URL => 'CWidget', WIDGET_WEB => 'CWidget', WIDGET_TOP_HOSTS => 'CWidget' ]; } /** * Get reference field name for widgets of the given type. * * @static * * @return string|null */ public static function getReferenceField(string $type): ?string { switch ($type) { case WIDGET_MAP: case WIDGET_NAV_TREE: return 'reference'; default: return null; } } /** * Get foreign reference field names for widgets of the given type. * * @static * * @return array */ public static function getForeignReferenceFields(string $type): array { switch ($type) { case WIDGET_MAP: return ['filter_widget_reference']; default: return []; } } /** * Get default widget dimensions. * * @static * * @return array */ private static function getDefaultDimensions(): array { return [ WIDGET_ACTION_LOG => ['width' => 12, 'height' => 5], WIDGET_CLOCK => ['width' => 4, 'height' => 3], WIDGET_DATA_OVER => ['width' => 12, 'height' => 5], WIDGET_DISCOVERY => ['width' => 6, 'height' => 3], WIDGET_FAV_GRAPHS => ['width' => 4, 'height' => 3], WIDGET_FAV_MAPS => ['width' => 4, 'height' => 3], WIDGET_GEOMAP => ['width' => 12, 'height' => 5], WIDGET_ITEM => ['width' => 4, 'height' => 3], WIDGET_GRAPH => ['width' => 12, 'height' => 5], WIDGET_GRAPH_PROTOTYPE => ['width' => 16, 'height' => 5], WIDGET_HOST_AVAIL => ['width' => 6, 'height' => 3], WIDGET_MAP => ['width' => 18, 'height' => 5], WIDGET_NAV_TREE => ['width' => 6, 'height' => 5], WIDGET_PLAIN_TEXT => ['width' => 6, 'height' => 3], WIDGET_PROBLEM_HOSTS => ['width' => 12, 'height' => 5], WIDGET_PROBLEMS => ['width' => 12, 'height' => 5], WIDGET_PROBLEMS_BY_SV => ['width' => 12, 'height' => 5], WIDGET_SLA_REPORT => ['width' => 12, 'height' => 5], WIDGET_SVG_GRAPH => ['width' => 12, 'height' => 5], WIDGET_SYSTEM_INFO => ['width' => 12, 'height' => 5], WIDGET_TRIG_OVER => ['width' => 12, 'height' => 5], WIDGET_URL => ['width' => 12, 'height' => 5], WIDGET_WEB => ['width' => 6, 'height' => 3], WIDGET_TOP_HOSTS => ['width' => 12, 'height' => 5] ]; } /** * Get default values for widgets. * * @static * * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD * * @return array */ public static function getDefaults(string $context): array { $ret = []; $dimensions = self::getDefaultDimensions(); $js_clases = self::getJSClasses(); foreach (self::getKnownWidgetTypes($context) as $type => $name) { $ret[$type] = [ 'name' => $name, 'size' => $dimensions[$type], 'js_class' => $js_clases[$type], 'iterator' => self::isIterator($type), 'reference_field' => self::getReferenceField($type), 'foreign_reference_fields' => self::getForeignReferenceFields($type) ]; } return $ret; } /** * Check if widget type is supported in a given context. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * @param string $context CWidgetConfig::CONTEXT_DASHBOARD | CWidgetConfig::CONTEXT_TEMPLATE_DASHBOARD * * @return bool */ public static function isWidgetTypeSupportedInContext(string $type, string $context): bool { switch ($context) { case self::CONTEXT_DASHBOARD: return true; case self::CONTEXT_TEMPLATE_DASHBOARD: switch ($type) { case WIDGET_CLOCK: case WIDGET_GRAPH: case WIDGET_GRAPH_PROTOTYPE: case WIDGET_ITEM: case WIDGET_PLAIN_TEXT: case WIDGET_URL: return true; default: return false; } } } /** * Get default refresh rate for widget type. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * * @return int default refresh rate, 0 for no refresh */ public static function getDefaultRfRate(string $type): int { switch ($type) { case WIDGET_ACTION_LOG: case WIDGET_DATA_OVER: case WIDGET_TOP_HOSTS: case WIDGET_DISCOVERY: case WIDGET_GEOMAP: case WIDGET_GRAPH: case WIDGET_GRAPH_PROTOTYPE: case WIDGET_PLAIN_TEXT: case WIDGET_ITEM: case WIDGET_PROBLEM_HOSTS: case WIDGET_PROBLEMS: case WIDGET_PROBLEMS_BY_SV: case WIDGET_SVG_GRAPH: case WIDGET_TRIG_OVER: case WIDGET_WEB: return SEC_PER_MIN; case WIDGET_CLOCK: case WIDGET_FAV_GRAPHS: case WIDGET_FAV_MAPS: case WIDGET_HOST_AVAIL: case WIDGET_MAP: case WIDGET_NAV_TREE: case WIDGET_SYSTEM_INFO: return 15 * SEC_PER_MIN; case WIDGET_SLA_REPORT: case WIDGET_URL: return 0; } } /** * Get all possible widget refresh intervals. * * @return array */ public static function getRfRates() { return [ 0 => _('No refresh'), SEC_PER_MIN / 6 => _n('%1$s second', '%1$s seconds', 10), SEC_PER_MIN / 2 => _n('%1$s second', '%1$s seconds', 30), SEC_PER_MIN => _n('%1$s minute', '%1$s minutes', 1), SEC_PER_MIN * 2 => _n('%1$s minute', '%1$s minutes', 2), SEC_PER_MIN * 10 => _n('%1$s minute', '%1$s minutes', 10), SEC_PER_MIN * 15 => _n('%1$s minute', '%1$s minutes', 15) ]; } /** * Check if time selector is necessary for widget having specified type and fields. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * @param array $fields * * @return bool */ public static function usesTimeSelector(string $type, array $fields): bool { switch ($type) { case WIDGET_GRAPH: case WIDGET_GRAPH_PROTOTYPE: return true; case WIDGET_SVG_GRAPH: return !CWidgetFormSvgGraph::hasOverrideTime($fields); default: return false; } } /** * Check if widget type belongs to iterators. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * * @return bool */ public static function isIterator(string $type): bool { switch ($type) { case WIDGET_GRAPH_PROTOTYPE: return true; default: return false; } } /** * Check if widget has padding or not. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * @param array $fields Widget form fields * @param int $view_mode Widget view mode. ZBX_WIDGET_VIEW_MODE_NORMAL by default * * @return bool */ private static function hasPadding(string $type, array $fields, int $view_mode): bool { if ($view_mode == ZBX_WIDGET_VIEW_MODE_HIDDEN_HEADER) { switch ($type) { case WIDGET_CLOCK: case WIDGET_GRAPH: case WIDGET_MAP: case WIDGET_SVG_GRAPH: return true; default: return false; } } else { switch ($type) { case WIDGET_HOST_AVAIL: return (count($fields['interface_type']) != 1); case WIDGET_PROBLEMS_BY_SV: return $fields['show_type'] != WIDGET_PROBLEMS_BY_SV_SHOW_TOTALS; case WIDGET_GRAPH_PROTOTYPE: case WIDGET_ITEM: case WIDGET_URL: return false; default: return true; } } } /** * Get widget configuration based on widget type, fields and current view mode. * * @param string $type Widget type - 'WIDGET_*' constant. * @param array $fields Widget form fields * @param int $view_mode Widget view mode * * @return array */ public static function getConfiguration(string $type, array $fields, int $view_mode): array { return [ 'padding' => self::hasPadding($type, $fields, $view_mode) ]; } /** * Get Form object for widget with provided data. * * @static * * @param string $type Widget type - 'WIDGET_*' constant. * @param string $data JSON string with widget fields. * @param string|null $templateid Template ID for template dashboards or null for non-template dashboards. * * @return CWidgetForm */ public static function getForm(string $type, string $data, ?string $templateid): CWidgetForm { switch ($type) { case WIDGET_ACTION_LOG: return new CWidgetFormActionLog($data, $templateid); case WIDGET_CLOCK: return new CWidgetFormClock($data, $templateid); case WIDGET_DATA_OVER: return new CWidgetFormDataOver($data, $templateid); case WIDGET_GEOMAP: return new CWidgetFormGeoMap($data, $templateid); case WIDGET_GRAPH: return new CWidgetFormGraph($data, $templateid); case WIDGET_GRAPH_PROTOTYPE: return new CWidgetFormGraphPrototype($data, $templateid); case WIDGET_HOST_AVAIL: return new CWidgetFormHostAvail($data, $templateid); case WIDGET_MAP: return new CWidgetFormMap($data, $templateid); case WIDGET_NAV_TREE: return new CWidgetFormNavTree($data, $templateid); case WIDGET_PLAIN_TEXT: return new CWidgetFormPlainText($data, $templateid); case WIDGET_PROBLEM_HOSTS: return new CWidgetFormProblemHosts($data, $templateid); case WIDGET_PROBLEMS: return new CWidgetFormProblems($data, $templateid); case WIDGET_PROBLEMS_BY_SV: return new CWidgetFormProblemsBySv($data, $templateid); case WIDGET_SLA_REPORT: return new CWidgetFormSlaReport($data, $templateid); case WIDGET_SVG_GRAPH: return new CWidgetFormSvgGraph($data, $templateid); case WIDGET_SYSTEM_INFO: return new CWidgetFormSystemInfo($data, $templateid); case WIDGET_TRIG_OVER: return new CWidgetFormTrigOver($data, $templateid); case WIDGET_URL: return new CWidgetFormUrl($data, $templateid); case WIDGET_WEB: return new CWidgetFormWeb($data, $templateid); case WIDGET_ITEM: return new CWidgetFormItem($data, $templateid); case WIDGET_TOP_HOSTS: return new CWidgetFormTopHosts($data, $templateid); default: return new CWidgetForm($data, $templateid, $type); } } }