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 22function getRegexp($regexpId) { 23 return DBfetch(DBselect('SELECT re.* FROM regexps re WHERE regexpid='.zbx_dbstr($regexpId))); 24} 25 26function getRegexpExpressions($regexpId) { 27 $expressions = []; 28 29 $dbExpressions = DBselect( 30 'SELECT e.expressionid,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive'. 31 ' FROM expressions e'. 32 ' WHERE regexpid='.zbx_dbstr($regexpId) 33 ); 34 while ($expression = DBfetch($dbExpressions)) { 35 $expressions[$expression['expressionid']] = $expression; 36 } 37 38 return $expressions; 39} 40 41function addRegexp(array $regexp, array $expressions) { 42 try { 43 // check required fields 44 $dbFields = ['name' => null, 'test_string' => '']; 45 46 validateRegexp($expressions); 47 48 if (!check_db_fields($dbFields, $regexp)) { 49 throw new Exception(_('Incorrect arguments passed to function').' [addRegexp]'); 50 } 51 52 // check duplicate name 53 $sql = 'SELECT re.regexpid'. 54 ' FROM regexps re'. 55 ' WHERE re.name='.zbx_dbstr($regexp['name']); 56 57 if (DBfetch(DBselect($sql))) { 58 throw new Exception(_s('Regular expression "%s" already exists.', $regexp['name'])); 59 } 60 61 $regexpIds = DB::insert('regexps', [$regexp]); 62 $regexpId = reset($regexpIds); 63 64 addRegexpExpressions($regexpId, $expressions); 65 } 66 catch (Exception $e) { 67 error($e->getMessage()); 68 return false; 69 } 70 71 return true; 72} 73 74function updateRegexp(array $regexp, array $expressions) { 75 try { 76 $regexpId = $regexp['regexpid']; 77 unset($regexp['regexpid']); 78 79 validateRegexp($expressions); 80 81 // check existence 82 if (!getRegexp($regexpId)) { 83 throw new Exception(_('Regular expression does not exist.')); 84 } 85 86 // check required fields 87 $dbFields = ['name' => null]; 88 if (!check_db_fields($dbFields, $regexp)) { 89 throw new Exception(_('Incorrect arguments passed to function').' [updateRegexp]'); 90 } 91 92 // check duplicate name 93 $dbRegexp = DBfetch(DBselect( 94 'SELECT re.regexpid'. 95 ' FROM regexps re'. 96 ' WHERE re.name='.zbx_dbstr($regexp['name']) 97 )); 98 if ($dbRegexp && bccomp($regexpId, $dbRegexp['regexpid']) != 0) { 99 throw new Exception(_s('Regular expression "%s" already exists.', $regexp['name'])); 100 } 101 102 rewriteRegexpExpressions($regexpId, $expressions); 103 104 DB::update('regexps', [ 105 'values' => $regexp, 106 'where' => ['regexpid' => $regexpId] 107 ]); 108 } 109 catch (Exception $e) { 110 error($e->getMessage()); 111 return false; 112 } 113 114 return true; 115} 116 117function validateRegexp($expressions) { 118 $validator = new CRegexValidator([ 119 'messageInvalid' => _('Regular expression must be a string'), 120 'messageRegex' => _('Incorrect regular expression "%1$s": "%2$s"') 121 ]); 122 123 foreach ($expressions as $expression) { 124 switch ($expression['expression_type']) { 125 case EXPRESSION_TYPE_TRUE: 126 case EXPRESSION_TYPE_FALSE: 127 if (!$validator->validate($expression['expression'])) { 128 throw new Exception($validator->getError()); 129 } 130 break; 131 132 case EXPRESSION_TYPE_INCLUDED: 133 case EXPRESSION_TYPE_NOT_INCLUDED: 134 if ($expression['expression'] === '') { 135 throw new Exception(_('Expression cannot be empty')); 136 } 137 break; 138 139 case EXPRESSION_TYPE_ANY_INCLUDED: 140 foreach (explode($expression['exp_delimiter'], $expression['expression']) as $string) { 141 if ($expression['expression'] === '') { 142 throw new Exception(_('Expression cannot be empty')); 143 } 144 } 145 break; 146 } 147 } 148} 149 150/** 151 * Rewrite Zabbix regexp expressions. 152 * If all fields are equal to existing expression, that expression is not touched. 153 * Other expressions are removed and new ones created. 154 * 155 * @param string $regexpId 156 * @param array $expressions 157 */ 158function rewriteRegexpExpressions($regexpId, array $expressions) { 159 $dbExpressions = getRegexpExpressions($regexpId); 160 161 $expressionsToAdd = []; 162 $expressionsToUpdate = []; 163 164 foreach ($expressions as $expression) { 165 if (!isset($expression['expressionid'])) { 166 $expressionsToAdd[] = $expression; 167 } 168 elseif (isset($dbExpressions[$expression['expressionid']])) { 169 $expressionsToUpdate[] = $expression; 170 unset($dbExpressions[$expression['expressionid']]); 171 } 172 } 173 174 if ($dbExpressions) { 175 $dbExpressionIds = zbx_objectValues($dbExpressions, 'expressionid'); 176 deleteRegexpExpressions($dbExpressionIds); 177 } 178 179 if ($expressionsToAdd) { 180 addRegexpExpressions($regexpId, $expressionsToAdd); 181 } 182 183 if ($expressionsToUpdate) { 184 updateRegexpExpressions($expressionsToUpdate); 185 } 186} 187 188function addRegexpExpressions($regexpId, array $expressions) { 189 $dbFields = ['expression' => null, 'expression_type' => null]; 190 191 foreach ($expressions as &$expression) { 192 if (!check_db_fields($dbFields, $expression)) { 193 throw new Exception(_('Incorrect arguments passed to function').' [add_expression]'); 194 } 195 196 $expression['regexpid'] = $regexpId; 197 } 198 unset($expression); 199 200 DB::insert('expressions', $expressions); 201} 202 203function updateRegexpExpressions(array $expressions) { 204 foreach ($expressions as &$expression) { 205 $expressionId = $expression['expressionid']; 206 unset($expression['expressionid']); 207 208 DB::update('expressions', [ 209 'values' => $expression, 210 'where' => ['expressionid' => $expressionId] 211 ]); 212 } 213 unset($expression); 214} 215 216function deleteRegexpExpressions(array $expressionIds) { 217 DB::delete('expressions', ['expressionid' => $expressionIds]); 218} 219 220function expression_type2str($type = null) { 221 $types = [ 222 EXPRESSION_TYPE_INCLUDED => _('Character string included'), 223 EXPRESSION_TYPE_ANY_INCLUDED => _('Any character string included'), 224 EXPRESSION_TYPE_NOT_INCLUDED => _('Character string not included'), 225 EXPRESSION_TYPE_TRUE => _('Result is TRUE'), 226 EXPRESSION_TYPE_FALSE => _('Result is FALSE') 227 ]; 228 229 if ($type === null) { 230 return $types; 231 } 232 elseif (isset($types[$type])) { 233 return $types[$type]; 234 } 235 else { 236 return _('Unknown'); 237 } 238} 239 240function expressionDelimiters() { 241 return [ 242 ',' => ',', 243 '.' => '.', 244 '/' => '/' 245 ]; 246} 247