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 * Trigger expression converter from 2.2 to 2.4. 24 */ 25class C20TriggerConverter extends CConverter { 26 27 /** 28 * A parser for function macros. 29 * 30 * @var CFunctionMacroParser 31 */ 32 protected $function_macro_parser; 33 34 /** 35 * A parser for LLD macros. 36 * 37 * @var CMacroParser 38 */ 39 protected $lld_macro_parser; 40 41 /** 42 * An item key converter. 43 * 44 * @var C20ItemKeyConverter 45 */ 46 protected $itemKeyConverter; 47 48 public function __construct() { 49 $this->function_macro_parser = new CFunctionMacroParser(); 50 $this->lld_macro_parser = new CLLDMacroParser(); 51 $this->itemKeyConverter = new C20ItemKeyConverter(); 52 } 53 54 /** 55 * Convert a trigger expression from 2.2 format to 2.4. 56 * 57 * The method will replace old operators with their analogues: "&" with "and", "|" - "or" and "#" - "<>". 58 * 59 * @param string $expression 60 * 61 * @return string 62 */ 63 public function convert($expression) { 64 // find all the operators that need to be replaced 65 $found_operators = []; 66 for ($pos = 0; isset($expression[$pos]); $pos++) { 67 switch ($expression[$pos]) { 68 case '{': 69 // skip function macros 70 if ($this->function_macro_parser->parse($expression, $pos) != CParser::PARSE_FAIL) { 71 $new_expression = '{'. 72 $this->function_macro_parser->getHost().':'. 73 $this->itemKeyConverter->convert($this->function_macro_parser->getItem()).'.'. 74 $this->function_macro_parser->getFunction(). 75 '}'; 76 77 $expression = substr_replace($expression, $new_expression, $pos, 78 $this->function_macro_parser->getLength() 79 ); 80 81 $pos += strlen($new_expression) - 1; 82 } 83 else { 84 // if it's not a function macro, try to parse it as an LLD macro 85 if ($this->lld_macro_parser->parse($expression, $pos) != CParser::PARSE_FAIL) { 86 $pos += $this->lld_macro_parser->getLength() - 1; 87 } 88 } 89 // otherwise just continue as is, other macros don't contain any of these characters 90 break; 91 92 case '&': 93 case '|': 94 case '#': 95 $found_operators[$pos] = $expression[$pos]; 96 break; 97 } 98 } 99 100 // replace the operators 101 foreach (array_reverse($found_operators, true) as $pos => $operator) { 102 switch ($operator) { 103 case '&': 104 $expression = $this->replaceLogicalOperator($expression, 'and', $pos); 105 106 break; 107 case '|': 108 $expression = $this->replaceLogicalOperator($expression, 'or', $pos); 109 110 break; 111 case '#': 112 $expression = substr_replace($expression, '<>', $pos, 1); 113 114 break; 115 } 116 } 117 118 return $expression; 119 } 120 121 /** 122 * Replaces an operator at the given position and removes extra spaces around it. 123 * 124 * @param string $expression 125 * @param string $newOperator 126 * @param int $pos 127 * 128 * @return string 129 */ 130 protected function replaceLogicalOperator($expression, $newOperator, $pos) { 131 $left = substr($expression, 0, $pos); 132 $right = substr($expression, $pos + 1); 133 134 return rtrim($left).' '.$newOperator.' '.ltrim($right); 135 } 136 137} 138