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 22/** 23 * Class for override widget field used in Graph widget configuration overrides tab. 24 */ 25class CWidgetFieldGraphOverride extends CWidgetField { 26 27 /** 28 * Create widget field for Graph Override selection. 29 * 30 * @param string $name Field name in form. 31 * @param string $label Label for the field in form. 32 */ 33 public function __construct($name, $label) { 34 parent::__construct($name, $label); 35 36 $this->setSaveType(ZBX_WIDGET_FIELD_TYPE_STR); 37 $this->setValidationRules(['type' => API_OBJECTS, 'fields' => [ 38 'hosts' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED], 39 'items' => ['type' => API_STRINGS_UTF8, 'flags' => API_REQUIRED], 40 'color' => ['type' => API_COLOR], 41 'type' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_TYPE_LINE, SVG_GRAPH_TYPE_POINTS, SVG_GRAPH_TYPE_STAIRCASE])], 42 'width' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))], 43 'pointsize' => ['type' => API_INT32, 'in' => implode(',', range(1, 10))], 44 'transparency' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))], 45 'fill' => ['type' => API_INT32, 'in' => implode(',', range(0, 10))], 46 'missingdatafunc' => ['type' => API_INT32, 'in' => implode(',', [SVG_GRAPH_MISSING_DATA_NONE, SVG_GRAPH_MISSING_DATA_CONNECTED, SVG_GRAPH_MISSING_DATA_TREAT_AS_ZERO])], 47 'axisy' => ['type' => API_INT32, 'in' => implode(',', [GRAPH_YAXIS_SIDE_LEFT, GRAPH_YAXIS_SIDE_RIGHT])], 48 'timeshift' => ['type' => API_TIME_UNIT, 'in' => implode(':', [ZBX_MIN_TIMESHIFT, ZBX_MAX_TIMESHIFT])] 49 ]]); 50 $this->setDefault([]); 51 } 52 53 /** 54 * Set additional flags, which can be used in configuration form. 55 * 56 * @param int $flags 57 * 58 * @return $this 59 */ 60 public function setFlags($flags) { 61 parent::setFlags($flags); 62 63 if ($flags & self::FLAG_NOT_EMPTY) { 64 $strict_validation_rules = $this->getValidationRules(); 65 self::setValidationRuleFlag($strict_validation_rules['fields']['hosts'], API_NOT_EMPTY); 66 self::setValidationRuleFlag($strict_validation_rules['fields']['items'], API_NOT_EMPTY); 67 self::setValidationRuleFlag($strict_validation_rules['fields']['color'], API_NOT_EMPTY); 68 self::setValidationRuleFlag($strict_validation_rules['fields']['timeshift'], API_NOT_EMPTY); 69 $this->setStrictValidationRules($strict_validation_rules); 70 } 71 else { 72 $this->setStrictValidationRules(null); 73 } 74 75 return $this; 76 } 77 78 public function setValue($value) { 79 foreach ($value as &$val) { 80 // Values received from frontend are strings. Values received from database comes as arrays. 81 // TODO: remove hack with modifying of unvalidated data. 82 if (array_key_exists('hosts', $val)) { 83 $val['hosts'] = CWidgetHelper::splitPatternIntoParts($val['hosts']); 84 } 85 if (array_key_exists('items', $val)) { 86 $val['items'] = CWidgetHelper::splitPatternIntoParts($val['items']); 87 } 88 } 89 unset($val); 90 91 $this->value = $value; 92 93 return $this; 94 } 95 96 /** 97 * Default values filled in newly created data set or used as unspecified values. 98 * 99 * @return array 100 */ 101 public static function getDefaults() { 102 return [ 103 'hosts' => [], 104 'items' => [] 105 ]; 106 } 107 108 /** 109 * Returns array of supported override options. 110 * 111 * @return array 112 */ 113 public static function getOverrideOptions() { 114 return ['color', 'width', 'type', 'transparency', 'fill', 'pointsize', 'missingdatafunc', 'axisy', 'timeshift']; 115 } 116 117 /** 118 * Function makes field specific validation for values set using self::setValue(). 119 * 120 * @param bool $strict Either to make a strict validation. 121 * 122 * @return array $errors List of errors found during validation. 123 */ 124 public function validate($strict = false) { 125 $errors = parent::validate($strict); 126 $value = $this->getValue(); 127 $label = ($this->label === null) ? $this->name : $this->label; 128 129 // Validate options. 130 if (!$errors && $strict) { 131 foreach ($value as $index => $overrides) { 132 if (!array_intersect(self::getOverrideOptions(), array_keys($overrides))) { 133 $errors[] = _s('Invalid parameter "%1$s": %2$s.', $label.'/'.($index + 1), 134 _('at least one override option must be specified') 135 ); 136 break; 137 } 138 } 139 } 140 141 return $errors; 142 } 143 144 /** 145 * Prepares array entry for widget field, ready to be passed to CDashboard API functions. 146 * Reference is needed here to avoid array merging in CWidgetForm::fieldsToApi method. With large number of widget 147 * fields it causes significant performance decrease. 148 * 149 * @param array $widget_fields reference to Array of widget fields. 150 */ 151 public function toApi(array &$widget_fields = []) { 152 $value = $this->getValue(); 153 154 foreach ($value as $index => $val) { 155 // Hosts and items fields are stored as arrays to bypass length limit. 156 foreach ($val['hosts'] as $num => $pattern_item) { 157 $widget_fields[] = [ 158 'type' => ZBX_WIDGET_FIELD_TYPE_STR, 159 'name' => $this->name.'.hosts.'.$index.'.'.$num, 160 'value' => $pattern_item 161 ]; 162 } 163 foreach ($val['items'] as $num => $pattern_item) { 164 $widget_fields[] = [ 165 'type' => ZBX_WIDGET_FIELD_TYPE_STR, 166 'name' => $this->name.'.items.'.$index.'.'.$num, 167 'value' => $pattern_item 168 ]; 169 } 170 171 foreach (self::getOverrideOptions() as $opt) { 172 if (array_key_exists($opt, $val)) { 173 $widget_fields[] = [ 174 'type' => ($opt === 'color' || $opt === 'timeshift') 175 ? ZBX_WIDGET_FIELD_TYPE_STR 176 : ZBX_WIDGET_FIELD_TYPE_INT32, 177 'name' => $this->name.'.'.$opt.'.'.$index, 178 'value' => $val[$opt] 179 ]; 180 } 181 } 182 } 183 } 184} 185