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 * Class containing methods for operations with map elements. 24 * 25 * @return mixed 26 */ 27abstract class CMapElement extends CApiService { 28 29 protected function checkSelementInput(&$selements, $method) { 30 $create = ($method === 'createSelements'); 31 $update = ($method === 'updateSelements'); 32 33 $element_types = [SYSMAP_ELEMENT_TYPE_HOST, SYSMAP_ELEMENT_TYPE_MAP, SYSMAP_ELEMENT_TYPE_TRIGGER, 34 SYSMAP_ELEMENT_TYPE_HOST_GROUP, SYSMAP_ELEMENT_TYPE_IMAGE 35 ]; 36 37 $elementtype_validator = new CLimitedSetValidator(['values' => $element_types]); 38 39 if ($update) { 40 $db_selements = $this->fetchSelementsByIds(zbx_objectValues($selements, 'selementid')); 41 $selements = $this->extendFromObjects(zbx_toHash($selements, 'selementid'), $db_selements, ['elementtype', 'elements']); 42 } 43 44 foreach ($selements as &$selement) { 45 if (!is_array($selement)) { 46 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 47 } 48 49 if ($create) { 50 // Check required parameters. 51 $missing_keys = array_diff(['sysmapid', 'elementtype', 'iconid_off'], array_keys($selement)); 52 53 if ($missing_keys) { 54 self::exception(ZBX_API_ERROR_PARAMETERS, 55 _s('Map element is missing parameters: %1$s', implode(', ', $missing_keys)) 56 ); 57 } 58 } 59 60 if (array_key_exists('urls', $selement)) { 61 $url_validate_options = ['allow_user_macro' => false]; 62 if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) { 63 $url_validate_options['allow_inventory_macro'] = INVENTORY_URL_MACRO_HOST; 64 } 65 elseif ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 66 $url_validate_options['allow_inventory_macro'] = INVENTORY_URL_MACRO_TRIGGER; 67 } 68 else { 69 $url_validate_options['allow_inventory_macro'] = INVENTORY_URL_MACRO_NONE; 70 } 71 72 foreach ($selement['urls'] as $url_data) { 73 if (!CHtmlUrlValidator::validate($url_data['url'], $url_validate_options)) { 74 self::exception(ZBX_API_ERROR_PARAMETERS, _('Wrong value for url field.')); 75 } 76 } 77 } 78 79 if ($update && array_key_exists('selementid', $selement) 80 && array_key_exists($selement['selementid'], $db_selements)) { 81 $db_selement = $db_selements[$selement['selementid']]; 82 } 83 84 if (!$elementtype_validator->validate($selement['elementtype'])) { 85 self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value for field "%1$s": %2$s.', 86 'elementtype', _s('value must be one of %1$s', implode(', ', $element_types)) 87 )); 88 } 89 90 if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_IMAGE) { 91 unset($selement['elements']); 92 } 93 else { 94 if (!array_key_exists('elements', $selement)) { 95 self::exception(ZBX_API_ERROR_PARAMETERS, 96 _s('Map element is missing parameters: %1$s', 'elements') 97 ); 98 } 99 100 if (!is_array($selement['elements'])) { 101 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 102 } 103 104 if (!$selement['elements']) { 105 self::exception(ZBX_API_ERROR_PARAMETERS, 106 _s('Incorrect value for field "%1$s": %2$s.', 'elements', _('cannot be empty')) 107 ); 108 } 109 } 110 111 if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 112 foreach ($selement['elements'] as $element) { 113 if (!array_key_exists('triggerid', $element)) { 114 self::exception(ZBX_API_ERROR_PARAMETERS, 115 _s('Map element is missing parameters: %1$s', 'triggerid') 116 ); 117 } 118 119 if (is_array($element['triggerid'])) { 120 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 121 } 122 elseif ($element['triggerid'] === '' || $element['triggerid'] === null 123 || $element['triggerid'] === false) { 124 self::exception(ZBX_API_ERROR_PARAMETERS, 125 _s('Incorrect value for field "%1$s": %2$s.', 'triggerid', _('cannot be empty')) 126 ); 127 } 128 } 129 } 130 else { 131 if (array_key_exists('elements', $selement)) { 132 switch ($selement['elementtype']) { 133 case SYSMAP_ELEMENT_TYPE_HOST_GROUP: 134 $field = 'groupid'; 135 break; 136 137 case SYSMAP_ELEMENT_TYPE_HOST: 138 $field = 'hostid'; 139 break; 140 141 case SYSMAP_ELEMENT_TYPE_MAP: 142 $field = 'sysmapid'; 143 break; 144 } 145 146 $elements = reset($selement['elements']); 147 148 if (!is_array($elements)) { 149 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 150 } 151 152 if (!array_key_exists($field, $elements)) { 153 self::exception(ZBX_API_ERROR_PARAMETERS, 154 _s('Map element is missing parameters: %1$s', $field) 155 ); 156 } 157 158 if (is_array($elements[$field])) { 159 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 160 } 161 elseif ($elements[$field] === '' || $elements[$field] === null || $elements[$field] === false) { 162 self::exception(ZBX_API_ERROR_PARAMETERS, 163 _s('Incorrect value for field "%1$s": %2$s.', $field, _('cannot be empty')) 164 ); 165 } 166 167 if (count($selement['elements']) > 1) { 168 self::exception(ZBX_API_ERROR_PARAMETERS, 169 _s('Incorrect value for field "%1$s": %2$s.', 'elements', _('incorrect element count')) 170 ); 171 } 172 } 173 } 174 175 if (isset($selement['iconid_off']) && $selement['iconid_off'] == 0) { 176 self::exception(ZBX_API_ERROR_PARAMETERS, _s('No icon for map element ""%1$s".', 177 array_key_exists('label', $selement) ? $selement['label'] : '' 178 )); 179 } 180 181 if ($create) { 182 $selement['urls'] = array_key_exists('urls', $selement) ? $selement['urls'] : []; 183 } 184 } 185 unset($selement); 186 187 // check permissions to used objects 188 if (!CMapHelper::checkSelementPermissions($selements)) { 189 self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); 190 } 191 192 return $update ? $db_selements : true; 193 } 194 195 /** 196 * Checks that shape color attributes are valid. 197 * 198 * @throws APIException if input is invalid. 199 * 200 * @param array $shapes An array of shapes. 201 */ 202 protected function checkShapeInput($shapes) { 203 $color_validator = new CColorValidator(); 204 $fields = ['border_color', 'background_color', 'font_color']; 205 206 foreach ($shapes as $shape) { 207 foreach ($fields as $field) { 208 if (array_key_exists($field, $shape) && $shape[$field] !== '' 209 && !$color_validator->validate($shape[$field])) { 210 self::exception(ZBX_API_ERROR_PARAMETERS, $color_validator->getError()); 211 } 212 } 213 } 214 } 215 216 /** 217 * Returns a hash of map elements with the given IDs. The result also includes URL assigned to the elements. 218 * 219 * @param array $selementIds 220 * 221 * @return array 222 */ 223 protected function fetchSelementsByIds(array $selementIds) { 224 $selements = API::getApiService()->select('sysmaps_elements', [ 225 'output' => API_OUTPUT_EXTEND, 226 'filter' => ['selementid' => $selementIds], 227 'preservekeys' => true 228 ]); 229 230 if ($selements) { 231 foreach ($selements as &$selement) { 232 $selement['urls'] = []; 233 $selement['elements'] = []; 234 } 235 unset($selement); 236 237 $selementUrls = API::getApiService()->select('sysmap_element_url', [ 238 'output' => API_OUTPUT_EXTEND, 239 'filter' => ['selementid' => $selementIds] 240 ]); 241 foreach ($selementUrls as $selementUrl) { 242 $selements[$selementUrl['selementid']]['urls'][] = $selementUrl; 243 } 244 245 $selement_triggers = API::getApiService()->select('sysmap_element_trigger', [ 246 'output' => ['selement_triggerid', 'selementid', 'triggerid'], 247 'filter' => ['selementid' => $selementIds] 248 ]); 249 250 foreach ($selement_triggers as $selement_trigger) { 251 $selements[$selement_trigger['selementid']]['elements'][] = [ 252 'selement_triggerid' => $selement_trigger['selement_triggerid'], 253 'triggerid' => $selement_trigger['triggerid'] 254 ]; 255 } 256 257 $single_element_types = [SYSMAP_ELEMENT_TYPE_HOST, SYSMAP_ELEMENT_TYPE_MAP, SYSMAP_ELEMENT_TYPE_HOST_GROUP]; 258 foreach ($selements as &$selement) { 259 if (in_array($selement['elementtype'], $single_element_types)) { 260 switch ($selement['elementtype']) { 261 case SYSMAP_ELEMENT_TYPE_HOST_GROUP: 262 $field = 'groupid'; 263 break; 264 265 case SYSMAP_ELEMENT_TYPE_HOST: 266 $field = 'hostid'; 267 break; 268 269 case SYSMAP_ELEMENT_TYPE_MAP: 270 $field = 'sysmapid'; 271 break; 272 } 273 $selement['elements'][] = [$field => $selement['elementid']]; 274 } 275 276 unset($selement['elementid']); 277 } 278 unset($selement); 279 } 280 281 return $selements; 282 } 283 284 protected function checkLinkInput($links, $method) { 285 $update = ($method == 'updateLink'); 286 $delete = ($method == 'deleteLink'); 287 288 // permissions 289 if ($update || $delete) { 290 $linkDbFields = ['linkid' => null]; 291 292 $dbLinks = API::getApiService()->select('sysmap_element_url', [ 293 'filter' => ['selementid' => zbx_objectValues($links, 'linkid')], 294 'output' => ['linkid'], 295 'preservekeys' => true 296 ]); 297 } 298 else { 299 $linkDbFields = [ 300 'sysmapid' => null, 301 'selementid1' => null, 302 'selementid2' => null 303 ]; 304 } 305 306 $colorValidator = new CColorValidator(); 307 308 foreach ($links as $link) { 309 if (!check_db_fields($linkDbFields, $link)) { 310 self::exception(ZBX_API_ERROR_PARAMETERS, _('Wrong fields for map link.')); 311 } 312 313 if (isset($link['color']) && !$colorValidator->validate($link['color'])) { 314 self::exception(ZBX_API_ERROR_PARAMETERS, $colorValidator->getError()); 315 } 316 317 if ($update || $delete) { 318 if (!isset($dbLinks[$link['linkid']])) { 319 self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); 320 } 321 } 322 } 323 324 return true; 325 } 326 327 /** 328 * Add element to sysmap. 329 * 330 * @param array $elements[0,...]['sysmapid'] 331 * @param array $elements[0,...]['elementid'] 332 * @param array $elements[0,...]['elementtype'] 333 * @param array $elements[0,...]['label'] 334 * @param array $elements[0,...]['x'] 335 * @param array $elements[0,...]['y'] 336 * @param array $elements[0,...]['iconid_off'] 337 * @param array $elements[0,...]['iconid_on'] 338 * @param array $elements[0,...]['iconid_disabled'] 339 * @param array $elements[0,...]['urls'][0,...] 340 * @param array $elements[0,...]['label_location'] 341 * 342 * @return array 343 */ 344 protected function createSelements(array $selements) { 345 $selements = zbx_toArray($selements); 346 347 $this->checkSelementInput($selements, __FUNCTION__); 348 349 $single_element_types = [SYSMAP_ELEMENT_TYPE_HOST, SYSMAP_ELEMENT_TYPE_MAP, SYSMAP_ELEMENT_TYPE_HOST_GROUP]; 350 foreach ($selements as &$selement) { 351 if (in_array($selement['elementtype'], $single_element_types)) { 352 $selement['elementid'] = reset($selement['elements'][0]); 353 } 354 elseif ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 355 unset($selement['elementid']); 356 } 357 } 358 unset($selement); 359 360 $selementids = DB::insert('sysmaps_elements', $selements); 361 362 $triggerids = []; 363 364 foreach ($selementids as $key => $selementid) { 365 if ($selements[$key]['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 366 foreach ($selements[$key]['elements'] as $element) { 367 $triggerids[$element['triggerid']] = true; 368 } 369 } 370 } 371 372 $db_triggers = API::Trigger()->get([ 373 'output' => ['triggerid', 'priority'], 374 'triggerids' => array_keys($triggerids), 375 'preservekeys' => true 376 ]); 377 378 $triggers = []; 379 380 foreach ($selementids as $key => $selementid) { 381 if ($selements[$key]['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 382 foreach ($selements[$key]['elements'] as $element) { 383 $priority = $db_triggers[$element['triggerid']]['priority']; 384 $triggers[$selementid][$priority][] = [ 385 'selementid' => $selementid, 386 'triggerid' => $element['triggerid'] 387 ]; 388 } 389 krsort($triggers[$selementid]); 390 } 391 } 392 393 $triggers_to_add = []; 394 395 foreach ($triggers as $selement_triggers) { 396 foreach ($selement_triggers as $selement_trigger_priorities) { 397 foreach ($selement_trigger_priorities as $selement_trigger_priority) { 398 $triggers_to_add[] = $selement_trigger_priority; 399 } 400 } 401 } 402 403 DB::insert('sysmap_element_trigger', $triggers_to_add); 404 405 $insertUrls = []; 406 407 foreach ($selementids as $key => $selementid) { 408 foreach ($selements[$key]['urls'] as $url) { 409 $url['selementid'] = $selementid; 410 411 $insertUrls[] = $url; 412 } 413 } 414 415 DB::insert('sysmap_element_url', $insertUrls); 416 417 return ['selementids' => $selementids]; 418 } 419 420 /** 421 * Update element to sysmap. 422 * 423 * @param array $elements[0,...]['selementid'] 424 * @param array $elements[0,...]['sysmapid'] 425 * @param array $elements[0,...]['elementid'] 426 * @param array $elements[0,...]['elementtype'] 427 * @param array $elements[0,...]['label'] 428 * @param array $elements[0,...]['x'] 429 * @param array $elements[0,...]['y'] 430 * @param array $elements[0,...]['iconid_off'] 431 * @param array $elements[0,...]['iconid_on'] 432 * @param array $elements[0,...]['iconid_disabled'] 433 * @param array $elements[0,...]['url'] 434 * @param array $elements[0,...]['label_location'] 435 */ 436 protected function updateSelements(array $selements) { 437 $selements = zbx_toArray($selements); 438 $selementIds = []; 439 440 $db_selements = $this->checkSelementInput($selements, __FUNCTION__); 441 442 $update = []; 443 $urlsToDelete = []; 444 $urlsToUpdate = []; 445 $urlsToAdd = []; 446 $triggers_to_add = []; 447 $triggers_to_delete = []; 448 $triggerids = []; 449 450 foreach ($selements as &$selement) { 451 $db_selement = $db_selements[$selement['selementid']]; 452 453 // Change type from something to trigger. 454 if ($selement['elementtype'] != $db_selement['elementtype'] 455 && $selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 456 $selement['elementid'] = 0; 457 458 foreach ($selement['elements'] as $element) { 459 $triggerids[$element['triggerid']] = true; 460 } 461 } 462 463 // Change type from trigger to something. 464 if ($selement['elementtype'] != $db_selement['elementtype'] 465 && $db_selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 466 foreach ($db_selement['elements'] as $db_element) { 467 $triggers_to_delete[] = $db_element['selement_triggerid']; 468 } 469 } 470 471 if ($selement['elementtype'] != SYSMAP_ELEMENT_TYPE_IMAGE 472 && $selement['elementtype'] != SYSMAP_ELEMENT_TYPE_TRIGGER) { 473 $selement['elementid'] = reset($selement['elements'][0]); 474 } 475 476 $db_elements = $db_selement['elements']; 477 478 foreach ($db_selement['elements'] as &$element) { 479 unset($element['selement_triggerid']); 480 } 481 unset($element); 482 483 if ($selement['elementtype'] == $db_selement['elementtype'] 484 && $selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 485 foreach ($db_elements as $element) { 486 $triggers_to_delete[] = $element['selement_triggerid']; 487 } 488 489 foreach ($selement['elements'] as $element) { 490 $triggerids[$element['triggerid']] = true; 491 } 492 } 493 494 $update[] = [ 495 'values' => $selement, 496 'where' => ['selementid' => $selement['selementid']] 497 ]; 498 $selementIds[] = $selement['selementid']; 499 500 if (!isset($selement['urls'])) { 501 continue; 502 } 503 504 $diffUrls = zbx_array_diff($selement['urls'], $db_selement['urls'], 'name'); 505 506 // add 507 foreach ($diffUrls['first'] as $newUrl) { 508 $newUrl['selementid'] = $selement['selementid']; 509 $urlsToAdd[] = $newUrl; 510 } 511 512 // update url 513 foreach ($diffUrls['both'] as $updUrl) { 514 $urlsToUpdate[] = [ 515 'values' => $updUrl, 516 'where' => [ 517 'selementid' => $selement['selementid'], 518 'name' => $updUrl['name'] 519 ] 520 ]; 521 } 522 523 // delete url 524 $urlsToDelete = array_merge($urlsToDelete, zbx_objectValues($diffUrls['second'], 'sysmapelementurlid')); 525 } 526 unset($selement); 527 528 $db_triggers = API::Trigger()->get([ 529 'output' => ['triggerid', 'priority'], 530 'triggerids' => array_keys($triggerids), 531 'preservekeys' => true 532 ]); 533 534 $triggers = []; 535 536 foreach ($selements as $key => $selement) { 537 if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_TRIGGER) { 538 $selementid = $selement['selementid']; 539 540 foreach ($selement['elements'] as $element) { 541 $priority = $db_triggers[$element['triggerid']]['priority']; 542 $triggers[$selementid][$priority][] = [ 543 'selementid' => $selementid, 544 'triggerid' => $element['triggerid'] 545 ]; 546 } 547 krsort($triggers[$selementid]); 548 } 549 } 550 551 $triggers_to_add = []; 552 553 foreach ($triggers as $selement_triggers) { 554 foreach ($selement_triggers as $selement_trigger_priorities) { 555 foreach ($selement_trigger_priorities as $selement_trigger_priority) { 556 $triggers_to_add[] = $selement_trigger_priority; 557 } 558 } 559 } 560 561 DB::update('sysmaps_elements', $update); 562 563 if (!empty($urlsToDelete)) { 564 DB::delete('sysmap_element_url', ['sysmapelementurlid' => $urlsToDelete]); 565 } 566 567 if (!empty($urlsToUpdate)) { 568 DB::update('sysmap_element_url', $urlsToUpdate); 569 } 570 571 if (!empty($urlsToAdd)) { 572 DB::insert('sysmap_element_url', $urlsToAdd); 573 } 574 575 if ($triggers_to_delete) { 576 DB::delete('sysmap_element_trigger', ['selement_triggerid' => $triggers_to_delete]); 577 } 578 579 if ($triggers_to_add) { 580 DB::insert('sysmap_element_trigger', $triggers_to_add); 581 } 582 583 return ['selementids' => $selementIds]; 584 } 585 586 /** 587 * Delete element from map. 588 * 589 * @param array $selements multidimensional array with selement objects 590 * @param array $selements[0, ...]['selementid'] selementid to delete 591 */ 592 protected function deleteSelements(array $selements) { 593 $selements = zbx_toArray($selements); 594 $selementIds = zbx_objectValues($selements, 'selementid'); 595 596 DB::delete('sysmaps_elements', ['selementid' => $selementIds]); 597 598 return $selementIds; 599 } 600 601 /** 602 * Add shape to sysmap. 603 * 604 * @param array $shapes Multidimensional array with shape properties. 605 */ 606 protected function createShapes(array $shapes) { 607 $shapes = zbx_toArray($shapes); 608 609 $this->checkShapeInput($shapes); 610 611 DB::insert('sysmap_shape', $shapes); 612 } 613 614 /** 615 * Update shapes to sysmap. 616 * 617 * @param array $shapes Multidimensional array with shape properties. 618 */ 619 protected function updateShapes(array $shapes) { 620 $shapes = zbx_toArray($shapes); 621 622 $this->checkShapeInput($shapes); 623 624 $update = []; 625 foreach ($shapes as $shape) { 626 $shapeid = $shape['sysmap_shapeid']; 627 unset($shape['sysmap_shapeid']); 628 629 if ($shape) { 630 $update[] = [ 631 'values' => $shape, 632 'where' => ['sysmap_shapeid' => $shapeid] 633 ]; 634 } 635 } 636 637 DB::update('sysmap_shape', $update); 638 } 639 640 /** 641 * Delete shapes from map. 642 * 643 * @param array $shapes Multidimensional array with shape properties. 644 */ 645 protected function deleteShapes(array $shapes) { 646 $shapes = zbx_toArray($shapes); 647 $shapeids = zbx_objectValues($shapes, 'sysmap_shapeid'); 648 649 DB::delete('sysmap_shape', ['sysmap_shapeid' => $shapeids]); 650 } 651 652 /** 653 * Create link. 654 * 655 * @param array $links 656 * @param array $links[0,...]['sysmapid'] 657 * @param array $links[0,...]['selementid1'] 658 * @param array $links[0,...]['selementid2'] 659 * @param array $links[0,...]['drawtype'] 660 * @param array $links[0,...]['color'] 661 * 662 * @return array 663 */ 664 protected function createLinks(array $links) { 665 $links = zbx_toArray($links); 666 667 $this->checkLinkInput($links, __FUNCTION__); 668 669 $linkIds = DB::insert('sysmaps_links', $links); 670 671 return ['linkids' => $linkIds]; 672 } 673 674 protected function updateLinks($links) { 675 $links = zbx_toArray($links); 676 677 $this->checkLinkInput($links, __FUNCTION__); 678 679 $udpateLinks = []; 680 foreach ($links as $link) { 681 $udpateLinks[] = ['values' => $link, 'where' => ['linkid' => $link['linkid']]]; 682 } 683 684 DB::update('sysmaps_links', $udpateLinks); 685 686 return ['linkids' => zbx_objectValues($links, 'linkid')]; 687 } 688 689 /** 690 * Delete Link from map. 691 * 692 * @param array $links multidimensional array with link objects 693 * @param array $links[0, ...]['linkid'] link ID to delete 694 * 695 * @return array 696 */ 697 protected function deleteLinks($links) { 698 zbx_value2array($links); 699 $linkIds = zbx_objectValues($links, 'linkid'); 700 701 $this->checkLinkInput($links, __FUNCTION__); 702 703 DB::delete('sysmaps_links', ['linkid' => $linkIds]); 704 705 return ['linkids' => $linkIds]; 706 } 707 708 /** 709 * Add link trigger to link (sysmap). 710 * 711 * @param array $links[0,...]['linkid'] 712 * @param array $links[0,...]['triggerid'] 713 * @param array $links[0,...]['drawtype'] 714 * @param array $links[0,...]['color'] 715 */ 716 protected function createLinkTriggers($linkTriggers) { 717 $linkTriggers = zbx_toArray($linkTriggers); 718 719 $this->validateCreateLinkTriggers($linkTriggers); 720 721 $linkTriggerIds = DB::insert('sysmaps_link_triggers', $linkTriggers); 722 723 return ['linktriggerids' => $linkTriggerIds]; 724 } 725 726 protected function validateCreateLinkTriggers(array $linkTriggers) { 727 $linkTriggerDbFields = [ 728 'linkid' => null, 729 'triggerid' => null 730 ]; 731 732 $colorValidator = new CColorValidator(); 733 734 foreach ($linkTriggers as $linkTrigger) { 735 if (!check_db_fields($linkTriggerDbFields, $linkTrigger)) { 736 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 737 } 738 739 if (isset($linkTrigger['color']) && !$colorValidator->validate($linkTrigger['color'])) { 740 self::exception(ZBX_API_ERROR_PARAMETERS, $colorValidator->getError()); 741 } 742 } 743 } 744 745 protected function updateLinkTriggers($linkTriggers) { 746 $linkTriggers = zbx_toArray($linkTriggers); 747 $this->validateUpdateLinkTriggers($linkTriggers); 748 749 $linkTriggerIds = zbx_objectValues($linkTriggers, 'linktriggerid'); 750 751 $updateLinkTriggers = []; 752 foreach ($linkTriggers as $linkTrigger) { 753 $updateLinkTriggers[] = [ 754 'values' => $linkTrigger, 755 'where' => ['linktriggerid' => $linkTrigger['linktriggerid']] 756 ]; 757 } 758 759 DB::update('sysmaps_link_triggers', $updateLinkTriggers); 760 761 return ['linktriggerids' => $linkTriggerIds]; 762 } 763 764 protected function validateUpdateLinkTriggers(array $linkTriggers) { 765 $linkTriggerDbFields = ['linktriggerid' => null]; 766 767 $colorValidator = new CColorValidator(); 768 769 foreach ($linkTriggers as $linkTrigger) { 770 if (!check_db_fields($linkTriggerDbFields, $linkTrigger)) { 771 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 772 } 773 774 if (isset($linkTrigger['color']) && !$colorValidator->validate($linkTrigger['color'])) { 775 self::exception(ZBX_API_ERROR_PARAMETERS, $colorValidator->getError()); 776 } 777 } 778 } 779 780 protected function deleteLinkTriggers($linkTriggers) { 781 $linkTriggers = zbx_toArray($linkTriggers); 782 $this->validateDeleteLinkTriggers($linkTriggers); 783 784 $linkTriggerIds = zbx_objectValues($linkTriggers, 'linktriggerid'); 785 786 DB::delete('sysmaps_link_triggers', ['linktriggerid' => $linkTriggerIds]); 787 788 return ['linktriggerids' => $linkTriggerIds]; 789 } 790 791 protected function validateDeleteLinkTriggers(array $linkTriggers) { 792 $linktriggerDbFields = ['linktriggerid' => null]; 793 794 foreach ($linkTriggers as $linkTrigger) { 795 if (!check_db_fields($linktriggerDbFields, $linkTrigger)) { 796 self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); 797 } 798 } 799 } 800} 801