You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
10 KiB

1 year ago
<?php
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
require_once dirname(__FILE__).'/include/config.inc.php';
require_once dirname(__FILE__).'/include/maps.inc.php';
require_once dirname(__FILE__).'/include/forms.inc.php';
$page['title'] = _('Configuration of network maps');
$page['file'] = 'sysmap.php';
$page['scripts'] = ['class.svg.canvas.js', 'class.svg.map.js', 'class.cmap.js',
'colorpicker.js', 'class.tagfilteritem.js'
];
$page['type'] = detect_page_type();
if (!CWebUser::checkAccess(CRoleHelper::ACTIONS_EDIT_MAPS)) {
access_deny(ACCESS_DENY_PAGE);
}
require_once dirname(__FILE__).'/include/page_header.php';
// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION
$fields = [
'sysmapid' => [T_ZBX_INT, O_MAND, P_SYS, DB_ID, null],
'selementid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null],
'sysmap' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({action}) && {action} == "update"'],
// actions
'action' => [T_ZBX_STR, O_OPT, P_ACT, IN('"update","expand"'), null],
'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null],
'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null],
'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null],
// ajax
'favobj' => [T_ZBX_STR, O_OPT, P_ACT, null, null],
'favid' => [T_ZBX_STR, O_OPT, P_ACT, null, null],
'name' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({action}) && {action} == "expand"'],
'source' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({action}) && {action} == "expand"']
];
check_fields($fields);
/*
* Ajax
*/
if (isset($_REQUEST['favobj'])) {
if (getRequest('favobj') === 'sysmap' && hasRequest('action')) {
if (getRequest('action') === 'update') {
$sysmapid = getRequest('sysmapid', 0);
@ob_start();
try {
DBstart();
$sysmap = API::Map()->get([
'sysmapids' => $sysmapid,
'editable' => true,
'output' => ['sysmapid']
]);
$sysmap = reset($sysmap);
if ($sysmap === false) {
throw new Exception(_('Access denied!'));
}
$sysmapUpdate = json_decode($_REQUEST['sysmap'], true);
$sysmapUpdate['sysmapid'] = $sysmapid;
$sysmapUpdate['lines'] = [];
if (array_key_exists('selements', $sysmapUpdate)) {
foreach ($sysmapUpdate['selements'] as $element) {
if (!array_key_exists('tags', $element)) {
continue;
}
if (array_key_exists('elementtype', $element)
&& ($element['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST
|| $element['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST_GROUP)) {
foreach ($element['tags'] as $key => $tag) {
if ($tag['tag'] === '' && $tag['value'] === '') {
unset($element['tags'][$key]);
}
}
}
else {
unset($element['tags']);
}
}
}
if (array_key_exists('shapes', $sysmapUpdate)) {
foreach ($sysmapUpdate['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) {
$sysmapUpdate['lines'][$key] = CMapHelper::convertShapeToLine($shape);
unset($sysmapUpdate['shapes'][$key]);
}
}
unset($shape);
}
$result = API::Map()->update($sysmapUpdate);
if ($result !== false) {
$url = (new CUrl('sysmaps.php'))
->setArgument('page', CPagerHelper::loadPage('sysmaps.php', null))
->getUrl();
echo
'if (confirm('.json_encode(_('Map is updated! Return to map list?')).')) {'.
'location.href = "'.$url.'";'.
'}';
}
else {
throw new Exception(_('Map update failed.'));
}
DBend(true);
}
catch (Exception $e) {
DBend(false);
$msg = [$e->getMessage()];
foreach (get_and_clear_messages() as $errMsg) {
$msg[] = $errMsg['type'].': '.$errMsg['message'];
}
ob_clean();
echo 'alert('.zbx_jsvalue(implode("\r\n", $msg)).');';
}
@ob_flush();
session_write_close();
exit();
}
elseif (getRequest('action') === 'expand') {
$values = ['selements' => [], 'links' => [], 'shapes' => []];
$return = [];
$name = getRequest('name');
$sources = json_decode(getRequest('source'), true);
foreach ($sources as $num => $source) {
if (is_array($source) && (array_key_exists('label', $source) || array_key_exists('text', $source))) {
if (array_key_exists('inherited_label', $source) && $source['inherited_label'] !== null) {
$source['label'] = $source['inherited_label'];
}
if (array_key_exists('elementtype', $source) && array_key_exists('elements', $source)
&& is_array($source['elements']) && CMapHelper::checkSelementPermissions([$source])) {
$element_type = 'selements';
}
else {
$element_type = array_key_exists('label', $source) ? 'links' : 'shapes';
}
$values[$element_type][$num] = $source;
}
else {
$return[$num] = null;
}
}
$values['links'] = CMacrosResolverHelper::resolveMapLinkLabelMacros($values['links'], ['label' => 'label']);
$values['shapes'] = CMacrosResolverHelper::resolveMapShapeLabelMacros($name, $values['shapes'],
['text' => 'label']
);
if ($values['selements']) {
// Resolve macros in map element labels.
$values['selements'] = CMacrosResolverHelper::resolveMacrosInMapElements($values['selements'],
['resolve_element_label' => true]
);
}
foreach ($values['selements'] + $values['links'] + $values['shapes'] as $num => $value) {
$return[$num] = $value['label'];
}
ksort($return);
echo json_encode($return);
session_write_close();
exit();
}
}
}
if ($page['type'] != PAGE_TYPE_HTML) {
require_once dirname(__FILE__).'/include/page_footer.php';
}
/*
* Permissions
*/
if (isset($_REQUEST['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
]);
if (!$sysmap) {
access_deny();
}
else {
$sysmap = reset($sysmap);
}
}
/*
* Display
*/
$sysmap['links'] = CMacrosResolverHelper::resolveMapLinkLabelMacros($sysmap['links'], ['label' => 'expanded']);
$sysmap['shapes'] = CMacrosResolverHelper::resolveMapShapeLabelMacros($sysmap['name'], $sysmap['shapes'],
['text' => 'expanded']
);
$data = [
'sysmap' => $sysmap,
'iconList' => [],
'defaultAutoIconId' => null,
'defaultIconId' => null,
'defaultIconName' => null
];
// Apply inherited element label properties.
$data['sysmap'] = CMapHelper::applyMapElementLabelProperties($data['sysmap']);
// get selements
addElementNames($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');
// Extend $selement adding resolved label as property named 'expanded'.
$resolve_opt = ['resolve_element_label' => true];
$selements_resolved = CMacrosResolverHelper::resolveMacrosInMapElements($data['sysmap']['selements'], $resolve_opt);
// Set extended and restore original labels.
foreach ($data['sysmap']['selements'] as $selementid => &$selement) {
$selement['expanded'] = $selements_resolved[$selementid]['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'];
}
order_result($link['linktriggers'], 'desc_exp');
}
unset($link);
// get iconmapping
if ($data['sysmap']['iconmapid']) {
$iconMap = API::IconMap()->get([
'iconmapids' => $data['sysmap']['iconmapid'],
'output' => ['default_iconid'],
'preservekeys' => true
]);
$iconMap = reset($iconMap);
$data['defaultAutoIconId'] = $iconMap['default_iconid'];
}
$images = API::Image()->get([
'output' => ['imageid', 'name'],
'filter' => ['imagetype' => IMAGE_TYPE_ICON],
'select_image' => true
]);
foreach ($images as $image) {
$image['image'] = base64_decode($image['image']);
$ico = imagecreatefromstring($image['image']);
$data['iconList'][] = [
'imageid' => $image['imageid'],
'name' => $image['name'],
'width' => imagesx($ico),
'height' => imagesy($ico)
];
if ($image['name'] == MAP_DEFAULT_ICON || !isset($data['defaultIconId'])) {
$data['defaultIconId'] = $image['imageid'];
$data['defaultIconName'] = $image['name'];
}
}
if ($data['iconList']) {
CArrayHelper::sort($data['iconList'], ['name']);
$data['iconList'] = array_values($data['iconList']);
}
$data['theme'] = getUserGraphTheme();
// render view
echo (new CView('monitoring.sysmap.constructor', $data))->getOutput();
require_once dirname(__FILE__).'/include/page_footer.php';