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 italic($str) { 23 if (is_array($str)) { 24 foreach ($str as $key => $val) { 25 if (is_string($val)) { 26 $em = new CTag('em', true); 27 $em->addItem($val); 28 $str[$key] = $em; 29 } 30 } 31 } 32 elseif (is_string($str)) { 33 $em = new CTag('em', true, ''); 34 $em->addItem($str); 35 $str = $em; 36 } 37 return $str; 38} 39 40function bold($str) { 41 if (is_array($str)) { 42 foreach ($str as $key => $val) { 43 if (is_string($val)) { 44 $str[$key] = new CTag('b', true, $val); 45 } 46 } 47 48 return $str; 49 } 50 51 return new CTag('b', true, $str); 52} 53 54function make_decoration($haystack, $needle, $class = null) { 55 $result = $haystack; 56 57 $tmpHaystack = mb_strtolower($haystack); 58 $tmpNeedle = mb_strtolower($needle); 59 $pos = mb_strpos($tmpHaystack, $tmpNeedle); 60 61 if ($pos !== false) { 62 $start = CHtml::encode(mb_substr($haystack, 0, $pos)); 63 $end = CHtml::encode(mb_substr($haystack, $pos + mb_strlen($needle))); 64 $found = CHtml::encode(mb_substr($haystack, $pos, mb_strlen($needle))); 65 66 if (is_null($class)) { 67 $result = [$start, bold($found), $end]; 68 } 69 else { 70 $result = [$start, (new CSpan($found))->addClass($class), $end]; 71 } 72 } 73 74 return $result; 75} 76 77function nbsp($str) { 78 return str_replace(' ', SPACE, $str); 79} 80 81function prepareUrlParam($value, $name = null) { 82 if (is_array($value)) { 83 $result = ''; 84 85 foreach ($value as $key => $param) { 86 $result .= prepareUrlParam($param, isset($name) ? $name.'['.$key.']' : $key); 87 } 88 } 89 else { 90 $result = '&'.$name.'='.urlencode($value); 91 } 92 93 return $result; 94} 95 96/** 97 * Get ready for url params. 98 * 99 * @param mixed $param param name or array with data depend from $getFromRequest 100 * @param bool $getFromRequest detect data source - input array or $_REQUEST variable 101 * @param string $name if $_REQUEST variable is used this variable not used 102 * 103 * @return string 104 */ 105function url_param($param, $getFromRequest = true, $name = null) { 106 if (is_array($param)) { 107 if ($getFromRequest) { 108 fatal_error(_('URL parameter cannot be array.')); 109 } 110 } 111 else { 112 if (is_null($name)) { 113 if (!$getFromRequest) { 114 fatal_error(_('URL parameter name is empty.')); 115 } 116 117 $name = $param; 118 } 119 } 120 121 if ($getFromRequest) { 122 $value =& $_REQUEST[$param]; 123 } 124 else { 125 $value =& $param; 126 } 127 128 return isset($value) ? prepareUrlParam($value, $name) : ''; 129} 130 131function url_params(array $params) { 132 $result = ''; 133 134 foreach ($params as $param) { 135 $result .= url_param($param); 136 } 137 138 return $result; 139} 140 141function BR() { 142 return new CTag('br'); 143} 144 145function get_icon($type, $params = []) { 146 switch ($type) { 147 case 'favourite': 148 if (CFavorite::exists($params['fav'], $params['elid'], $params['elname'])) { 149 $icon = (new CRedirectButton(SPACE, null)) 150 ->addClass(ZBX_STYLE_BTN_REMOVE_FAV) 151 ->setTitle(_('Remove from favourites')) 152 ->onClick('rm4favorites("'.$params['elname'].'", "'.$params['elid'].'");'); 153 } 154 else { 155 $icon = (new CRedirectButton(SPACE, null)) 156 ->addClass(ZBX_STYLE_BTN_ADD_FAV) 157 ->setTitle(_('Add to favourites')) 158 ->onClick('add2favorites("'.$params['elname'].'", "'.$params['elid'].'");'); 159 } 160 $icon->setId('addrm_fav'); 161 162 return $icon; 163 164 case 'fullscreen': 165 $url = new CUrl(); 166 167 if ($params['fullscreen'] == 0) { 168 $url->setArgument('fullscreen', '1'); 169 170 $icon = (new CRedirectButton(SPACE, $url->getUrl())) 171 ->setTitle(_('Fullscreen')) 172 ->addClass(ZBX_STYLE_BTN_MAX); 173 } 174 else { 175 $url->setArgument('fullscreen', '0'); 176 177 $icon = (new CRedirectButton(SPACE, $url->getUrl())) 178 ->setTitle(_('Normal view')) 179 ->addClass(ZBX_STYLE_BTN_MIN); 180 } 181 182 return $icon; 183 184 case 'dashconf': 185 $icon = (new CRedirectButton(SPACE, 'dashconf.php')) 186 ->addClass(ZBX_STYLE_BTN_CONF) 187 ->setTitle(_('Configure')); 188 189 if ($params['enabled']) { 190 $icon = [$icon, (new CDiv())->addClass(ZBX_STYLE_ACTIVE_INDIC)]; 191 } 192 193 return $icon; 194 195 case 'screenconf': 196 return (new CRedirectButton(SPACE, null)) 197 ->addClass(ZBX_STYLE_BTN_CONF) 198 ->setTitle(_('Refresh time')); 199 200 case 'overviewhelp': 201 return (new CRedirectButton(SPACE, null)) 202 ->addClass(ZBX_STYLE_BTN_INFO); 203 204 case 'reset': 205 return (new CRedirectButton(SPACE, null)) 206 ->addClass(ZBX_STYLE_BTN_RESET) 207 ->setTitle(_('Reset')) 208 ->onClick('timeControl.objectReset();'); 209 } 210 211 return null; 212} 213 214/** 215 * Create CDiv with host/template information and references to it's elements 216 * 217 * @param string $currentElement 218 * @param int $hostid 219 * @param int $lld_ruleid 220 * 221 * @return object 222 */ 223function get_header_host_table($current_element, $hostid, $lld_ruleid = 0) { 224 $options = [ 225 'output' => [ 226 'hostid', 'status', 'proxy_hostid', 'name', 'maintenance_status', 'flags', 'available', 'snmp_available', 227 'jmx_available', 'ipmi_available', 'error', 'snmp_error', 'jmx_error', 'ipmi_error' 228 ], 229 'selectHostDiscovery' => ['ts_delete'], 230 'hostids' => [$hostid], 231 'editable' => true 232 ]; 233 if ($lld_ruleid == 0) { 234 $options['selectApplications'] = API_OUTPUT_COUNT; 235 $options['selectItems'] = API_OUTPUT_COUNT; 236 $options['selectTriggers'] = API_OUTPUT_COUNT; 237 $options['selectGraphs'] = API_OUTPUT_COUNT; 238 $options['selectDiscoveries'] = API_OUTPUT_COUNT; 239 $options['selectHttpTests'] = API_OUTPUT_COUNT; 240 } 241 242 // get hosts 243 $db_host = API::Host()->get($options); 244 245 if (!$db_host) { 246 $options = [ 247 'output' => ['templateid', 'name', 'flags'], 248 'templateids' => [$hostid], 249 'editable' => true 250 ]; 251 if ($lld_ruleid == 0) { 252 $options['selectApplications'] = API_OUTPUT_COUNT; 253 $options['selectItems'] = API_OUTPUT_COUNT; 254 $options['selectTriggers'] = API_OUTPUT_COUNT; 255 $options['selectGraphs'] = API_OUTPUT_COUNT; 256 $options['selectScreens'] = API_OUTPUT_COUNT; 257 $options['selectDiscoveries'] = API_OUTPUT_COUNT; 258 $options['selectHttpTests'] = API_OUTPUT_COUNT; 259 } 260 261 // get templates 262 $db_host = API::Template()->get($options); 263 264 $is_template = true; 265 } 266 else { 267 $is_template = false; 268 } 269 270 if (!$db_host) { 271 return null; 272 } 273 274 $db_host = reset($db_host); 275 276 // get lld-rules 277 if ($lld_ruleid != 0) { 278 $db_discovery_rule = API::DiscoveryRule()->get([ 279 'output' => ['name'], 280 'selectItems' => API_OUTPUT_COUNT, 281 'selectTriggers' => API_OUTPUT_COUNT, 282 'selectGraphs' => API_OUTPUT_COUNT, 283 'selectHostPrototypes' => API_OUTPUT_COUNT, 284 'itemids' => [$lld_ruleid], 285 'editable' => true 286 ]); 287 $db_discovery_rule = reset($db_discovery_rule); 288 } 289 290 /* 291 * list and host (template) name 292 */ 293 $list = (new CList())->addClass(ZBX_STYLE_OBJECT_GROUP); 294 295 if ($is_template) { 296 $template = new CSpan( 297 new CLink($db_host['name'], 'templates.php?form=update&templateid='.$db_host['templateid']) 298 ); 299 300 if ($current_element === '') { 301 $template->addClass(ZBX_STYLE_SELECTED); 302 } 303 304 $list->addItem([ 305 new CSpan( 306 new CLink(_('All templates'), 'templates.php?templateid='.$db_host['templateid'].url_param('groupid')) 307 ), 308 '/', 309 $template 310 ]); 311 312 $db_host['hostid'] = $db_host['templateid']; 313 } 314 else { 315 $proxy_name = ''; 316 317 if ($db_host['proxy_hostid'] != 0) { 318 $db_proxies = API::Proxy()->get([ 319 'output' => ['host'], 320 'proxyids' => [$db_host['proxy_hostid']] 321 ]); 322 323 $proxy_name = CHtml::encode($db_proxies[0]['host']).NAME_DELIMITER; 324 } 325 326 $name = $proxy_name.CHtml::encode($db_host['name']); 327 328 switch ($db_host['status']) { 329 case HOST_STATUS_MONITORED: 330 if ($db_host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 331 $status = (new CSpan(_('In maintenance')))->addClass(ZBX_STYLE_ORANGE); 332 } 333 else { 334 $status = (new CSpan(_('Enabled')))->addClass(ZBX_STYLE_GREEN); 335 } 336 break; 337 case HOST_STATUS_NOT_MONITORED: 338 $status = (new CSpan(_('Disabled')))->addClass(ZBX_STYLE_RED); 339 break; 340 default: 341 $status = _('Unknown'); 342 break; 343 } 344 345 $host = new CSpan(new CLink($name, 'hosts.php?form=update&hostid='.$db_host['hostid'])); 346 347 if ($current_element === '') { 348 $host->addClass(ZBX_STYLE_SELECTED); 349 } 350 351 $list->addItem([ 352 new CSpan(new CLink(_('All hosts'), 'hosts.php?hostid='.$db_host['hostid'].url_param('groupid'))), 353 '/', 354 $host 355 ]); 356 $list->addItem($status); 357 $list->addItem(getHostAvailabilityTable($db_host)); 358 359 if ($db_host['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $db_host['hostDiscovery']['ts_delete'] != 0) { 360 $lifetime_indicator = getHostLifetimeIndicator(time(), $db_host['hostDiscovery']['ts_delete']); 361 $list->addItem((new CDiv($lifetime_indicator))->addClass(ZBX_STYLE_STATUS_CONTAINER)); 362 } 363 } 364 365 /* 366 * the count of rows 367 */ 368 if ($lld_ruleid == 0) { 369 // applications 370 $applications = new CSpan([ 371 new CLink(_('Applications'), 'applications.php?hostid='.$db_host['hostid']), 372 CViewHelper::showNum($db_host['applications']) 373 ]); 374 if ($current_element == 'applications') { 375 $applications->addClass(ZBX_STYLE_SELECTED); 376 } 377 $list->addItem($applications); 378 379 // items 380 $items = new CSpan([ 381 new CLink(_('Items'), 'items.php?filter_set=1&hostid='.$db_host['hostid']), 382 CViewHelper::showNum($db_host['items']) 383 ]); 384 if ($current_element == 'items') { 385 $items->addClass(ZBX_STYLE_SELECTED); 386 } 387 $list->addItem($items); 388 389 // triggers 390 $triggers = new CSpan([ 391 new CLink(_('Triggers'), 'triggers.php?hostid='.$db_host['hostid']), 392 CViewHelper::showNum($db_host['triggers']) 393 ]); 394 if ($current_element == 'triggers') { 395 $triggers->addClass(ZBX_STYLE_SELECTED); 396 } 397 $list->addItem($triggers); 398 399 // graphs 400 $graphs = new CSpan([ 401 new CLink(_('Graphs'), 'graphs.php?hostid='.$db_host['hostid']), 402 CViewHelper::showNum($db_host['graphs']) 403 ]); 404 if ($current_element == 'graphs') { 405 $graphs->addClass(ZBX_STYLE_SELECTED); 406 } 407 $list->addItem($graphs); 408 409 // screens 410 if ($is_template) { 411 $screens = new CSpan([ 412 new CLink(_('Screens'), 'screenconf.php?templateid='.$db_host['hostid']), 413 CViewHelper::showNum($db_host['screens']) 414 ]); 415 if ($current_element == 'screens') { 416 $screens->addClass(ZBX_STYLE_SELECTED); 417 } 418 $list->addItem($screens); 419 } 420 421 // discovery rules 422 $lld_rules = new CSpan([ 423 new CLink(_('Discovery rules'), 'host_discovery.php?hostid='.$db_host['hostid']), 424 CViewHelper::showNum($db_host['discoveries']) 425 ]); 426 if ($current_element == 'discoveries') { 427 $lld_rules->addClass(ZBX_STYLE_SELECTED); 428 } 429 $list->addItem($lld_rules); 430 431 // web scenarios 432 $http_tests = new CSpan([ 433 new CLink(_('Web scenarios'), 'httpconf.php?hostid='.$db_host['hostid']), 434 CViewHelper::showNum($db_host['httpTests']) 435 ]); 436 if ($current_element == 'web') { 437 $http_tests->addClass(ZBX_STYLE_SELECTED); 438 } 439 $list->addItem($http_tests); 440 } 441 else { 442 $discovery_rule = (new CSpan())->addItem( 443 new CLink( 444 CHtml::encode($db_discovery_rule['name']), 445 'host_discovery.php?form=update&itemid='.$db_discovery_rule['itemid'] 446 ) 447 ); 448 449 if ($current_element == 'discoveries') { 450 $discovery_rule->addClass(ZBX_STYLE_SELECTED); 451 } 452 453 $list->addItem([ 454 (new CSpan())->addItem( 455 new CLink(_('Discovery list'), 'host_discovery.php?hostid='.$db_host['hostid'].url_param('groupid')) 456 ), 457 '/', 458 $discovery_rule 459 ]); 460 461 // item prototypes 462 $item_prototypes = new CSpan([ 463 new CLink(_('Item prototypes'), 'disc_prototypes.php?parent_discoveryid='.$db_discovery_rule['itemid']), 464 CViewHelper::showNum($db_discovery_rule['items']) 465 ]); 466 if ($current_element == 'items') { 467 $item_prototypes->addClass(ZBX_STYLE_SELECTED); 468 } 469 $list->addItem($item_prototypes); 470 471 // trigger prototypes 472 $trigger_prototypes = new CSpan([ 473 new CLink(_('Trigger prototypes'), 474 'trigger_prototypes.php?parent_discoveryid='.$db_discovery_rule['itemid'] 475 ), 476 CViewHelper::showNum($db_discovery_rule['triggers']) 477 ]); 478 if ($current_element == 'triggers') { 479 $trigger_prototypes->addClass(ZBX_STYLE_SELECTED); 480 } 481 $list->addItem($trigger_prototypes); 482 483 // graph prototypes 484 $graph_prototypes = new CSpan([ 485 new CLink(_('Graph prototypes'), 'graphs.php?parent_discoveryid='.$db_discovery_rule['itemid']), 486 CViewHelper::showNum($db_discovery_rule['graphs']) 487 ]); 488 if ($current_element == 'graphs') { 489 $graph_prototypes->addClass(ZBX_STYLE_SELECTED); 490 } 491 $list->addItem($graph_prototypes); 492 493 // host prototypes 494 if ($db_host['flags'] == ZBX_FLAG_DISCOVERY_NORMAL) { 495 $host_prototypes = new CSpan([ 496 new CLink(_('Host prototypes'), 'host_prototypes.php?parent_discoveryid='.$db_discovery_rule['itemid']), 497 CViewHelper::showNum($db_discovery_rule['hostPrototypes']) 498 ]); 499 if ($current_element == 'hosts') { 500 $host_prototypes->addClass(ZBX_STYLE_SELECTED); 501 } 502 $list->addItem($host_prototypes); 503 } 504 } 505 506 return $list; 507} 508 509/** 510 * Create CDiv with sysmap information 511 * 512 * @param int $sysmapid 513 * @param string $name 514 * 515 * @return object 516 */ 517function get_header_sysmap_table($sysmapid, $name, $fullscreen, $severity_min) { 518 $list = (new CList()) 519 ->addClass(ZBX_STYLE_OBJECT_GROUP) 520 ->addItem([ 521 (new CSpan())->addItem(new CLink(_('All maps'), 'sysmaps.php')), 522 '/', 523 (new CSpan()) 524 ->addClass(ZBX_STYLE_SELECTED) 525 ->addItem( 526 new CLink($name, 'zabbix.php?action=map.view&sysmapid='.$sysmapid.'&fullscreen='.$fullscreen. 527 '&severity_min='.$severity_min 528 ) 529 ) 530 ]); 531 532 // get map parent maps 533 $parent_sysmaps = get_parent_sysmaps($sysmapid); 534 if ($parent_sysmaps) { 535 $hor_list = new CHorList(); 536 537 foreach ($parent_sysmaps as $parent_sysmap) { 538 $hor_list->addItem( 539 new CLink($parent_sysmap['name'], 'zabbix.php?action=map.view'. 540 '&sysmapid='.$parent_sysmap['sysmapid'].'&fullscreen='.$fullscreen.'&severity_min='.$severity_min 541 ) 542 ); 543 } 544 545 $list->addItem(new CSpan(_('Upper level maps').':')); 546 $list->addItem($hor_list); 547 } 548 549 return $list; 550} 551 552/** 553 * Renders a form footer with the given buttons. 554 * 555 * @param CButtonInterface $main_button main button that will be displayed on the left 556 * @param CButtonInterface[] $other_buttons 557 * 558 * @return CDiv 559 * 560 * @throws InvalidArgumentException if an element of $other_buttons contain something other than CButtonInterface 561 */ 562function makeFormFooter(CButtonInterface $main_button = null, array $other_buttons = []) { 563 foreach ($other_buttons as $other_button) { 564 $other_button->addClass(ZBX_STYLE_BTN_ALT); 565 } 566 567 if ($main_button !== null) { 568 array_unshift($other_buttons, $main_button); 569 } 570 571 return (new CList()) 572 ->addClass(ZBX_STYLE_TABLE_FORMS) 573 ->addItem([ 574 (new CDiv())->addClass(ZBX_STYLE_TABLE_FORMS_TD_LEFT), 575 (new CDiv($other_buttons)) 576 ->addClass(ZBX_STYLE_TABLE_FORMS_TD_RIGHT) 577 ->addClass('tfoot-buttons') 578 ]); 579} 580 581/** 582 * Returns zbx, snmp, jmx, ipmi availability status icons and the discovered host lifetime indicator. 583 * 584 * @param array $host an array of host data 585 * 586 * @return CDiv 587 */ 588function getHostAvailabilityTable($host) { 589 $container = (new CDiv())->addClass(ZBX_STYLE_STATUS_CONTAINER); 590 591 foreach (['zbx' => '', 'snmp' => 'snmp_', 'jmx' => 'jmx_', 'ipmi' => 'ipmi_'] as $type => $prefix) { 592 switch ($host[$prefix.'available']) { 593 case HOST_AVAILABLE_TRUE: 594 $ai = (new CSpan($type))->addClass(ZBX_STYLE_STATUS_GREEN); 595 break; 596 case HOST_AVAILABLE_FALSE: 597 $ai = (new CSpan($type))->addClass(ZBX_STYLE_STATUS_RED); 598 599 if ($host[$prefix.'error'] !== '') { 600 $ai 601 ->addClass(ZBX_STYLE_CURSOR_POINTER) 602 ->setHint($host[$prefix.'error'], ZBX_STYLE_RED); 603 } 604 605 break; 606 case HOST_AVAILABLE_UNKNOWN: 607 $ai = (new CSpan($type))->addClass(ZBX_STYLE_STATUS_GREY); 608 break; 609 } 610 $container->addItem($ai); 611 } 612 613 return $container; 614} 615 616/** 617 * Returns the discovered host group lifetime indicator. 618 * 619 * @param string $current_time current Unix timestamp 620 * @param array $ts_delete deletion timestamp of the host group 621 * 622 * @return CDiv 623 */ 624function getHostGroupLifetimeIndicator($current_time, $ts_delete) { 625 // Check if the element should've been deleted in the past. 626 if ($current_time > $ts_delete) { 627 $warning = _( 628 'The host group is not discovered anymore and will be deleted the next time discovery rule is processed.' 629 ); 630 } 631 else { 632 $warning = _s( 633 'The host group is not discovered anymore and will be deleted in %1$s (on %2$s at %3$s).', 634 zbx_date2age($ts_delete), 635 zbx_date2str(DATE_FORMAT, $ts_delete), 636 zbx_date2str(TIME_FORMAT, $ts_delete) 637 ); 638 } 639 640 return makeWarningIcon($warning); 641} 642 643/** 644 * Returns the discovered host lifetime indicator. 645 * 646 * @param string $current_time current Unix timestamp 647 * @param array $ts_delete deletion timestamp of the host 648 * 649 * @return CDiv 650 */ 651function getHostLifetimeIndicator($current_time, $ts_delete) { 652 // Check if the element should've been deleted in the past. 653 if ($current_time > $ts_delete) { 654 $warning = _( 655 'The host is not discovered anymore and will be deleted the next time discovery rule is processed.' 656 ); 657 } 658 else { 659 $warning = _s( 660 'The host is not discovered anymore and will be deleted in %1$s (on %2$s at %3$s).', 661 zbx_date2age($ts_delete), 662 zbx_date2str(DATE_FORMAT, $ts_delete), 663 zbx_date2str(TIME_FORMAT, $ts_delete) 664 ); 665 } 666 667 return makeWarningIcon($warning); 668} 669 670/** 671 * Returns the discovered application lifetime indicator. 672 * 673 * @param string $current_time current Unix timestamp 674 * @param array $ts_delete deletion timestamp of the application 675 * 676 * @return CDiv 677 */ 678function getApplicationLifetimeIndicator($current_time, $ts_delete) { 679 // Check if the element should've been deleted in the past. 680 if ($current_time > $ts_delete) { 681 $warning = _( 682 'The application is not discovered anymore and will be deleted the next time discovery rule is processed.' 683 ); 684 } 685 else { 686 $warning = _s( 687 'The application is not discovered anymore and will be deleted in %1$s (on %2$s at %3$s).', 688 zbx_date2age($ts_delete), 689 zbx_date2str(DATE_FORMAT, $ts_delete), 690 zbx_date2str(TIME_FORMAT, $ts_delete) 691 ); 692 } 693 694 return makeWarningIcon($warning); 695} 696 697/** 698 * Returns the discovered item lifetime indicator. 699 * 700 * @param string $current_time current Unix timestamp 701 * @param array $ts_delete deletion timestamp of the item 702 * 703 * @return CDiv 704 */ 705function getItemLifetimeIndicator($current_time, $ts_delete) { 706 // Check if the element should've been deleted in the past. 707 if ($current_time > $ts_delete) { 708 $warning = _( 709 'The item is not discovered anymore and will be deleted the next time discovery rule is processed.' 710 ); 711 } 712 else { 713 $warning = _s( 714 'The item is not discovered anymore and will be deleted in %1$s (on %2$s at %3$s).', 715 zbx_date2age($ts_delete), 716 zbx_date2str(DATE_FORMAT, $ts_delete), 717 zbx_date2str(TIME_FORMAT, $ts_delete) 718 ); 719 } 720 721 return makeWarningIcon($warning); 722} 723 724/** 725 * Create array with all inputs required for date selection and calendar. 726 * 727 * @param string $name 728 * @param int|array $date unix timestamp/date array(Y,m,d,H,i) 729 * @param string|null $relatedCalendar name of the calendar which must be closed when this calendar opens 730 * 731 * @return array 732 */ 733function createDateSelector($name, $date, $relatedCalendar = null) { 734 $onClick = 'var pos = getPosition(this); pos.top += 10; pos.left += 16; CLNDR["'.$name. 735 '_calendar"].clndr.clndrshow(pos.top, pos.left);'; 736 if ($relatedCalendar) { 737 $onClick .= ' CLNDR["'.$relatedCalendar.'_calendar"].clndr.clndrhide();'; 738 } 739 740 if (is_array($date)) { 741 $y = $date['y']; 742 $m = $date['m']; 743 $d = $date['d']; 744 $h = $date['h']; 745 $i = $date['i']; 746 } 747 else { 748 $y = date('Y', $date); 749 $m = date('m', $date); 750 $d = date('d', $date); 751 $h = date('H', $date); 752 $i = date('i', $date); 753 } 754 755 $fields = [ 756 (new CNumericBox($name.'_year', $y, 4)) 757 ->setWidth(ZBX_TEXTAREA_4DIGITS_WIDTH) 758 ->setAttribute('placeholder', _('yyyy')), 759 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 760 '-', 761 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 762 (new CTextBox($name.'_month', $m, false, 2)) 763 ->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH) 764 ->addStyle('text-align: right;') 765 ->setAttribute('placeholder', _('mm')) 766 ->onChange('validateDatePartBox(this, 1, 12, 2);'), 767 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 768 '-', 769 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 770 (new CTextBox($name.'_day', $d, false, 2)) 771 ->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH) 772 ->addStyle('text-align: right;') 773 ->setAttribute('placeholder', _('dd')) 774 ->onChange('validateDatePartBox(this, 1, 31, 2);'), 775 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 776 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 777 (new CTextBox($name.'_hour', $h, false, 2)) 778 ->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH) 779 ->addStyle('text-align: right;') 780 ->setAttribute('placeholder', _('hh')) 781 ->onChange('validateDatePartBox(this, 0, 23, 2);'), 782 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 783 ':', 784 (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN), 785 (new CTextBox($name.'_minute', $i, false, 2)) 786 ->setWidth(ZBX_TEXTAREA_2DIGITS_WIDTH) 787 ->addStyle('text-align: right;') 788 ->setAttribute('placeholder', _('mm')) 789 ->onChange('validateDatePartBox(this, 0, 59, 2);'), 790 (new CButton()) 791 ->addClass(ZBX_STYLE_ICON_CAL) 792 ->onClick($onClick) 793 ]; 794 795 zbx_add_post_js('create_calendar(null,'. 796 '["'.$name.'_day","'.$name.'_month","'.$name.'_year","'.$name.'_hour","'.$name.'_minute"],'. 797 '"'.$name.'_calendar",'. 798 '"'.$name.'");' 799 ); 800 801 return $fields; 802} 803 804/** 805 * Renders a page footer. 806 * 807 * @param bool $with_logo 808 * @param bool $with_version 809 * 810 * @return CDiv 811 */ 812function makePageFooter($with_version = true) 813{ 814 return (new CDiv([ 815 $with_version ? 'Zabbix '.ZABBIX_VERSION.'. ' : null, 816 '© '.ZABBIX_COPYRIGHT_FROM.'–'.ZABBIX_COPYRIGHT_TO.', ', 817 (new CLink('Zabbix SIA', 'http://www.zabbix.com/')) 818 ->addClass(ZBX_STYLE_GREY) 819 ->addClass(ZBX_STYLE_LINK_ALT) 820 ->setAttribute('target', '_blank') 821 ]))->addClass(ZBX_STYLE_FOOTER); 822} 823 824/** 825 * Renders a drop-down menu for the Administration->General section. 826 * 827 * @param string $selected 828 * 829 * @return CComboBox 830 */ 831function makeAdministrationGeneralMenu($selected) 832{ 833 return new CComboBox('configDropDown', $selected, 'redirect(this.options[this.selectedIndex].value);', [ 834 'adm.gui.php' => _('GUI'), 835 'adm.housekeeper.php' => _('Housekeeping'), 836 'adm.images.php' => _('Images'), 837 'adm.iconmapping.php' => _('Icon mapping'), 838 'adm.regexps.php' => _('Regular expressions'), 839 'adm.macros.php' => _('Macros'), 840 'adm.valuemapping.php' => _('Value mapping'), 841 'adm.workingtime.php' => _('Working time'), 842 'adm.triggerseverities.php' => _('Trigger severities'), 843 'adm.triggerdisplayoptions.php' => _('Trigger displaying options'), 844 'adm.other.php' => _('Other') 845 ]); 846} 847 848/** 849 * Renders an error icon like [x] with error message 850 * 851 * @param string $error 852 * 853 * @return CSpan 854 */ 855function makeErrorIcon($error) 856{ 857 return (new CSpan(bold('×'))) 858 ->addClass(ZBX_STYLE_STATUS_RED) 859 ->addClass(ZBX_STYLE_CURSOR_POINTER) 860 ->setHint($error, ZBX_STYLE_RED); 861} 862 863/** 864 * Renders an unknown icon like [?] with error message 865 * 866 * @param string $error 867 * 868 * @return CSpan 869 */ 870function makeUnknownIcon($error) 871{ 872 return (new CSpan(bold('?'))) 873 ->addClass(ZBX_STYLE_STATUS_GREY) 874 ->addClass(ZBX_STYLE_CURSOR_POINTER) 875 ->setHint($error, ZBX_STYLE_RED); 876} 877 878/** 879 * Renders a warning icon like [!] with error message 880 * 881 * @param string $error 882 * 883 * @return CSpan 884 */ 885function makeWarningIcon($error) 886{ 887 return (new CSpan(bold('!'))) 888 ->addClass(ZBX_STYLE_STATUS_YELLOW) 889 ->addClass(ZBX_STYLE_CURSOR_POINTER) 890 ->setHint($error); 891} 892 893/** 894 * Renders a debug button 895 * 896 * @return CButton 897 */ 898function makeDebugButton() 899{ 900 return (new CDiv( 901 (new CLink(_('Debug'), '#debug')) 902 ->onClick("javascript: if (!isset('state', this)) { this.state = 'none'; }". 903 "this.state = (this.state == 'none' ? 'block' : 'none');". 904 "jQuery(this)". 905 ".text(this.state == 'none' ? ".CJs::encodeJson(_('Debug'))." : ".CJs::encodeJson(_('Hide debug')).")". 906 ".blur();". 907 "showHideByName('zbx_debug_info', this.state);" 908 ) 909 ))->addClass(ZBX_STYLE_BTN_DEBUG); 910} 911 912/** 913 * Returns css for trigger severity backgrounds 914 * 915 * @param array $config 916 * @param array $config[severity_color_0] 917 * @param array $config[severity_color_1] 918 * @param array $config[severity_color_2] 919 * @param array $config[severity_color_3] 920 * @param array $config[severity_color_4] 921 * @param array $config[severity_color_5] 922 * 923 * @return string 924 */ 925function getTriggerSeverityCss($config) 926{ 927 $severities = [ 928 ZBX_STYLE_NA_BG => $config['severity_color_0'], 929 ZBX_STYLE_INFO_BG => $config['severity_color_1'], 930 ZBX_STYLE_WARNING_BG => $config['severity_color_2'], 931 ZBX_STYLE_AVERAGE_BG => $config['severity_color_3'], 932 ZBX_STYLE_HIGH_BG => $config['severity_color_4'], 933 ZBX_STYLE_DISASTER_BG => $config['severity_color_5'] 934 ]; 935 936 $css = ''; 937 938 foreach ($severities as $class => $color) { 939 $css .= '.'.$class.', .'.$class.' input[type="radio"]:checked + label { background-color: #'.$color.' }'."\n"; 940 } 941 942 return $css; 943} 944