diff -ru ../orzbx/hosts.php ./hosts.php --- ../orzbx/hosts.php 2018-09-14 00:04:46.000000000 -0800 +++ ./hosts.php 2018-09-27 16:05:27.206610239 -0800 @@ -21,6 +21,7 @@ require_once dirname(__FILE__).'/include/config.inc.php'; require_once dirname(__FILE__).'/include/hostgroups.inc.php'; +require_once dirname(__FILE__).'/include/maps.inc.php'; require_once dirname(__FILE__).'/include/forms.inc.php'; if (hasRequest('action') && getRequest('action') == 'host.export' && hasRequest('hosts')) { @@ -115,7 +116,12 @@ 'filter_port' => [T_ZBX_STR, O_OPT, null, null, null], // sort and sortorder 'sort' => [T_ZBX_STR, O_OPT, P_SYS, IN('"name","status"'), null], - 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null] + 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null], + // add to map + 'sysmapid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], + 'iconid_off' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], + // selement to link to on map + 'map_link_to_element' => [T_ZBX_STR, O_OPT, null, null, null] ]; check_fields($fields); @@ -262,7 +268,7 @@ // filter only normal and discovery created hosts $options = [ - 'output' => ['hostid'], + 'output' => ['hostid', 'name'], 'hostids' => $hostIds, 'selectInventory' => ['inventory_mode'], 'selectGroups' => ['groupid'], @@ -437,6 +443,143 @@ throw new Exception(); } + // add hosts to map ------------------------------------------------------------------------------------ + // We had to add the name to the output columns when fetching hosts above + + if (isset($visible['sysmapid'])) { + $sysmap = API::Map()->get([ + 'output' => ['sysmapid', 'name', 'expand_macros', 'grid_show', 'grid_align', 'grid_size', 'width', 'height', + 'iconmapid', 'backgroundid', 'label_location', 'label_type', 'label_format', 'label_type_host', + 'label_type_hostgroup', 'label_type_trigger', 'label_type_map', 'label_type_image', 'label_string_host', + 'label_string_hostgroup', 'label_string_trigger', 'label_string_map', 'label_string_image' + ], + 'selectShapes' => ['sysmap_shapeid', 'type', 'x', 'y', 'width', 'height', 'text', 'font', 'font_size', + 'font_color', 'text_halign', 'text_valign', 'border_type', 'border_width', 'border_color', + 'background_color', 'zindex' + ], + 'selectLines' => ['sysmap_shapeid', 'x1', 'y1', 'x2', 'y2', 'line_type', 'line_width', 'line_color', 'zindex'], + 'selectSelements' => API_OUTPUT_EXTEND, + 'selectLinks' => API_OUTPUT_EXTEND, + 'sysmapids' => getRequest('sysmapid'), + 'editable' => true, + 'preservekeys' => true + ]); + $sysmap = reset($sysmap); + + if ($sysmap === false) { + throw new Exception(_('Access denied!')); + } + + $data['sysmap']= $sysmap; + + // get selements + add_elementNames($data['sysmap']['selements']); + + foreach ($data['sysmap']['lines'] as $line) { + $data['sysmap']['shapes'][] = CMapHelper::convertLineToShape($line); + } + unset($data['sysmap']['lines']); + + $data['sysmap']['selements'] = zbx_toHash($data['sysmap']['selements'], 'selementid'); + $data['sysmap']['shapes'] = zbx_toHash($data['sysmap']['shapes'], 'sysmap_shapeid'); + $data['sysmap']['links'] = zbx_toHash($data['sysmap']['links'], 'linkid'); + + $data['sysmap'] = CMapHelper::setElementInheritedLabels($data['sysmap']); + foreach ($data['sysmap']['selements'] as &$selement) { + if ($selement['inherited_label'] !== null) { + $label = $selement['label']; + $selement['label'] = $selement['inherited_label']; + } + + $selement['expanded'] = CMacrosResolverHelper::resolveMapLabelMacrosAll($selement); + + if ($selement['inherited_label'] !== null) { + $selement['label'] = $label; + } + } + unset($selement); + + // get links + foreach ($data['sysmap']['links'] as &$link) { + foreach ($link['linktriggers'] as $lnum => $linkTrigger) { + $dbTrigger = API::Trigger()->get([ + 'triggerids' => $linkTrigger['triggerid'], + 'output' => ['description', 'expression'], + 'selectHosts' => API_OUTPUT_EXTEND, + 'preservekeys' => true, + 'expandDescription' => true + ]); + $dbTrigger = reset($dbTrigger); + $host = reset($dbTrigger['hosts']); + + $link['linktriggers'][$lnum]['desc_exp'] = $host['name'].NAME_DELIMITER.$dbTrigger['description']; + } + + $link['expanded'] = CMacrosResolverHelper::resolveMapLabelMacros($link['label']); + order_result($link['linktriggers'], 'desc_exp'); + } + unset($link); + + // add the selected hosts and link + $map_link_to_element = getRequest('map_link_to_element'); + $i = 0; + foreach ($hosts as $host) { + $data['sysmap']['selements']['new' . $i] = [ + 'selementid' => 'new' . $i, + 'elementtype' => '0', + 'label' => "{HOST.NAME}\r\n{HOST.CONN}", + 'label_location' => '-1', + 'iconid_off' => getRequest('iconid_off'), + 'iconid_on' => '0', + 'iconid_maintenance' => '0', + 'iconid_disabled' => '0', + 'use_iconmap' => '0', + 'x' => $i * 10, + 'y' => $i * 10, + 'elements' => [ + '0' => [ + 'hostid' => $host['hostid'], + 'elementName' => $host['name'] + ] + ] + ]; + + if ($map_link_to_element != '') { + $data['sysmap']['links']['newlnk' . $i] = [ + 'linkid' => 'newlnk' . $i, + 'selementid1' => 'new' . $i, + 'selementid2' => $map_link_to_element + ]; + } + + $i = $i + 1; + } + + if (array_key_exists('shapes', $data['sysmap'])) { + foreach ($data['sysmap']['shapes'] as $key => &$shape) { + if (array_key_exists('sysmap_shapeid', $shape) && !is_numeric($shape['sysmap_shapeid'])) { + unset($shape['sysmap_shapeid']); + } + if ($shape['type'] == SYSMAP_SHAPE_TYPE_LINE) { + $data['sysmap']['lines'][$key] = CMapHelper::convertShapeToLine($shape); + unset($data['sysmap']['shapes'][$key]); + } + } + unset($shape); + } + + // echo "
".json_encode($data['sysmap'], JSON_PRETTY_PRINT).""; + + $result = API::Map()->update($data['sysmap']); + + if ($result !== false) { + // echo 'if (confirm('.CJs::encodeJson(_('Map is updated! Return?')).')) { location.href = "sysmaps.php"; }'; + } + else { + throw new Exception(_('Map update failed.')); + } + } + DBend(true); uncheckTableRows(); diff -ru ../orzbx/include/views/configuration.host.massupdate.php ./include/views/configuration.host.massupdate.php --- ../orzbx/include/views/configuration.host.massupdate.php 2018-09-14 00:04:46.000000000 -0800 +++ ./include/views/configuration.host.massupdate.php 2018-09-27 16:05:27.198610017 -0800 @@ -335,17 +335,75 @@ ->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;') ); + + +// Add hosts to map +$mapsFormList = new CFormList('mapsFormList'); +$maps = API::Map()->get(['editable' => true]); +order_result($maps, 'name'); + +$maps_list = []; +foreach ($maps as $map) { + $maps_list[$map['sysmapid']] = $map['name']; +} + +$data['iconList']=[]; +$iconList = API::Image()->get([ + 'output' => ['imageid', 'name'], + 'filter' => ['imagetype' => IMAGE_TYPE_ICON], + 'preservekeys' => true +]); +order_result($iconList, 'name'); + +foreach ($iconList as $icon) { + $data['iconList'][$icon['imageid']] = $icon['name']; +} + + // ask for map, default icon, element to link to +$mapsFormTable = (new CTable()) + ->addRow([new CLabel(_('Map'), 'sysmapid'), + (new CComboBox('sysmapid', null, null, $maps_list)) + ->onChange('jQuery("#linkToName").val(""); jQuery("#map_link_to_element").val("");') + ]) + ->addRow([new CLabel(_('Default Icon'), 'iconid_off'), new CComboBox('iconid_off', null, null, $data['iconList'])]) + ->addRow([new CLabel(_('Link To'), 'linkToName'), + (new CTextBox('linkToName')) + ->setReadonly(true) + ->setId('linkToName') + ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH), + (new CVar('map_link_to_element', '')), + (new CButton(null, _('Select'))) + ->addClass(ZBX_STYLE_BTN_GREY) + ->onClick( + 'return PopUp("popup.php?srctbl=sysmap_elements&srcfld1=selementid&srcfld2=expanded'. + '&dstfrm='.$hostView->getName().'&dstfld1=map_link_to_element&dstfld2=linkToName&sysmapid='. + '" + jQuery("select#sysmapid").val());') + ]) + ->setAttribute('style', 'width: 100%;'); + +$mapsFormList->addRow( + (new CVisibilityBox('visible[sysmapid]', 'mapDiv', _('None'))) + ->setLabel(_('Add to map')) + ->setChecked(isset($data['visible']['sysmapid'])), + (new CDiv($mapsFormTable)) + ->setId('mapDiv') + ->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR) + ->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;') +); + // append tabs to form $hostTab = (new CTabView()) ->addTab('hostTab', _('Host'), $hostFormList) ->addTab('templatesTab', _('Templates'), $templatesFormList) ->addTab('ipmiTab', _('IPMI'), $ipmiFormList) ->addTab('inventoryTab', _('Inventory'), $inventoryFormList); + // reset the tab when opening the form for the first time if (!hasRequest('masssave') && !hasRequest('inventory_mode')) { $hostTab->setSelected(0); } $hostTab->addTab('encryptionTab', _('Encryption'), $encryption_form_list); +$hostTab->addTab('mapsTab', _('Map'), $mapsFormList); // append buttons to form $hostTab->setFooter(makeFormFooter( diff -ru ../orzbx/popup.php ./popup.php --- ../orzbx/popup.php 2018-09-14 00:04:46.000000000 -0800 +++ ./popup.php 2018-09-27 16:18:57.693032306 -0800 @@ -22,6 +22,7 @@ require_once dirname(__FILE__).'/include/config.inc.php'; require_once dirname(__FILE__).'/include/hostgroups.inc.php'; require_once dirname(__FILE__).'/include/hosts.inc.php'; +require_once dirname(__FILE__).'/include/maps.inc.php'; require_once dirname(__FILE__).'/include/triggers.inc.php'; require_once dirname(__FILE__).'/include/items.inc.php'; require_once dirname(__FILE__).'/include/users.inc.php'; @@ -100,6 +101,10 @@ $page['title'] = _('Maps'); $min_user_type = USER_TYPE_ZABBIX_USER; break; + case 'sysmap_elements': + $page['title'] = _('Map Elements'); + $min_user_type = USER_TYPE_ZABBIX_USER; + break; case 'screens2': $page['title'] = _('Screens'); $min_user_type = USER_TYPE_ZABBIX_USER; @@ -147,6 +152,7 @@ 'graph_prototypes' => '"graphid", "name"', 'item_prototypes' => '"itemid", "name", "flags", "master_itemname"', 'sysmaps' => '"sysmapid", "name"', + 'sysmap_elements' => '"selementid", "label", "expanded"', 'help_items' => '"key"', 'screens' => '"screenid"', 'screens2' => '"screenid", "name"', @@ -198,6 +204,7 @@ 'noempty' => [T_ZBX_STR, O_OPT, null, null, null], 'select' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 'submitParent' => [T_ZBX_INT, O_OPT, null, IN('0,1'), null], + 'sysmapid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], // for limiting sysmap_elements to a specific map 'templateid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 'with_webitems' => [T_ZBX_INT, O_OPT, null, IN('0,1'), null] ]; @@ -276,6 +283,7 @@ $parentDiscoveryId = getRequest('parent_discoveryid'); $templateid = getRequest('templateid'); $with_webitems = (bool) getRequest('with_webitems', true); +$sysmapid = getRequest('sysmapid'); if (isset($onlyHostid)) { $_REQUEST['hostid'] = $onlyHostid; @@ -438,6 +446,9 @@ if (hasRequest('templateid')) { $frmTitle->addVar('templateid', $templateid); } +if (getRequest('sysmapid')) { + $frmTitle->addVar('sysmapid', getRequest('sysmapid')); +} // adding param to a form, so that it would remain when page is refreshed $frmTitle->addVar('dstfrm', $dstfrm); @@ -1594,6 +1605,95 @@ $form->addItem($table); $widget->addItem($form)->show(); } + + + + +/* + * sysmap_elements + */ +elseif ($srctbl == 'sysmap_elements') { + $form = (new CForm()) + ->setName('sysmapelform') + ->setId('sysmapels'); + + $table = (new CTableInfo()) + ->setHeader([ + null, + _('Name') + ]); + + $options = [ + 'output' => API_OUTPUT_EXTEND, + 'preservekeys' => true, + 'selectSelements' => API_OUTPUT_EXTEND, + 'sysmapids' => $sysmapid, + 'editable' => true + ]; + + $sysmaps = API::Map()->get($options); + $sysmaps = reset($sysmaps); + if ($sysmaps === false) { + throw new Exception(_('Access denied!')); + } + + $sysmaps['selements'] = zbx_toHash($sysmaps['selements'], 'selementid'); + + $sysmaps = CMapHelper::setElementInheritedLabels($sysmaps); + foreach ($sysmaps['selements'] as &$selement) { + if ($selement['inherited_label'] !== null) { + $label = $selement['label']; + $selement['label'] = $selement['inherited_label']; + } + + $selement['expanded'] = CMacrosResolverHelper::resolveMapLabelMacrosAll($selement); + + if ($selement['inherited_label'] !== null) { + $selement['label'] = $label; + } + } + unset($selement); + order_result($sysmaps['selements'], $srcfld2); + + foreach ($sysmaps['selements'] as $selement) { + if (isset($excludeids[$selement['selementid']])) { + $description = $selement[$srcfld2]; + } + else { + $description = new CLink($selement[$srcfld2], 'javascript:void(0);'); + $js_object = []; + + $elements = []; + + if (array_key_exists($srcfld1, $selement)) { + $elements[] = ['id' => $dstfld1, 'value' => $selement[$srcfld1]]; + } + if ($srcfld2 && array_key_exists($srcfld2, $selement)) { + $elements[] = ['id' => $dstfld2, 'value' => $selement[$srcfld2]]; + } + if ($elements) { + $js_object['elements'] = $elements; + } + + if ($js_object) { + $description->setAttribute('data-object', $js_object); + } + } + + $table->addRow([ + null, + $description + ]); + unset($description); + } + + $form->addItem($table); + $widget->addItem($form)->show(); +} + + + + /* * Screens */