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 22class CControllerPopupTriggerExpr extends CController { 23 private $metrics = []; 24 private $param1SecCount = []; 25 private $param1Sec = []; 26 private $param1Str = []; 27 private $param2SecCount = []; 28 private $param2SecMode = []; 29 private $param3SecVal = []; 30 private $param3SecPercent = []; 31 private $paramSecIntCount = []; 32 private $paramForecast = []; 33 private $paramTimeleft = []; 34 private $allowedTypesAny = []; 35 private $allowedTypesNumeric = []; 36 private $allowedTypesStr = []; 37 private $allowedTypesLog = []; 38 private $allowedTypesInt = []; 39 private $functions = []; 40 private $operators = []; 41 42 protected function init() { 43 $this->disableSIDvalidation(); 44 45 $this->metrics = [ 46 PARAM_TYPE_TIME => _('Time'), 47 PARAM_TYPE_COUNTS => _('Count') 48 ]; 49 50 /* 51 * C - caption 52 * T - type 53 * M - metrics 54 * A - asterisk 55 */ 56 $this->param1SecCount = [ 57 'last' => [ 58 'C' => _('Last of').' (T)', 59 'T' => T_ZBX_INT, 60 'M' => $this->metrics, 61 'A' => true 62 ], 63 'shift' => [ 64 'C' => _('Time shift'), 65 'T' => T_ZBX_INT, 66 'A' => false 67 ] 68 ]; 69 70 $this->param1Sec = [ 71 'last' => [ 72 'C' => _('Last of').' (T)', 73 'T' => T_ZBX_INT, 74 'A' => true 75 ] 76 ]; 77 78 $this->param1Str = [ 79 'pattern' => [ 80 'C' => 'T', 81 'T' => T_ZBX_STR, 82 'A' => false 83 ] 84 ]; 85 86 $this->param2SecCount = [ 87 'pattern' => [ 88 'C' => 'V', 89 'T' => T_ZBX_STR, 90 'A' => false 91 ], 92 'last' => [ 93 'C' => _('Last of').' (T)', 94 'T' => T_ZBX_INT, 95 'M' => $this->metrics, 96 'A' => false 97 ] 98 ]; 99 100 $this->param2SecMode = [ 101 'last' => [ 102 'C' => _('Last of').' (T)', 103 'T' => T_ZBX_INT, 104 'A' => true 105 ], 106 'mode' => [ 107 'C' => 'Mode', 108 'T' => T_ZBX_STR, 109 'A' => false 110 ] 111 ]; 112 113 $this->param3SecVal = [ 114 'last' => [ 115 'C' => _('Last of').' (T)', 116 'T' => T_ZBX_INT, 117 'M' => $this->metrics, 118 'A' => true 119 ], 120 'v' => [ 121 'C' => 'V', 122 'T' => T_ZBX_STR, 123 'A' => false 124 ], 125 'o' => [ 126 'C' => 'O', 127 'T' => T_ZBX_STR, 128 'A' => false 129 ], 130 'shift' => [ 131 'C' => _('Time shift'), 132 'T' => T_ZBX_INT, 133 'A' => false 134 ] 135 ]; 136 137 $this->param3SecPercent = [ 138 'last' => [ 139 'C' => _('Last of').' (T)', 140 'T' => T_ZBX_INT, 141 'M' => $this->metrics, 142 'A' => true 143 ], 144 'shift' => [ 145 'C' => _('Time shift'), 146 'T' => T_ZBX_INT, 147 'A' => false 148 ], 149 'p' => [ 150 'C' => _('Percentage').' (P)', 151 'T' => T_ZBX_DBL, 152 'A' => true 153 ] 154 ]; 155 156 $this->paramSecIntCount = [ 157 'last' => [ 158 'C' => _('Last of').' (T)', 159 'T' => T_ZBX_INT, 160 'M' => $this->metrics, 161 'A' => true 162 ], 163 'mask' => [ 164 'C' => _('Mask'), 165 'T' => T_ZBX_STR, 166 'A' => true 167 ], 168 'shift' => [ 169 'C' => _('Time shift'), 170 'T' => T_ZBX_INT, 171 'A' => false 172 ] 173 ]; 174 175 $this->paramForecast = [ 176 'last' => [ 177 'C' => _('Last of').' (T)', 178 'T' => T_ZBX_INT, 179 'M' => $this->metrics, 180 'A' => true 181 ], 182 'shift' => [ 183 'C' => _('Time shift'), 184 'T' => T_ZBX_INT, 185 'A' => false 186 ], 187 'time' => [ 188 'C' => _('Time').' (t)', 189 'T' => T_ZBX_INT, 190 'A' => true 191 ], 192 'fit' => [ 193 'C' => _('Fit'), 194 'T' => T_ZBX_STR, 195 'A' => false 196 ], 197 'mode' => [ 198 'C' => _('Mode'), 199 'T' => T_ZBX_STR, 200 'A' => false 201 ] 202 ]; 203 204 $this->paramTimeleft = [ 205 'last' => [ 206 'C' => _('Last of').' (T)', 207 'T' => T_ZBX_INT, 208 'M' => $this->metrics, 209 'A' => true 210 ], 211 'shift' => [ 212 'C' => _('Time shift'), 213 'T' => T_ZBX_INT, 214 'A' => false 215 ], 216 't' => [ 217 'C' => _('Threshold'), 218 'T' => T_ZBX_DBL, 219 'A' => true 220 ], 221 'fit' => [ 222 'C' => _('Fit'), 223 'T' => T_ZBX_STR, 224 'A' => false 225 ] 226 ]; 227 228 $this->allowedTypesAny = [ 229 ITEM_VALUE_TYPE_FLOAT => 1, 230 ITEM_VALUE_TYPE_STR => 1, 231 ITEM_VALUE_TYPE_LOG => 1, 232 ITEM_VALUE_TYPE_UINT64 => 1, 233 ITEM_VALUE_TYPE_TEXT => 1 234 ]; 235 236 $this->allowedTypesNumeric = [ 237 ITEM_VALUE_TYPE_FLOAT => 1, 238 ITEM_VALUE_TYPE_UINT64 => 1 239 ]; 240 241 $this->allowedTypesStr = [ 242 ITEM_VALUE_TYPE_STR => 1, 243 ITEM_VALUE_TYPE_LOG => 1, 244 ITEM_VALUE_TYPE_TEXT => 1 245 ]; 246 247 $this->allowedTypesLog = [ 248 ITEM_VALUE_TYPE_LOG => 1 249 ]; 250 251 $this->allowedTypesInt = [ 252 ITEM_VALUE_TYPE_UINT64 => 1 253 ]; 254 255 $this->functions = [ 256 'abschange' => [ 257 'description' => _('abschange() - Absolute difference between last and previous value'), 258 'allowed_types' => $this->allowedTypesAny, 259 'operators' => ['=', '<>', '>', '<', '>=', '<='] 260 ], 261 'avg' => [ 262 'description' => _('avg() - Average value of a period T'), 263 'params' => $this->param1SecCount, 264 'allowed_types' => $this->allowedTypesNumeric, 265 'operators' => ['=', '<>', '>', '<', '>=', '<='] 266 ], 267 'delta' => [ 268 'description' => _('delta() - Difference between MAX and MIN value of a period T'), 269 'params' => $this->param1SecCount, 270 'allowed_types' => $this->allowedTypesNumeric, 271 'operators' => ['=', '<>', '>', '<', '>=', '<='] 272 ], 273 'change' => [ 274 'description' => _('change() - Difference between last and previous value'), 275 'allowed_types' => $this->allowedTypesAny, 276 'operators' => ['=', '<>', '>', '<', '>=', '<='] 277 ], 278 'count' => [ 279 'description' => _('count() - Number of successfully retrieved values V (which fulfill operator O) for period T'), 280 'params' => $this->param3SecVal, 281 'allowed_types' => $this->allowedTypesAny, 282 'operators' => ['=', '<>', '>', '<', '>=', '<='] 283 ], 284 'diff' => [ 285 'description' => _('diff() - Difference between last and preceding values (1 - true, 0 - false)'), 286 'allowed_types' => $this->allowedTypesAny, 287 'operators' => ['=', '<>'] 288 ], 289 'last' => [ 290 'description' => _('last() - Last (most recent) T value'), 291 'params' => $this->param1SecCount, 292 'allowed_types' => $this->allowedTypesAny, 293 'operators' => ['=', '<>', '>', '<', '>=', '<='] 294 ], 295 'max' => [ 296 'description' => _('max() - Maximum value for period T'), 297 'params' => $this->param1SecCount, 298 'allowed_types' => $this->allowedTypesNumeric, 299 'operators' => ['=', '<>', '>', '<', '>=', '<='] 300 ], 301 'min' => [ 302 'description' => _('min() - Minimum value for period T'), 303 'params' => $this->param1SecCount, 304 'allowed_types' => $this->allowedTypesNumeric, 305 'operators' => ['=', '<>', '>', '<', '>=', '<='] 306 ], 307 'percentile' => [ 308 'description' => _('percentile() - Percentile P of a period T'), 309 'params' => $this->param3SecPercent, 310 'allowed_types' => $this->allowedTypesNumeric, 311 'operators' => ['=', '<>', '>', '<', '>=', '<='] 312 ], 313 'prev' => [ 314 'description' => _('prev() - Previous value'), 315 'allowed_types' => $this->allowedTypesAny, 316 'operators' => ['=', '<>', '>', '<', '>=', '<='] 317 ], 318 'str' => [ 319 'description' => _('str() - Find string V in last (most recent) value (1 - found, 0 - not found)'), 320 'params' => $this->param2SecCount, 321 'allowed_types' => $this->allowedTypesStr, 322 'operators' => ['=', '<>'] 323 ], 324 'strlen' => [ 325 'description' => _('strlen() - Length of last (most recent) T value in characters'), 326 'params' => $this->param1SecCount, 327 'allowed_types' => $this->allowedTypesStr, 328 'operators' => ['=', '<>', '>', '<', '>=', '<='] 329 ], 330 'sum' => [ 331 'description' => _('sum() - Sum of values of a period T'), 332 'params' => $this->param1SecCount, 333 'allowed_types' => $this->allowedTypesNumeric, 334 'operators' => ['=', '<>', '>', '<', '>=', '<='] 335 ], 336 'date' => [ 337 'description' => _('date() - Current date'), 338 'allowed_types' => $this->allowedTypesAny, 339 'operators' => ['=', '<>', '>', '<', '>=', '<='] 340 ], 341 'dayofweek' => [ 342 'description' => _('dayofweek() - Day of week'), 343 'allowed_types' => $this->allowedTypesAny, 344 'operators' => ['=', '<>', '>', '<', '>=', '<='] 345 ], 346 'dayofmonth' => [ 347 'description' => _('dayofmonth() - Day of month'), 348 'allowed_types' => $this->allowedTypesAny, 349 'operators' => ['=', '<>', '>', '<', '>=', '<='] 350 ], 351 'fuzzytime' => [ 352 'description' => _('fuzzytime() - Difference between item value (as timestamp) and Zabbix server timestamp is less than or equal to T seconds (1 - true, 0 - false)'), 353 'params' => $this->param1Sec, 354 'allowed_types' => $this->allowedTypesNumeric, 355 'operators' => ['=', '<>'] 356 ], 357 'regexp' => [ 358 'description' => _('regexp() - Regular expression V matching last value in period T (1 - match, 0 - no match)'), 359 'params' => $this->param2SecCount, 360 'allowed_types' => $this->allowedTypesStr, 361 'operators' => ['=', '<>'] 362 ], 363 'iregexp' => [ 364 'description' => _('iregexp() - Regular expression V matching last value in period T (non case-sensitive; 1 - match, 0 - no match)'), 365 'params' => $this->param2SecCount, 366 'allowed_types' => $this->allowedTypesStr, 367 'operators' => ['=', '<>'] 368 ], 369 'logeventid' => [ 370 'description' => _('logeventid() - Event ID of last log entry matching regular expression T (1 - match, 0 - no match)'), 371 'params' => $this->param1Str, 372 'allowed_types' => $this->allowedTypesLog, 373 'operators' => ['=', '<>'] 374 ], 375 'logseverity' => [ 376 'description' => _('logseverity() - Log severity of the last log entry'), 377 'allowed_types' => $this->allowedTypesLog, 378 'operators' => ['=', '<>', '>', '<', '>=', '<='] 379 ], 380 'logsource' => [ 381 'description' => _('logsource() - Log source of the last log entry matching parameter T (1 - match, 0 - no match)'), 382 'params' => $this->param1Str, 383 'allowed_types' => $this->allowedTypesLog, 384 'operators' => ['=', '<>'] 385 ], 386 'now' => [ 387 'description' => _('now() - Number of seconds since the Epoch'), 388 'allowed_types' => $this->allowedTypesAny, 389 'operators' => ['=', '<>', '>', '<', '>=', '<='] 390 ], 391 'time' => [ 392 'description' => _('time() - Current time'), 393 'allowed_types' => $this->allowedTypesAny, 394 'operators' => ['=', '<>', '>', '<', '>=', '<='] 395 ], 396 'nodata' => [ 397 'description' => _('nodata() - No data received during period of time T (1 - true, 0 - false), Mode (strict - ignore proxy time delay in sending data)'), 398 'params' => $this->param2SecMode, 399 'allowed_types' => $this->allowedTypesAny, 400 'operators' => ['=', '<>'] 401 ], 402 'band' => [ 403 'description' => _('band() - Bitwise AND of last (most recent) T value and mask'), 404 'params' => $this->paramSecIntCount, 405 'allowed_types' => $this->allowedTypesInt, 406 'operators' => ['=', '<>'] 407 ], 408 'forecast' => [ 409 'description' => _('forecast() - Forecast for next t seconds based on period T'), 410 'params' => $this->paramForecast, 411 'allowed_types' => $this->allowedTypesNumeric, 412 'operators' => ['=', '<>', '>', '<', '>=', '<='] 413 ], 414 'timeleft' => [ 415 'description' => _('timeleft() - Time to reach threshold estimated based on period T'), 416 'params' => $this->paramTimeleft, 417 'allowed_types' => $this->allowedTypesNumeric, 418 'operators' => ['=', '<>', '>', '<', '>=', '<='] 419 ] 420 ]; 421 422 CArrayHelper::sort($this->functions, ['description']); 423 424 foreach ($this->functions as $function) { 425 foreach ($function['operators'] as $operator) { 426 $this->operators[$operator] = true; 427 } 428 } 429 } 430 431 protected function checkInput() { 432 $fields = [ 433 'dstfrm' => 'string|fatal', 434 'dstfld1' => 'string|not_empty', 435 'expression' => 'string', 436 'itemid' => 'db items.itemid', 437 'parent_discoveryid' => 'db items.itemid', 438 'function' => 'in '.implode(',', array_keys($this->functions)), 439 'operator' => 'in '.implode(',', array_keys($this->operators)), 440 'params' => '', 441 'paramtype' => 'in '.implode(',', [PARAM_TYPE_TIME, PARAM_TYPE_COUNTS]), 442 'value' => 'string|not_empty', 443 'hostid' => 'db hosts.hostid', 444 'groupid' => 'db hosts_groups.hostgroupid', 445 'add' => 'in 1' 446 ]; 447 448 $ret = $this->validateInput($fields); 449 450 if (!$ret) { 451 $output = []; 452 if (($messages = getMessages()) !== null) { 453 $output['errors'] = $messages->toString(); 454 } 455 456 if ($this->hasInput('add')) { 457 $this->setResponse( 458 (new CControllerResponseData(['main_block' => json_encode($output)]))->disableView() 459 ); 460 } 461 else { 462 $ret = true; 463 } 464 } 465 466 return $ret; 467 } 468 469 protected function checkPermissions() { 470 return true; 471 } 472 473 protected function doAction() { 474 $itemid = $this->getInput('itemid', 0); 475 $function = $this->getInput('function', 'last'); 476 $operator = $this->getInput('operator', '='); 477 $param_type = $this->getInput('paramtype', PARAM_TYPE_TIME); 478 $dstfld1 = $this->getInput('dstfld1'); 479 $expression = $this->getInput('expression', ''); 480 $params = $this->getInput('params', []); 481 $value = $this->getInput('value', 0); 482 483 // Opening the popup when editing an expression in the trigger constructor. 484 if (($dstfld1 === 'expr_temp' || $dstfld1 === 'recovery_expr_temp') && $expression !== '') { 485 $expression = utf8RawUrlDecode($expression); 486 487 $expression_data = new CTriggerExpression(); 488 $result = $expression_data->parse($expression); 489 490 if ($result) { 491 $function_macro_tokens = $result->getTokensByType( 492 CTriggerExprParserResult::TOKEN_TYPE_FUNCTION_MACRO 493 ); 494 495 if ($function_macro_tokens) { 496 $function_macro_token = $function_macro_tokens[0]; 497 $function = $function_macro_token['data']['functionName']; 498 499 // Determine param type. 500 $params = $function_macro_token['data']['functionParams']; 501 $param_number = in_array($function, ['regexp', 'iregexp', 'str']) ? 1 : 0; 502 if (array_key_exists($param_number, $params) && is_string($params[$param_number]) 503 && $params[$param_number] !== '' && $params[$param_number][0] === '#' 504 && !in_array($function, ['fuzzytime', 'nodata'])) { 505 $param_type = PARAM_TYPE_COUNTS; 506 $params[$param_number] = substr($params[$param_number], 1); 507 } 508 else { 509 $param_type = PARAM_TYPE_TIME; 510 } 511 512 /* 513 * Try to find an operator and a value. 514 * The value and operator can be extracted only if they immediately follow the item function macro. 515 */ 516 $tokens = $result->getTokens(); 517 foreach ($tokens as $key => $token) { 518 if ($token['type'] == CTriggerExprParserResult::TOKEN_TYPE_FUNCTION_MACRO) { 519 if (array_key_exists($key + 2, $tokens) 520 && $tokens[$key + 1]['type'] == CTriggerExprParserResult::TOKEN_TYPE_OPERATOR 521 && array_key_exists($function, $this->functions) 522 && in_array($tokens[$key + 1]['value'], 523 $this->functions[$function]['operators'])) { 524 $operator = $tokens[$key + 1]['value']; 525 526 $value = ''; 527 $i = 2; 528 529 if (array_key_exists($key + 3, $tokens) 530 && $tokens[$key + 2]['type'] == CTriggerExprParserResult::TOKEN_TYPE_OPERATOR) { 531 $value .= $tokens[$key + 2]['value']; 532 $i++; 533 } 534 535 $value .= ($tokens[$key + $i]['type'] == CTriggerExprParserResult::TOKEN_TYPE_STRING) 536 ? $tokens[$key + $i]['data']['string'] 537 : $tokens[$key + $i]['value']; 538 } 539 else { 540 break; 541 } 542 } 543 } 544 545 // Find the item. 546 $item = API::Item()->get([ 547 'output' => ['itemid', 'hostid', 'name', 'key_', 'value_type'], 548 'selectHosts' => ['name'], 549 'webitems' => true, 550 'filter' => [ 551 'host' => $function_macro_token['data']['host'], 552 'key_' => $function_macro_token['data']['item'], 553 'flags' => null 554 ] 555 ]); 556 557 if (($item = reset($item)) !== false) { 558 $itemid = $item['itemid']; 559 } 560 else { 561 error(_('Unknown host item, no such item in selected host')); 562 } 563 } 564 } 565 } 566 // Opening an empty form or switching a function. 567 else { 568 $item = API::Item()->get([ 569 'output' => ['itemid', 'hostid', 'name', 'key_', 'value_type'], 570 'selectHosts' => ['host', 'name'], 571 'itemids' => $itemid, 572 'webitems' => true, 573 'filter' => ['flags' => null] 574 ]); 575 576 $item = reset($item); 577 } 578 579 if ($itemid) { 580 $items = CMacrosResolverHelper::resolveItemNames([$item]); 581 $item = $items[0]; 582 583 $item_value_type = $item['value_type']; 584 $item_key = $item['key_']; 585 $item_host_data = reset($item['hosts']); 586 $description = $item_host_data['name'].NAME_DELIMITER.$item['name_expanded']; 587 } 588 else { 589 $item_key = ''; 590 $description = ''; 591 $item_value_type = null; 592 } 593 594 if ($param_type === null && array_key_exists($function, $this->functions) 595 && array_key_exists('params', $this->functions[$function]) 596 && array_key_exists('M', $this->functions[$function]['params'])) { 597 $param_type = is_array($this->functions[$function]['params']['M']) 598 ? reset($this->functions[$function]['params']['M']) 599 : $this->functions[$function]['params']['M']; 600 } 601 elseif ($param_type === null) { 602 $param_type = PARAM_TYPE_TIME; 603 } 604 605 $data = [ 606 'parent_discoveryid' => $this->getInput('parent_discoveryid', ''), 607 'dstfrm' => $this->getInput('dstfrm'), 608 'dstfld1' => $dstfld1, 609 'itemid' => $itemid, 610 'value' => $value, 611 'params' => $params, 612 'paramtype' => $param_type, 613 'item_description' => $description, 614 'functions' => $this->functions, 615 'function' => $function, 616 'operator' => $operator, 617 'item_key' => $item_key, 618 'itemValueType' => $item_value_type, 619 'selectedFunction' => null, 620 'groupid' => $this->getInput('groupid', 0), 621 'hostid' => $this->getInput('hostid', 0) 622 ]; 623 624 // Check if submitted function is usable with selected item. 625 foreach ($data['functions'] as $id => $f) { 626 if (($data['itemValueType'] === null || array_key_exists($item_value_type, $f['allowed_types'])) 627 && $id === $function) { 628 $data['selectedFunction'] = $id; 629 break; 630 } 631 } 632 633 if ($data['selectedFunction'] === null) { 634 $data['selectedFunction'] = 'last'; 635 $data['function'] = 'last'; 636 } 637 638 // Remove functions that not correspond to chosen item. 639 foreach ($data['functions'] as $id => $f) { 640 if ($data['itemValueType'] !== null && !array_key_exists($data['itemValueType'], $f['allowed_types'])) { 641 unset($data['functions'][$id]); 642 643 // Take first available function from list and change to first available operator for that function. 644 if ($id === $data['function']) { 645 $data['function'] = key($data['functions']); 646 $data['operator'] = reset($data['functions'][$data['function']]['operators']); 647 } 648 } 649 } 650 651 // Create and validate trigger expression before inserting it into textarea field. 652 if ($this->getInput('add', false)) { 653 try { 654 if ($data['item_description']) { 655 if ($data['paramtype'] == PARAM_TYPE_COUNTS 656 && array_key_exists('last', $data['params']) 657 && $data['params']['last'] !== '') { 658 $data['params']['last'] = zbx_is_int($data['params']['last']) 659 ? '#'.$data['params']['last'] 660 : $data['params']['last']; 661 } 662 elseif ($data['paramtype'] == PARAM_TYPE_TIME && in_array($function, ['last', 'band', 'strlen'])) { 663 $data['params']['last'] = ''; 664 } 665 666 // Quote function param. 667 $quoted_params = []; 668 foreach ($data['params'] as $param) { 669 $quoted_params[] = quoteFunctionParam($param); 670 } 671 672 $data['expression'] = sprintf('{%s:%s.%s(%s)}%s%s', 673 $item_host_data['host'], 674 $data['item_key'], 675 $function, 676 rtrim(implode(',', $quoted_params), ','), 677 $operator, 678 CTriggerExpression::quoteString($data['value']) 679 ); 680 681 // Validate trigger expression. 682 $trigger_expression = new CTriggerExpression(); 683 684 if ($trigger_expression->parse($data['expression'])) { 685 $expression_data = reset($trigger_expression->expressions); 686 687 // Validate trigger function. 688 $trigger_function_validator = new CFunctionValidator(); 689 $is_valid = $trigger_function_validator->validate([ 690 'function' => $expression_data['function'], 691 'functionName' => $expression_data['functionName'], 692 'functionParamList' => $expression_data['functionParamList'], 693 'valueType' => $data['itemValueType'] 694 ]); 695 696 if ($is_valid === false) { 697 error($trigger_function_validator->getError()); 698 } 699 } 700 else { 701 error($trigger_expression->error); 702 } 703 704 // Quote function param. 705 if (array_key_exists('insert', $data)) { 706 foreach ($data['params'] as $pnum => $param) { 707 $data['params'][$pnum] = quoteFunctionParam($param); 708 } 709 } 710 } 711 else { 712 error(_('Item not selected')); 713 } 714 } 715 catch (Exception $e) { 716 error($e->getMessage()); 717 error(_('Cannot insert trigger expression')); 718 } 719 720 if (($messages = getMessages()) !== null) { 721 $output = [ 722 'errors' => $messages->toString() 723 ]; 724 } 725 else { 726 $output = [ 727 'expression' => $data['expression'], 728 'dstfld1' => $data['dstfld1'], 729 'dstfrm' => $data['dstfrm'] 730 ]; 731 } 732 733 $this->setResponse( 734 (new CControllerResponseData(['main_block' => json_encode($output)]))->disableView() 735 ); 736 } 737 else { 738 $this->setResponse(new CControllerResponseData( 739 $data + [ 740 'title' => _('Condition'), 741 'errors' => hasErrorMesssages() ? getMessages() : null, 742 'user' => [ 743 'debug_mode' => $this->getDebugMode() 744 ] 745 ] 746 )); 747 } 748 } 749} 750