1<?php
2
3// Pandora FMS - http://pandorafms.com
4// ==================================================
5// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
6// Please see http://pandorafms.org for full contribution list
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the  GNU Lesser General Public License
10// as published by the Free Software Foundation; version 2
11
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17/**
18 * @package Include
19 * @subpackage TAGS
20 */
21
22 /**
23 * Find a tag searching by tag's or description name.
24 *
25 * @param string $tag_name_description Name or description of the tag that it's currently searched.
26 * @param array $filter Array with pagination parameters.
27 * @param bool $only_names Whether to return only names or all fields.
28 * @param bool $count To return the number of items.
29 *
30 * @return mixed Returns an array with the tag selected by name or false.
31 * When the count parameter is enabled, returns an integer.
32 */
33function tags_search_tag ($tag_name_description = false, $filter = false, $only_names = false, $count = false) {
34	global $config;
35
36	if ($filter === false)
37		$filter = array();
38
39	if (isset($filter['name'])) {
40		if (empty($tag_name_description))
41			$tag_name_description = $filter['name'];
42		unset($filter['name']);
43	}
44
45	if ($tag_name_description) {
46		switch ($config["dbtype"]) {
47			case "mysql":
48				$filter[] = '((name COLLATE utf8_general_ci LIKE "%'. $tag_name_description .'%") OR
49						(description COLLATE utf8_general_ci LIKE "%'. $tag_name_description .'%"))';
50				break;
51			case "postgresql":
52				$filter[] = '((name LIKE \'%'. $tag_name_description .'%\') OR
53						(description LIKE \'%'. $tag_name_description .'%\'))';
54				break;
55			case "oracle":
56				$filter[] = '(UPPER(name) LIKE UPPER (\'%'. $tag_name_description .'%\') OR
57						UPPER(dbms_lob.substr(description, 4000, 1)) LIKE UPPER (\'%'. $tag_name_description .'%\'))';
58				break;
59		}
60	}
61
62	// Default order
63	set_unless_defined($filter['order'], 'name');
64
65	$fields = '*';
66	if ($only_names) {
67		$fields = array('id_tag', 'name');
68	}
69
70	// It will return the count
71	if ($count) {
72		unset($filter['order']);
73		unset($filter['limit']);
74		unset($filter['offset']);
75
76		if (!empty($filter))
77			return (int) db_get_value_filter('COUNT(id_tag)', 'ttag', $filter);
78		else
79			return (int) db_get_value('COUNT(id_tag)', 'ttag');
80	}
81
82	$result = db_get_all_rows_filter('ttag', $filter, $fields);
83
84	if ($result === false)
85		$result = array();
86
87	if ($only_names) {
88		$result_tags = array();
89		foreach ($result as $tag) {
90			$result_tags[$tag['id_tag']] = $tag['name'];
91		}
92		$result = $result_tags;
93	}
94
95	return $result;
96}
97
98/**
99 * Create a new tag.
100 *
101 * @param array $values Array with all values to insert.
102 *
103 * @return mixed Tag id or false.
104 */
105function tags_create_tag($values) {
106	if (empty($values)) {
107		return false;
108	}
109
110	//No create tag if the tag exists
111	if (tags_get_id($values["name"])) {
112		return false;
113	}
114
115	return db_process_sql_insert('ttag',$values);
116}
117
118/**
119 * Search tag by id.
120 *
121 * @param array $id Int with tag id info.
122 *
123 * @return mixed Array with the seleted tag or false.
124 */
125function tags_search_tag_id($id) {
126	return db_get_row ('ttag', 'id_tag', $id);
127}
128
129/**
130 * Get tag name.
131 *
132 * @param array $id Int with tag id info.
133 *
134 * @return mixed String with tag name or false.
135 */
136function tags_get_name($id) {
137	return db_get_value_filter ('name', 'ttag', array('id_tag' => $id));
138}
139
140/**
141 * Get tag id given the tag name.
142 *
143 * @param string Tag name.
144 *
145 * @return int Tag id.
146 */
147function tags_get_id($name) {
148	return db_get_value_filter ('id_tag', 'ttag', array('name' => $name));
149}
150
151/**
152 * Get tag description.
153 *
154 * @param array $id Int with tag id info.
155 *
156 * @return mixed String with tag description or false.
157 */
158function tags_get_description($id) {
159	return db_get_value_filter('description', 'ttag', array('id_tag' => $id));
160}
161
162/**
163 * Get tag url.
164 *
165 * @param array $id Int with tag id info.
166 *
167 * @return mixed String with tag url or false.
168 */
169function tags_get_url($id) {
170	return db_get_value_filter('description', 'ttag', array('id_tag' => $id));
171}
172
173/**
174 * Get tag's module count.
175 *
176 * @param array $id Int with tag id info.
177 *
178 * @return int Tag's count.
179 */
180function tags_get_modules_count ($id) {
181	$num_modules = tags_get_local_modules_count($id);
182	$num_policy_modules = tags_get_policy_modules_count($id);
183
184	return $num_modules + $num_policy_modules;
185}
186
187/**
188 * Get tag's local module count.
189 *
190 * @param array $id Int with tag id info.
191 *
192 * @return int Local module tag's count.
193 */
194function tags_get_local_modules_count ($id) {
195	$field = 'COUNT(id_tag)';
196	$filter = array('id_tag' => $id);
197
198	$num_modules = (int) db_get_value_filter($field, 'ttag_module', $filter);
199
200	return $num_modules;
201}
202
203/**
204 * Get module tag's count.
205 *
206 * @param array $id Int with agent module id info.
207 *
208 * @return int Module tag's count.
209 */
210function tags_get_modules_tag_count ($id) {
211	$field = 'COUNT(id_agente_modulo)';
212	$filter = array('id_agente_modulo' => $id);
213
214	$num_modules = (int) db_get_value_filter($field, 'ttag_module', $filter);
215
216	return $num_modules;
217}
218
219/**
220 * Get tag's policy module count.
221 *
222 * @param array $id Int with tag id info.
223 *
224 * @return int Policy module tag's count.
225 */
226function tags_get_policy_modules_count ($id) {
227	$field = 'COUNT(id_tag)';
228	$filter = array('id_tag' => $id);
229
230	$num_policy_modules = (int) db_get_value_filter($field, 'ttag_policy_module', $filter);
231
232	return $num_policy_modules;
233}
234
235/**
236 * Updates a tag by id.
237 *
238 * @param array $id Int with tag id info.
239 * @param string $where Where clause to update record.
240 *
241 * @return bool True or false if something goes wrong.
242 */
243function tags_update_tag($values, $where) {
244	return db_process_sql_update ('ttag', $values, $where);
245}
246
247/**
248 * Delete a tag by id.
249 *
250 * @param array $id Int with tag id info.
251 *
252 * @return bool True or false if something goes wrong.
253 */
254function tags_delete_tag ($id_tag) {
255	$errn = 0;
256
257	$result_tag = db_process_delete_temp ('ttag', 'id_tag', $id_tag);
258	if ($result_tag === false)
259		$errn++;
260
261	$result_module = db_process_delete_temp ('ttag_module', 'id_tag', $id_tag);
262	if ($result_module === false)
263		$errn++;
264
265	$result_policy = db_process_delete_temp ('ttag_policy_module', 'id_tag', $id_tag);
266	if ($result_policy === false)
267		$errn++;
268
269	if ($errn == 0) {
270		return true;
271	}
272	else {
273		return false;
274	}
275
276}
277
278function tags_remove_tag($id_tag, $id_module) {
279	$result = (bool)db_process_sql_delete('ttag_module',
280		array('id_tag' => $id_tag,
281			'id_agente_modulo' => $id_module));
282
283	return $result;
284}
285
286/**
287 * Get tag's total count.
288 *
289 * @return mixed Int with the tag's count.
290 */
291function tags_get_tag_count($filter = false) {
292
293	$tag_name = false;
294	if (isset($filter['name'])) {
295		$tag_name = $filter['name'];
296		unset($filter['name']);
297	}
298
299	return tags_search_tag($tag_name, $filter, false, true);
300}
301
302/**
303 * Inserts tag's array of a module.
304 *
305 * @param int $id_agent_module Module's id.
306 * @param array $tags Array with tags to associate to the module.
307 *
308 * @return bool True or false if something goes wrong.
309 */
310function tags_insert_module_tag ($id_agent_module, $tags) {
311	$errn = 0;
312
313	$values = array();
314
315	if($tags == false) {
316		$tags = array();
317	}
318
319	foreach ($tags as $tag) {
320		//Protect against default insert
321		if (empty($tag))
322			continue;
323
324		$values['id_tag'] = $tag;
325		$values['id_agente_modulo'] = $id_agent_module;
326		$result_tag = db_process_sql_insert('ttag_module', $values);
327		if ($result_tag === false)
328			$errn++;
329	}
330
331	return $errn;
332}
333
334/**
335 * Inserts tag's array of a policy module.
336 *
337 * @param int $id_agent_module Policy module's id.
338 * @param array $tags Array with tags to associate to the module.
339 *
340 * @return bool True or false if something goes wrong.
341 */
342function tags_insert_policy_module_tag ($id_agent_module, $tags) {
343	$errn = 0;
344
345	$values = array();
346	foreach ($tags as $tag) {
347		//Protect against default insert
348		if (empty($tag))
349			continue;
350
351		$values['id_tag'] = $tag;
352		$values['id_policy_module'] = $id_agent_module;
353		$result_tag = db_process_sql_insert('ttag_policy_module', $values, false);
354		if ($result_tag === false)
355			$errn++;
356	}
357
358	if ($errn > 0) {
359		return false;
360	}
361	else {
362		return true;
363	}
364}
365
366/**
367 * Updates tag's array of a module.
368 *
369 * @param int $id_agent_module Module's id.
370 * @param array $tags Array with tags to associate to the module.
371 * @param bool $autocommit Whether to do automatical commit or not.
372 *
373 * @return bool True or false if something goes wrong.
374 */
375function tags_update_module_tag ($id_agent_module, $tags,
376	$autocommit = false, $update_policy_tags = true) {
377	$errn = 0;
378
379	if (empty($tags))
380		$tags = array();
381
382	if ($update_policy_tags) {
383		/* First delete module tag entries */
384		$result_tag = db_process_sql_delete('ttag_module',
385			array('id_agente_modulo' => $id_agent_module));
386	}
387	else {
388		$result_tag = db_process_sql_delete('ttag_module',
389			array('id_agente_modulo' => $id_agent_module,
390				'id_policy_module' => '0'));
391	}
392
393	$values = array();
394	foreach ($tags as $tag) {
395		//Protect against default insert
396		if (empty($tag))
397			continue;
398
399		$values['id_tag'] = $tag;
400		$values['id_agente_modulo'] = $id_agent_module;
401		$result_tag = db_process_sql_insert('ttag_module', $values, false);
402		if ($result_tag === false)
403			$errn++;
404	}
405
406}
407
408/**
409 * Updates tag's array of a policy module.
410 *
411 * @param int $id_policy_module Policy module's id.
412 * @param array $tags Array with tags to associate to the module.
413 * @param bool $autocommit Whether to do automatical commit or not.
414 *
415 * @return bool True or false if something goes wrong.
416 */
417function tags_update_policy_module_tag ($id_policy_module, $tags, $autocommit = false) {
418	$errn = 0;
419
420	if (empty($tags))
421		$tags = array();
422
423	/* First delete module tag entries */
424	$result_tag = db_process_sql_delete ('ttag_policy_module', array('id_policy_module' => $id_policy_module));
425
426	$values = array();
427	foreach ($tags as $tag) {
428		//Protect against default insert
429		if (empty($tag))
430			continue;
431
432		$values['id_tag'] = $tag;
433		$values['id_policy_module'] = $id_policy_module;
434		$result_tag = db_process_sql_insert('ttag_policy_module', $values, false);
435		if ($result_tag === false)
436			$errn++;
437	}
438
439}
440
441/**
442 * Select all tags of a module.
443 *
444 * @param int $id_agent_module Module's id.
445 *
446 * @return mixed Array with module tags or false if something goes wrong.
447 */
448function tags_get_module_tags ($id, $policy = false) {
449	if (empty($id))
450		return false;
451
452	if ($policy) {
453		$tags = db_get_all_rows_filter('ttag_policy_module',
454			array('id_policy_module' => $id), false);
455	}
456	else {
457		$tags = db_get_all_rows_filter('ttag_module',
458			array('id_agente_modulo' => $id), false);
459	}
460
461	if ($tags === false)
462		return array();
463
464	$return = array();
465	foreach ($tags as $tag) {
466		$return[] = $tag['id_tag'];
467	}
468
469	return $return;
470}
471
472/**
473 * Select all tags of a policy module.
474 *
475 * @param int $id_policy_module Policy module's id.
476 *
477 * @return mixed Array with module tags or false if something goes wrong.
478 */
479function tags_get_policy_module_tags ($id_policy_module) {
480	if (empty($id_policy_module))
481		return false;
482
483	$tags = db_get_all_rows_filter('ttag_policy_module',
484		array('id_policy_module' => $id_policy_module), false);
485
486	if ($tags === false)
487		return false;
488
489	$return = array();
490	foreach ($tags as $tag) {
491		$return[] = $tag['id_tag'];
492	}
493
494	return $return;
495}
496
497/**
498 * Select all tags.
499 *
500 * @return mixed Array with tags.
501 */
502function tags_get_all_tags ($return_url = false) {
503	$tags = db_get_all_fields_in_table('ttag', 'name', '', 'name');
504
505	if ($tags === false)
506		return false;
507
508	$return = array();
509	foreach ($tags as $tag) {
510		$return[$tag['id_tag']] = $tag['name'];
511		if ($return_url) {
512			$return[$tag['id_tag']] .= ' ' . $tag['url'];
513		}
514	}
515
516	return $return;
517}
518
519/**
520 * Get the tags required
521 *
522 * @return mixed Array with tags.
523 */
524function tags_get_tags ($ids) {
525	$all_tags = tags_get_all_tags(true);
526
527	$tags = array();
528	foreach ($ids as $id) {
529		if (isset($all_tags[$id])) {
530			$tags[$id] = $all_tags[$id];
531		}
532	}
533
534	return $tags;
535}
536
537function tags_get_agents($id_tag, $id_policy_module = 0) {
538
539	$agents = db_get_all_rows_sql("
540		SELECT id_agente
541		FROM tagente
542		WHERE id_agente IN (
543			SELECT t1.id_agente
544			FROM tagente_modulo t1
545			WHERE t1.id_agente_modulo IN (
546				SELECT t2.id_agente_modulo
547				FROM ttag_module t2
548				WHERE id_tag = " . $id_tag . "
549					AND id_policy_module = " . $id_policy_module . "))");
550
551	if (empty($agents)) {
552		return array();
553	}
554
555
556	$temp = array();
557	foreach ($agents as $agent) {
558		$temp[] = $agent['id_agente'];
559	}
560	$agents = $temp;
561
562	return $agents;
563}
564
565/**
566 * Give format to tags when go concatened with url.
567 *
568 * @param string name of tags serialized
569 * @param bool flag to return the url or not
570 *
571 * @return string Tags with url format
572 */
573function tags_get_tags_formatted ($tags_array, $get_url = true) {
574	if(!is_array($tags_array)) {
575		$tags_array = explode(',',$tags_array);
576	}
577
578	$tags = array();
579	foreach($tags_array as $t) {
580		$tag_url = explode(' ', trim($t));
581		$tag = $tag_url[0];
582		if(isset($tag_url[1]) && $tag_url[1] != '' && $get_url) {
583			$title = $tag_url[1];
584			//$link = '<a href="'.$tag_url[1].'" target="_blank">'.html_print_image('images/zoom.png',true, array('alt' => $title, 'title' => $title)).'</a>';
585			$link = '<a href="javascript: openURLTagWindow(\'' . $tag_url[1] . '\');">' . html_print_image('images/zoom.png', true, array('title' => __('Click here to open a popup window with URL tag'))) . '</a>';
586
587		}
588		else {
589			$link = '';
590		}
591
592		$tags[] = $tag.$link;
593	}
594
595	$tags = implode(',',$tags);
596
597	$tags = str_replace(',',' , ',$tags);
598
599	return $tags;
600}
601
602/**
603 * Get the tags (more restrictive) of an access flag in a group
604 *
605 * @param string id of the user
606 * @param string id of the group
607 * @param string access flag (AR,AW...)
608 * @param string return_mode
609 * 			- 'data' for return array with groups and tags
610 * 			- 'module_condition' for return string with sql condition for tagente_module
611 * 			- 'event_condition' for return string with sql condition for tevento
612 *
613 * @return mixed/string Tag ids
614 */
615
616function tags_get_acl_tags($id_user, $id_group, $access = 'AR',
617	$return_mode = 'module_condition', $query_prefix = '',
618	$query_table = '', $meta = false, $childrens_ids = array(),
619	$force_group_and_tag = false) {
620
621	global $config;
622
623	if ($id_user == false) {
624		$id_user = $config['id_user'];
625	}
626
627	if (is_user_admin ($id_user)) {
628		switch ($return_mode) {
629			case 'data':
630				return array();
631				break;
632			case 'event_condition':
633			case 'module_condition':
634				return "";
635				break;
636		}
637	}
638
639	if ($id_group == 0) {
640		// Don't filter
641		$id_group = array();
642	}
643	elseif (empty($id_group)) {
644		return ERR_WRONG_PARAMETERS;
645	}
646	elseif (!is_array($id_group)) {
647		$id_group = array($id_group);
648	}
649	$groups = $id_group;
650
651	$acl_column = get_acl_column($access);
652	if (empty($acl_column)) {
653		return ERR_WRONG_PARAMETERS;
654	}
655
656	$acltags = tags_get_user_module_and_tags($id_user, $access);
657
658
659	// Delete the groups without tag restrictions from the acl tags array if $force_group_and_tag == false
660	// Delete the groups that aren't in the received groups id
661	$acltags_aux = array();
662	foreach ($acltags as $group_id => $tags) {
663		if (!empty($groups) && array_search($group_id, $groups) === false) {
664			unset($acltags[$group_id]);
665		}
666		else {
667			if (!empty($tags))
668				$tags = explode(",", $tags);
669			$acltags_aux[$group_id] = $tags;
670		}
671	}
672	// Clean the possible empty elements
673	if (!$force_group_and_tag)
674		$acltags_aux = array_filter($acltags_aux);
675	$acltags = $acltags_aux;
676
677	switch ($return_mode) {
678		case 'data':
679			// Stop here and return the array
680			return $acltags;
681			break;
682		case 'module_condition':
683			// Return the condition of the tags for tagente_modulo table
684
685			$condition = tags_get_acl_tags_module_condition($acltags,
686				$query_table);
687			if (!empty($condition)) {
688				return " $query_prefix " . $condition;
689			}
690			break;
691		case 'event_condition':
692			// Return the condition of the tags for tevento table
693			$condition = tags_get_acl_tags_event_condition($acltags, $meta, $force_group_and_tag);
694			if (!empty($condition)) {
695				return " $query_prefix " . "(" . $condition . ")";
696			}
697			break;
698	}
699
700	return "";
701}
702
703/**
704 * Transform the acl_groups data into a SQL condition
705 *
706 * @param mixed acl_groups data calculated in tags_get_acl_tags function
707 *
708 * @return string SQL condition for tagente_module
709 */
710function tags_get_acl_tags_module_condition($acltags, $modules_table = '') {
711	if (!empty($modules_table))
712		$modules_table .= '.';
713
714	$condition = '';
715	$group_conditions = array();
716
717	// The acltags array contains the groups with the acl propagation applied
718	// after the changes done into the 'tags_get_user_module_and_tags' function.
719	foreach ($acltags as $group_id => $group_tags) {
720		$tag_join = '';
721		if (!empty($group_tags)) {
722			$tag_join = sprintf('INNER JOIN ttag_module ttmc
723									ON tamc.id_agente_modulo = ttmc.id_agente_modulo
724										AND ttmc.id_tag IN (%s)',
725								is_array($group_tags) ? implode(',', $group_tags) : $group_tags);
726		}
727
728		$agent_condition = sprintf('SELECT tamc.id_agente_modulo
729									FROM tagente_modulo tamc
730									%s
731									INNER JOIN tagente tac
732										ON tamc.id_agente = tac.id_agente
733											AND tac.id_grupo = %d',
734									$tag_join, $group_id);
735		$sql_condition = sprintf('(%sid_agente_modulo IN (%s))', $modules_table, $agent_condition);
736
737		$group_conditions[] = $sql_condition;
738
739		$i++;
740	}
741
742	if (!empty($group_conditions))
743		$condition = implode(' OR ', $group_conditions);
744	$condition = !empty($condition) ? "($condition)" : '';
745
746	return $condition;
747}
748
749// The old function will be keeped to serve as reference of the changes done
750/**
751 * Transform the acl_groups data into a SQL condition
752 *
753 * @param mixed acl_groups data calculated in tags_get_acl_tags function
754 *
755 * @return string SQL condition for tagente_module
756 */
757function tags_get_acl_tags_module_condition_old($acltags, $modules_table = '') {
758	if (!empty($modules_table)) {
759		$modules_table .= '.';
760	}
761
762	$condition = '';
763
764	// Fix: Wrap SQL expression with "()" to avoid bad SQL sintax that makes Pandora retrieve all modules without taking care of id_agent => id_agent = X AND (sql_tag_expression)
765	$i = 0;
766	foreach ($acltags as $group_id => $group_tags) {
767		if ($condition != '') {
768			$condition .= ' OR ';
769		}
770
771		// Fix: Wrap SQL expression with "()" to avoid bad SQL sintax that makes Pandora retrieve all modules without taking care of id_agent => id_agent = X AND (sql_tag_expression)
772		if ($i == 0)
773			$condition .= ' ( ' . "\n";
774
775		// Group condition (The module belongs to an agent of the group X)
776		// Juanma (08/05/2014) Fix: Now group and tag is checked at the same time, before only tag was checked due to a bad condition
777		if (!array_key_exists(0, $acltags)) {
778			// Juanma (08/05/2014) Fix: get all groups recursively (Acl proc func!)
779			$group_condition = sprintf('%sid_agente IN (SELECT id_agente FROM tagente WHERE id_grupo IN (%s))', $modules_table, implode(',', array_values(groups_get_id_recursive($group_id))));
780		}
781		else {
782			//Avoid the user profiles with all group access.
783			$group_condition = " 1 = 1 ";
784		}
785
786		//When the acl is only group without tags
787		if (empty($group_tags)) {
788			$condition .= "($group_condition)\n";
789		}
790		else {
791			if (is_array($group_tags)) {
792				$group_tags_query = implode(',',$group_tags);
793			} else {
794				$group_tags_query = $group_tags;
795			}
796			// Tags condition (The module has at least one of the restricted tags)
797			$tags_condition = sprintf('%sid_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag IN (%s))', $modules_table, $group_tags_query);
798
799			$condition .=
800				"	( \n" .
801				"		$group_condition \n" .
802				"			AND \n" .
803				"		$tags_condition \n" .
804				"	)\n";
805		}
806
807		$i++;
808	}
809
810	// Fix: Wrap SQL expression with "()" to avoid bad SQL sintax that makes Pandora retrieve all modules without taking care of id_agent => id_agent = X AND (sql_tag_expression)
811	if (!empty($acltags))
812		$condition .= ' ) ';
813
814	//Avoid the user profiles with all group access.
815	//if (!empty($condition)) {
816	if (!empty($condition) &&
817		!array_key_exists(0, array_keys($acltags))) {
818		$condition = sprintf("\n((%s) OR %sid_agente NOT IN (SELECT id_agente FROM tagente WHERE id_grupo IN (%s)))", $condition, $modules_table, implode(',',array_keys($acltags)));
819	}
820
821	return $condition;
822}
823
824/**
825 * Transform the acl_groups data into a SQL condition
826 *
827 * @param mixed acl_groups data calculated in tags_get_acl_tags function
828 *
829 * @return string SQL condition for tagente_module
830 */
831
832function tags_get_acl_tags_event_condition($acltags, $meta = false, $force_group_and_tag = false, $force_equal = false) {
833
834	global $config;
835	$condition = '';
836
837	// Get all tags of the system
838	$all_tags = tags_get_all_tags(false);
839
840	// Juanma (08/05/2014) Fix : Will have all groups  retrieved (also propagated ones)
841	$_groups_not_in = '';
842
843	foreach ($acltags as $group_id => $group_tags) {
844		// Group condition (The module belongs to an agent of the group X)
845		// Juanma (08/05/2014) Fix : Get all groups (children also, Propagate ACL func!)
846		$group_condition = sprintf('id_grupo IN (%s)', implode(',', array_values(groups_get_id_recursive($group_id))));
847		$_groups_not_in .= implode(',', array_values(groups_get_id_recursive($group_id))) . ',';
848
849		// Tags condition (The module has at least one of the restricted tags)
850		$tags_condition = '';
851		if (empty($group_tags)) {
852			$tags_condition = "id_grupo = ".$group_id;
853		}
854		else {
855			if (!is_array($group_tags)) {
856				$group_tags = explode(',', $group_tags);
857			}
858
859			foreach ($group_tags as $tag) {
860				// If the tag ID doesnt exist, ignore
861				if (!isset($all_tags[$tag])) {
862					continue;
863				}
864
865				if ($tags_condition != '') {
866					$tags_condition .= " OR \n";
867				}
868
869				//~ // Add as condition all the posibilities of the serialized tags
870				//~ $tags_condition .= sprintf('tags LIKE "%s,%%"',io_safe_input($all_tags[$tag]));
871				//~ $tags_condition .= sprintf(' OR tags LIKE "%%,%s,%%"',io_safe_input($all_tags[$tag]));
872				//~ $tags_condition .= sprintf(' OR tags LIKE "%%,%s"',io_safe_input($all_tags[$tag]));
873				//~ $tags_condition .= sprintf(' OR tags LIKE "%s %%"',io_safe_input($all_tags[$tag]));
874				//~ $tags_condition .= sprintf(' OR tags LIKE "%%,%s %%"',io_safe_input($all_tags[$tag]));
875
876				if ($force_group_and_tag) {
877					if (!empty($all_tags[$tag])) {
878						if ($force_equal) {
879							$tags_condition .= sprintf('(tags = "%s"',io_safe_input($all_tags[$tag]));
880						} else {
881							$tags_condition .= "(tags LIKE '%".io_safe_input($all_tags[$tag])."%'";
882						}
883						$childrens = groups_get_childrens($group_id, null, true);
884
885						if (empty($childrens)) {
886							$tags_condition .= sprintf(' AND id_grupo = %d )', $group_id);
887						} else {
888							$childrens_ids[] = $group_id;
889							foreach ($childrens as $child) {
890								$childrens_ids[] = (int)$child['id_grupo'];
891							}
892							$ids_str = implode(',', $childrens_ids);
893
894							$tags_condition .= sprintf(' AND id_grupo IN (%s) )', $ids_str);
895						}
896					} else {
897						$tags_condition .= "id_grupo = ".$group_id;
898					}
899				} else {
900					if ($force_equal) {
901						$tags_condition .= sprintf('tags = "%s"',io_safe_input($all_tags[$tag]));
902					} else {
903						$tags_condition .= "tags LIKE '%".io_safe_input($all_tags[$tag])."%'";
904					}
905				}
906			}
907		}
908
909		// If there is not tag condition ignore
910		if (empty($tags_condition)) {
911			continue;
912		}
913
914		if ($condition != '') {
915			$condition .= ' OR ';
916		}
917
918		$condition .= "($tags_condition)\n";
919	}
920
921	//Commented because ACLs propagation don't work
922/*
923	if (!empty($condition)) {
924		// Juanma (08/05/2014) Fix : Also add events of other groups (taking care of propagate ACLs func!)
925		if (!empty($_groups_not_in))
926			$condition = sprintf("\n((%s) OR id_grupo NOT IN (%s))", $condition, rtrim($_groups_not_in, ','));
927	}
928*/
929
930	return $condition;
931}
932
933/**
934 * Check if a user has assigned acl tags or not (if is admin, is like not acl tags)
935 *
936 * @param string ID of the user (with false the user will be taked from config)
937 *
938 * @return bool true if the user has tags and false if not
939 */
940function tags_has_user_acl_tags($id_user = false) {
941	global $config;
942
943	if($id_user === false) {
944		$id_user = $config['id_user'];
945	}
946
947	if(is_user_admin($id_user)) {
948		return false;
949	}
950
951	$query = sprintf("SELECT count(*)
952			FROM tusuario_perfil, tperfil
953			WHERE tperfil.id_perfil = tusuario_perfil.id_perfil AND
954			tusuario_perfil.id_usuario = '%s' AND tags != ''",
955			$id_user);
956
957	$user_tags = db_get_value_sql($query);
958
959	return (bool)$user_tags;
960}
961
962/**
963 * Get the tags of a user in an ACL flag
964 *
965 * @param string ID of the user (with false the user will be taked from config)
966 * @param string Access flag where check what tags have the user
967 *
968 * @return string SQL condition for tagente_module
969 */
970function tags_get_user_tags($id_user = false, $access = 'AR') {
971	global $config;
972
973	//users_is_strict_acl
974
975	if ($id_user === false) {
976		$id_user = $config['id_user'];
977	}
978
979	// Get all tags to have the name of all of them
980	$all_tags = tags_get_all_tags();
981
982	// If at least one of the profiles of this access flag hasent
983	// tags restrictions, the user can see all tags
984	$acl_column = get_acl_column($access);
985
986	if (empty($acl_column)) {
987		return array();
988	}
989
990	switch ($config["dbtype"]) {
991		case "mysql":
992		case "postgresql":
993			$query = sprintf("
994				SELECT count(*)
995				FROM tusuario_perfil, tperfil
996				WHERE tperfil.id_perfil = tusuario_perfil.id_perfil
997					AND tusuario_perfil.id_usuario = '%s'
998					AND tperfil.%s = 1
999					AND tags <> ''",
1000				$id_user, $acl_column);
1001			break;
1002		case "oracle":
1003			$query = sprintf("
1004				SELECT count(*)
1005				FROM tusuario_perfil, tperfil
1006				WHERE tperfil.id_perfil = tusuario_perfil.id_perfil
1007					AND tusuario_perfil.id_usuario = '%s'
1008					AND tperfil.%s = 1
1009					AND dbms_lob.getlength(tags) > 0",
1010				$id_user, $acl_column);
1011			break;
1012	}
1013
1014	$profiles_without_tags = db_get_value_sql($query);
1015
1016	if ($profiles_without_tags == 0) {
1017		//--------------------------------------------------------------
1018		// FIXED FOR TICKET #1921
1019		//
1020		// If the user is setted with strict ACL, the pandora does not
1021		// show any tags. Thanks Mr. C from T.
1022		//
1023		//--------------------------------------------------------------
1024		if (users_is_strict_acl($id_user)) {
1025			return array();
1026		}
1027		else {
1028			return $all_tags;
1029		}
1030	}
1031
1032	// Get the tags of the required access flag for each group
1033	$tags = tags_get_acl_tags($id_user, 0, $access, 'data');
1034	// If there are wrong parameters or fail ACL check, return false
1035	if ($tags_user === ERR_WRONG_PARAMETERS || $tags_user === ERR_ACL) {
1036		return array();
1037	}
1038
1039	// Merge the tags to get an array with all of them
1040	$user_tags_id = array();
1041
1042	foreach ($tags as $t) {
1043		if (empty($user_tags_id)) {
1044			$user_tags_id = $t;
1045		}
1046		else {
1047			$user_tags_id = array_unique(array_merge($t,$user_tags_id));
1048		}
1049	}
1050
1051	// Set the format id=>name to tags
1052	$user_tags = array();
1053	foreach ($user_tags_id as $id) {
1054		if (!isset($all_tags[$id])) {
1055			continue;
1056		}
1057		$user_tags[$id] = $all_tags[$id];
1058	}
1059
1060
1061	return $user_tags;
1062}
1063
1064function tags_get_tags_for_module_search($id_user = false, $access = 'AR') {
1065    global $config;
1066
1067	//users_is_strict_acl
1068
1069	if ($id_user === false) {
1070		$id_user = $config['id_user'];
1071	}
1072
1073	// Get all tags to have the name of all of them
1074	$all_tags = tags_get_all_tags();
1075
1076	// If at least one of the profiles of this access flag hasent
1077	// tags restrictions, the user can see all tags
1078	$acl_column = get_acl_column($access);
1079
1080	if (empty($acl_column)) {
1081		return array();
1082	}
1083
1084	switch ($config["dbtype"]) {
1085		case "mysql":
1086		case "postgresql":
1087			$query = sprintf("
1088				SELECT count(*)
1089				FROM tusuario_perfil, tperfil
1090				WHERE tperfil.id_perfil = tusuario_perfil.id_perfil
1091					AND tusuario_perfil.id_usuario = '%s'
1092					AND tperfil.%s = 1
1093					AND tags <> ''",
1094				$id_user, $acl_column);
1095			break;
1096		case "oracle":
1097			$query = sprintf("
1098				SELECT count(*)
1099				FROM tusuario_perfil, tperfil
1100				WHERE tperfil.id_perfil = tusuario_perfil.id_perfil
1101					AND tusuario_perfil.id_usuario = '%s'
1102					AND tperfil.%s = 1
1103					AND dbms_lob.getlength(tags) > 0",
1104				$id_user, $acl_column);
1105			break;
1106	}
1107
1108	$profiles_without_tags = db_get_value_sql($query);
1109
1110	if ($profiles_without_tags == 0) {
1111		//--------------------------------------------------------------
1112		// FIXED FOR TICKET #1921
1113		//
1114		// If the user is setted with strict ACL, the pandora does not
1115		// show any tags. Thanks Mr. C from T.
1116		//
1117		//--------------------------------------------------------------
1118		return false;
1119	}
1120    // Get the tags of the required access flag for each group
1121	$tags = tags_get_acl_tags($id_user, 0, $access, 'data');
1122	// If there are wrong parameters or fail ACL check, return false
1123	if ($tags_user === ERR_WRONG_PARAMETERS || $tags_user === ERR_ACL) {
1124		return array();
1125	}
1126
1127	// Merge the tags to get an array with all of them
1128	$user_tags_id = array();
1129
1130	foreach ($tags as $t) {
1131		if (empty($user_tags_id)) {
1132			$user_tags_id = $t;
1133		}
1134		else {
1135			$user_tags_id = array_unique(array_merge($t,$user_tags_id));
1136		}
1137	}
1138
1139	// Set the format id=>name to tags
1140	$user_tags = array();
1141	foreach ($user_tags_id as $id) {
1142		if (!isset($all_tags[$id])) {
1143			continue;
1144		}
1145		$user_tags[$id] = $all_tags[$id];
1146	}
1147
1148
1149	return $user_tags;
1150}
1151
1152function tags_check_acl_by_module($id_module = 0, $id_user = false,
1153	$access = 'AW') {
1154
1155	global $config;
1156
1157
1158	$return = false;
1159
1160	if (!empty($id_module)) {
1161		$tags = tags_get_module_tags($id_module);
1162		$group = modules_get_agent_group($id_module);
1163
1164		if ($id_user === false) {
1165			$id_user = $config["id_user"];
1166		}
1167
1168		$return = tags_check_acl($id_user, $group, $access, $tags, true);
1169	}
1170
1171	return $return;
1172}
1173
1174/**
1175 * Check the ACLs with tags
1176 *
1177 * @param string ID of the user (with false the user will be taked from config)
1178 * @param string id of the group (0 means for at least one)
1179 * @param string access flag (AR,AW...)
1180 * @param mixed tags to be checked (array() means for at least one)
1181 *
1182 * @return bool true if the acl check has success, false otherwise
1183 */
1184function tags_check_acl($id_user, $id_group, $access, $tags = array(), $flag_id_tag = false) {
1185	global $config;
1186
1187	if ($id_user === false) {
1188		$id_user = $config['id_user'];
1189	}
1190
1191	// Get parents to check in propagate ACL cases
1192	if (!is_array($id_group) && $id_group != 0) {
1193		$id_group = array($id_group);
1194		$group = db_get_row_filter('tgrupo',
1195			array('id_grupo' => $id_group));
1196		$parents = groups_get_parents($group['parent'], true);
1197
1198		foreach ($parents as $parent) {
1199			$id_group[] = $parent['id_grupo'];
1200		}
1201	}
1202
1203	$acls = tags_get_acl_tags($id_user, $id_group, $access, 'data');
1204
1205	// If there are wrong parameters or fail ACL check, return false
1206	if ($acls === ERR_WRONG_PARAMETERS || $acls === ERR_ACL) {
1207		return false;
1208	}
1209
1210	// If there are not tags restrictions or tags passed, check the group access
1211	if (empty($acls) || empty($tags)) {
1212		if (!is_array($id_group))
1213			$group_id_array = array($id_group);
1214
1215		foreach ($id_group as $group) {
1216			if (check_acl($id_user, $group, $access))
1217				return true;
1218		}
1219	}
1220
1221	# Fix: If user profile has more than one group, due to ACL propagation then id_group can be an array
1222	if (is_array($id_group)) {
1223
1224		foreach ($id_group  as $group) {
1225			if ($group > 0) {
1226				if (array_key_exists(0, $acls)) {
1227					//There is a All group
1228
1229					foreach ($tags as $tag) {
1230						if (in_array($tag, $acls[0])) {
1231							return true;
1232						}
1233						else {
1234							return false;
1235						}
1236					}
1237				}
1238				else if (isset($acls[$group])) {
1239					foreach ($tags as $tag) {
1240						if (!$flag_id_tag)
1241							$tag = tags_get_id($tag);
1242
1243						if (in_array($tag, $acls[$group])) {
1244							return true;
1245						}
1246					}
1247				}
1248				else {
1249					return false;
1250				}
1251			}
1252			else {
1253
1254				foreach ($acls as $acl_tags) {
1255					foreach ($tags as $tag) {
1256						if (!$flag_id_tag)
1257							$tag = tags_get_id($tag);
1258
1259						if (in_array($tag, $acl_tags)) {
1260							return true;
1261						}
1262					}
1263				}
1264			}
1265		}
1266	}
1267	else {
1268		if ($id_group > 0) {
1269			if (isset($acls[$id_group])) {
1270				foreach ($tags as $tag) {
1271					if (!$flag_id_tag)
1272						$tag = tags_get_id($tag);
1273
1274					if (in_array($tag, $acls[$id_group])) {
1275						return true;
1276					}
1277				}
1278			}
1279			else {
1280				return false;
1281			}
1282		}
1283		else {
1284			foreach ($acls as $acl_tags) {
1285				foreach ($tags as $tag) {
1286					if (!$flag_id_tag)
1287						$tag = tags_get_id($tag);
1288
1289					if (in_array($tag, $acl_tags)) {
1290						return true;
1291					}
1292				}
1293			}
1294		}
1295	}
1296
1297	return false;
1298}
1299
1300function tags_check_acl_event($id_user, $id_group, $access, $tags = array(),$p = false) {
1301	global $config;
1302
1303	if($id_user === false) {
1304		$id_user = $config['id_user'];
1305	}
1306
1307	$acls = tags_get_acl_tags($id_user, $id_group, $access, 'data');
1308
1309	// If there are wrong parameters or fail ACL check, return false
1310	if($acls === ERR_WRONG_PARAMETERS || $acls === ERR_ACL) {
1311		return false;
1312	}
1313
1314	// If there are not tags restrictions or tags passed, check the group access
1315	if (empty($acls) || empty($tags)) {
1316		if (!is_array($id_group))
1317			$group_id_array = array($id_group);
1318
1319		foreach ($id_group as $group) {
1320			if (check_acl($id_user, $group, $access))
1321				return true;
1322		}
1323	}
1324
1325	# Fix: If user profile has more than one group, due to ACL propagation then id_group can be an array
1326	if (is_array($id_group)) {
1327
1328		foreach ($id_group  as $group) {
1329			if ($group > 0) {
1330				if (isset($acls[$group])) {
1331					foreach ($tags as $tag) {
1332						$tag = tags_get_id($tag);
1333						if (in_array($tag, $acls[$group])) {
1334							return true;
1335						}
1336					}
1337				}
1338				else {
1339					//return false;
1340					$return = false;
1341				}
1342			}
1343			else {
1344				foreach ($acls as $acl_tags) {
1345					foreach ($tags as $tag) {
1346						$tag = tags_get_id($tag);
1347						if (in_array($tag, $acl_tags)) {
1348							return true;
1349						}
1350					}
1351				}
1352			}
1353
1354		}
1355
1356	}
1357	else {
1358		if ($id_group > 0) {
1359			if (isset($acls[$id_group])) {
1360				foreach ($tags as $tag) {
1361					$tag = tags_get_id($tag);
1362
1363					if (in_array($tag, $acls[$id_group])) {
1364						return true;
1365					}
1366				}
1367			}
1368			else {
1369				//return false;
1370				$return = false;
1371			}
1372		}
1373		else {
1374			foreach ($acls as $acl_tags) {
1375				foreach ($tags as $tag) {
1376					$tag = tags_get_id($tag);
1377					if (in_array($tag, $acl_tags)) {
1378						return true;
1379					}
1380				}
1381			}
1382		}
1383	}
1384	//return false;
1385	$return = false;
1386
1387	if ($return == false) {
1388		$parent = db_get_value('parent','tgrupo','id_grupo',$id_group);
1389
1390		if ($parent !== 0) {
1391			$propagate = db_get_value('propagate','tgrupo','id_grupo',$parent);
1392			if ($propagate == 1) {
1393				$acl_parent = tags_check_acl_event($id_user, $parent, $access, $tags,$p);
1394				return $acl_parent;
1395			}
1396		}
1397	}
1398}
1399
1400/* This function checks event ACLs */
1401function tags_checks_event_acl($id_user, $id_group, $access, $tags = array(), $childrens_ids = array()) {
1402	global $config;
1403
1404	if($id_user === false) {
1405		$id_user = $config['id_user'];
1406	}
1407
1408	if (users_is_admin($id_user)) {
1409		return true;
1410	}
1411
1412	$tags_user = tags_get_acl_tags($id_user, $id_group, $access, 'data', '', '', true, $childrens_ids, true);
1413	// If there are wrong parameters or fail ACL check, return false
1414	if ($tags_user === ERR_WRONG_PARAMETERS || $tags_user === ERR_ACL) {
1415		return false;
1416	}
1417
1418	//check user without tags
1419	$sql = "SELECT id_usuario FROM tusuario_perfil
1420		WHERE id_usuario = '".$config["id_user"]."' AND tags = ''
1421			AND id_perfil IN (
1422				SELECT id_perfil
1423				FROM tperfil
1424				WHERE ".get_acl_column($access)." = 1)
1425			AND id_grupo = ".$id_group;
1426	$user_has_perm_without_tags = db_get_all_rows_sql ($sql);
1427
1428	if ($user_has_perm_without_tags) {
1429		return true;
1430	}
1431
1432	$tags_str = '';
1433	if (!empty($tags)) {
1434		foreach ($tags as $tag) {
1435			$tag_id = tags_get_id($tag);
1436			$tags_aux[$tag_id] = $tag_id;
1437		}
1438		$tags_str = implode(',', $tags_aux);
1439	}
1440
1441	$query = sprintf("SELECT tags, id_grupo
1442				FROM tusuario_perfil, tperfil
1443				WHERE tperfil.id_perfil = tusuario_perfil.id_perfil AND
1444					tusuario_perfil.id_usuario = '%s' AND
1445					tperfil.%s = 1
1446				ORDER BY id_grupo", $id_user, get_acl_column($access));
1447	$user_tags = db_get_all_rows_sql($query);
1448
1449	if ($user_tags === false) {
1450		$user_tags = array();
1451	}
1452
1453	foreach ($user_tags as $user_tag) {
1454		$tags_user = $user_tag['tags'];
1455		$id_group_user = $user_tag['id_grupo'];
1456		$childrens = groups_get_childrens($id_group_user, null, true);
1457
1458		if (empty($childrens)) {
1459			$group_ids = $id_group_user;
1460		} else {
1461			$childrens_ids[] = $id_group_user;
1462			foreach ($childrens as $child) {
1463				$childrens_ids[] = (int)$child['id_grupo'];
1464			}
1465			$group_ids = implode(',', $childrens_ids);
1466		}
1467		$sql = "SELECT id_usuario FROM tusuario_perfil
1468					WHERE id_usuario = '".$config["id_user"]."' AND tags IN ('$tags_str')
1469					AND id_perfil IN (SELECT id_perfil FROM tperfil WHERE ".get_acl_column($access)."=1)
1470					AND id_grupo IN ($group_ids)";
1471		$has_perm = db_get_value_sql ($sql);
1472
1473		if ($has_perm) {
1474			return true;
1475		}
1476	}
1477
1478	return false;
1479}
1480
1481/**
1482 * Get the number of the agents that pass the filters.
1483 *
1484 * @param mixed $id_tag Id in integer or a set of ids into an array.
1485 * @param array $groups_and_tags Array with strict ACL rules.
1486 * @param array $agent_filter Filter of the agents.
1487 * This filter support the following fields:
1488 * -'status': (mixed) Agent status. Single or grouped into an array. e.g.: AGENT_STATUS_CRITICAL.
1489 * -'name': (string) Agent name. e.g.: "agent_1".
1490 * @param array $module_filter Filter of the modules.
1491 * This filter support the following fields:
1492 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1493 * -'name': (string) Module name. e.g.: "module_1".
1494 * @param bool $realtime Search realtime values or the values processed by the server.
1495 *
1496 * @return int Number of monitors.
1497 *
1498 */
1499function tags_get_agents_counter ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1500
1501	// Avoid mysql error
1502	if (empty($id_tag))
1503		return false;
1504
1505	$groups_clause = "";
1506	if (!empty($groups_and_tags)) {
1507
1508		$groups_id = array();
1509		foreach ($groups_and_tags as $group_id => $tags) {
1510			if (!empty($tags)) {
1511				$tags_arr = explode(',', $tags);
1512				foreach ($tags_arr as $tag) {
1513					if ($tag == $id_tag) {
1514						$hierarchy_groups = groups_get_id_recursive($group_id);
1515						$groups_id = array_merge($groups_id, $hierarchy_groups);
1516					}
1517				}
1518			}
1519		}
1520		if (array_search(0, $groups_id) === false) {
1521			$groups_id = array_unique($groups_id);
1522			$groups_id_str = implode(",", $groups_id);
1523			$groups_clause = " AND ta.id_grupo IN ($groups_id_str)";
1524		}
1525	}
1526
1527	$agent_name_filter = "";
1528	$agent_status = AGENT_STATUS_ALL;
1529	if (!empty($agent_filter)) {
1530		// Name
1531		if (isset($agent_filter["name"]) && !empty($agent_filter["name"])) {
1532			$agent_name_filter = "AND ta.nombre LIKE '%" . $agent_filter["name"] . "%'";
1533		}
1534		// Status
1535		if (isset($agent_filter["status"])) {
1536			if (is_array($agent_filter["status"]))
1537				$agent_status = array_unique($agent_filter["status"]);
1538			else
1539				$agent_status = $agent_filter["status"];
1540		}
1541	}
1542
1543	$module_name_filter = "";
1544	$module_status_filter = "";
1545	$module_status_array = array();
1546	if (!empty($module_filter)) {
1547		// IMPORTANT: The module filters will force the realtime search
1548		$realtime = true;
1549
1550		// Name
1551		if (isset($module_filter["name"]) && !empty($module_filter["name"])) {
1552			$module_name_filter = "AND tam.nombre LIKE '%" . $module_filter["name"] . "%'";
1553		}
1554		// Status
1555		if (isset($module_filter["status"])) {
1556			$module_status = $module_filter["status"];
1557			if (is_array($module_status))
1558				$module_status = array_unique($module_status);
1559			else
1560				$module_status = array($module_status);
1561
1562			foreach ($module_status as $status) {
1563				switch ($status) {
1564					case AGENT_MODULE_STATUS_ALL:
1565						$module_status_array[] = AGENT_MODULE_STATUS_CRITICAL_ALERT;
1566						$module_status_array[] = AGENT_MODULE_STATUS_CRITICAL_BAD;
1567						$module_status_array[] = AGENT_MODULE_STATUS_WARNING_ALERT;
1568						$module_status_array[] = AGENT_MODULE_STATUS_WARNING;
1569						$module_status_array[] = AGENT_MODULE_STATUS_UNKNOWN;
1570						$module_status_array[] = AGENT_MODULE_STATUS_NO_DATA;
1571						$module_status_array[] = AGENT_MODULE_STATUS_NOT_INIT;
1572						$module_status_array[] = AGENT_MODULE_STATUS_NORMAL_ALERT;
1573						$module_status_array[] = AGENT_MODULE_STATUS_NORMAL;
1574						break;
1575					case AGENT_MODULE_STATUS_CRITICAL_ALERT:
1576					case AGENT_MODULE_STATUS_CRITICAL_BAD:
1577						$module_status_array[] = AGENT_MODULE_STATUS_CRITICAL_ALERT;
1578						$module_status_array[] = AGENT_MODULE_STATUS_CRITICAL_BAD;
1579						break;
1580					case AGENT_MODULE_STATUS_WARNING_ALERT:
1581					case AGENT_MODULE_STATUS_WARNING:
1582						$module_status_array[] = AGENT_MODULE_STATUS_WARNING_ALERT;
1583						$module_status_array[] = AGENT_MODULE_STATUS_WARNING;
1584						break;
1585					case AGENT_MODULE_STATUS_UNKNOWN:
1586						$module_status_array[] = AGENT_MODULE_STATUS_UNKNOWN;
1587						break;
1588					case AGENT_MODULE_STATUS_NO_DATA:
1589					case AGENT_MODULE_STATUS_NOT_INIT:
1590						$module_status_array[] = AGENT_MODULE_STATUS_NO_DATA;
1591						$module_status_array[] = AGENT_MODULE_STATUS_NOT_INIT;
1592						break;
1593					case AGENT_MODULE_STATUS_NORMAL_ALERT:
1594					case AGENT_MODULE_STATUS_NORMAL:
1595						$module_status_array[] = AGENT_MODULE_STATUS_NORMAL_ALERT;
1596						$module_status_array[] = AGENT_MODULE_STATUS_NORMAL;
1597						break;
1598				}
1599			}
1600			if (!empty($module_status_array)) {
1601				$module_status_array = array_unique($module_status_array);
1602				$status_str = implode(",", $module_status_array);
1603
1604				$module_status_filter = "INNER JOIN tagente_estado tae
1605											ON tam.id_agente_modulo = tae.id_agente_modulo
1606												AND tae.estado IN ($status_str)";
1607			}
1608		}
1609	}
1610
1611	$count = 0;
1612	if ($realtime) {
1613		$sql = "SELECT DISTINCT ta.id_agente
1614				FROM tagente ta
1615				INNER JOIN tagente_modulo tam
1616					ON ta.id_agente = tam.id_agente
1617						AND tam.disabled = 0
1618						$module_name_filter
1619				$module_status_filter
1620				INNER JOIN ttag_module ttm
1621					ON ttm.id_tag = $id_tag
1622						AND tam.id_agente_modulo = ttm.id_agente_modulo
1623				WHERE ta.disabled = 0
1624					$agent_name_filter
1625					$groups_clause";
1626		$agents = db_get_all_rows_sql($sql);
1627
1628		if ($agents === false)
1629			return $count;
1630
1631		if ($agent_status == AGENT_STATUS_ALL)
1632			return count($agents);
1633
1634		foreach ($agents as $agent) {
1635			$agent_filter["id"] = $agent["id_agente"];
1636
1637			$total = 0;
1638			$critical = 0;
1639			$warning = 0;
1640			$unknown = 0;
1641			$not_init = 0;
1642			$normal = 0;
1643			// Without module filter
1644			if (empty($module_status_array)) {
1645				$total = (int) tags_get_total_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1646				$critical = (int) tags_get_critical_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1647				$warning = (int) tags_get_warning_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1648				$unknown = (int) tags_get_unknown_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1649				$not_init = (int) tags_get_not_init_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1650				$normal = (int) tags_get_normal_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1651			}
1652			// With module filter
1653			else {
1654				foreach ($module_status_array as $status) {
1655					switch ($status) {
1656						case AGENT_MODULE_STATUS_CRITICAL_ALERT:
1657						case AGENT_MODULE_STATUS_CRITICAL_BAD:
1658							$critical = (int) tags_get_critical_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1659							break;
1660						case AGENT_MODULE_STATUS_WARNING_ALERT:
1661						case AGENT_MODULE_STATUS_WARNING:
1662							$warning = (int) tags_get_warning_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1663							break;
1664						case AGENT_MODULE_STATUS_UNKNOWN:
1665							$unknown = (int) tags_get_unknown_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1666							break;
1667						case AGENT_MODULE_STATUS_NO_DATA:
1668						case AGENT_MODULE_STATUS_NOT_INIT:
1669							$not_init = (int) tags_get_not_init_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1670							break;
1671						case AGENT_MODULE_STATUS_NORMAL_ALERT:
1672						case AGENT_MODULE_STATUS_NORMAL:
1673							$normal = (int) tags_get_normal_monitors ($id_tag, $groups_and_tags, $agent_filter, $module_filter);
1674							break;
1675					}
1676				}
1677
1678				$total = $critical + $warning + $unknown + $not_init + $normal;
1679			}
1680
1681			if (!is_array($agent_status)) {
1682				switch ($agent_status) {
1683					case AGENT_STATUS_CRITICAL:
1684						if ($critical > 0)
1685							$count ++;
1686						break;
1687					case AGENT_STATUS_WARNING:
1688						if ($total > 0 && $critical = 0 && $warning > 0)
1689							$count ++;
1690						break;
1691					case AGENT_STATUS_UNKNOWN:
1692						if ($critical == 0 && $warning == 0 && $unknown > 0)
1693							$count ++;
1694						break;
1695					case AGENT_STATUS_NOT_INIT:
1696						if ($total == 0 || $total == $not_init)
1697							$count ++;
1698						break;
1699					case AGENT_STATUS_NORMAL:
1700						if ($critical == 0 && $warning == 0 && $unknown == 0 && $normal > 0)
1701							$count ++;
1702						break;
1703					default:
1704						// The status doesn't exist
1705						return 0;
1706				}
1707			}
1708			else {
1709				if (array_search(AGENT_STATUS_CRITICAL, $agent_status) !== false) {
1710					if ($critical > 0)
1711						$count ++;
1712				}
1713				else if (array_search(AGENT_STATUS_WARNING, $agent_status) !== false) {
1714					if ($total > 0 && $critical = 0 && $warning > 0)
1715						$count ++;
1716				}
1717				else if (array_search(AGENT_STATUS_UNKNOWN, $agent_status) !== false) {
1718					if ($critical == 0 && $warning == 0 && $unknown > 0)
1719						$count ++;
1720				}
1721				else if (array_search(AGENT_STATUS_NOT_INIT, $agent_status) !== false) {
1722					if ($total == 0 || $total == $not_init)
1723						$count ++;
1724				}
1725				else if (array_search(AGENT_STATUS_NORMAL, $agent_status) !== false) {
1726					if ($critical == 0 && $warning == 0 && $unknown == 0 && $normal > 0)
1727						$count ++;
1728				}
1729				// Invalid status
1730				else {
1731					return 0;
1732				}
1733			}
1734		}
1735	}
1736	else {
1737		$status_filter = "";
1738		// Transform the element into a one element array
1739		if (!is_array($agent_status))
1740			$agent_status = array($agent_status);
1741
1742		// Support for multiple status. It counts the agents for each status and sum the result
1743		foreach ($agent_status as $status) {
1744			switch ($agent_status) {
1745				case AGENT_STATUS_ALL:
1746					$status_filter = "";
1747					break;
1748				case AGENT_STATUS_CRITICAL:
1749					$status_filter = "AND ta.critical_count > 0";
1750					break;
1751				case AGENT_STATUS_WARNING:
1752					$status_filter = "AND ta.total_count > 0
1753									AND ta.critical_count = 0
1754									AND ta.warning_count > 0";
1755					break;
1756				case AGENT_STATUS_UNKNOWN:
1757					$status_filter = "AND ta.critical_count = 0
1758									AND ta.warning_count = 0
1759									AND ta.unknown_count > 0";
1760					break;
1761				case AGENT_STATUS_NOT_INIT:
1762					$status_filter = "AND (ta.total_count = 0
1763										OR ta.total_count = ta.notinit_count)";
1764					break;
1765				case AGENT_STATUS_NORMAL:
1766					$status_filter = "AND ta.critical_count = 0
1767									AND ta.warning_count = 0
1768									AND ta.unknown_count = 0
1769									AND ta.normal_count > 0";
1770					break;
1771				default:
1772					// The type doesn't exist
1773					return 0;
1774			}
1775
1776			$sql = "SELECT COUNT(DISTINCT ta.id_agente)
1777					FROM tagente ta
1778					INNER JOIN tagente_modulo tam
1779						ON ta.id_agente = tam.id_agente
1780							AND tam.disabled = 0
1781							$module_name_filter
1782					$module_status_filter
1783					INNER JOIN ttag_module ttm
1784						ON ttm.id_tag = $id_tag
1785							AND tam.id_agente_modulo = ttm.id_agente_modulo
1786					WHERE ta.disabled = 0
1787						$status_filter
1788						$agent_name_filter
1789						$groups_clause";
1790
1791			$count += (int) db_get_sql($sql);
1792		}
1793	}
1794
1795	return $count;
1796}
1797
1798/**
1799 * Get the number of the agents that pass the filters.
1800 *
1801 * @param mixed $id_tag Id in integer or a set of ids into an array.
1802 * @param array $groups_and_tags Array with strict ACL rules.
1803 * @param array $agent_filter Filter of the agents.
1804 * This filter support the following fields:
1805 * -'name': (string) Agent name. e.g.: "agent_1".
1806 * @param array $module_filter Filter of the modules.
1807 * This filter support the following fields:
1808 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1809 * -'name': (string) Module name. e.g.: "module_1".
1810 * @param bool $realtime Search realtime values or the values processed by the server.
1811 *
1812 * @return int Number of monitors.
1813 *
1814 */
1815function tags_get_total_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1816	// Always modify the agent status filter
1817	$agent_filter["status"] = AGENT_STATUS_ALL;
1818	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1819}
1820
1821/**
1822 * Get the number of the normal agents that pass the filters.
1823 *
1824 * @param mixed $id_tag Id in integer or a set of ids into an array.
1825 * @param array $groups_and_tags Array with strict ACL rules.
1826 * @param array $agent_filter Filter of the agents.
1827 * This filter support the following fields:
1828 * -'name': (string) Agent name. e.g.: "agent_1".
1829 * @param array $module_filter Filter of the modules.
1830 * This filter support the following fields:
1831 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1832 * -'name': (string) Module name. e.g.: "module_1".
1833 * @param bool $realtime Search realtime values or the values processed by the server.
1834 *
1835 * @return int Number of monitors.
1836 *
1837 */
1838function tags_get_normal_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1839	// Always modify the agent status filter
1840	$agent_filter["status"] = AGENT_STATUS_NORMAL;
1841	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1842}
1843
1844/**
1845 * Get the number of the warning agents that pass the filters.
1846 *
1847 * @param mixed $id_tag Id in integer or a set of ids into an array.
1848 * @param array $groups_and_tags Array with strict ACL rules.
1849 * @param array $agent_filter Filter of the agents.
1850 * This filter support the following fields:
1851 * -'name': (string) Agent name. e.g.: "agent_1".
1852 * @param array $module_filter Filter of the modules.
1853 * This filter support the following fields:
1854 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1855 * -'name': (string) Module name. e.g.: "module_1".
1856 * @param bool $realtime Search realtime values or the values processed by the server.
1857 *
1858 * @return int Number of monitors.
1859 *
1860 */
1861function tags_get_warning_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1862	// Always modify the agent status filter
1863	$agent_filter["status"] = AGENT_STATUS_WARNING;
1864	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1865}
1866
1867/**
1868 * Get the number of the critical agents that pass the filters.
1869 *
1870 * @param mixed $id_tag Id in integer or a set of ids into an array.
1871 * @param array $groups_and_tags Array with strict ACL rules.
1872 * @param array $agent_filter Filter of the agents.
1873 * This filter support the following fields:
1874 * -'name': (string) Agent name. e.g.: "agent_1".
1875 * @param array $module_filter Filter of the modules.
1876 * This filter support the following fields:
1877 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1878 * -'name': (string) Module name. e.g.: "module_1".
1879 * @param bool $realtime Search realtime values or the values processed by the server.
1880 *
1881 * @return int Number of monitors.
1882 *
1883 */
1884function tags_get_critical_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1885	// Always modify the agent status filter
1886	$agent_filter["status"] = AGENT_STATUS_CRITICAL;
1887	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1888}
1889
1890/**
1891 * Get the number of the unknown agents that pass the filters.
1892 *
1893 * @param mixed $id_tag Id in integer or a set of ids into an array.
1894 * @param array $groups_and_tags Array with strict ACL rules.
1895 * @param array $agent_filter Filter of the agents.
1896 * This filter support the following fields:
1897 * -'name': (string) Agent name. e.g.: "agent_1".
1898 * @param array $module_filter Filter of the modules.
1899 * This filter support the following fields:
1900 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1901 * -'name': (string) Module name. e.g.: "module_1".
1902 * @param bool $realtime Search realtime values or the values processed by the server.
1903 *
1904 * @return int Number of monitors.
1905 *
1906 */
1907function tags_get_unknown_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1908	// Always modify the agent status filter
1909	$agent_filter["status"] = AGENT_STATUS_UNKNOWN;
1910	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1911}
1912
1913/**
1914 * Get the number of the not init agents that pass the filters.
1915 *
1916 * @param mixed $id_tag Id in integer or a set of ids into an array.
1917 * @param array $groups_and_tags Array with strict ACL rules.
1918 * @param array $agent_filter Filter of the agents.
1919 * This filter support the following fields:
1920 * -'name': (string) Agent name. e.g.: "agent_1".
1921 * @param array $module_filter Filter of the modules.
1922 * This filter support the following fields:
1923 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1924 * -'name': (string) Module name. e.g.: "module_1".
1925 * @param bool $realtime Search realtime values or the values processed by the server.
1926 *
1927 * @return int Number of monitors.
1928 *
1929 */
1930function tags_get_not_init_agents ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array(), $realtime = true) {
1931	// Always modify the agent status filter
1932	$agent_filter["status"] = AGENT_STATUS_NOT_INIT;
1933	return tags_get_agents_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter, $realtime);
1934}
1935
1936/**
1937 * Get the number of the monitors that pass the filters.
1938 *
1939 * @param mixed $id_tag Id in integer or a set of ids into an array.
1940 * @param array $groups_and_tags Array with strict ACL rules.
1941 * @param array $agent_filter Filter of the agents.
1942 * This filter support the following fields:
1943 * -'name': (string) Agent name. e.g.: "agent_1".
1944 * -'id': (mixed) Agent id. e.g.: "1".
1945 * @param array $module_filter Filter of the modules.
1946 * This filter support the following fields:
1947 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
1948 * -'name': (string) Module name. e.g.: "module_1".
1949 *
1950 * @return int Number of monitors.
1951 *
1952 */
1953function tags_get_monitors_counter ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
1954
1955	// Avoid mysql error
1956	if (empty($id_tag))
1957		return false;
1958
1959	$groups_clause = "";
1960	if (!empty($groups_and_tags)) {
1961
1962		$groups_id = array();
1963		foreach ($groups_and_tags as $group_id => $tags) {
1964			if (!empty($tags)) {
1965				$tags_arr = explode(',', $tags);
1966				foreach ($tags_arr as $tag) {
1967					if ($tag == $id_tag) {
1968						$hierarchy_groups = groups_get_id_recursive($group_id);
1969						$groups_id = array_merge($groups_id, $hierarchy_groups);
1970					}
1971				}
1972			}
1973		}
1974		if (array_search(0, $groups_id) === false) {
1975			$groups_id = array_unique($groups_id);
1976			$groups_id_str = implode(",", $groups_id);
1977			$groups_clause = " AND ta.id_grupo IN ($groups_id_str)";
1978		}
1979	}
1980
1981	$agent_name_filter = "";
1982	$agents_clause = "";
1983	if (!empty($agent_filter)) {
1984		// Name
1985		if (isset($agent_filter["name"]) && !empty($agent_filter["name"])) {
1986			$agent_name_filter = "AND ta.nombre LIKE '%" . $agent_filter["name"] . "%'";
1987		}
1988		// ID
1989		if (isset($agent_filter["id"])) {
1990			if (is_array($agent_filter["id"]))
1991				$agents = array_unique($agent_filter["id"]);
1992			else
1993				$agents = array($agent_filter["id"]);
1994			$agents_str = implode (",", $agents);
1995			$agents_clause = "AND ta.id_agente IN ($agents_str)";
1996		}
1997	}
1998
1999	$module_name_filter = "";
2000	$module_status_array = "";
2001	$modules_clause = "";
2002	if (!empty($module_filter)) {
2003		// Name
2004		if (isset($module_filter["name"]) && !empty($module_filter["name"])) {
2005			$module_name_filter = "AND tam.nombre LIKE '%" . $module_filter["name"] . "%'";
2006		}
2007		// Status
2008		if (isset($module_filter["status"])) {
2009			$module_status = $module_filter["status"];
2010			if (is_array($module_status))
2011				$module_status = array_unique($module_status);
2012			else
2013				$module_status = array($module_status);
2014
2015			$status_array = "";
2016			foreach ($module_status as $status) {
2017				switch ($status) {
2018					case AGENT_MODULE_STATUS_ALL:
2019						$status_array[] = AGENT_MODULE_STATUS_CRITICAL_ALERT;
2020						$status_array[] = AGENT_MODULE_STATUS_CRITICAL_BAD;
2021						$status_array[] = AGENT_MODULE_STATUS_WARNING_ALERT;
2022						$status_array[] = AGENT_MODULE_STATUS_WARNING;
2023						$status_array[] = AGENT_MODULE_STATUS_UNKNOWN;
2024						$status_array[] = AGENT_MODULE_STATUS_NO_DATA;
2025						$status_array[] = AGENT_MODULE_STATUS_NOT_INIT;
2026						$status_array[] = AGENT_MODULE_STATUS_NORMAL_ALERT;
2027						$status_array[] = AGENT_MODULE_STATUS_NORMAL;
2028						break;
2029					case AGENT_MODULE_STATUS_CRITICAL_ALERT:
2030					case AGENT_MODULE_STATUS_CRITICAL_BAD:
2031						$status_array[] = AGENT_MODULE_STATUS_CRITICAL_ALERT;
2032						$status_array[] = AGENT_MODULE_STATUS_CRITICAL_BAD;
2033						break;
2034					case AGENT_MODULE_STATUS_WARNING_ALERT:
2035					case AGENT_MODULE_STATUS_WARNING:
2036						$status_array[] = AGENT_MODULE_STATUS_WARNING_ALERT;
2037						$status_array[] = AGENT_MODULE_STATUS_WARNING;
2038						break;
2039					case AGENT_MODULE_STATUS_UNKNOWN:
2040						$status_array[] = AGENT_MODULE_STATUS_UNKNOWN;
2041						break;
2042					case AGENT_MODULE_STATUS_NO_DATA:
2043					case AGENT_MODULE_STATUS_NOT_INIT:
2044						$status_array[] = AGENT_MODULE_STATUS_NO_DATA;
2045						$status_array[] = AGENT_MODULE_STATUS_NOT_INIT;
2046						break;
2047					case AGENT_MODULE_STATUS_NORMAL_ALERT:
2048					case AGENT_MODULE_STATUS_NORMAL:
2049						$status_array[] = AGENT_MODULE_STATUS_NORMAL_ALERT;
2050						$status_array[] = AGENT_MODULE_STATUS_NORMAL;
2051						break;
2052					default:
2053						// The status doesn't exist
2054						return false;
2055				}
2056			}
2057			if (!empty($status_array)) {
2058				$status_array = array_unique($status_array);
2059				$status_str = implode(",", $status_array);
2060
2061				$modules_clause = "AND tae.estado IN ($status_str)";
2062			}
2063		}
2064	}
2065
2066	$sql = "SELECT COUNT(DISTINCT tam.id_agente_modulo)
2067			FROM tagente_modulo tam
2068			INNER JOIN tagente_estado tae
2069				ON tam.id_agente_modulo = tae.id_agente_modulo
2070					$modules_clause
2071			INNER JOIN ttag_module ttm
2072				ON ttm.id_tag = $id_tag
2073					AND tam.id_agente_modulo = ttm.id_agente_modulo
2074			INNER JOIN tagente ta
2075				ON tam.id_agente = ta.id_agente
2076					AND ta.disabled = 0
2077					$agent_name_filter
2078					$agents_clause
2079					$groups_clause
2080			WHERE tam.disabled = 0
2081				$module_name_filter";
2082
2083	$count = db_get_sql ($sql);
2084
2085	return $count;
2086}
2087
2088/**
2089 * Get the number of the total monitors that pass the filters.
2090 *
2091 * @param mixed $id_tag Id in integer or a set of ids into an array.
2092 * @param array $groups_and_tags Array with strict ACL rules.
2093 * @param array $agent_filter Filter of the agents.
2094 * This filter support the following fields:
2095 * -'id': (mixed) Agent id. e.g.: "1".
2096 * @param array $module_filter Filter of the modules.
2097 * This filter support the following fields:
2098 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2099 * -'name': (string) Module name. e.g.: "module_1".
2100 *
2101 * @return int Number of monitors.
2102 *
2103 */
2104function tags_get_total_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2105	// Always modify the module status filter
2106	$module_filter["status"] = AGENT_MODULE_STATUS_ALL;
2107	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2108}
2109
2110/**
2111 * Get the number of the normal monitors that pass the filters.
2112 *
2113 * @param mixed $id_tag Id in integer or a set of ids into an array.
2114 * @param array $groups_and_tags Array with strict ACL rules.
2115 * @param array $agent_filter Filter of the agents.
2116 * This filter support the following fields:
2117 * -'id': (mixed) Agent id. e.g.: "1".
2118 * @param array $module_filter Filter of the modules.
2119 * This filter support the following fields:
2120 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2121 * -'name': (string) Module name. e.g.: "module_1".
2122 *
2123 * @return int Number of monitors.
2124 *
2125 */
2126function tags_get_normal_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2127	// Always modify the module status filter
2128	$module_filter["status"] = AGENT_MODULE_STATUS_NORMAL;
2129	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2130}
2131
2132/**
2133 * Get the number of the critical monitors that pass the filters.
2134 *
2135 * @param mixed $id_tag Id in integer or a set of ids into an array.
2136 * @param array $groups_and_tags Array with strict ACL rules.
2137 * @param array $agent_filter Filter of the agents.
2138 * This filter support the following fields:
2139 * -'id': (mixed) Agent id. e.g.: "1".
2140 * @param array $module_filter Filter of the modules.
2141 * This filter support the following fields:
2142 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2143 * -'name': (string) Module name. e.g.: "module_1".
2144 *
2145 * @return int Number of monitors.
2146 *
2147 */
2148function tags_get_critical_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2149	// Always modify the module status filter
2150	$module_filter["status"] = AGENT_MODULE_STATUS_CRITICAL_BAD;
2151	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2152}
2153
2154/**
2155 * Get the number of the warning monitors that pass the filters.
2156 *
2157 * @param mixed $id_tag Id in integer or a set of ids into an array.
2158 * @param array $groups_and_tags Array with strict ACL rules.
2159 * @param array $agent_filter Filter of the agents.
2160 * This filter support the following fields:
2161 * -'id': (mixed) Agent id. e.g.: "1".
2162 * @param array $module_filter Filter of the modules.
2163 * This filter support the following fields:
2164 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2165 * -'name': (string) Module name. e.g.: "module_1".
2166 *
2167 * @return int Number of monitors.
2168 *
2169 */
2170function tags_get_warning_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2171	// Always modify the module status filter
2172	$module_filter["status"] = AGENT_MODULE_STATUS_WARNING;
2173	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2174}
2175
2176/**
2177 * Get the number of the not init monitors that pass the filters.
2178 *
2179 * @param mixed $id_tag Id in integer or a set of ids into an array.
2180 * @param array $groups_and_tags Array with strict ACL rules.
2181 * @param array $agent_filter Filter of the agents.
2182 * This filter support the following fields:
2183 * -'id': (mixed) Agent id. e.g.: "1".
2184 * @param array $module_filter Filter of the modules.
2185 * This filter support the following fields:
2186 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2187 * -'name': (string) Module name. e.g.: "module_1".
2188 *
2189 * @return int Number of monitors.
2190 *
2191 */
2192function tags_get_not_init_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2193	// Always modify the module status filter
2194	$module_filter["status"] = AGENT_MODULE_STATUS_NOT_INIT;
2195	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2196}
2197
2198/**
2199 * Get the number of the unknown monitors that pass the filters.
2200 *
2201 * @param mixed $id_tag Id in integer or a set of ids into an array.
2202 * @param array $groups_and_tags Array with strict ACL rules.
2203 * @param array $agent_filter Filter of the agents.
2204 * This filter support the following fields:
2205 * -'id': (mixed) Agent id. e.g.: "1".
2206 * @param array $module_filter Filter of the modules.
2207 * This filter support the following fields:
2208 * -'status': (mixed) Module status. Single or grouped into an array. e.g.: AGENT_MODULE_STATUS_CRITICAL.
2209 * -'name': (string) Module name. e.g.: "module_1".
2210 *
2211 * @return int Number of monitors.
2212 *
2213 */
2214function tags_get_unknown_monitors ($id_tag, $groups_and_tags = array(), $agent_filter = array(), $module_filter = array()) {
2215	// Always modify the module status filter
2216	$module_filter["status"] = AGENT_MODULE_STATUS_UNKNOWN;
2217	return tags_get_monitors_counter($id_tag, $groups_and_tags, $agent_filter, $module_filter);
2218}
2219
2220/**
2221 * Get the monitors fired alerts count.
2222 *
2223 * @param int $id_tag Id of the tag to filter the modules.
2224 * @param array $groups_and_tags Array with strict ACL rules.
2225 * @param mixed $id_agente Id or ids of the agent to filter the modules.
2226 *
2227 * @return mixed Returns the count of the modules fired alerts or false on error.
2228 */
2229function tags_monitors_fired_alerts ($id_tag, $groups_and_tags = array(), $id_agente = false) {
2230
2231	// Avoid mysql error
2232	if (empty($id_tag))
2233		return;
2234
2235	$groups_clause = "";
2236	if (!empty($groups_and_tags)) {
2237
2238		$groups_id = array();
2239		foreach ($groups_and_tags as $group_id => $tags) {
2240			if (!empty($tags)) {
2241				$tags_arr = explode(',', $tags);
2242				foreach ($tags_arr as $tag) {
2243					if ($tag == $id_tag) {
2244						$hierarchy_groups = groups_get_id_recursive($group_id);
2245						$groups_id = array_merge($groups_id, $hierarchy_groups);
2246					}
2247				}
2248			}
2249		}
2250		if (array_search(0, $groups_id) === false) {
2251			$groups_id_str = implode(",", $groups_id);
2252			$groups_clause = " AND tagente.id_grupo IN ($groups_id_str)";
2253		}
2254	}
2255	$agents_clause = "";
2256	if ($id_agente !== false) {
2257		if (is_array($id_agente)) {
2258			$id_agente = implode(",", $id_agente);
2259		}
2260		$agents_clause = " AND tagente.id_agente IN ($id_agente)";
2261	}
2262
2263	$sql = "SELECT COUNT(talert_template_modules.id)
2264		FROM talert_template_modules, tagente_modulo, tagente_estado, tagente
2265		WHERE tagente_modulo.id_agente = tagente.id_agente
2266		AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
2267		AND tagente_modulo.disabled = 0 AND tagente.disabled = 0
2268		AND talert_template_modules.disabled = 0
2269		AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo
2270		AND times_fired > 0
2271		AND tagente_modulo.id_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag = $id_tag)
2272		$agents_clause
2273		$groups_clause";
2274
2275	$count = db_get_sql ($sql);
2276
2277	return $count;
2278}
2279
2280/**
2281 * Get the monitors alerts count.
2282 *
2283 * @param int $id_tag Id of the tag to filter the modules alerts.
2284 * @param array $groups_and_tags Array with strict ACL rules.
2285 * @param mixed $id_agente Id or ids of the agent to filter the modules.
2286 *
2287 * @return mixed Returns the count of the modules alerts or false on error.
2288 */
2289function tags_get_monitors_alerts ($id_tag, $groups_and_tags = array(), $id_agente = false) {
2290
2291	// Avoid mysql error
2292	if (empty($id_tag))
2293		return;
2294
2295	$groups_clause = "";
2296	if (!empty($groups_and_tags)) {
2297
2298		$groups_id = array();
2299		foreach ($groups_and_tags as $group_id => $tags) {
2300			if (!empty($tags)) {
2301				$tags_arr = explode(',', $tags);
2302				foreach ($tags_arr as $tag) {
2303					if ($tag == $id_tag) {
2304						$hierarchy_groups = groups_get_id_recursive($group_id);
2305						$groups_id = array_merge($groups_id, $hierarchy_groups);
2306					}
2307				}
2308			}
2309		}
2310		if (array_search(0, $groups_id) === false) {
2311			$groups_id_str = implode(",", $groups_id);
2312			$groups_clause = " AND tagente.id_grupo IN ($groups_id_str)";
2313		}
2314	}
2315	$agents_clause = "";
2316	if ($id_agente !== false) {
2317		if (is_array($id_agente)) {
2318			$id_agente = implode(",", $id_agente);
2319		}
2320		$agents_clause = " AND tagente.id_agente IN ($id_agente)";
2321	}
2322
2323	$sql = "SELECT COUNT(talert_template_modules.id)
2324		FROM talert_template_modules, tagente_modulo, tagente_estado, tagente
2325		WHERE tagente_modulo.id_agente = tagente.id_agente
2326		AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
2327		AND tagente_modulo.disabled = 0 AND tagente.disabled = 0
2328		AND	talert_template_modules.disabled = 0
2329		AND talert_template_modules.id_agent_module = tagente_modulo.id_agente_modulo
2330		AND tagente_modulo.id_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag = $id_tag)
2331		$agents_clause
2332		$groups_clause";
2333
2334	$count = db_get_sql ($sql);
2335
2336	return $count;
2337}
2338
2339function __add_acltags (&$acltags, $group_id, $tags_str) {
2340	if (!isset($acltags[$group_id])) {
2341		// Add the new element
2342		$acltags[$group_id] = $tags_str;
2343	}
2344	else {
2345		// Add the tags. The empty tags have priority cause mean more permissions
2346		$existing_tags = $acltags[$group_id];
2347
2348		if (!empty($existing_tags)) {
2349			$existing_tags_array = explode(",", $existing_tags);
2350
2351			// Store the empty tags
2352			if (empty($tags_str)) {
2353				$acltags[$group_id] = '';
2354			}
2355			// Merge the old and new tabs
2356			else {
2357				$new_tags_array = explode(",", $tags_str);
2358
2359				$final_tags_array = array_merge($existing_tags_array, $new_tags_array);
2360				$final_tags_str = implode(",", $final_tags_array);
2361
2362				if (! empty($final_tags_str))
2363					$acltags[$group_id] = $final_tags_str;
2364			}
2365		}
2366	}
2367
2368	// Propagation
2369	$propagate = (bool) db_get_value('propagate', 'tgrupo', 'id_grupo', $group_id);
2370	if ($propagate) {
2371		$sql = "SELECT id_grupo FROM tgrupo WHERE parent = $group_id";
2372		$children = db_get_all_rows_sql($sql);
2373
2374		if ($children === false)
2375			$children = array();
2376
2377		foreach ($children as $children_group) {
2378			// Add the tags to the children (recursive)
2379			__add_acltags($acltags, $children_group['id_grupo'], $tags_str);
2380		}
2381	}
2382}
2383
2384/* Return array with groups and their tags */
2385function tags_get_user_module_and_tags ($id_user = false, $access = 'AR', $strict_user = false) {
2386	global $config;
2387
2388	if ($id_user == false) {
2389		$id_user = $config['id_user'];
2390	}
2391
2392	$acl_column = get_acl_column($access);
2393
2394	$sql = sprintf("SELECT tags, id_grupo
2395					FROM tusuario_perfil, tperfil
2396					WHERE tperfil.id_perfil = tusuario_perfil.id_perfil AND
2397						tusuario_perfil.id_usuario = '%s' AND
2398						tperfil.%s = 1
2399					ORDER BY id_grupo", $id_user, $acl_column);
2400	$tags_and_groups = db_get_all_rows_sql($sql);
2401
2402	if ($tags_and_groups === false)
2403		$tags_and_groups = array();
2404
2405	$acltags = array();
2406
2407	// Change the 'All' group with all groups
2408	$user_groups = users_get_groups($id_user, $access, false);
2409	$user_groups_ids = array();
2410	if (!empty($user_groups) && is_array($user_groups)) {
2411		$user_groups_ids = array_keys($user_groups);
2412	}
2413
2414	// If the user is admin, he should have access to the all group with the required permission
2415	if (is_user_admin($id_user))
2416		array_unshift($tags_and_groups, array('id_grupo' => 0, 'tags' => ''));
2417
2418	$tags_and_groups_aux = array();
2419	foreach ($tags_and_groups as $data) {
2420		// All group
2421		if ((int)$data['id_grupo'] === 0) {
2422			// All group with empty tags. All groups without tags permission!
2423			if (empty($data['tags'])) {
2424				foreach ($user_groups_ids as $group_id) {
2425					$acltags[$group_id] = '';
2426				}
2427
2428				return $acltags; // End of the function
2429			}
2430			// Create a new element for every group with the tags
2431			else {
2432				foreach ($user_groups_ids as $group_id) {
2433					$tags_and_groups_aux[] = array(
2434							'id_grupo' => $group_id,
2435							'tags' => $data['tags']
2436						);
2437				}
2438			}
2439		}
2440		// Specific group
2441		else {
2442			$tags_and_groups_aux[] = $data;
2443		}
2444	}
2445	$tags_and_groups = $tags_and_groups_aux;
2446	unset($tags_and_groups_aux);
2447
2448
2449	foreach ($tags_and_groups as $group_tag) {
2450		__add_acltags($acltags, $group_tag['id_grupo'], $group_tag['tags']);
2451	}
2452
2453
2454	return $acltags;
2455}
2456
2457/**
2458 * Get agents filtering by id_tag.
2459 *
2460 * @param int $id_tag Id of the tag to search total agents
2461 *
2462 * @return mixed Returns count of agents with this tag or false if they aren't.
2463 */
2464function tags_get_all_user_agents ($id_tag = false, $id_user = false, $groups_and_tags = array(), $filter = false, $fields = false, $meta = true, $strict_user = true, $return_all_fields = false) {
2465
2466	global $config;
2467
2468	if (empty($id_tag)) {
2469		$tag_filter = '';
2470	} else {
2471		$tag_filter = " AND tagente_modulo.id_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag = $id_tag) ";
2472	}
2473	if (empty($id_user)) {
2474		$id_user = $config['id_user'];
2475	}
2476
2477	if (!is_array ($fields)) {
2478		$fields = array ();
2479		$fields[0] = "id_agente";
2480		$fields[1] = "nombre";
2481	}
2482
2483	$select_fields = implode(',',$fields);
2484
2485	$groups_clause = "";
2486	if ($strict_user) {
2487		if (!empty($groups_and_tags)) {
2488			$groups_clause = " AND ".tags_get_acl_tags_module_condition($groups_and_tags, "tagente_modulo");
2489		}
2490	} else {
2491		$groups_clause = " AND tagente.id_grupo IN (".implode(',', array_keys($groups_and_tags)).")";
2492	}
2493
2494	if (!empty($filter['id_group'])) {
2495		if (is_array($filter['id_group']))
2496			$groups_str = implode(",", $filter['id_group']);
2497		else
2498			$groups_str = $filter['id_group'];
2499		$groups_clause .= " AND tagente.id_grupo IN ($groups_str)";
2500	}
2501
2502	$status_sql = '';
2503	if (isset($filter['status'])) {
2504		switch ($filter['status']) {
2505			case AGENT_STATUS_NORMAL:
2506				$status_sql =
2507					" AND (normal_count = total_count)";
2508				break;
2509			case AGENT_STATUS_WARNING:
2510				$status_sql =
2511					"AND (critical_count = 0 AND warning_count > 0)";
2512				break;
2513			case AGENT_STATUS_CRITICAL:
2514				$status_sql =
2515					"AND (critical_count > 0)";
2516				break;
2517			case AGENT_STATUS_UNKNOWN:
2518				$status_sql =
2519					"AND (critical_count = 0 AND warning_count = 0
2520						AND unknown_count > 0)";
2521				break;
2522			case AGENT_STATUS_NOT_NORMAL:
2523				$status_sql = " AND (normal_count <> total_count)";
2524				break;
2525			case AGENT_STATUS_NOT_INIT:
2526				$status_sql = "AND (notinit_count = total_count)";
2527				break;
2528		}
2529
2530	}
2531	$disabled_sql = '';
2532	if (!empty($filter['disabled'])) {
2533		$disabled_sql = " AND disabled = ".$filter['disabled'];
2534	}
2535
2536	$order_by_condition = '';
2537	if (!empty($filter['order'])) {
2538		$order_by_condition = " ORDER BY ".$filter['order'];
2539	}
2540	else {
2541		$order_by_condition = " ORDER BY tagente.nombre ASC";
2542	}
2543	$limit_sql = '';
2544	if (isset($filter['offset'])) {
2545		$offset = $filter['offset'];
2546	}
2547	if (isset($filter['limit'])) {
2548		$limit = $filter['limit'];
2549	}
2550
2551	if (isset($offset) && isset($limit)) {
2552		$limit_sql = " LIMIT $offset, $limit ";
2553	}
2554
2555	if (!empty($filter['group_by'])) {
2556		$group_by = " GROUP BY ".$filter['group_by'];
2557	}
2558	else {
2559		$group_by = " GROUP BY tagente.nombre";
2560	}
2561
2562	$id_agent_search = '';
2563	if (!empty($filter['id_agent'])) {
2564		$id_agent_search = " AND tagente.id_agente = ".$filter['id_agent'];
2565	}
2566
2567	$search_sql = "";
2568	$void_agents = "";
2569	if ($filter) {
2570		if (($filter['search']) != "") {
2571			$string = io_safe_input ($filter['search']);
2572			$search_sql = ' AND (tagente.nombre COLLATE utf8_general_ci LIKE "%'.$string.'%")';
2573		}
2574
2575		if (isset($filter['show_void_agents'])) {
2576			if (!$filter['show_void_agents']) {
2577				$void_agents = " AND tagente_modulo.delete_pending = 0";
2578			}
2579		}
2580	}
2581
2582	$user_agents_sql = "SELECT ".$select_fields ."
2583		FROM tagente, tagente_modulo
2584		WHERE tagente.id_agente = tagente_modulo.id_agente
2585		". $tag_filter .
2586		$groups_clause . $search_sql . $void_agents .
2587		$status_sql .
2588		$disabled_sql .
2589		$group_by .
2590		$order_by_condition .
2591		$limit_sql;
2592
2593	$user_agents = db_get_all_rows_sql($user_agents_sql);
2594
2595	if ($user_agents == false) {
2596		$user_agents = array();
2597	}
2598	if ($return_all_fields) {
2599		return $user_agents;
2600	}
2601	if (!$meta) {
2602		$user_agents_aux = array();
2603
2604		foreach ($user_agents as $ua) {
2605			$user_agents_aux[$ua['id_agente']] = $ua['nombre'];
2606		}
2607		return $user_agents_aux;
2608	}
2609	return $user_agents;
2610}
2611
2612function tags_get_agent_modules ($id_agent, $id_tag = false, $groups_and_tags = array(), $fields = false, $filter = false, $return_all_fields = false, $get_filter_status = -1) {
2613
2614	global $config;
2615
2616	// Avoid mysql error
2617	if (empty($id_agent))
2618		return false;
2619
2620	if (empty($id_tag)) {
2621		$tag_filter = "";
2622	} else {
2623		$tag_filter = " AND tagente_modulo.id_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag = $id_tag) ";
2624	}
2625
2626	if (!is_array ($fields)) {
2627		$fields = array ();
2628		$fields[0] = "tagente_modulo.id_agente_modulo";
2629		$fields[1] = "tagente_modulo.nombre";
2630	}
2631	$select_fields = implode(',',$fields);
2632
2633	if ($filter) {
2634		$filter_sql = '';
2635		if (isset($filter['disabled'])) {
2636			$filter_sql .= " AND tagente_modulo.disabled = ".$filter['disabled'];
2637		}
2638		if (isset($filter['nombre'])) {
2639			$filter_sql .= ' AND tagente_modulo.nombre LIKE "' .$filter['nombre'].'"';
2640		}
2641
2642	}
2643
2644	if (!empty($groups_and_tags)) {
2645		$agent_group = db_get_value('id_grupo', 'tagente', 'id_agente', $id_agent);
2646		if (isset($groups_and_tags[$agent_group]) && ($groups_and_tags[$agent_group] != '')) {
2647			//~ $tag_filter = " AND ttag_module.id_tag IN (".$groups_and_tags[$agent_group].")";
2648			$tag_filter .= " AND tagente_modulo.id_agente_modulo IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag IN (".$groups_and_tags[$agent_group]."))";
2649		}
2650	}
2651
2652	if ($get_filter_status != -1) {
2653		$agent_modules_sql = "SELECT ".$select_fields ."
2654			FROM tagente_modulo, tagente_estado
2655			WHERE tagente_modulo.id_agente=". $id_agent .
2656			" AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
2657			 AND tagente_estado.estado = ".$get_filter_status .
2658			$tag_filter .
2659			$filter_sql ."
2660			ORDER BY nombre";
2661	}
2662	else {
2663
2664		$agent_modules_sql = "SELECT ".$select_fields ."
2665			FROM tagente_modulo
2666			WHERE id_agente=". $id_agent .
2667			$tag_filter .
2668			$filter_sql ."
2669			ORDER BY nombre";
2670	}
2671
2672	$agent_modules = db_get_all_rows_sql($agent_modules_sql);
2673
2674	if ($agent_modules == false) {
2675		$agent_modules = array();
2676	}
2677
2678	if ($return_all_fields) {
2679		$result = array();
2680		foreach ($agent_modules as $am) {
2681			$am['status'] = modules_get_agentmodule_status($am['id_agente_modulo']);
2682			$am['isinit'] = modules_get_agentmodule_is_init($am['id_agente_modulo']);
2683			if ($am['isinit']) {
2684
2685			}
2686			$result[$am['id_agente_modulo']] = $am;
2687		}
2688		return $result;
2689	}
2690
2691	$result = array();
2692	foreach ($agent_modules as $am) {
2693		$result[$am['id_agente_modulo']] = $am['nombre'];
2694	}
2695
2696	return $result;
2697}
2698
2699function tags_get_module_policy_tags($id_tag, $id_module) {
2700	if (empty($id_tag))
2701		return false;
2702
2703	$id_module_policy = db_get_value_filter('id_policy_module',
2704		'ttag_module',
2705		array('id_tag' => $id_tag, 'id_agente_modulo' => $id_module));
2706
2707	return $id_module_policy;
2708}
2709?>
2710