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/maps.inc.php'; 24require_once dirname(__FILE__).'/include/ident.inc.php'; 25require_once dirname(__FILE__).'/include/forms.inc.php'; 26 27$page['title'] = _('Configuration of network maps'); 28$page['file'] = 'sysmaps.php'; 29$page['type'] = detect_page_type(PAGE_TYPE_HTML); 30$page['scripts'] = ['multiselect.js']; 31 32require_once dirname(__FILE__).'/include/page_header.php'; 33 34// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 35$fields = [ 36 'maps' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 37 'sysmapid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, 38 'isset({form}) && ({form} === "update" || {form} === "full_clone")' 39 ], 40 'name' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', _('Name')], 41 'width' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 65535), 'isset({add}) || isset({update})', _('Width')], 42 'height' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 65535), 'isset({add}) || isset({update})', _('Height')], 43 'backgroundid' => [T_ZBX_INT, O_OPT, null, DB_ID, 'isset({add}) || isset({update})'], 44 'iconmapid' => [T_ZBX_INT, O_OPT, null, DB_ID, 'isset({add}) || isset({update})'], 45 'expandproblem' => [T_ZBX_INT, O_OPT, null, 46 IN([SYSMAP_PROBLEMS_NUMBER, SYSMAP_SINGLE_PROBLEM, SYSMAP_PROBLEMS_NUMBER_CRITICAL]), null 47 ], 48 'markelements' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 1), null], 49 'show_unack' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 2), null], 50 'highlight' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 1), null], 51 'label_format' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 1), null], 52 'label_type_host' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL, MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 53 'label_type_hostgroup' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL, MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 54 'label_type_trigger' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL, MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 55 'label_type_map' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL, MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 56 'label_type_image' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL, MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 57 'label_string_host' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 58 'label_string_hostgroup' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 59 'label_string_trigger' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 60 'label_string_map' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 61 'label_string_image' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 62 'label_type' => [T_ZBX_INT, O_OPT, null, BETWEEN(MAP_LABEL_TYPE_LABEL,MAP_LABEL_TYPE_CUSTOM), 'isset({add}) || isset({update})'], 63 'label_location' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 3), 'isset({add}) || isset({update})'], 64 'urls' => [T_ZBX_STR, O_OPT, null, null, null], 65 'severity_min' => [T_ZBX_INT, O_OPT, null, IN('0,1,2,3,4,5'), null], 66 'show_suppressed' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 1), null], 67 'userid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 68 'private' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 1), null], 69 'users' => [T_ZBX_INT, O_OPT, null, null, null], 70 'userGroups' => [T_ZBX_INT, O_OPT, null, null, null], 71 // actions 72 'action' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, IN('"map.export","map.massdelete"'), null], 73 'add' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 74 'update' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 75 'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 76 'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 77 // form 78 'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 79 'form_refresh' => [T_ZBX_INT, O_OPT, null, null, null], 80 // filter 81 'filter_set' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 82 'filter_rst' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 83 'filter_name' => [T_ZBX_STR, O_OPT, null, null, null], 84 // sort and sortorder 85 'sort' => [T_ZBX_STR, O_OPT, P_SYS, IN('"height","name","width"'), null], 86 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null] 87]; 88check_fields($fields); 89 90/* 91 * Permissions 92 */ 93if (hasRequest('sysmapid')) { 94 $sysmap = API::Map()->get([ 95 'sysmapids' => getRequest('sysmapid'), 96 'editable' => true, 97 'output' => API_OUTPUT_EXTEND, 98 'selectUrls' => API_OUTPUT_EXTEND, 99 'selectUsers' => ['userid', 'permission'], 100 'selectUserGroups' => ['usrgrpid', 'permission'] 101 ]); 102 if (empty($sysmap)) { 103 access_deny(); 104 } 105 else { 106 $sysmap = reset($sysmap); 107 } 108} 109else { 110 $sysmap = []; 111} 112 113/* 114 * Actions 115 */ 116if (hasRequest('add') || hasRequest('update')) { 117 $map = [ 118 'name' => getRequest('name'), 119 'width' => getRequest('width'), 120 'height' => getRequest('height'), 121 'backgroundid' => getRequest('backgroundid'), 122 'iconmapid' => getRequest('iconmapid'), 123 'highlight' => getRequest('highlight', 0), 124 'markelements' => getRequest('markelements', 0), 125 'expandproblem' => getRequest('expandproblem', DB::getDefault('sysmaps', 'expandproblem')), 126 'label_format' => getRequest('label_format', 0), 127 'label_type_host' => getRequest('label_type_host', 2), 128 'label_type_hostgroup' => getRequest('label_type_hostgroup', 2), 129 'label_type_trigger' => getRequest('label_type_trigger', 2), 130 'label_type_map' => getRequest('label_type_map', 2), 131 'label_type_image' => getRequest('label_type_image', 2), 132 'label_string_host' => getRequest('label_string_host', ''), 133 'label_string_hostgroup' => getRequest('label_string_hostgroup', ''), 134 'label_string_trigger' => getRequest('label_string_trigger', ''), 135 'label_string_map' => getRequest('label_string_map', ''), 136 'label_string_image' => getRequest('label_string_image', ''), 137 'label_type' => getRequest('label_type'), 138 'label_location' => getRequest('label_location'), 139 'show_unack' => getRequest('show_unack', 0), 140 'severity_min' => getRequest('severity_min', TRIGGER_SEVERITY_NOT_CLASSIFIED), 141 'show_suppressed' => getRequest('show_suppressed', 0), 142 'urls' => getRequest('urls', []), 143 'userid' => getRequest('userid', ''), 144 'private' => getRequest('private', PRIVATE_SHARING), 145 'users' => getRequest('users', []), 146 'userGroups' => getRequest('userGroups', []) 147 ]; 148 149 foreach ($map['urls'] as $unum => $url) { 150 if (zbx_empty($url['name']) && zbx_empty($url['url'])) { 151 unset($map['urls'][$unum]); 152 } 153 } 154 155 DBstart(); 156 157 if (hasRequest('update')) { 158 // TODO check permission by new value. 159 $map['sysmapid'] = getRequest('sysmapid'); 160 161 // Only administrators can set map owner. 162 if (CWebUser::getType() == USER_TYPE_ZABBIX_USER) { 163 unset($map['userid']); 164 } 165 // Map update with inaccessible user. 166 elseif (CWebUser::getType() == USER_TYPE_ZABBIX_ADMIN && $map['userid'] === '') { 167 $user_exist = API::User()->get([ 168 'output' => ['userid'], 169 'userids' => [$sysmap['userid']] 170 ]); 171 172 if (!$user_exist) { 173 unset($map['userid']); 174 } 175 } 176 177 $result = API::Map()->update($map); 178 179 $messageSuccess = _('Network map updated'); 180 $messageFailed = _('Cannot update network map'); 181 $auditAction = AUDIT_ACTION_UPDATE; 182 } 183 else { 184 if (getRequest('form') === 'full_clone') { 185 $maps = API::Map()->get([ 186 'output' => [], 187 'selectSelements' => ['selementid', 'elements', 'elementtype', 'iconid_off', 'iconid_on', 'label', 188 'label_location', 'x', 'y', 'iconid_disabled', 'iconid_maintenance', 'elementsubtype', 'areatype', 189 'width', 'height', 'viewtype', 'use_iconmap', 'application', 'urls' 190 ], 191 'selectShapes' => ['type', 'x', 'y', 'width', 'height', 'text', 'font', 'font_size', 'font_color', 192 'text_halign', 'text_valign', 'border_type', 'border_width', 'border_color', 'background_color', 193 'zindex' 194 ], 195 'selectLines' => ['x1', 'y1', 'x2', 'y2', 'line_type', 'line_width', 'line_color', 'zindex'], 196 'selectLinks' => ['selementid1', 'selementid2', 'drawtype', 'color', 'label', 'linktriggers'], 197 'sysmapids' => $sysmap['sysmapid'] 198 ]); 199 200 if ($maps) { 201 $map['selements'] = $maps[0]['selements']; 202 $map['shapes'] = $maps[0]['shapes']; 203 $map['lines'] = $maps[0]['lines']; 204 $map['links'] = $maps[0]['links']; 205 } 206 } 207 208 $result = API::Map()->create($map); 209 210 $messageSuccess = _('Network map added'); 211 $messageFailed = _('Cannot add network map'); 212 $auditAction = AUDIT_ACTION_ADD; 213 } 214 215 if ($result) { 216 add_audit($auditAction, AUDIT_RESOURCE_MAP, 'Name ['.$map['name'].']'); 217 unset($_REQUEST['form']); 218 } 219 220 $result = DBend($result); 221 222 if ($result) { 223 uncheckTableRows(); 224 } 225 show_messages($result, $messageSuccess, $messageFailed); 226} 227elseif ((hasRequest('delete') && hasRequest('sysmapid')) || (hasRequest('action') && getRequest('action') == 'map.massdelete')) { 228 $sysmapIds = getRequest('maps', []); 229 230 if (hasRequest('sysmapid')) { 231 $sysmapIds[] = getRequest('sysmapid'); 232 } 233 234 DBstart(); 235 236 $maps = API::Map()->get([ 237 'sysmapids' => $sysmapIds, 238 'output' => ['sysmapid', 'name'], 239 'editable' => true 240 ]); 241 $result = API::Map()->delete($sysmapIds); 242 243 if ($result) { 244 unset($_REQUEST['form']); 245 246 foreach ($maps as $map) { 247 add_audit_ext(AUDIT_ACTION_DELETE, AUDIT_RESOURCE_MAP, $map['sysmapid'], $map['name'], null, null, null); 248 } 249 } 250 251 $result = DBend($result); 252 253 if ($result) { 254 uncheckTableRows(); 255 } 256 else { 257 uncheckTableRows(null, zbx_objectValues($maps, 'sysmapid')); 258 } 259 show_messages($result, _('Network map deleted'), _('Cannot delete network map')); 260} 261 262/* 263 * Display 264 */ 265if (hasRequest('form')) { 266 $current_userid = CWebUser::$data['userid']; 267 $userids[$current_userid] = $current_userid; 268 $user_groupids = []; 269 270 if (!hasRequest('sysmapid') || hasRequest('form_refresh')) { 271 // Map owner 272 $map_owner = getRequest('userid', $current_userid); 273 $userids[$map_owner] = $map_owner; 274 275 foreach (getRequest('users', []) as $user) { 276 $userids[$user['userid']] = $user['userid']; 277 } 278 279 foreach (getRequest('userGroups', []) as $user_group) { 280 $user_groupids[$user_group['usrgrpid']] = $user_group['usrgrpid']; 281 } 282 } 283 else { 284 // Map owner. 285 $userids[$sysmap['userid']] = $sysmap['userid']; 286 287 foreach ($sysmap['users'] as $user) { 288 $userids[$user['userid']] = $user['userid']; 289 } 290 291 foreach ($sysmap['userGroups'] as $user_group) { 292 $user_groupids[$user_group['usrgrpid']] = $user_group['usrgrpid']; 293 } 294 } 295 296 $data['users'] = API::User()->get([ 297 'output' => ['userid', 'alias', 'name', 'surname'], 298 'userids' => $userids, 299 'preservekeys' => true 300 ]); 301 302 $data['user_groups'] = API::UserGroup()->get([ 303 'output' => ['usrgrpid', 'name'], 304 'usrgrpids' => $user_groupids, 305 'preservekeys' => true 306 ]); 307 308 if (!hasRequest('sysmapid') || hasRequest('form_refresh')) { 309 $data['sysmap'] = [ 310 'sysmapid' => getRequest('sysmapid'), 311 'name' => getRequest('name', ''), 312 'width' => getRequest('width', 800), 313 'height' => getRequest('height', 600), 314 'backgroundid' => getRequest('backgroundid', 0), 315 'iconmapid' => getRequest('iconmapid', 0), 316 'label_format' => getRequest('label_format', 0), 317 'label_type_host' => getRequest('label_type_host', 2), 318 'label_type_hostgroup' => getRequest('label_type_hostgroup', 2), 319 'label_type_trigger' => getRequest('label_type_trigger', 2), 320 'label_type_map' => getRequest('label_type_map', 2), 321 'label_type_image' => getRequest('label_type_image', 2), 322 'label_string_host' => getRequest('label_string_host', ''), 323 'label_string_hostgroup' => getRequest('label_string_hostgroup', ''), 324 'label_string_trigger' => getRequest('label_string_trigger', ''), 325 'label_string_map' => getRequest('label_string_map', ''), 326 'label_string_image' => getRequest('label_string_image', ''), 327 'label_type' => getRequest('label_type', 0), 328 'label_location' => getRequest('label_location', 0), 329 'highlight' => getRequest('highlight', 0), 330 'markelements' => getRequest('markelements', 0), 331 'expandproblem' => getRequest('expandproblem', DB::getDefault('sysmaps', 'expandproblem')), 332 'show_unack' => getRequest('show_unack', 0), 333 'severity_min' => getRequest('severity_min', TRIGGER_SEVERITY_NOT_CLASSIFIED), 334 'show_suppressed' => getRequest('show_suppressed', 0), 335 'urls' => getRequest('urls', []), 336 'userid' => getRequest('userid', hasRequest('form_refresh') ? '' : $current_userid), 337 'private' => getRequest('private', PRIVATE_SHARING), 338 'users' => getRequest('users', []), 339 'userGroups' => getRequest('userGroups', []) 340 ]; 341 } 342 else { 343 $data['sysmap'] = $sysmap; 344 } 345 346 $data['current_user_userid'] = $current_userid; 347 $data['form_refresh'] = getRequest('form_refresh'); 348 349 // config 350 $data['config'] = select_config(); 351 352 // advanced labels 353 $data['labelTypes'] = sysmapElementLabel(); 354 $data['labelTypesLimited'] = $data['labelTypes']; 355 unset($data['labelTypesLimited'][MAP_LABEL_TYPE_IP]); 356 $data['labelTypesImage'] = $data['labelTypesLimited']; 357 unset($data['labelTypesImage'][MAP_LABEL_TYPE_STATUS]); 358 359 // images 360 $data['images'] = API::Image()->get([ 361 'output' => ['imageid', 'name'], 362 'filter' => ['imagetype' => IMAGE_TYPE_BACKGROUND] 363 ]); 364 order_result($data['images'], 'name'); 365 366 // icon maps 367 $data['iconMaps'] = API::IconMap()->get([ 368 'output' => ['iconmapid', 'name'], 369 'preservekeys' => true 370 ]); 371 order_result($data['iconMaps'], 'name'); 372 373 // render view 374 echo (new CView('monitoring.sysmap.edit', $data))->getOutput(); 375} 376else { 377 CProfile::delete('web.maps.sysmapid'); 378 379 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 380 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 381 382 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 383 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 384 385 if (hasRequest('filter_set')) { 386 CProfile::update('web.sysmapconf.filter_name', getRequest('filter_name', ''), PROFILE_TYPE_STR); 387 } 388 elseif (hasRequest('filter_rst')) { 389 DBStart(); 390 CProfile::delete('web.sysmapconf.filter_name'); 391 DBend(); 392 } 393 394 $config = select_config(); 395 396 $data = [ 397 'filter' => [ 398 'name' => CProfile::get('web.sysmapconf.filter_name', '') 399 ], 400 'sort' => $sortField, 401 'sortorder' => $sortOrder, 402 'profileIdx' => 'web.sysmapconf.filter', 403 'active_tab' => CProfile::get('web.sysmapconf.filter.active', 1) 404 ]; 405 406 // get maps 407 $data['maps'] = API::Map()->get([ 408 'output' => ['sysmapid', 'name', 'width', 'height'], 409 'sortfield' => $sortField, 410 'limit' => $config['search_limit'] + 1, 411 'search' => [ 412 'name' => ($data['filter']['name'] === '') ? null : $data['filter']['name'] 413 ], 414 'preservekeys' => true 415 ]); 416 417 order_result($data['maps'], $sortField, $sortOrder); 418 419 // pager 420 if (hasRequest('page')) { 421 $data['page'] = getRequest('page'); 422 } 423 elseif (isRequestMethod('get') && !hasRequest('cancel')) { 424 $data['page'] = 1; 425 } 426 else { 427 $data['page'] = CPagerHelper::loadPage($page['file']); 428 } 429 430 CPagerHelper::savePage($page['file'], $data['page']); 431 432 $data['paging'] = CPagerHelper::paginate($data['page'], $data['maps'], $sortOrder, new CUrl('sysmaps.php')); 433 434 if (CWebUser::getType() != USER_TYPE_SUPER_ADMIN) { 435 $editable_maps = API::Map()->get([ 436 'output' => [], 437 'sysmapids' => array_keys($data['maps']), 438 'editable' => true, 439 'preservekeys' => true 440 ]); 441 442 foreach ($data['maps'] as &$map) { 443 $map['editable'] = array_key_exists($map['sysmapid'], $editable_maps); 444 } 445 unset($map); 446 } 447 448 // render view 449 echo (new CView('monitoring.sysmap.list', $data))->getOutput(); 450} 451 452require_once dirname(__FILE__).'/include/page_footer.php'; 453