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 * NOTE - menu array format:
24 * first level:
25 *	'label' = main menu title.
26 *	'default_page_id	= default page url from 'pages' then opened menu.
27 *	'pages' = collection of pages which are displayed from this menu.
28 *	these pages are saved a last visited submenu of main menu.
29 *
30 * second level (pages):
31 *	'url' = real url for this page
32 *	'label' =  submenu title, if missing, menu skipped, but remembered as last visited page.
33 *	'sub_pages' = collection of pages for displaying but not remembered as last visited.
34 */
35function zbx_construct_menu(&$main_menu, &$sub_menus, &$page, $action = null) {
36	$zbx_menu = [
37		'view' => [
38			'label' => _('Monitoring'),
39			'user_type' => USER_TYPE_ZABBIX_USER,
40			'default_page_id' => 0,
41			'pages' => [
42				[
43					'url' => 'zabbix.php',
44					'action' => 'dashboard.view',
45					'active_if' => ['dashboard.list', 'dashboard.view'],
46					'label' => _('Dashboard')
47				],
48				[
49					'url' => 'zabbix.php',
50					'action' => 'problem.view',
51					'active_if' => ['problem.view', 'acknowledge.edit'],
52					'label' => _('Problems'),
53					'sub_pages' => ['tr_events.php']
54				],
55				[
56					'url' => 'overview.php',
57					'label' => _('Overview')
58				],
59				[
60					'url' => 'zabbix.php',
61					'action' => 'web.view',
62					'active_if' => ['web.view'],
63					'label' => _('Web'),
64					'sub_pages' => ['httpdetails.php']
65				],
66				[
67					'url' => 'latest.php',
68					'label' => _('Latest data'),
69					'sub_pages' => ['history.php', 'chart.php']
70				],
71				[
72					'url' => 'charts.php',
73					'label' => _('Graphs'),
74					'sub_pages' => ['chart2.php', 'chart3.php', 'chart6.php', 'chart7.php']
75				],
76				[
77					'url' => 'screens.php',
78					'label' => _('Screens'),
79					'sub_pages' => [
80						'screenconf.php',
81						'screenedit.php',
82						'screen.import.php',
83						'slides.php',
84						'slideconf.php'
85					]
86				],
87				[
88					'url' => 'zabbix.php',
89					'action' => 'map.view',
90					'active_if' => ['map.view'],
91					'label' => _('Maps'),
92					'sub_pages' => ['image.php', 'sysmaps.php', 'sysmap.php', 'map.php', 'map.import.php']
93				],
94				[
95					'url' => 'zabbix.php',
96					'action' => 'discovery.view',
97					'active_if' => ['discovery.view'],
98					'label' => _('Discovery'),
99					'user_type' => USER_TYPE_ZABBIX_ADMIN
100				],
101				[
102					'url' => 'srv_status.php',
103					'active_if' => ['report.services'],
104					'label' => _('Services'),
105					'sub_pages' => ['chart5.php']
106				],
107				[
108					'url' => 'chart3.php'
109				],
110				[
111					'url' => 'imgstore.php'
112				],
113				[
114					'url' => 'search.php'
115				],
116				[
117					'url' => 'jsrpc.php'
118				]
119			]
120		],
121		'cm' => [
122			'label' => _('Inventory'),
123			'user_type' => USER_TYPE_ZABBIX_USER,
124			'default_page_id' => 0,
125			'pages' => [
126				[
127					'url' => 'hostinventoriesoverview.php',
128					'label' => _('Overview')
129				],
130				[
131					'url' => 'hostinventories.php',
132					'label' => _('Hosts')
133				]
134			]
135		],
136		'reports' => [
137			'label' => _('Reports'),
138			'user_type' => USER_TYPE_ZABBIX_USER,
139			'default_page_id' => 0,
140			'pages' => [
141				[
142					'url' => 'zabbix.php',
143					'action' => 'report.status',
144					'active_if' => ['report.status'],
145					'label' => _('System information'),
146					'user_type' => USER_TYPE_SUPER_ADMIN
147				],
148				[
149					'url' => 'report2.php',
150					'label' => _('Availability report'),
151					'sub_pages' => ['chart4.php']
152				],
153				[
154					'url' => 'toptriggers.php',
155					'label' => _('Triggers top 100')
156				],
157				[
158					'url' => 'auditlogs.php',
159					'label' => _('Audit'),
160					'user_type' => USER_TYPE_SUPER_ADMIN
161				],
162				[
163					'url' => 'auditacts.php',
164					'label' => _('Action log'),
165					'user_type' => USER_TYPE_SUPER_ADMIN
166				],
167				[
168					'url' => 'report4.php',
169					'label' => _('Notifications'),
170					'user_type' => USER_TYPE_ZABBIX_ADMIN
171				]
172			]
173		],
174		'config' => [
175			'label' => _('Configuration'),
176			'user_type' => USER_TYPE_ZABBIX_ADMIN,
177			'default_page_id' => 0,
178			'pages' => [
179				[
180					'url' => 'conf.import.php'
181				],
182				[
183					'url' => 'hostgroups.php',
184					'label' => _('Host groups')
185				],
186				[
187					'url' => 'templates.php',
188					'label' => _('Templates'),
189					'sub_pages' => [
190						'screenconf.php',
191						'screenedit.php'
192					]
193				],
194				[
195					'url' => 'hosts.php',
196					'label' => _('Hosts'),
197					'sub_pages' => [
198						'items.php',
199						'triggers.php',
200						'graphs.php',
201						'applications.php',
202						'host_discovery.php',
203						'disc_prototypes.php',
204						'trigger_prototypes.php',
205						'host_prototypes.php',
206						'httpconf.php'
207					]
208				],
209				[
210					'url' => 'maintenance.php',
211					'label' => _('Maintenance')
212				],
213				[
214					'url' => 'actionconf.php',
215					'label' => _('Actions')
216				],
217				[
218					'user_type' => USER_TYPE_SUPER_ADMIN,
219					'url' => 'correlation.php',
220					'label' => _('Event correlation')
221				],
222				[
223					'url' => 'discoveryconf.php',
224					'label' => _('Discovery')
225				],
226				[
227					'url' => 'services.php',
228					'label' => _('Services')
229				]
230			]
231		],
232		'admin' => [
233			'label' => _('Administration'),
234			'user_type' => USER_TYPE_SUPER_ADMIN,
235			'default_page_id' => 0,
236			'pages' => [
237				[
238					'url' => 'adm.gui.php',
239					'label' => _('General'),
240					'sub_pages' => [
241						'adm.housekeeper.php',
242						'adm.images.php',
243						'adm.iconmapping.php',
244						'adm.regexps.php',
245						'adm.macros.php',
246						'adm.valuemapping.php',
247						'adm.workingtime.php',
248						'adm.triggerseverities.php',
249						'adm.triggerdisplayoptions.php',
250						'adm.other.php'
251					]
252				],
253				[
254					'url' => 'zabbix.php',
255					'action' => 'proxy.list',
256					'active_if' => ['proxy.edit', 'proxy.list'],
257					'label' => _('Proxies')
258				],
259				[
260					'url' => 'zabbix.php',
261					'action' => 'authentication.edit',
262					'active_if' => ['authentication.edit'],
263					'label' => _('Authentication')
264				],
265				[
266					'url' => 'usergrps.php',
267					'label' => _('User groups')
268				],
269				[
270					'url' => 'users.php',
271					'label' => _('Users')
272				],
273				[
274					'url' => 'zabbix.php',
275					'action' => 'mediatype.list',
276					'active_if' => ['mediatype.edit', 'mediatype.list'],
277					'label' => _('Media types')
278				],
279				[
280					'url' => 'zabbix.php',
281					'action' => 'script.list',
282					'active_if' => ['script.edit', 'script.list'],
283					'label' => _('Scripts')
284				],
285				[
286					'url' => 'queue.php',
287					'label' => _('Queue')
288				]
289			]
290		],
291		'login' => [
292			'label' => _('Login'),
293			'user_type' => 0,
294			'default_page_id' => 0,
295			'pages' => [
296				[
297					'url' => 'index.php',
298					'sub_pages' => ['profile.php']
299				]
300			]
301		]
302	];
303
304	$denied_page_requested = false;
305	$page_exists = false;
306	$deny = true;
307
308	foreach ($zbx_menu as $label => $menu) {
309		$show_menu = true;
310
311		if (isset($menu['user_type'])) {
312			$show_menu &= ($menu['user_type'] <= CWebUser::$data['type']);
313		}
314		if ($label == 'login') {
315			$show_menu = false;
316		}
317
318		$menu_class = null;
319		$sub_menus[$label] = [];
320
321		foreach ($menu['pages'] as $sub_page) {
322			$show_sub_menu = true;
323
324			// show check
325			if (!isset($sub_page['label'])) {
326				$show_sub_menu = false;
327			}
328			if (!isset($sub_page['user_type'])) {
329				$sub_page['user_type'] = $menu['user_type'];
330			}
331			if (CWebUser::$data['type'] < $sub_page['user_type']) {
332				$show_sub_menu = false;
333			}
334
335			$row = [
336				'menu_text' => array_key_exists('label', $sub_page) ? $sub_page['label'] : '',
337				'menu_url' => $sub_page['url'],
338				'menu_action' => array_key_exists('action', $sub_page) ? $sub_page['action'] : null,
339				'selected' => false
340			];
341
342			if ($action == null) {
343				$sub_menu_active = ($page['file'] == $sub_page['url']);
344
345				// Quick and dirty hack to display correct menu for templated screens.
346				if (array_key_exists('sub_pages', $sub_page)) {
347					if ((str_in_array('screenconf.php', $sub_page['sub_pages'])
348							|| str_in_array('screenedit.php', $sub_page['sub_pages']))
349								&& ($page['file'] === 'screenconf.php' || $page['file'] === 'screenedit.php')) {
350						if ($label === 'view') {
351							$sub_menu_active |= getRequest('templateid') ? false : true;
352						}
353						elseif ($label === 'config') {
354							$sub_menu_active |= getRequest('templateid') ? true : false;
355						}
356					}
357					elseif (str_in_array($page['file'], $sub_page['sub_pages'])) {
358						$sub_menu_active |= true;
359					}
360				}
361				else {
362					$sub_menu_active |= false;
363				}
364			}
365			else {
366				$sub_menu_active = array_key_exists('active_if', $sub_page) && str_in_array($action, $sub_page['active_if']);
367			}
368
369			if ($sub_menu_active) {
370				// permission check
371				$deny &= (CWebUser::$data['type'] < $menu['user_type'] || CWebUser::$data['type'] < $sub_page['user_type']);
372
373				$menu_class = 'selected';
374				$page_exists = true;
375				$page['menu'] = $label;
376				$row['selected'] = true;
377
378				if (!defined('ZBX_PAGE_NO_MENU')) {
379					CProfile::update('web.menu.'.$label.'.last', $sub_page['url'], PROFILE_TYPE_STR);
380				}
381			}
382
383			if ($show_sub_menu) {
384				$sub_menus[$label][] = $row;
385			}
386		}
387
388		if ($page_exists && $deny) {
389			$denied_page_requested = true;
390		}
391
392		if (!$show_menu) {
393			unset($sub_menus[$label]);
394			continue;
395		}
396
397		if ($sub_menus[$label][$menu['default_page_id']]['menu_action'] === null) {
398			$menu_url = $sub_menus[$label][$menu['default_page_id']]['menu_url'];
399		}
400		else {
401			$menu_url = $sub_menus[$label][$menu['default_page_id']]['menu_url'].'?action='.$sub_menus[$label][$menu['default_page_id']]['menu_action'];
402		}
403		$mmenu_entry = (new CListItem(
404			(new CLink($menu['label']))
405				->onClick('javascript: MMenu.mouseOver(\''.$label.'\');')
406				->onKeyup('javascript: MMenu.keyUp(\''.$label.'\', event);')
407				->setAttribute('tabindex', 0)
408		))
409			->addClass($menu_class)
410			->setId($label);
411
412		array_push($main_menu, $mmenu_entry);
413	}
414
415	if (!$page_exists) {
416		$denied_page_requested = true;
417	}
418
419	return $denied_page_requested;
420}
421