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 22require_once dirname(__FILE__).'/include/config.inc.php'; 23require_once dirname(__FILE__).'/include/forms.inc.php'; 24require_once dirname(__FILE__).'/include/actions.inc.php'; 25require_once dirname(__FILE__).'/include/triggers.inc.php'; 26 27$page['title'] = _('Configuration of actions'); 28$page['file'] = 'actionconf.php'; 29$page['scripts'] = ['multiselect.js']; 30 31require_once dirname(__FILE__).'/include/page_header.php'; 32// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 33$fields = [ 34 'actionid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, 'isset({form}) && {form} == "update"'], 35 'name' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', 36 _('Name') 37 ], 38 'eventsource' => [T_ZBX_INT, O_OPT, null, 39 IN([EVENT_SOURCE_TRIGGERS, EVENT_SOURCE_DISCOVERY, 40 EVENT_SOURCE_AUTO_REGISTRATION, EVENT_SOURCE_INTERNAL 41 ]), 42 null 43 ], 44 'evaltype' => [T_ZBX_INT, O_OPT, null, 45 IN([CONDITION_EVAL_TYPE_AND_OR, CONDITION_EVAL_TYPE_AND, 46 CONDITION_EVAL_TYPE_OR, CONDITION_EVAL_TYPE_EXPRESSION 47 ]), 48 'isset({add}) || isset({update})' 49 ], 50 'formula' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 51 'esc_period' => [T_ZBX_STR, O_OPT, null, null, null, _('Default operation step duration')], 52 'status' => [T_ZBX_INT, O_OPT, null, IN([ACTION_STATUS_ENABLED, ACTION_STATUS_DISABLED]), 53 null 54 ], 55 'def_shortdata' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 56 'def_longdata' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 57 'r_shortdata' => [T_ZBX_STR, O_OPT, null, null, null], 58 'r_longdata' => [T_ZBX_STR, O_OPT, null, null, null], 59 'ack_shortdata' => [T_ZBX_STR, O_OPT, null, null, null], 60 'ack_longdata' => [T_ZBX_STR, O_OPT, null, null, null], 61 'g_actionid' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 62 'conditions' => [null, O_OPT, null, null, null], 63 'new_condition' => [null, O_OPT, null, null, 'isset({add_condition})'], 64 'operations' => [null, O_OPT, null, null, null], 65 'edit_operationid' => [T_ZBX_STR, O_OPT, P_ACT, null, null], 66 'new_operation' => [null, O_OPT, null, null, null], 67 'recovery_operations' => [null, O_OPT, null, null, null], 68 'edit_recovery_operationid' => [T_ZBX_STR, O_OPT, P_ACT, null, null], 69 'new_recovery_operation' => [null, O_OPT, null, null, null], 70 'ack_operations' => [null, O_OPT, null, null, null], 71 'edit_ack_operationid' => [T_ZBX_STR, O_OPT, P_ACT, null, null], 72 'new_ack_operation' => [null, O_OPT, null, null, null], 73 'opconditions' => [null, O_OPT, null, null, null], 74 'new_opcondition' => [null, O_OPT, null, null, 'isset({add_opcondition})'], 75 // actions 76 'action' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, 77 IN('"action.massdelete","action.massdisable","action.massenable"'), 78 null 79 ], 80 'add_condition' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 81 'cancel_new_condition' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 82 'add_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 83 'cancel_new_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 84 'add_recovery_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 85 'cancel_new_recovery_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 86 'add_ack_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 87 'cancel_new_ack_operation' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 88 'add_opcondition' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 89 'cancel_new_opcondition' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 90 'pause_suppressed' => [T_ZBX_STR, O_OPT, null, 91 IN([ACTION_PAUSE_SUPPRESSED_FALSE, ACTION_PAUSE_SUPPRESSED_TRUE]), 92 null, 93 _('Pause operations for suppressed problems') 94 ], 95 'add' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 96 'update' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 97 'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 98 'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 99 'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 100 'form_refresh' => [T_ZBX_INT, O_OPT, null, null, null], 101 // filter 102 'filter_set' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 103 'filter_rst' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 104 'filter_name' => [T_ZBX_STR, O_OPT, null, null, null], 105 'filter_status' => [T_ZBX_INT, O_OPT, null, IN([-1, ACTION_STATUS_ENABLED, ACTION_STATUS_DISABLED]), null], 106 // sort and sortorder 107 'sort' => [T_ZBX_STR, O_OPT, P_SYS, IN('"name","status"'), null], 108 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null] 109]; 110 111$dataValid = check_fields($fields); 112$edit_ack_operationid = null; 113$new_ack_operation = getRequest('new_ack_operation', []); 114$ack_operations = getRequest('ack_operations', []); 115 116if ($dataValid && hasRequest('eventsource') && !hasRequest('form')) { 117 CProfile::update('web.actionconf.eventsource', getRequest('eventsource'), PROFILE_TYPE_INT); 118} 119 120if (isset($_REQUEST['actionid'])) { 121 $actionPermissions = API::Action()->get([ 122 'output' => ['actionid'], 123 'actionids' => $_REQUEST['actionid'], 124 'editable' => true 125 ]); 126 if (empty($actionPermissions)) { 127 access_deny(); 128 } 129} 130 131/* 132 * Actions 133 */ 134if (hasRequest('cancel_new_operation')) { 135 unset($_REQUEST['new_operation']); 136} 137elseif (hasRequest('cancel_new_opcondition')) { 138 unset($_REQUEST['new_opcondition']); 139} 140elseif (hasRequest('cancel_new_recovery_operation')) { 141 unset($_REQUEST['new_recovery_operation']); 142} 143elseif (hasRequest('cancel_new_ack_operation')) { 144 $new_ack_operation = []; 145} 146elseif (hasRequest('add') || hasRequest('update')) { 147 $action = [ 148 'name' => getRequest('name'), 149 'status' => getRequest('status', ACTION_STATUS_DISABLED), 150 'esc_period' => getRequest('esc_period', DB::getDefault('actions', 'esc_period')), 151 'def_shortdata' => getRequest('def_shortdata', ''), 152 'def_longdata' => getRequest('def_longdata', ''), 153 'r_shortdata' => getRequest('r_shortdata', ''), 154 'r_longdata' => getRequest('r_longdata', ''), 155 'ack_shortdata' => getRequest('ack_shortdata', ''), 156 'ack_longdata' => getRequest('ack_longdata', ''), 157 'operations' => getRequest('operations', []), 158 'recovery_operations' => getRequest('recovery_operations', []), 159 'acknowledge_operations' => getRequest('ack_operations', []) 160 ]; 161 162 foreach (['operations', 'recovery_operations', 'acknowledge_operations'] as $operation_key) { 163 foreach ($action[$operation_key] as &$operation) { 164 if (array_key_exists('opmessage', $operation) 165 && !array_key_exists('default_msg', $operation['opmessage'])) { 166 $operation['opmessage']['default_msg'] = 0; 167 } 168 } 169 unset($operation); 170 } 171 172 foreach ($action['operations'] as &$operation) { 173 if ($operation['operationtype'] == OPERATION_TYPE_GROUP_ADD 174 || $operation['operationtype'] == OPERATION_TYPE_GROUP_REMOVE) { 175 $operation['opgroup'] = []; 176 177 foreach ($operation['groupids'] as $groupid) { 178 $operation['opgroup'][] = ['groupid' => $groupid]; 179 } 180 unset($operation['groupids']); 181 } 182 elseif ($operation['operationtype'] == OPERATION_TYPE_TEMPLATE_ADD 183 || $operation['operationtype'] == OPERATION_TYPE_TEMPLATE_REMOVE) { 184 $operation['optemplate'] = []; 185 186 foreach ($operation['templateids'] as $templateid) { 187 $operation['optemplate'][] = ['templateid' => $templateid]; 188 } 189 unset($operation['templateids']); 190 } 191 } 192 unset($operation); 193 194 $filter = [ 195 'conditions' => getRequest('conditions', []), 196 'evaltype' => getRequest('evaltype') 197 ]; 198 199 if ($filter['evaltype'] == CONDITION_EVAL_TYPE_EXPRESSION) { 200 if (count($filter['conditions']) > 1) { 201 $filter['formula'] = getRequest('formula'); 202 } 203 else { 204 // if only one or no conditions are left, reset the evaltype to "and/or" and clear the formula 205 $filter['formula'] = ''; 206 $filter['evaltype'] = CONDITION_EVAL_TYPE_AND_OR; 207 } 208 } 209 $action['filter'] = $filter; 210 211 $eventsource = getRequest('eventsource', CProfile::get('web.actionconf.eventsource', EVENT_SOURCE_TRIGGERS)); 212 213 if ($eventsource == EVENT_SOURCE_TRIGGERS) { 214 $action['pause_suppressed'] = getRequest('pause_suppressed', ACTION_PAUSE_SUPPRESSED_FALSE); 215 } 216 217 DBstart(); 218 219 if (hasRequest('update')) { 220 $action['actionid'] = getRequest('actionid'); 221 222 $result = API::Action()->update($action); 223 224 $messageSuccess = _('Action updated'); 225 $messageFailed = _('Cannot update action'); 226 } 227 else { 228 $action['eventsource'] = $eventsource; 229 230 $result = API::Action()->create($action); 231 232 $messageSuccess = _('Action added'); 233 $messageFailed = _('Cannot add action'); 234 } 235 236 if ($result) { 237 unset($_REQUEST['form']); 238 } 239 240 $result = DBend($result); 241 242 if ($result) { 243 uncheckTableRows(); 244 } 245 show_messages($result, $messageSuccess, $messageFailed); 246} 247elseif (hasRequest('delete') && hasRequest('actionid')) { 248 $result = API::Action()->delete([getRequest('actionid')]); 249 250 if ($result) { 251 unset($_REQUEST['form'], $_REQUEST['actionid']); 252 uncheckTableRows(); 253 } 254 show_messages($result, _('Action deleted'), _('Cannot delete action')); 255} 256elseif (hasRequest('add_condition') && hasRequest('new_condition')) { 257 $newCondition = getRequest('new_condition'); 258 259 if ($newCondition) { 260 $conditions = getRequest('conditions', []); 261 262 // When adding new condition, in order to check for an existing condition, it must have a not null value. 263 if ($newCondition['conditiontype'] == CONDITION_TYPE_SUPPRESSED) { 264 $newCondition['value'] = ''; 265 } 266 267 // check existing conditions and remove duplicate condition values 268 foreach ($conditions as $condition) { 269 if ($newCondition['conditiontype'] == $condition['conditiontype']) { 270 if (is_array($newCondition['value'])) { 271 foreach ($newCondition['value'] as $key => $newValue) { 272 if ($condition['value'] == $newValue) { 273 unset($newCondition['value'][$key]); 274 } 275 } 276 } 277 else { 278 if ($newCondition['value'] == $condition['value'] && (!array_key_exists('value2', $newCondition) 279 || $newCondition['value2'] === $condition['value2'])) { 280 $newCondition['value'] = null; 281 } 282 } 283 } 284 } 285 286 $usedFormulaIds = zbx_objectValues($conditions, 'formulaid'); 287 288 $validateConditions = $conditions; 289 290 if (isset($newCondition['value'])) { 291 $newConditionValues = zbx_toArray($newCondition['value']); 292 foreach ($newConditionValues as $newValue) { 293 $condition = $newCondition; 294 $condition['value'] = $newValue; 295 $condition['formulaid'] = CConditionHelper::getNextFormulaId($usedFormulaIds); 296 $usedFormulaIds[] = $condition['formulaid']; 297 $validateConditions[] = $condition; 298 } 299 } 300 301 $conditionsValid = true; 302 if ($validateConditions) { 303 $filterConditionValidator = new CActionCondValidator(); 304 foreach ($validateConditions as $condition) { 305 if (!$filterConditionValidator->validate($condition)) { 306 $conditionsValid = false; 307 break; 308 } 309 } 310 } 311 312 if ($conditionsValid) { 313 $_REQUEST['conditions'] = $validateConditions; 314 } 315 else { 316 error($filterConditionValidator->getError()); 317 show_error_message(_('Cannot add action condition')); 318 } 319 } 320} 321elseif (hasRequest('add_opcondition') && hasRequest('new_opcondition')) { 322 $new_opcondition = getRequest('new_opcondition'); 323 324 try { 325 CAction::validateOperationConditions($new_opcondition); 326 $new_operation = getRequest('new_operation', []); 327 328 if (!isset($new_operation['opconditions'])) { 329 $new_operation['opconditions'] = []; 330 } 331 if (!str_in_array($new_opcondition, $new_operation['opconditions'])) { 332 array_push($new_operation['opconditions'], $new_opcondition); 333 } 334 335 $_REQUEST['new_operation'] = $new_operation; 336 337 unset($_REQUEST['new_opcondition']); 338 } 339 catch (APIException $e) { 340 error($e->getMessage()); 341 } 342} 343elseif (hasRequest('add_operation') && hasRequest('new_operation')) { 344 $new_operation = $_REQUEST['new_operation']; 345 $result = true; 346 347 switch ($new_operation['operationtype']) { 348 case OPERATION_TYPE_GROUP_ADD: 349 case OPERATION_TYPE_GROUP_REMOVE: 350 $new_operation['opgroup'] = []; 351 352 if (array_key_exists('groupids', $new_operation)) { 353 foreach ($new_operation['groupids'] as $groupid) { 354 $new_operation['opgroup'][] = ['groupid' => $groupid]; 355 } 356 unset($new_operation['groupids']); 357 } 358 break; 359 360 case OPERATION_TYPE_TEMPLATE_ADD: 361 case OPERATION_TYPE_TEMPLATE_REMOVE: 362 $new_operation['optemplate'] = []; 363 364 if (array_key_exists('templateids', $new_operation)) { 365 foreach ($new_operation['templateids'] as $templateid) { 366 $new_operation['optemplate'][] = ['templateid' => $templateid]; 367 } 368 unset($new_operation['templateids']); 369 } 370 break; 371 } 372 373 $eventsource = getRequest('eventsource', CProfile::get('web.actionconf.eventsource', EVENT_SOURCE_TRIGGERS)); 374 375 $new_operation['recovery'] = ACTION_OPERATION; 376 $new_operation['eventsource'] = $eventsource; 377 378 if (API::Action()->validateOperationsIntegrity($new_operation)) { 379 $_REQUEST['operations'] = getRequest('operations', []); 380 381 $uniqOperations = [ 382 OPERATION_TYPE_HOST_ADD => 0, 383 OPERATION_TYPE_HOST_REMOVE => 0, 384 OPERATION_TYPE_HOST_ENABLE => 0, 385 OPERATION_TYPE_HOST_DISABLE => 0, 386 OPERATION_TYPE_HOST_INVENTORY => 0 387 ]; 388 389 if (array_key_exists($new_operation['operationtype'], $uniqOperations)) { 390 $uniqOperations[$new_operation['operationtype']]++; 391 392 foreach ($_REQUEST['operations'] as $operationId => $operation) { 393 if (array_key_exists($operation['operationtype'], $uniqOperations) 394 && (!array_key_exists('id', $new_operation) 395 || bccomp($new_operation['id'], $operationId) != 0)) { 396 $uniqOperations[$operation['operationtype']]++; 397 } 398 } 399 400 if ($uniqOperations[$new_operation['operationtype']] > 1) { 401 $result = false; 402 error(_s('Operation "%s" already exists.', operation_type2str($new_operation['operationtype']))); 403 show_messages(); 404 } 405 } 406 407 if ($result) { 408 if (isset($_REQUEST['new_operation']['id'])) { 409 $_REQUEST['operations'][$_REQUEST['new_operation']['id']] = $_REQUEST['new_operation']; 410 } 411 else { 412 $_REQUEST['operations'][] = $_REQUEST['new_operation']; 413 } 414 415 sortOperations($eventsource, $_REQUEST['operations']); 416 } 417 418 unset($_REQUEST['new_operation']); 419 } 420} 421elseif (hasRequest('add_recovery_operation') && hasRequest('new_recovery_operation')) { 422 $new_recovery_operation = getRequest('new_recovery_operation'); 423 424 $eventsource = getRequest('eventsource', CProfile::get('web.actionconf.eventsource', EVENT_SOURCE_TRIGGERS)); 425 426 $new_recovery_operation['recovery'] = ACTION_RECOVERY_OPERATION; 427 $new_recovery_operation['eventsource'] = $eventsource; 428 429 if (API::Action()->validateOperationsIntegrity($new_recovery_operation)) { 430 $_REQUEST['recovery_operations'] = getRequest('recovery_operations', []); 431 432 if (isset($_REQUEST['new_recovery_operation']['id'])) { 433 $_REQUEST['recovery_operations'][$_REQUEST['new_recovery_operation']['id']] = $_REQUEST['new_recovery_operation']; 434 } 435 else { 436 $_REQUEST['recovery_operations'][] = $_REQUEST['new_recovery_operation']; 437 } 438 439 unset($_REQUEST['new_recovery_operation']); 440 } 441} 442elseif (hasRequest('add_ack_operation') && $new_ack_operation) { 443 $new_ack_operation['recovery'] = ACTION_ACKNOWLEDGE_OPERATION; 444 $new_ack_operation['eventsource'] = EVENT_SOURCE_TRIGGERS; 445 446 if (API::Action()->validateOperationsIntegrity($new_ack_operation)) { 447 if (array_key_exists('id', $new_ack_operation)) { 448 $ack_operations[$new_ack_operation['id']] = $new_ack_operation; 449 } 450 else { 451 $ack_operations[] = $new_ack_operation; 452 } 453 $new_ack_operation = []; 454 } 455} 456elseif (hasRequest('edit_operationid')) { 457 $_REQUEST['edit_operationid'] = array_keys($_REQUEST['edit_operationid']); 458 $edit_operationid = $_REQUEST['edit_operationid'] = array_pop($_REQUEST['edit_operationid']); 459 $_REQUEST['operations'] = getRequest('operations', []); 460 461 if (isset($_REQUEST['operations'][$edit_operationid])) { 462 $_REQUEST['new_operation'] = $_REQUEST['operations'][$edit_operationid]; 463 $_REQUEST['new_operation']['id'] = $edit_operationid; 464 } 465} 466elseif (hasRequest('edit_recovery_operationid')) { 467 $_REQUEST['edit_recovery_operationid'] = array_keys($_REQUEST['edit_recovery_operationid']); 468 $edit_recovery_operationid = array_pop($_REQUEST['edit_recovery_operationid']); 469 $_REQUEST['edit_recovery_operationid'] = $edit_recovery_operationid; 470 $_REQUEST['recovery_operations'] = getRequest('recovery_operations', []); 471 472 if (array_key_exists($edit_recovery_operationid, $_REQUEST['recovery_operations'])) { 473 $_REQUEST['new_recovery_operation'] = $_REQUEST['recovery_operations'][$edit_recovery_operationid]; 474 $_REQUEST['new_recovery_operation']['id'] = $edit_recovery_operationid; 475 } 476} 477elseif (hasRequest('edit_ack_operationid')) { 478 $edit_ack_operationid = key(getRequest('edit_ack_operationid')); 479 480 if (array_key_exists($edit_ack_operationid, $ack_operations)) { 481 $new_ack_operation = $ack_operations[$edit_ack_operationid]; 482 $new_ack_operation['id'] = $edit_ack_operationid; 483 } 484} 485elseif (hasRequest('action') && str_in_array(getRequest('action'), ['action.massenable', 'action.massdisable']) && hasRequest('g_actionid')) { 486 $status = (getRequest('action') == 'action.massenable') ? ACTION_STATUS_ENABLED : ACTION_STATUS_DISABLED; 487 $actionids = (array) getRequest('g_actionid', []); 488 $actions_count = count($actionids); 489 $actions = []; 490 491 foreach ($actionids as $actionid) { 492 $actions[] = ['actionid' => $actionid, 'status' => $status]; 493 } 494 495 $result = API::Action()->update($actions); 496 497 if ($result && array_key_exists('actionids', $result)) { 498 $message = $status == ACTION_STATUS_ENABLED 499 ? _n('Action enabled', 'Actions enabled', $actions_count) 500 : _n('Action disabled', 'Actions disabled', $actions_count); 501 502 show_messages(true, $message); 503 uncheckTableRows(); 504 } 505 else { 506 $message = $status == ACTION_STATUS_ENABLED 507 ? _n('Cannot enable action', 'Cannot enable actions', $actions_count) 508 : _n('Cannot disable action', 'Cannot disable actions', $actions_count); 509 510 show_messages(false, null, $message); 511 } 512} 513elseif (hasRequest('action') && getRequest('action') == 'action.massdelete' && hasRequest('g_actionid')) { 514 $result = API::Action()->delete(getRequest('g_actionid')); 515 516 if ($result) { 517 uncheckTableRows(); 518 } 519 show_messages($result, _('Selected actions deleted'), _('Cannot delete selected actions')); 520} 521 522if (hasRequest('action') && hasRequest('g_actionid') && !$result) { 523 $actions = API::Action()->get([ 524 'actionids' => getRequest('g_actionid'), 525 'output' => [], 526 'editable' => true 527 ]); 528 uncheckTableRows(null, zbx_objectValues($actions, 'actionid')); 529} 530 531/* 532 * Display 533 */ 534show_messages(); 535 536$config = select_config(); 537 538if (hasRequest('form')) { 539 $data = [ 540 'form' => getRequest('form'), 541 'actionid' => getRequest('actionid'), 542 'new_condition' => getRequest('new_condition', []), 543 'new_operation' => getRequest('new_operation'), 544 'new_recovery_operation' => getRequest('new_recovery_operation'), 545 'new_ack_operation' => $new_ack_operation, 546 'config' => $config 547 ]; 548 549 if ($data['actionid']) { 550 $data['action'] = API::Action()->get([ 551 'actionids' => $data['actionid'], 552 'selectOperations' => API_OUTPUT_EXTEND, 553 'selectRecoveryOperations' => ['operationid', 'actionid', 'operationtype', 'opmessage', 'opmessage_grp', 554 'opmessage_usr', 'opcommand', 'opcommand_hst', 'opcommand_grp' 555 ], 556 'selectAcknowledgeOperations' => ['operationid', 'actionid', 'operationtype', 'opmessage', 'opmessage_grp', 557 'opmessage_usr', 'opcommand', 'opcommand_hst', 'opcommand_grp' 558 ], 559 'selectFilter' => ['formula', 'conditions', 'evaltype'], 560 'output' => API_OUTPUT_EXTEND, 561 'editable' => true 562 ]); 563 $data['action'] = reset($data['action']); 564 565 $data['action']['recovery_operations'] = $data['action']['recoveryOperations']; 566 $data['action']['ack_operations'] = $data['action']['acknowledgeOperations']; 567 unset($data['action']['recoveryOperations'], $data['action']['acknowledgeOperations']); 568 569 foreach ($data['action']['operations'] as &$operation) { 570 if ($operation['operationtype'] == OPERATION_TYPE_GROUP_ADD 571 || $operation['operationtype'] == OPERATION_TYPE_GROUP_REMOVE) { 572 $operation = [ 573 'actionid' => $operation['actionid'], 574 'operationid' => $operation['operationid'], 575 'operationtype' => $operation['operationtype'], 576 'groupids' => zbx_objectValues($operation['opgroup'], 'groupid') 577 ]; 578 } 579 elseif ($operation['operationtype'] == OPERATION_TYPE_TEMPLATE_ADD 580 || $operation['operationtype'] == OPERATION_TYPE_TEMPLATE_REMOVE) { 581 $operation = [ 582 'actionid' => $operation['actionid'], 583 'operationid' => $operation['operationid'], 584 'operationtype' => $operation['operationtype'], 585 'templateids' => zbx_objectValues($operation['optemplate'], 'templateid') 586 ]; 587 } 588 } 589 unset($operation); 590 591 $data['eventsource'] = $data['action']['eventsource']; 592 } 593 else { 594 $data['eventsource'] = getRequest('eventsource', 595 CProfile::get('web.actionconf.eventsource', EVENT_SOURCE_TRIGGERS) 596 ); 597 $data['esc_period'] = getRequest('esc_period'); 598 } 599 600 if (array_key_exists('action', $data) && array_key_exists('actionid', $data['action']) 601 && !hasRequest('form_refresh')) { 602 sortOperations($data['eventsource'], $data['action']['operations']); 603 } 604 else { 605 $data['action']['name'] = getRequest('name'); 606 $data['action']['esc_period'] = getRequest('esc_period', DB::getDefault('actions', 'esc_period')); 607 $data['action']['status'] = getRequest('status', hasRequest('form_refresh') ? 1 : 0); 608 $data['action']['operations'] = getRequest('operations', []); 609 $data['action']['recovery_operations'] = getRequest('recovery_operations', []); 610 $data['action']['ack_operations'] = $ack_operations; 611 612 $data['action']['filter']['evaltype'] = getRequest('evaltype'); 613 $data['action']['filter']['formula'] = getRequest('formula'); 614 $data['action']['filter']['conditions'] = getRequest('conditions', []); 615 616 if ($data['actionid'] && hasRequest('form_refresh')) { 617 $data['action']['def_shortdata'] = getRequest('def_shortdata', ''); 618 $data['action']['def_longdata'] = getRequest('def_longdata', ''); 619 $data['action']['r_shortdata'] = getRequest('r_shortdata', ''); 620 $data['action']['r_longdata'] = getRequest('r_longdata', ''); 621 $data['action']['ack_shortdata'] = getRequest('ack_shortdata', ''); 622 $data['action']['ack_longdata'] = getRequest('ack_longdata', ''); 623 624 if ($data['eventsource'] == EVENT_SOURCE_TRIGGERS) { 625 $data['action']['pause_suppressed'] = getRequest('pause_suppressed', ACTION_PAUSE_SUPPRESSED_FALSE); 626 } 627 } 628 else { 629 if ($data['eventsource'] == EVENT_SOURCE_TRIGGERS) { 630 $data['action']['def_shortdata'] = getRequest('def_shortdata', ACTION_DEFAULT_SUBJ_PROBLEM); 631 $data['action']['def_longdata'] = getRequest('def_longdata', ACTION_DEFAULT_MSG_PROBLEM); 632 $data['action']['r_shortdata'] = getRequest('r_shortdata', ACTION_DEFAULT_SUBJ_RECOVERY); 633 $data['action']['r_longdata'] = getRequest('r_longdata', ACTION_DEFAULT_MSG_RECOVERY); 634 $data['action']['ack_shortdata'] = getRequest('ack_shortdata', ACTION_DEFAULT_SUBJ_ACKNOWLEDGE); 635 $data['action']['ack_longdata'] = getRequest('ack_longdata', ACTION_DEFAULT_MSG_ACKNOWLEDGE); 636 $data['action']['pause_suppressed'] = getRequest('pause_suppressed', 637 hasRequest('form_refresh') ? ACTION_PAUSE_SUPPRESSED_FALSE : ACTION_PAUSE_SUPPRESSED_TRUE 638 ); 639 } 640 elseif ($data['eventsource'] == EVENT_SOURCE_DISCOVERY) { 641 $data['action']['def_shortdata'] = getRequest('def_shortdata', ACTION_DEFAULT_SUBJ_DISCOVERY); 642 $data['action']['def_longdata'] = getRequest('def_longdata', ACTION_DEFAULT_MSG_DISCOVERY); 643 } 644 elseif ($data['eventsource'] == EVENT_SOURCE_AUTO_REGISTRATION) { 645 $data['action']['def_shortdata'] = getRequest('def_shortdata', ACTION_DEFAULT_SUBJ_AUTOREG); 646 $data['action']['def_longdata'] = getRequest('def_longdata', ACTION_DEFAULT_MSG_AUTOREG); 647 } 648 else { 649 $data['action']['def_shortdata'] = getRequest('def_shortdata', ''); 650 $data['action']['def_longdata'] = getRequest('def_longdata', ''); 651 $data['action']['r_shortdata'] = getRequest('r_shortdata', ''); 652 $data['action']['r_longdata'] = getRequest('r_longdata', ''); 653 $data['action']['ack_shortdata'] = getRequest('ack_shortdata', ''); 654 $data['action']['ack_longdata'] = getRequest('ack_longdata', ''); 655 } 656 } 657 } 658 659 $data['allowedConditions'] = get_conditions_by_eventsource($data['eventsource']); 660 $data['allowedOperations'] = getAllowedOperations($data['eventsource']); 661 662 if (!hasRequest('add_condition')) { 663 $data['action']['filter']['conditions'] = CConditionHelper::sortConditionsByFormulaId( 664 $data['action']['filter']['conditions'] 665 ); 666 } 667 668 // Add default values for new condition. 669 $data['new_condition'] += [ 670 'conditiontype' => CONDITION_TYPE_TRIGGER_NAME, 671 'operator' => CONDITION_OPERATOR_LIKE, 672 'value' => '' 673 ]; 674 675 if (!str_in_array($data['new_condition']['conditiontype'], $data['allowedConditions'])) { 676 $data['new_condition']['conditiontype'] = $data['allowedConditions'][0]; 677 } 678 679 // New operation. 680 if ($data['new_operation'] && !is_array($data['new_operation'])) { 681 $data['new_operation'] = [ 682 'operationtype' => OPERATION_TYPE_MESSAGE, 683 'esc_period' => '0', 684 'esc_step_from' => 1, 685 'esc_step_to' => 1, 686 'evaltype' => 0 687 ]; 688 } 689 690 if (is_array($data['new_operation'])) { 691 switch ($data['new_operation']['operationtype']) { 692 case OPERATION_TYPE_GROUP_ADD: 693 case OPERATION_TYPE_GROUP_REMOVE: 694 if (!array_key_exists('groupids', $data['new_operation'])) { 695 $data['new_operation']['groupids'] = []; 696 } 697 698 if ($data['new_operation']['groupids']) { 699 $data['new_operation']['groups'] = API::HostGroup()->get([ 700 'groupids' => $data['new_operation']['groupids'], 701 'output' => ['groupid', 'name'], 702 'editable' => true 703 ]); 704 705 foreach ($data['new_operation']['groups'] as &$group) { 706 $group['id'] = $group['groupid']; 707 unset($group['groupid']); 708 } 709 unset($group); 710 } 711 else { 712 $data['new_operation']['groups'] = []; 713 } 714 break; 715 716 case OPERATION_TYPE_TEMPLATE_ADD: 717 case OPERATION_TYPE_TEMPLATE_REMOVE: 718 if (!array_key_exists('templateids', $data['new_operation'])) { 719 $data['new_operation']['templateids'] = []; 720 } 721 722 if ($data['new_operation']['templateids']) { 723 $data['new_operation']['templates'] = API::Template()->get([ 724 'templateids' => $data['new_operation']['templateids'], 725 'output' => ['templateid', 'name'], 726 'editable' => true 727 ]); 728 729 foreach ($data['new_operation']['templates'] as &$template) { 730 $template['id'] = $template['templateid']; 731 unset($template['templateid']); 732 } 733 unset($template); 734 } 735 else { 736 $data['new_operation']['templates'] = []; 737 } 738 break; 739 740 case OPERATION_TYPE_HOST_INVENTORY: 741 if (!array_key_exists('opinventory', $data['new_operation'])) { 742 $data['new_operation']['opinventory'] = ['inventory_mode' => HOST_INVENTORY_MANUAL]; 743 } 744 break; 745 } 746 } 747 748 // New recovery operation. 749 if ($data['new_recovery_operation'] && !is_array($data['new_recovery_operation'])) { 750 $data['new_recovery_operation'] = ['operationtype' => OPERATION_TYPE_MESSAGE]; 751 } 752 753 $data['available_mediatypes'] = API::MediaType()->get(['output' => ['mediatypeid', 'description', 'status']]); 754 order_result($data['available_mediatypes'], 'description'); 755 756 if ($data['new_ack_operation'] && !is_array($data['new_ack_operation'])) { 757 $data['new_ack_operation'] = [ 758 'operationtype' => OPERATION_TYPE_MESSAGE, 759 'ack_short' => ACTION_DEFAULT_SUBJ_ACKNOWLEDGE, 760 'ack_long' => ACTION_DEFAULT_MSG_ACKNOWLEDGE 761 ]; 762 } 763 if ($data['new_ack_operation'] && !array_key_exists('opmessage', $data['new_ack_operation']) 764 && $data['new_ack_operation']['operationtype'] != OPERATION_TYPE_COMMAND) { 765 $data['new_ack_operation']['opmessage'] = [ 766 'default_msg' => 1, 767 'mediatypeid' => 0, 768 'subject' => ACTION_DEFAULT_SUBJ_ACKNOWLEDGE, 769 'message' => ACTION_DEFAULT_MSG_ACKNOWLEDGE 770 ]; 771 } 772 773 // Render view. 774 $actionView = new CView('configuration.action.edit', $data); 775 $actionView->render(); 776 $actionView->show(); 777} 778else { 779 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 780 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 781 782 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 783 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 784 785 // filter 786 if (hasRequest('filter_set')) { 787 CProfile::update('web.actionconf.filter_name', getRequest('filter_name', ''), PROFILE_TYPE_STR); 788 CProfile::update('web.actionconf.filter_status', getRequest('filter_status', -1), PROFILE_TYPE_INT); 789 } 790 elseif (hasRequest('filter_rst')) { 791 CProfile::delete('web.actionconf.filter_name'); 792 CProfile::delete('web.actionconf.filter_status'); 793 } 794 795 $filter = [ 796 'name' => CProfile::get('web.actionconf.filter_name', ''), 797 'status' => CProfile::get('web.actionconf.filter_status', -1) 798 ]; 799 800 $data = [ 801 'eventsource' => getRequest('eventsource', CProfile::get('web.actionconf.eventsource', EVENT_SOURCE_TRIGGERS)), 802 'sort' => $sortField, 803 'sortorder' => $sortOrder, 804 'filter' => $filter, 805 'config' => $config, 806 'profileIdx' => 'web.actionconf.filter', 807 'active_tab' => CProfile::get('web.actionconf.filter.active', 1) 808 ]; 809 810 $data['actions'] = API::Action()->get([ 811 'output' => API_OUTPUT_EXTEND, 812 'search' => [ 813 'name' => ($filter['name'] === '') ? null : $filter['name'] 814 ], 815 'filter' => [ 816 'eventsource' => $data['eventsource'], 817 'status' => ($filter['status'] == -1) ? null : $filter['status'] 818 ], 819 'selectFilter' => ['formula', 'conditions', 'evaltype'], 820 'selectOperations' => API_OUTPUT_EXTEND, 821 'editable' => true, 822 'sortfield' => $sortField, 823 'limit' => $config['search_limit'] + 1 824 ]); 825 826 foreach ($data['actions'] as &$action) { 827 foreach ($action['operations'] as &$operation) { 828 switch ($operation['operationtype']) { 829 case OPERATION_TYPE_GROUP_ADD: 830 case OPERATION_TYPE_GROUP_REMOVE: 831 $operation = [ 832 'operationtype' => $operation['operationtype'], 833 'groupids' => zbx_objectValues($operation['opgroup'], 'groupid') 834 ]; 835 break; 836 837 case OPERATION_TYPE_TEMPLATE_ADD: 838 case OPERATION_TYPE_TEMPLATE_REMOVE: 839 $operation = [ 840 'operationtype' => $operation['operationtype'], 841 'templateids' => zbx_objectValues($operation['optemplate'], 'templateid') 842 ]; 843 break; 844 } 845 } 846 unset($operation); 847 } 848 unset($action); 849 850 // sorting && paging 851 order_result($data['actions'], $sortField, $sortOrder); 852 $data['paging'] = getPagingLine($data['actions'], $sortOrder, new CUrl('actionconf.php')); 853 854 // render view 855 $actionView = new CView('configuration.action.list', $data); 856 $actionView->render(); 857 $actionView->show(); 858} 859 860require_once dirname(__FILE__).'/include/page_footer.php'; 861