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 * Validate import data from Zabbix 1.8.
24 */
25class C10XmlValidator extends CXmlValidatorGeneral {
26
27	/**
28	 * Base validation function.
29	 *
30	 * @param array  $data	import data
31	 * @param string $path	XML path (for error reporting)
32	 *
33	 * @return array		Validator does some manipulation for the incoming data. For example, converts empty tags to
34	 *						an array, if desired. Converted array is returned.
35	 */
36	public function validate(array $data, string $path) {
37		$rules = ['type' => XML_ARRAY, 'rules' => [
38			'version' =>				['type' => XML_STRING | XML_REQUIRED],
39			'date' =>					['type' => XML_STRING, 'ex_validate' => [$this, 'validateDate']],
40			'time' =>					['type' => XML_STRING, 'ex_validate' => [$this, 'validateTime']],
41			'hosts' =>					['type' => XML_INDEXED_ARRAY, 'prefix' => 'host', 'rules' => [
42				'host' =>					['type' => XML_ARRAY, 'rules' => [
43					'name' =>					['type' => XML_STRING | XML_REQUIRED],
44					'proxy_hostid' =>			['type' => XML_STRING],
45					'useip' =>					['type' => XML_STRING | XML_REQUIRED],
46					'dns' =>					['type' => XML_STRING | XML_REQUIRED],
47					'ip' =>						['type' => XML_STRING | XML_REQUIRED],
48					'port' =>					['type' => XML_STRING | XML_REQUIRED],
49					'status' =>					['type' => XML_STRING | XML_REQUIRED],
50					'useipmi' =>				['type' => XML_STRING],
51					'ipmi_ip' =>				['type' => XML_STRING],
52					'ipmi_port' =>				['type' => XML_STRING],
53					'ipmi_authtype' =>			['type' => XML_STRING],
54					'ipmi_privilege' =>			['type' => XML_STRING],
55					'ipmi_username' =>			['type' => XML_STRING],
56					'ipmi_password' =>			['type' => XML_STRING],
57					'groups' =>					['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'group', 'rules' => [
58						'group' =>					['type' => XML_STRING]
59					]],
60					'items' =>					['type' => XML_INDEXED_ARRAY, 'prefix' => 'item', 'rules' => [
61						'item' =>					['type' => XML_ARRAY, 'rules' => [
62							'type' =>					['type' => XML_STRING | XML_REQUIRED],
63							'key' =>					['type' => XML_STRING | XML_REQUIRED],
64							'value_type' =>				['type' => XML_STRING | XML_REQUIRED],
65							'description' =>			['type' => XML_STRING | XML_REQUIRED],
66							'ipmi_sensor' =>			['type' => XML_STRING | XML_REQUIRED],
67							'delay' =>					['type' => XML_STRING | XML_REQUIRED],
68							'history' =>				['type' => XML_STRING | XML_REQUIRED],
69							'trends' =>					['type' => XML_STRING | XML_REQUIRED],
70							'status' =>					['type' => XML_STRING | XML_REQUIRED],
71							'data_type' =>				['type' => XML_STRING | XML_REQUIRED],
72							'units' =>					['type' => XML_STRING | XML_REQUIRED],
73							'multiplier' =>				['type' => XML_STRING | XML_REQUIRED],
74							'delta' =>					['type' => XML_STRING | XML_REQUIRED],
75							'formula' =>				['type' => XML_STRING | XML_REQUIRED],
76							'lastlogsize' =>			['type' => XML_STRING | XML_REQUIRED],
77							'logtimefmt' =>				['type' => XML_STRING | XML_REQUIRED],
78							'delay_flex' =>				['type' => XML_STRING | XML_REQUIRED],
79							'authtype' =>				['type' => XML_STRING | XML_REQUIRED],
80							'username' =>				['type' => XML_STRING | XML_REQUIRED],
81							'password' =>				['type' => XML_STRING | XML_REQUIRED],
82							'publickey' =>				['type' => XML_STRING | XML_REQUIRED],
83							'privatekey' =>				['type' => XML_STRING | XML_REQUIRED],
84							'params' =>					['type' => XML_STRING | XML_REQUIRED],
85							'trapper_hosts' =>			['type' => XML_STRING | XML_REQUIRED],
86							'snmp_community' =>			['type' => XML_STRING | XML_REQUIRED],
87							'snmp_oid' =>				['type' => XML_STRING | XML_REQUIRED],
88							'snmp_port' =>				['type' => XML_STRING | XML_REQUIRED],
89							'snmpv3_securityname' =>	['type' => XML_STRING | XML_REQUIRED],
90							'snmpv3_securitylevel' =>	['type' => XML_STRING | XML_REQUIRED],
91							'snmpv3_authpassphrase' =>	['type' => XML_STRING | XML_REQUIRED],
92							'snmpv3_privpassphrase' =>	['type' => XML_STRING | XML_REQUIRED],
93							'valuemapid' =>				['type' => XML_STRING],
94							'applications' =>			['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'application', 'rules' => [
95								'application' =>			['type' => XML_STRING]
96							]]
97						]]
98					]],
99					'triggers' =>				['type' => XML_INDEXED_ARRAY, 'prefix' => 'trigger', 'rules' => [
100						'trigger' =>				['type' => XML_ARRAY, 'rules' => [
101							'description' =>			['type' => XML_STRING | XML_REQUIRED],
102							'type' =>					['type' => XML_STRING | XML_REQUIRED],
103							'expression' =>				['type' => XML_STRING | XML_REQUIRED],
104							'url' =>					['type' => XML_STRING | XML_REQUIRED],
105							'status' =>					['type' => XML_STRING | XML_REQUIRED],
106							'priority' =>				['type' => XML_STRING | XML_REQUIRED],
107							'comments' =>				['type' => XML_STRING | XML_REQUIRED]
108						]]
109					]],
110					'templates' =>				['type' => XML_INDEXED_ARRAY, 'prefix' => 'template', 'rules' => [
111						'template' =>				['type' => XML_STRING]
112					]],
113					'graphs' =>					['type' => XML_INDEXED_ARRAY, 'prefix' => 'graph', 'rules' => [
114						'graph' =>					['type' => XML_ARRAY, 'rules' => [
115							'name' =>					['type' => XML_STRING | XML_REQUIRED],
116							'width' =>					['type' => XML_STRING | XML_REQUIRED],
117							'height' =>					['type' => XML_STRING | XML_REQUIRED],
118							// The tag 'ymin_type' should be validated before the 'ymin_item_key' because it is used in 'ex_validate' method.
119							'ymin_type' =>				['type' => XML_STRING | XML_REQUIRED],
120							'ymin_item_key' =>			['type' => XML_STRING | XML_REQUIRED, 'ex_validate' => [$this, 'validateYMinItem']],
121							// The tag 'ymax_type' should be validated before the 'ymax_item_key' because it is used in 'ex_validate' method.
122							'ymax_type' =>				['type' => XML_STRING | XML_REQUIRED],
123							'ymax_item_key' =>			['type' => XML_STRING | XML_REQUIRED, 'ex_validate' => [$this, 'validateYMaxItem']],
124							'show_work_period' =>		['type' => XML_STRING | XML_REQUIRED],
125							'show_triggers' =>			['type' => XML_STRING | XML_REQUIRED],
126							'graphtype' =>				['type' => XML_STRING | XML_REQUIRED],
127							'yaxismin' =>				['type' => XML_STRING | XML_REQUIRED],
128							'yaxismax' =>				['type' => XML_STRING | XML_REQUIRED],
129							'show_legend' =>			['type' => XML_STRING | XML_REQUIRED],
130							'show_3d' =>				['type' => XML_STRING | XML_REQUIRED],
131							'percent_left' =>			['type' => XML_STRING | XML_REQUIRED],
132							'percent_right' =>			['type' => XML_STRING | XML_REQUIRED],
133							'graph_elements' =>			['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'graph_element', 'rules' => [
134								'graph_element' =>			['type' => XML_ARRAY, 'rules' => [
135									'item' =>					['type' => XML_STRING | XML_REQUIRED, 'ex_validate' => [$this, 'validateGraphItem']],
136									'drawtype' =>				['type' => XML_STRING | XML_REQUIRED],
137									'sortorder' =>				['type' => XML_STRING | XML_REQUIRED],
138									'color' =>					['type' => XML_STRING | XML_REQUIRED],
139									'yaxisside' =>				['type' => XML_STRING | XML_REQUIRED],
140									'calc_fnc' =>				['type' => XML_STRING | XML_REQUIRED],
141									'type' =>					['type' => XML_STRING | XML_REQUIRED],
142									'periods_cnt' =>			['type' => XML_STRING | XML_REQUIRED]
143								]]
144							]]
145						]]
146					]],
147					'macros' =>					['type' => XML_INDEXED_ARRAY, 'prefix' => 'macro', 'rules' => [
148						'macro' =>					['type' => XML_ARRAY, 'rules' => [
149							'value' =>					['type' => XML_STRING | XML_REQUIRED],
150							'name' =>					['type' => XML_STRING | XML_REQUIRED]
151						]]
152					]],
153					'host_profile' =>			['type' => XML_ARRAY, 'rules' => [
154						'devicetype' =>				['type' => XML_STRING | XML_REQUIRED],
155						'name' =>					['type' => XML_STRING | XML_REQUIRED],
156						'os' =>						['type' => XML_STRING | XML_REQUIRED],
157						'serialno' =>				['type' => XML_STRING | XML_REQUIRED],
158						'tag' =>					['type' => XML_STRING | XML_REQUIRED],
159						'macaddress' =>				['type' => XML_STRING | XML_REQUIRED],
160						'hardware' =>				['type' => XML_STRING | XML_REQUIRED],
161						'software' =>				['type' => XML_STRING | XML_REQUIRED],
162						'contact' =>				['type' => XML_STRING | XML_REQUIRED],
163						'location' =>				['type' => XML_STRING | XML_REQUIRED],
164						'notes' =>					['type' => XML_STRING | XML_REQUIRED]
165					]],
166					'host_profiles_ext' =>		['type' => XML_ARRAY, 'rules' => [
167						'device_alias' =>			['type' => XML_STRING | XML_REQUIRED],
168						'device_type' =>			['type' => XML_STRING | XML_REQUIRED],
169						'device_chassis' =>			['type' => XML_STRING | XML_REQUIRED],
170						'device_os' =>				['type' => XML_STRING | XML_REQUIRED],
171						'device_os_short' =>		['type' => XML_STRING | XML_REQUIRED],
172						'device_hw_arch' =>			['type' => XML_STRING | XML_REQUIRED],
173						'device_serial' =>			['type' => XML_STRING | XML_REQUIRED],
174						'device_model' =>			['type' => XML_STRING | XML_REQUIRED],
175						'device_tag' =>				['type' => XML_STRING | XML_REQUIRED],
176						'device_vendor' =>			['type' => XML_STRING | XML_REQUIRED],
177						'device_contract' =>		['type' => XML_STRING | XML_REQUIRED],
178						'device_who' =>				['type' => XML_STRING | XML_REQUIRED],
179						'device_status' =>			['type' => XML_STRING | XML_REQUIRED],
180						'device_app_01' =>			['type' => XML_STRING | XML_REQUIRED],
181						'device_app_02' =>			['type' => XML_STRING | XML_REQUIRED],
182						'device_app_03' =>			['type' => XML_STRING | XML_REQUIRED],
183						'device_app_04' =>			['type' => XML_STRING | XML_REQUIRED],
184						'device_app_05' =>			['type' => XML_STRING | XML_REQUIRED],
185						'device_url_1' =>			['type' => XML_STRING | XML_REQUIRED],
186						'device_url_2' =>			['type' => XML_STRING | XML_REQUIRED],
187						'device_url_3' =>			['type' => XML_STRING | XML_REQUIRED],
188						'device_networks' =>		['type' => XML_STRING | XML_REQUIRED],
189						'device_notes' =>			['type' => XML_STRING | XML_REQUIRED],
190						'device_hardware' =>		['type' => XML_STRING | XML_REQUIRED],
191						'device_software' =>		['type' => XML_STRING | XML_REQUIRED],
192						'ip_subnet_mask' =>			['type' => XML_STRING | XML_REQUIRED],
193						'ip_router' =>				['type' => XML_STRING | XML_REQUIRED],
194						'ip_macaddress' =>			['type' => XML_STRING | XML_REQUIRED],
195						'oob_ip' =>					['type' => XML_STRING | XML_REQUIRED],
196						'oob_subnet_mask' =>		['type' => XML_STRING | XML_REQUIRED],
197						'oob_router' =>				['type' => XML_STRING | XML_REQUIRED],
198						'date_hw_buy' =>			['type' => XML_STRING | XML_REQUIRED],
199						'date_hw_install' =>		['type' => XML_STRING | XML_REQUIRED],
200						'date_hw_expiry' =>			['type' => XML_STRING | XML_REQUIRED],
201						'date_hw_decomm' =>			['type' => XML_STRING | XML_REQUIRED],
202						'site_street_1' =>			['type' => XML_STRING | XML_REQUIRED],
203						'site_street_2' =>			['type' => XML_STRING | XML_REQUIRED],
204						'site_street_3' =>			['type' => XML_STRING | XML_REQUIRED],
205						'site_city' =>				['type' => XML_STRING | XML_REQUIRED],
206						'site_state' =>				['type' => XML_STRING | XML_REQUIRED],
207						'site_country' =>			['type' => XML_STRING | XML_REQUIRED],
208						'site_zip' =>				['type' => XML_STRING | XML_REQUIRED],
209						'site_rack' =>				['type' => XML_STRING | XML_REQUIRED],
210						'site_notes' =>				['type' => XML_STRING | XML_REQUIRED],
211						'poc_1_name' =>				['type' => XML_STRING | XML_REQUIRED],
212						'poc_1_email' =>			['type' => XML_STRING | XML_REQUIRED],
213						'poc_1_phone_1' =>			['type' => XML_STRING | XML_REQUIRED],
214						'poc_1_phone_2' =>			['type' => XML_STRING | XML_REQUIRED],
215						'poc_1_cell' =>				['type' => XML_STRING | XML_REQUIRED],
216						'poc_1_screen' =>			['type' => XML_STRING | XML_REQUIRED],
217						'poc_1_notes' =>			['type' => XML_STRING | XML_REQUIRED],
218						'poc_2_name' =>				['type' => XML_STRING | XML_REQUIRED],
219						'poc_2_email' =>			['type' => XML_STRING | XML_REQUIRED],
220						'poc_2_phone_1' =>			['type' => XML_STRING | XML_REQUIRED],
221						'poc_2_phone_2' =>			['type' => XML_STRING | XML_REQUIRED],
222						'poc_2_cell' =>				['type' => XML_STRING | XML_REQUIRED],
223						'poc_2_screen' =>			['type' => XML_STRING | XML_REQUIRED],
224						'poc_2_notes' =>			['type' => XML_STRING | XML_REQUIRED]
225					]]
226				]]
227			]],
228			'dependencies' =>			['type' => XML_INDEXED_ARRAY, 'prefix' => 'dependency', 'rules' => [
229				'dependency' =>				['type' => XML_INDEXED_ARRAY, 'prefix' => 'depends', 'extra' => 'description', 'rules' => [
230					'depends' =>				['type' => XML_STRING],
231					'description' =>			['type' => XML_STRING | XML_REQUIRED]
232				]]
233			]],
234			'sysmaps' =>				['type' => XML_INDEXED_ARRAY, 'prefix' => 'sysmap', 'rules' => [
235				'sysmap' =>					['type' => XML_ARRAY, 'rules' => [
236					'selements' =>				['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'selement', 'rules' => [
237						'selement' =>				['type' => XML_ARRAY, 'rules' => [
238							'selementid' =>				['type' => XML_STRING | XML_REQUIRED],
239							// The tag 'elementtype' should be validated before the 'elementid' because it is used in 'ex_required' and 'ex_validate' methods.
240							'elementtype' =>			['type' => XML_STRING | XML_REQUIRED],
241							'elementid' =>				['type' => 0, 'ex_required' => [$this, 'requiredMapElement'], 'ex_validate' => [$this, 'validateMapElement']],
242							'iconid_on' =>				['type' => XML_ARRAY, 'rules' => [
243								'name' =>					['type' => XML_STRING | XML_REQUIRED]
244							]],
245							'iconid_off' =>				['type' => XML_ARRAY | XML_REQUIRED, 'rules' => [
246								'name' =>					['type' => XML_STRING | XML_REQUIRED]
247							]],
248							'iconid_unknown' =>			['type' => XML_ARRAY, 'rules' => [
249								'name' =>					['type' => XML_STRING | XML_REQUIRED]
250							]],
251							'iconid_disabled' =>		['type' => XML_ARRAY, 'rules' => [
252								'name' =>					['type' => XML_STRING | XML_REQUIRED]
253							]],
254							'iconid_maintenance' =>		['type' => XML_ARRAY, 'rules' => [
255								'name' =>					['type' => XML_STRING | XML_REQUIRED]
256							]],
257							'label' =>					['type' => XML_STRING | XML_REQUIRED],
258							'label_location' =>			['type' => XML_STRING],
259							'x' =>						['type' => XML_STRING | XML_REQUIRED],
260							'y' =>						['type' => XML_STRING | XML_REQUIRED],
261							'url' =>					['type' => XML_STRING]
262						]]
263					]],
264					'links' =>					['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'link', 'rules' => [
265						'link' =>					['type' => XML_ARRAY, 'rules' => [
266							'selementid1' =>			['type' => XML_STRING | XML_REQUIRED],
267							'selementid2' =>			['type' => XML_STRING | XML_REQUIRED],
268							'drawtype' =>				['type' => XML_STRING | XML_REQUIRED],
269							'color' =>					['type' => XML_STRING | XML_REQUIRED],
270							'label' =>					['type' => XML_STRING],
271							'linktriggers' =>			['type' => XML_INDEXED_ARRAY, 'prefix' => 'linktrigger', 'rules' => [
272								'linktrigger' =>			['type' => XML_ARRAY, 'rules' => [
273									'drawtype' =>				['type' => XML_STRING | XML_REQUIRED],
274									'color' =>					['type' => XML_STRING | XML_REQUIRED],
275									'triggerid' =>				['type' => XML_ARRAY | XML_REQUIRED, 'rules' => [
276										'host' =>					['type' => XML_STRING],
277										'description' =>			['type' => XML_STRING | XML_REQUIRED],
278										'expression' =>				['type' => XML_STRING | XML_REQUIRED]
279									]]
280								]]
281							]]
282						]]
283					]],
284					'name' =>					['type' => XML_STRING | XML_REQUIRED],
285					'width' =>					['type' => XML_STRING | XML_REQUIRED],
286					'height' =>					['type' => XML_STRING | XML_REQUIRED],
287					'backgroundid' =>			['type' => XML_ARRAY, 'rules' => [
288						'name' =>					['type' => XML_STRING | XML_REQUIRED]
289					]],
290					'label_type' =>				['type' => XML_STRING | XML_REQUIRED],
291					'label_location' =>			['type' => XML_STRING | XML_REQUIRED],
292					'highlight' =>				['type' => XML_STRING | XML_REQUIRED],
293					'expandproblem' =>			['type' => XML_STRING | XML_REQUIRED],
294					'markelements' =>			['type' => XML_STRING | XML_REQUIRED],
295					'show_unack' =>				['type' => XML_STRING | XML_REQUIRED]
296				]]
297			]],
298			'screens' =>				['type' => XML_INDEXED_ARRAY, 'prefix' => 'screen', 'rules' => [
299				'screen' =>					['type' => XML_ARRAY, 'rules' => [
300					'name' =>					['type' => XML_STRING | XML_REQUIRED],
301					'hsize' =>					['type' => XML_STRING | XML_REQUIRED],
302					'vsize' =>					['type' => XML_STRING | XML_REQUIRED],
303					'screenitems' =>			['type' => XML_INDEXED_ARRAY | XML_REQUIRED, 'prefix' => 'screenitem', 'rules' => [
304						'screenitem' =>				['type' => XML_ARRAY, 'rules' => [
305							'resourcetype' =>			['type' => XML_STRING | XML_REQUIRED],
306							'resourceid' =>				['type' => XML_REQUIRED],
307							'width' =>					['type' => XML_STRING | XML_REQUIRED],
308							'height' =>					['type' => XML_STRING | XML_REQUIRED],
309							'x' =>						['type' => XML_STRING | XML_REQUIRED],
310							'y' =>						['type' => XML_STRING | XML_REQUIRED],
311							'colspan' =>				['type' => XML_STRING | XML_REQUIRED],
312							'rowspan' =>				['type' => XML_STRING | XML_REQUIRED],
313							'elements' =>				['type' => XML_STRING | XML_REQUIRED],
314							'valign' =>					['type' => XML_STRING | XML_REQUIRED],
315							'halign' =>					['type' => XML_STRING | XML_REQUIRED],
316							'style' =>					['type' => XML_STRING | XML_REQUIRED],
317							'dynamic' =>				['type' => XML_STRING | XML_REQUIRED],
318							'url' =>					['type' => XML_STRING]
319						]]
320					]]
321				]]
322			]],
323			'images' =>					['type' => XML_INDEXED_ARRAY, 'prefix' => 'image', 'rules' => [
324				'image' =>					['type' => XML_ARRAY, 'rules' => [
325					'name' =>					['type' => XML_STRING | XML_REQUIRED],
326					'imagetype' =>				['type' => XML_STRING | XML_REQUIRED],
327					'encodedImage' =>			['type' => XML_STRING | XML_REQUIRED]
328				]]
329			]]
330		]];
331
332		return $this->doValidate($rules, $data, $path);
333	}
334
335	/**
336	 * Validate date format.
337	 *
338	 * @param string $data			import data
339	 * @param array  $parent_data	data's parent array
340	 * @param string $path			XML path
341	 *
342	 * @throws Exception			if the date is invalid
343	 */
344	public function validateDate($data, array $parent_data = null, $path) {
345		if (!preg_match('/^(0[1-9]|[1-2][0-9]|3[01])\.(0[1-9]|1[0-2])\.[0-9]{2}$/', $data)) {
346			throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _s('"%1$s" is expected', _x('DD.MM.YY', 'XML date format'))));
347		}
348
349		return $data;
350	}
351
352	/**
353	 * Validate time format.
354	 *
355	 * @param string $data			import data
356	 * @param array  $parent_data	data's parent array
357	 * @param string $path			XML path
358	 *
359	 * @throws Exception			if the time is invalid
360	 */
361	public function validateTime($data, array $parent_data = null, $path) {
362		if (!preg_match('/^(2[0-3]|[01][0-9])\.[0-5][0-9]$/', $data)) {
363			throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _s('"%1$s" is expected', _x('hh.mm', 'XML time format'))));
364		}
365
366		return $data;
367	}
368
369	/**
370	 * Validate Y Axis value.
371	 *
372	 * @param string $data			import data
373	 * @param array  $parent_data	data's parent array
374	 * @param string $path			XML path
375	 *
376	 * @throws Exception			if tag is invalid
377	 */
378	public function validateYMinItem($data, array $parent_data = null, $path) {
379		if (zbx_is_int($parent_data['ymin_type']) && $parent_data['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
380			if (strpos($data, ':') === false) {
381				throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _('"host:key" pair is expected')));
382			}
383		}
384		elseif ($data !== '') {
385			throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _('an empty string is expected')));
386		}
387
388		return $data;
389	}
390
391	/**
392	 * Validate Y Axis value.
393	 *
394	 * @param string $data			import data
395	 * @param array  $parent_data	data's parent array
396	 * @param string $path			XML path
397	 *
398	 * @throws Exception			if tag is invalid
399	 */
400	public function validateYMaxItem($data, array $parent_data = null, $path) {
401		if (zbx_is_int($parent_data['ymax_type']) && $parent_data['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
402			if (strpos($data, ':') === false) {
403				throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _('"host:key" pair is expected')));
404			}
405		}
406		elseif ($data !== '') {
407			throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _('an empty string is expected')));
408		}
409
410		return $data;
411	}
412
413	/**
414	 * Validate graph item.
415	 *
416	 * @param string $data			import data
417	 * @param array  $parent_data	data's parent array
418	 * @param string $path			XML path
419	 *
420	 * @throws Exception			if tag is invalid
421	 */
422	public function validateGraphItem($data, array $parent_data = null, $path) {
423		if (strpos($data, ':') === false) {
424			throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _('"host:key" pair is expected')));
425		}
426
427		return $data;
428	}
429
430	/**
431	 * Checking the map element for requirement.
432	 *
433	 * @param array  $parent_data	data's parent array
434	 *
435	 * @throws Exception			if the check is failed
436	 */
437	public function requiredMapElement(array $parent_data = null) {
438		if (zbx_is_int($parent_data['elementtype'])) {
439			switch ($parent_data['elementtype']) {
440				case SYSMAP_ELEMENT_TYPE_HOST:
441				case SYSMAP_ELEMENT_TYPE_MAP:
442				case SYSMAP_ELEMENT_TYPE_TRIGGER:
443				case SYSMAP_ELEMENT_TYPE_HOST_GROUP:
444					return true;
445			}
446		}
447
448		return false;
449	}
450
451	/**
452	 * Validate map element.
453	 *
454	 * @param string $data			import data
455	 * @param array  $parent_data	data's parent array
456	 * @param string $path			XML path
457	 *
458	 * @throws Exception			if the map element is invalid
459	 */
460	public function validateMapElement($data, array $parent_data = null, $path) {
461		if (zbx_is_int($parent_data['elementtype'])) {
462			switch ($parent_data['elementtype']) {
463				case SYSMAP_ELEMENT_TYPE_HOST:
464					$rules = ['type' => XML_ARRAY, 'rules' => [
465						'host' =>			['type' => XML_STRING | XML_REQUIRED]
466					]];
467					break;
468
469				case SYSMAP_ELEMENT_TYPE_MAP:
470					$rules = ['type' => XML_ARRAY, 'rules' => [
471						'name' =>			['type' => XML_STRING | XML_REQUIRED]
472					]];
473					break;
474
475				case SYSMAP_ELEMENT_TYPE_TRIGGER:
476					$rules = ['type' => XML_ARRAY, 'rules' => [
477						'host' =>			['type' => XML_STRING],
478						'description' =>	['type' => XML_STRING | XML_REQUIRED],
479						'expression' =>		['type' => XML_STRING | XML_REQUIRED]
480					]];
481					break;
482
483				case SYSMAP_ELEMENT_TYPE_HOST_GROUP:
484					$rules = ['type' => XML_ARRAY, 'rules' => [
485						'name' =>			['type' => XML_STRING | XML_REQUIRED]
486					]];
487					break;
488
489				default:
490					return $data;
491			}
492
493			$data = $this->doValidate($rules, $data, $path);
494		}
495
496		return $data;
497	}
498}
499