File: C52CalculatedItemConverter.php

package info (click to toggle)
zabbix 1%3A7.0.10%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 272,688 kB
  • sloc: sql: 946,050; ansic: 389,440; php: 292,698; javascript: 83,388; sh: 5,680; makefile: 3,285; java: 1,420; cpp: 694; perl: 64; xml: 56
file content (125 lines) | stat: -rw-r--r-- 3,501 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/


/**
 * Class to convert calculated item keys.
 */
class C52CalculatedItemConverter extends C52TriggerExpressionConverter {

	/**
	 * Item key parser.
	 *
	 * @var CItemKey
	 */
	protected $item_key_parser;

	/**
	 * Function parser.
	 *
	 * @var C10FunctionParser
	 */
	protected $function_parser;

	public function __construct() {
		$this->parser = new C10TriggerExpression([
			'allow_func_only' => true,
			'calculated' => true
		]);
		$this->item_key_parser = new CItemKey();
		$this->function_parser = new C10FunctionParser();
		$this->standalone_functions = getStandaloneFunctions();
	}

	/**
	 * Convert calculated item formula to 5.4 syntax.
	 *
	 * @param string $formula  Calculated item formula to convert.
	 *
	 * @return string
	 */
	public function convert($item) {
		$expression = preg_replace("/[\\r\\n\\t]/", '', $item['params']);

		if ($this->parser->parse($expression) === false) {
			return $item;
		}

		$functions = $this->parser->result->getTokensByType(C10TriggerExprParserResult::TOKEN_TYPE_FUNCTION);
		$this->hanged_refs = $this->checkHangedFunctionsPerHost($functions);

		for ($i = count($functions) - 1; $i >= 0; $i--) {
			$fn = $functions[$i]['data'] + ['host' => '', 'item' => ''];

			$query = $fn['functionParams'][0];
			$colon_pos = strpos($query, ':');
			$bracket_pos = strpos($query, '[');

			if ($colon_pos !== false && ($bracket_pos === false || $colon_pos < $bracket_pos)) {
				list($host_name, $item_key) = explode(':', $query, 2);
			}
			else {
				$host_name = '';
				$item_key = $query;
			}

			if ($this->item_key_parser->parse($item_key) === CParser::PARSE_SUCCESS) {
				array_shift($fn['functionParams']);
				array_shift($fn['functionParamsRaw']['parameters']);
				[$new_expr] = $this->convertFunction($fn, $host_name, $item_key);

				$expression = substr_replace($expression, $new_expr, $functions[$i]['pos'], $functions[$i]['length']);
			}
		}

		$item['params'] = $expression;

		return $item;
	}

	/**
	 * Check if each particular host reference would be linked through at least one functions according to the new
	 * trigger expression syntax.
	 *
	 * @param array $tokens
	 *
	 * @return array
	 */
	protected function checkHangedFunctionsPerHost(array $tokens): array {
		$hanged_refs = ['' => false];

		foreach ($tokens as $token) {
			$host_name = '';
			$fn = $token['data'];
			$item_key = $fn['functionParams'][0];
			$host_delimiter_pos = strpos($item_key, ':');

			if ($host_delimiter_pos === false || $host_delimiter_pos > strpos($item_key, '[')) {
				continue;
			}

			$host_name = substr($item_key, 0, $host_delimiter_pos);

			if (!array_key_exists($host_name, $hanged_refs)) {
				$hanged_refs[$host_name] = false;
			}
			if (!in_array($fn['functionName'], $this->standalone_functions)) {
				$hanged_refs[$host_name] = true;
			}
		}

		return $hanged_refs;
	}
}