. **/ namespace Widgets\SvgGraph\Includes; use CNumberParser, CParser, CWidgetsData; use Zabbix\Widgets\{ CWidgetField, CWidgetForm }; use Zabbix\Widgets\Fields\{ CWidgetFieldCheckBox, CWidgetFieldPatternSelectHost, CWidgetFieldMultiSelectOverrideHost, CWidgetFieldNumericBox, CWidgetFieldRadioButtonList, CWidgetFieldRangeControl, CWidgetFieldSelect, CWidgetFieldSeverities, CWidgetFieldTags, CWidgetFieldTextBox, CWidgetFieldTimePeriod }; /** * Graph widget form view. */ class WidgetForm extends CWidgetForm { public const LEGEND_ON = 1; public const LEGEND_STATISTIC_ON = 1; public const LEGEND_AGGREGATION_ON = 1; public const LEGEND_LINES_MODE_FIXED = 0; public const LEGEND_LINES_MODE_VARIABLE = 1; public const LEGEND_LINES_MIN = 1; public const LEGEND_LINES_MAX = 10; public const LEGEND_COLUMNS_MIN = 1; public const LEGEND_COLUMNS_MAX = 4; public const PERCENTILE_MIN = 1; public const PERCENTILE_MAX = 100; private bool $percentile_left_on = false; private bool $percentile_right_on = false; private bool $lefty_on = true; private bool $lefty_units_static = false; private bool $righty_on = true; private bool $righty_units_static = false; private bool $legend_on = true; private bool $legend_statistic_on = false; private bool $problems_on = false; public function validate(bool $strict = false): array { $errors = parent::validate($strict); $number_parser_w_suffix = new CNumberParser(['with_size_suffix' => true, 'with_time_suffix' => true]); $number_parser_wo_suffix = new CNumberParser(); // Percentiles if ($this->getFieldValue('percentile_left') == SVG_GRAPH_PERCENTILE_LEFT_ON) { $percentile_left_value = $this->getFieldValue('percentile_left_value'); if ($percentile_left_value !== '') { $percentile_left_value_calculated = $number_parser_wo_suffix->parse($percentile_left_value) == CParser::PARSE_SUCCESS ? $number_parser_wo_suffix->calcValue() : null; if ($percentile_left_value_calculated === null || $percentile_left_value_calculated < self::PERCENTILE_MIN || $percentile_left_value_calculated > self::PERCENTILE_MAX) { $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (left)'), _s('value must be between "%1$s" and "%2$s"', self::PERCENTILE_MIN, self::PERCENTILE_MAX) ); } } } if ($this->getFieldValue('percentile_right') == SVG_GRAPH_PERCENTILE_RIGHT_ON) { $percentile_right_value = $this->getFieldValue('percentile_right_value'); if ($percentile_right_value !== '') { $percentile_right_value_calculated = $number_parser_wo_suffix->parse($percentile_right_value) == CParser::PARSE_SUCCESS ? $number_parser_wo_suffix->calcValue() : null; if ($percentile_right_value_calculated === null || $percentile_right_value_calculated < self::PERCENTILE_MIN || $percentile_right_value_calculated > self::PERCENTILE_MAX) { $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Percentile line (right)'), _s('value must be between "%1$s" and "%2$s"', self::PERCENTILE_MIN, self::PERCENTILE_MAX) ); } } } // Validate Min/Max values in Axes tab. if ($this->getFieldValue('lefty') == SVG_GRAPH_AXIS_ON) { $lefty_min = $number_parser_w_suffix->parse($this->getFieldValue('lefty_min')) == CParser::PARSE_SUCCESS ? $number_parser_w_suffix->calcValue() : null; $lefty_max = $number_parser_w_suffix->parse($this->getFieldValue('lefty_max')) == CParser::PARSE_SUCCESS ? $number_parser_w_suffix->calcValue() : null; if ($lefty_min !== null && $lefty_max !== null && $lefty_min >= $lefty_max) { $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Left Y').': '._('Max'), _('Y axis MAX value must be greater than Y axis MIN value') ); } } if ($this->getFieldValue('righty') == SVG_GRAPH_AXIS_ON) { $righty_min = $number_parser_w_suffix->parse($this->getFieldValue('righty_min')) == CParser::PARSE_SUCCESS ? $number_parser_w_suffix->calcValue() : null; $righty_max = $number_parser_w_suffix->parse($this->getFieldValue('righty_max')) == CParser::PARSE_SUCCESS ? $number_parser_w_suffix->calcValue() : null; if ($righty_min !== null && $righty_max !== null && $righty_min >= $righty_max) { $errors[] = _s('Invalid parameter "%1$s": %2$s.', _('Right Y').': '._('Max'), _('Y axis MAX value must be greater than Y axis MIN value') ); } } return $errors; } protected function normalizeValues(array $values): array { $values = parent::normalizeValues($values); if (array_key_exists('percentile_left', $values)) { $this->percentile_left_on = $values['percentile_left'] == SVG_GRAPH_PERCENTILE_LEFT_ON; } if (!$this->percentile_left_on) { unset($values['percentile_left_value']); } if (array_key_exists('percentile_right', $values)) { $this->percentile_right_on = $values['percentile_right'] == SVG_GRAPH_PERCENTILE_RIGHT_ON; } if (!$this->percentile_right_on) { unset($values['percentile_right_value']); } if (array_key_exists('lefty', $values)) { $this->lefty_on = $values['lefty'] == SVG_GRAPH_AXIS_ON; } if (!$this->lefty_on) { unset($values['lefty_min'], $values['lefty_max'], $values['lefty_units']); } if (array_key_exists('lefty_units', $values)) { $this->lefty_units_static = $values['lefty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC; } if (!$this->lefty_on || !$this->lefty_units_static) { unset($values['lefty_static_units']); } if (array_key_exists('righty', $values)) { $this->righty_on = $values['righty'] == SVG_GRAPH_AXIS_ON; } if (!$this->righty_on) { unset($values['righty_min'], $values['righty_max'], $values['righty_units']); } if (array_key_exists('righty_units', $values)) { $this->righty_units_static = $values['righty_units'] == SVG_GRAPH_AXIS_UNITS_STATIC; } if (!$this->righty_on || !$this->righty_units_static) { unset($values['righty_static_units']); } if (array_key_exists('legend', $values)) { $this->legend_on = $values['legend'] == self::LEGEND_ON; } if (array_key_exists('legend_statistic', $values)) { $this->legend_statistic_on = $values['legend_statistic'] == self::LEGEND_STATISTIC_ON; } if (array_key_exists('show_problems', $values)) { $this->problems_on = $values['show_problems'] == SVG_GRAPH_PROBLEMS_ON; } if (!$this->problems_on) { unset($values['graph_item_problems'], $values['problemhosts'], $values['severities'], $values['problem_name'], $values['evaltype'], $values['tags'] ); } return $values; } public function addFields(): self { return $this ->initDataSetFields() ->initDisplayingOptionsFields() ->initTimePeriodFields() ->initAxesFields() ->initLegendFields() ->initProblemsFields() ->initOverridesFields() ->addField( new CWidgetFieldMultiSelectOverrideHost() ); } private function initDataSetFields(): self { return $this->addField( (new CWidgetFieldDataSet('ds', _('Data set')))->setFlags(CWidgetField::FLAG_NOT_EMPTY) ); } private function initDisplayingOptionsFields(): self { return $this ->addField( (new CWidgetFieldRadioButtonList('source', _('History data selection'), [ SVG_GRAPH_DATA_SOURCE_AUTO => _x('Auto', 'history source selection method'), SVG_GRAPH_DATA_SOURCE_HISTORY => _('History'), SVG_GRAPH_DATA_SOURCE_TRENDS => _('Trends') ]))->setDefault(SVG_GRAPH_DATA_SOURCE_AUTO) ) ->addField( new CWidgetFieldCheckBox('simple_triggers', _('Simple triggers')) ) ->addField( new CWidgetFieldCheckBox('working_time', _('Working time')) ) ->addField( new CWidgetFieldCheckBox('percentile_left', _('Percentile line (left)')) ) ->addField( (new CWidgetFieldTextBox('percentile_left_value', null)) ->setFlags(!$this->percentile_left_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( new CWidgetFieldCheckBox('percentile_right', _('Percentile line (right)')) ) ->addField( (new CWidgetFieldTextBox('percentile_right_value', null)) ->setFlags(!$this->percentile_right_on ? CWidgetField::FLAG_DISABLED : 0x00) ); } private function initTimePeriodFields(): self { return $this ->addField( (new CWidgetFieldTimePeriod('time_period', _('Time period'))) ->setDefault([ CWidgetField::FOREIGN_REFERENCE_KEY => CWidgetField::createTypedReference( CWidgetField::REFERENCE_DASHBOARD, CWidgetsData::DATA_TYPE_TIME_PERIOD ) ]) ->setDefaultPeriod(['from' => 'now-1h', 'to' => 'now']) ->setFlags(CWidgetField::FLAG_NOT_EMPTY | CWidgetField::FLAG_LABEL_ASTERISK) ); } private function initAxesFields(): self { return $this ->addField( (new CWidgetFieldCheckBox('lefty', _('Left Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON) ) ->addField( (new CWidgetFieldSelect('lefty_scale', _('Scale'), [ SVG_GRAPH_AXIS_SCALE_LINEAR => _('Linear'), SVG_GRAPH_AXIS_SCALE_LOGARITHMIC => _('Logarithmic') ]))->setDefault(SVG_GRAPH_AXIS_SCALE_LINEAR) ) ->addField( (new CWidgetFieldNumericBox('lefty_min', _('Min'))) ->prefixLabel(_('Left Y')) ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldNumericBox('lefty_max', _('Max'))) ->prefixLabel(_('Left Y')) ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldSelect('lefty_units', _('Units'), [ SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'), SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method') ])) ->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO) ->setFlags(!$this->lefty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldTextBox('lefty_static_units')) ->setFlags(!$this->lefty_on || !$this->lefty_units_static ? CWidgetField::FLAG_DISABLED : 0x00) ->setMaxLength(255) ) ->addField( (new CWidgetFieldCheckBox('righty', _('Right Y'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON) ) ->addField( (new CWidgetFieldSelect('righty_scale', _('Scale'), [ SVG_GRAPH_AXIS_SCALE_LINEAR => _('Linear'), SVG_GRAPH_AXIS_SCALE_LOGARITHMIC => _('Logarithmic') ]))->setDefault(SVG_GRAPH_AXIS_SCALE_LINEAR) ) ->addField( (new CWidgetFieldNumericBox('righty_min', _('Min'))) ->prefixLabel(_('Right Y')) ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldNumericBox('righty_max', _('Max'))) ->prefixLabel(_('Right Y')) ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldSelect('righty_units', _('Units'), [ SVG_GRAPH_AXIS_UNITS_AUTO => _x('Auto', 'history source selection method'), SVG_GRAPH_AXIS_UNITS_STATIC => _x('Static', 'history source selection method') ])) ->setDefault(SVG_GRAPH_AXIS_UNITS_AUTO) ->setFlags(!$this->righty_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldTextBox('righty_static_units', null)) ->setFlags(!$this->righty_on || !$this->righty_units_static ? CWidgetField::FLAG_DISABLED : 0x00) ->setMaxLength(255) ) ->addField( (new CWidgetFieldCheckBox('axisx', _('X-Axis'), _('Show')))->setDefault(SVG_GRAPH_AXIS_ON) ); } private function initLegendFields(): self { return $this ->addField( (new CWidgetFieldCheckBox('legend', _('Show legend')))->setDefault(self::LEGEND_ON) ) ->addField( (new CWidgetFieldCheckBox('legend_statistic', _('Display min/avg/max'))) ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldCheckBox('legend_aggregation', _('Show aggregation function'))) ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldRadioButtonList('legend_lines_mode', _('Rows'), [ self::LEGEND_LINES_MODE_FIXED => _('Fixed'), self::LEGEND_LINES_MODE_VARIABLE => _('Variable') ])) ->setDefault(self::LEGEND_LINES_MODE_FIXED) ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldRangeControl('legend_lines', _('Number of rows'), self::LEGEND_LINES_MIN, self::LEGEND_LINES_MAX )) ->setDefault(self::LEGEND_LINES_MIN) ->setFlags(!$this->legend_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldRangeControl('legend_columns', _('Number of columns'), self::LEGEND_COLUMNS_MIN, self::LEGEND_COLUMNS_MAX )) ->setDefault(self::LEGEND_COLUMNS_MAX) ->setFlags(!$this->legend_on || $this->legend_statistic_on ? CWidgetField::FLAG_DISABLED : 0x00) ); } private function initProblemsFields(): self { return $this ->addField( new CWidgetFieldCheckBox('show_problems', _('Show problems')) ) ->addField( (new CWidgetFieldCheckBox('graph_item_problems', _('Selected items only'))) ->setDefault(SVG_GRAPH_SELECTED_ITEM_PROBLEMS) ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField($this->isTemplateDashboard() ? null : (new CWidgetFieldPatternSelectHost('problemhosts', _('Problem hosts'))) ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldSeverities('severities', _('Severity'))) ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldTextBox('problem_name', _('Problem'))) ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldRadioButtonList('evaltype', _('Problem tags'), [ TAG_EVAL_TYPE_AND_OR => _('And/Or'), TAG_EVAL_TYPE_OR => _('Or') ])) ->setDefault(TAG_EVAL_TYPE_AND_OR) ->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ) ->addField( (new CWidgetFieldTags('tags'))->setFlags(!$this->problems_on ? CWidgetField::FLAG_DISABLED : 0x00) ); } private function initOverridesFields(): self { return $this->addField( (new CWidgetFieldOverride('or', _('Overrides')))->setFlags(CWidgetField::FLAG_NOT_EMPTY) ); } }