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
22class CMenuPopupHelper {
23
24	/**
25	 * Prepare data for favourite graphs menu popup.
26	 *
27	 * @return array
28	 */
29	public static function getFavouriteGraphs() {
30		$graphs = [];
31		$simple_graphs = [];
32
33		$favourites = CFavorite::get('web.favorite.graphids');
34
35		if ($favourites) {
36			$graphids = [];
37			$itemids = [];
38			$db_graphs = [];
39			$db_items = [];
40
41			foreach ($favourites as $favourite) {
42				if ($favourite['source'] === 'itemid') {
43					$itemids[$favourite['value']] = true;
44				}
45				else {
46					$graphids[$favourite['value']] = true;
47				}
48			}
49
50			if ($graphids) {
51				$db_graphs = API::Graph()->get([
52					'output' => ['graphid', 'name'],
53					'selectHosts' => ['hostid', 'name'],
54					'expandName' => true,
55					'graphids' => array_keys($graphids),
56					'preservekeys' => true
57				]);
58			}
59
60			if ($itemids) {
61				$db_items = API::Item()->get([
62					'output' => ['itemid', 'hostid', 'name', 'key_'],
63					'selectHosts' => ['hostid', 'name'],
64					'itemids' => array_keys($itemids),
65					'webitems' => true,
66					'preservekeys' => true
67				]);
68
69				$db_items = CMacrosResolverHelper::resolveItemNames($db_items);
70			}
71
72			foreach ($favourites as $favourite) {
73				$sourceid = $favourite['value'];
74
75				if ($favourite['source'] === 'itemid') {
76					if (array_key_exists($sourceid, $db_items)) {
77						$db_item = $db_items[$sourceid];
78
79						$simple_graphs[] = [
80							'id' => $sourceid,
81							'label' => $db_item['hosts'][0]['name'].NAME_DELIMITER.$db_item['name_expanded']
82						];
83					}
84				}
85				else {
86					if (array_key_exists($sourceid, $db_graphs)) {
87						$db_graph = $db_graphs[$sourceid];
88
89						$graphs[] = [
90							'id' => $sourceid,
91							'label' => $db_graph['hosts'][0]['name'].NAME_DELIMITER.$db_graph['name']
92						];
93					}
94				}
95			}
96		}
97
98		return [
99			'type' => 'favouriteGraphs',
100			'graphs' => $graphs,
101			'simpleGraphs' => $simple_graphs
102		];
103	}
104
105	/**
106	 * Prepare data for favourite maps menu popup.
107	 *
108	 * @return array
109	 */
110	public static function getFavouriteMaps() {
111		$maps = [];
112
113		$favourites = CFavorite::get('web.favorite.sysmapids');
114
115		if ($favourites) {
116			$mapids = [];
117
118			foreach ($favourites as $favourite) {
119				$mapids[$favourite['value']] = true;
120			}
121
122			$db_maps = API::Map()->get([
123				'output' => ['sysmapid', 'name'],
124				'sysmapids' => array_keys($mapids)
125			]);
126
127			foreach ($db_maps as $db_map) {
128				$maps[] = [
129					'id' => $db_map['sysmapid'],
130					'label' => $db_map['name']
131				];
132			}
133		}
134
135		return [
136			'type' => 'favouriteMaps',
137			'maps' => $maps
138		];
139	}
140
141	/**
142	 * Prepare data for favourite screens menu popup.
143	 *
144	 * @return array
145	 */
146	public static function getFavouriteScreens() {
147		$screens = $slideshows = [];
148
149		$favourites = CFavorite::get('web.favorite.screenids');
150
151		if ($favourites) {
152			$screenIds = $slideshowIds = [];
153
154			foreach ($favourites as $favourite) {
155				if ($favourite['source'] === 'screenid') {
156					$screenIds[$favourite['value']] = $favourite['value'];
157				}
158			}
159
160			$dbScreens = API::Screen()->get([
161				'output' => ['screenid', 'name'],
162				'screenids' => $screenIds,
163				'preservekeys' => true
164			]);
165
166			foreach ($favourites as $favourite) {
167				$sourceId = $favourite['value'];
168
169				if ($favourite['source'] === 'slideshowid') {
170					if (slideshow_accessible($sourceId, PERM_READ)) {
171						$dbSlideshow = get_slideshow_by_slideshowid($sourceId, PERM_READ);
172
173						if ($dbSlideshow) {
174							$slideshows[] = [
175								'id' => $dbSlideshow['slideshowid'],
176								'label' => $dbSlideshow['name']
177							];
178						}
179					}
180				}
181				else {
182					if (isset($dbScreens[$sourceId])) {
183						$dbScreen = $dbScreens[$sourceId];
184
185						$screens[] = [
186							'id' => $dbScreen['screenid'],
187							'label' => $dbScreen['name']
188						];
189					}
190				}
191			}
192		}
193
194		return [
195			'type' => 'favouriteScreens',
196			'screens' => $screens,
197			'slideshows' => $slideshows
198		];
199	}
200
201	/**
202	 * Prepare data for item history menu popup.
203	 *
204	 * @param array $item				item data
205	 * @param int   $item['itemid']		item id
206	 * @param int   $item['value_type']	item value type
207	 *
208	 * @return array
209	 */
210	public static function getHistory(array $item) {
211		return [
212			'type' => 'history',
213			'itemid' => $item['itemid'],
214			'hasLatestGraphs' => in_array($item['value_type'], [ITEM_VALUE_TYPE_UINT64, ITEM_VALUE_TYPE_FLOAT])
215		];
216	}
217
218	/**
219	 * Prepare data for host menu popup.
220	 *
221	 * @param array  $host						host data
222	 * @param string $host['hostid']			host id
223	 * @param string $host['status']			host status
224	 * @param array  $host['graphs']			host graphs
225	 * @param array  $host['screens']			host screens
226	 * @param array  $scripts					host scripts (optional)
227	 * @param string $scripts[]['name']			script name
228	 * @param string $scripts[]['scriptid']		script id
229	 * @param string $scripts[]['confirmation']	confirmation text
230	 * @param bool   $hasGoTo					"Go to" block in popup
231	 *
232	 * @return array
233	 */
234	public static function getHost(array $host, array $scripts = null, $hasGoTo = true) {
235		$data = [
236			'type' => 'host',
237			'hostid' => $host['hostid'],
238			'showGraphs' => (bool) $host['graphs'],
239			'showScreens' => (bool) $host['screens'],
240			'showTriggers' => ($host['status'] == HOST_STATUS_MONITORED),
241			'hasGoTo' => $hasGoTo
242		];
243
244		if ($scripts) {
245			foreach ($scripts as &$script) {
246				$script['name'] = implode('/', splitPath($script['name'], false, true));
247			}
248			unset($script);
249
250			CArrayHelper::sort($scripts, ['name']);
251
252			foreach (array_values($scripts) as $script) {
253				$data['scripts'][] = [
254					'name' => $script['name'],
255					'scriptid' => $script['scriptid'],
256					'confirmation' => $script['confirmation']
257				];
258			}
259		}
260
261		return $data;
262	}
263
264	/**
265	 * Prepare data for map menu popup.
266	 *
267	 * @param string $hostId					host id
268	 * @param array  $scripts					host scripts (optional)
269	 * @param string $scripts[]['name']			script name
270	 * @param string $scripts[]['scriptid']		script id
271	 * @param string $scripts[]['confirmation']	confirmation text
272	 * @param array  $gotos						goto links (optional)
273	 * @param array  $gotos['graphs']			link to host graphs page with url parameters ("name" => "value") (optional)
274	 * @param array  $gotos['screens']			link to host screen page with url parameters ("name" => "value") (optional)
275	 * @param array  $gotos['triggerStatus']	link to trigger status page with url parameters ("name" => "value") (optional)
276	 * @param array  $gotos['submap']			link to submap page with url parameters ("name" => "value") (optional)
277	 * @param array  $gotos['events']			link to events page with url parameters ("name" => "value") (optional)
278	 * @param array  $urls						local and global map urls (optional)
279	 * @param string $urls[]['name']			url name
280	 * @param string $urls[]['url']				url
281	 *
282	 * @return array
283	 */
284	public static function getMap($hostId, array $scripts = null, array $gotos = null, array $urls = null) {
285		$data = [
286			'type' => 'map'
287		];
288
289		if ($scripts) {
290			foreach ($scripts as &$script) {
291				$script['name'] = implode('/', splitPath($script['name'], false, true));
292			}
293			unset($script);
294			CArrayHelper::sort($scripts, ['name']);
295
296			$data['hostid'] = $hostId;
297
298			foreach (array_values($scripts) as $script) {
299				$data['scripts'][] = [
300					'name' => $script['name'],
301					'scriptid' => $script['scriptid'],
302					'confirmation' => $script['confirmation']
303				];
304			}
305		}
306
307		if ($gotos) {
308			$data['gotos'] = $gotos;
309		}
310
311		if ($urls) {
312			foreach ($urls as $url) {
313				$data['urls'][] = [
314					'label' => $url['name'],
315					'url' => $url['url']
316				];
317			}
318		}
319
320		return $data;
321	}
322
323	/**
324	 * Prepare data for refresh time menu popup.
325	 *
326	 * @param string $widgetName		widget name
327	 * @param string $currentRate		current rate value
328	 * @param bool   $multiplier		multiplier or time mode
329	 * @param array  $params			url parameters (optional)
330	 *
331	 * @return array
332	 */
333	public static function getRefresh($widgetName, $currentRate, $multiplier = false, array $params = []) {
334		return [
335			'type' => 'refresh',
336			'widgetName' => $widgetName,
337			'currentRate' => $currentRate,
338			'multiplier' => $multiplier,
339			'params' => $params
340		];
341	}
342
343	/**
344	 * Prepare data for trigger menu popup.
345	 *
346	 * @param array  $trigger							trigger data
347	 * @param string $trigger['triggerid']				trigger ID
348	 * @param int    $trigger['flags']					trigger flags (TRIGGER_FLAG_DISCOVERY*)
349	 * @param array  $trigger['hosts']					hosts, used by trigger expression
350	 * @param string $trigger['hosts'][]['hostid']		host ID
351	 * @param string $trigger['hosts'][]['name']		host name
352	 * @param string $trigger['hosts'][]['status']		host status
353	 * @param array  $trigger['items']					trigger items
354	 * @param string $trigger['items'][]['itemid']		item ID
355	 * @param string $trigger['items'][]['hostid']		host ID
356	 * @param string $trigger['items'][]['name']		item name
357	 * @param string $trigger['items'][]['key_']		item key
358	 * @param string $trigger['items'][]['value_type']	type of information of the item
359	 * @param string $trigger['url']					trigger URL
360	 * @param array  $acknowledge						acknowledge link parameters (optional)
361	 * @param string $acknowledge['eventid']			event ID
362	 * @param string $acknowledge['screenid']			screen ID (optional)
363	 * @param string $acknowledge['backurl']			return URL (optional)
364	 * @param string $eventTime							event navigation time parameter (optional)
365	 *
366	 * @return array
367	 */
368	public static function getTrigger(array $trigger, array $acknowledge = null, $eventTime = null) {
369		$hosts = [];
370		$showEvents = true;
371
372		foreach ($trigger['hosts'] as $host) {
373			$hosts[$host['hostid']] = $host['name'];
374
375			if ($host['status'] != HOST_STATUS_MONITORED) {
376				$showEvents = false;
377			}
378		}
379
380		$trigger['items'] = CMacrosResolverHelper::resolveItemNames($trigger['items']);
381
382		foreach ($trigger['items'] as &$item) {
383			$item['hostname'] = $hosts[$item['hostid']];
384		}
385		unset($item);
386
387		CArrayHelper::sort($trigger['items'], ['name', 'hostname', 'itemid']);
388
389		$hostCount = count($hosts);
390		$items = [];
391
392		foreach ($trigger['items'] as $item) {
393			$items[] = [
394				'name' => ($hostCount > 1)
395					? $hosts[$item['hostid']].NAME_DELIMITER.$item['name_expanded']
396					: $item['name_expanded'],
397				'params' => [
398					'itemid' => $item['itemid'],
399					'action' => in_array($item['value_type'], [ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64])
400						? HISTORY_GRAPH
401						: HISTORY_VALUES
402				]
403			];
404		}
405
406		$data = [
407			'type' => 'trigger',
408			'groupid' => $trigger['groupid'],
409			'hostid' => $trigger['hostid'],
410			'triggerid' => $trigger['triggerid'],
411			'items' => $items
412		];
413
414		if ($acknowledge !== null) {
415			$data['acknowledge'] = $acknowledge;
416		}
417
418		if ($eventTime !== null) {
419			$data['eventTime'] = $eventTime;
420		}
421
422		if ($trigger['url'] !== '') {
423			$data['url'] = CHtmlUrlValidator::validate($trigger['url'], false)
424				? $trigger['url']
425				: 'javascript: alert(\''._s('Provided URL "%1$s" is invalid.', zbx_jsvalue($trigger['url'], false,
426						false)).'\');';
427		}
428
429		if ($showEvents) {
430			$data['showEvents'] = true;
431		}
432		if (in_array(CWebUser::$data['type'], [USER_TYPE_ZABBIX_ADMIN, USER_TYPE_SUPER_ADMIN])
433				&& $trigger['flags'] == ZBX_FLAG_DISCOVERY_NORMAL) {
434			$data['configuration'] = true;
435		}
436
437		return $data;
438	}
439
440	/**
441	 * Prepare data for trigger log menu popup.
442	 *
443	 * @param string $itemId				item id
444	 * @param string $itemName				item name
445	 * @param array  $triggers				triggers (optional)
446	 * @param string $triggers[n]['id']		trigger id
447	 * @param string $triggers[n]['name']	trigger name
448	 *
449	 * @return array
450	 */
451	public static function getTriggerLog($itemId, $itemName, $triggers) {
452		return [
453			'type' => 'triggerLog',
454			'itemid' => $itemId,
455			'itemName' => $itemName,
456			'triggers' => $triggers
457		];
458	}
459
460	/**
461	 * Prepare data for trigger macro menu popup.
462	 *
463	 * @return array
464	 */
465	public static function getTriggerMacro() {
466		return [
467			'type' => 'triggerMacro'
468		];
469	}
470}
471