1<?php declare(strict_types = 1);
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 storing the result returned by the trigger expression parser.
24 */
25class CExpressionParserResult extends CParserResult {
26
27	const TOKEN_TYPE_OPEN_BRACE = 0;
28	const TOKEN_TYPE_CLOSE_BRACE = 1;
29	const TOKEN_TYPE_OPERATOR = 2;
30	const TOKEN_TYPE_NUMBER = 3;
31	const TOKEN_TYPE_MACRO = 4;
32	const TOKEN_TYPE_USER_MACRO = 5;
33	const TOKEN_TYPE_LLD_MACRO = 6;
34	const TOKEN_TYPE_STRING = 7;
35	const TOKEN_TYPE_FUNCTIONID_MACRO = 8;
36	const TOKEN_TYPE_HIST_FUNCTION = 9;
37	const TOKEN_TYPE_MATH_FUNCTION = 10;
38	const TOKEN_TYPE_EXPRESSION = 11;
39
40	/**
41	 * Array of tokens.
42	 *
43	 * @var array
44	 */
45	protected $tokens = [];
46
47	/**
48	 * Return the expression tokens.
49	 *
50	 * @see CExpressionParserResult::$token    for the structure of a token array
51	 *
52	 * @return array
53	 */
54	public function getTokens() {
55		return $this->tokens;
56	}
57
58	/**
59	 * Add a token to the result.
60	 *
61	 * @param CParserResult $token
62	 */
63	public function addTokens(array $tokens): void {
64		$this->tokens = array_merge($this->tokens, $tokens);
65	}
66
67	/**
68	 * Auxiliary method for getTokensOfTypes().
69	 *
70	 * @param array  $tokens
71	 * @param array  $types
72	 *
73	 * @return array
74	 */
75	private static function _getTokensOfTypes(array $tokens, array $types) {
76		$result = [];
77
78		foreach ($tokens as $token) {
79			if (in_array($token['type'], $types)) {
80				$result[] = $token;
81			}
82
83			if ($token['type'] == CExpressionParserResult::TOKEN_TYPE_EXPRESSION) {
84				$result = array_merge($result, self::_getTokensOfTypes($token['data']['tokens'], $types));
85			}
86			elseif ($token['type'] == CExpressionParserResult::TOKEN_TYPE_MATH_FUNCTION) {
87				foreach ($token['data']['parameters'] as $parameter) {
88					$result = array_merge($result, self::_getTokensOfTypes($parameter['data']['tokens'], $types));
89				}
90			}
91		}
92
93		return $result;
94	}
95
96	/**
97	 * Returns all tokens include nested of the given types.
98	 *
99	 * @param array  $types
100	 *
101	 * @return array
102	 */
103	public function getTokensOfTypes(array $types): array {
104		return self::_getTokensOfTypes($this->tokens, $types);
105	}
106
107	/**
108	 * Return list hosts found in parsed trigger expression.
109	 *
110	 * @return array
111	 */
112	public function getHosts(): array {
113		$hist_functions = $this->getTokensOfTypes([CExpressionParserResult::TOKEN_TYPE_HIST_FUNCTION]);
114		$hosts = [];
115
116		foreach ($hist_functions as $hist_function) {
117			$hosts[$hist_function['data']['parameters'][0]['data']['host']] = true;
118		}
119
120		return array_keys($hosts);
121	}
122}
123