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 Alerts
20 */
21
22require_once($config['homedir'] . "/include/functions_agents.php");
23require_once($config['homedir'] . '/include/functions_modules.php');
24require_once($config['homedir'] . '/include/functions_users.php');
25
26function alerts_get_alerts($id_group = 0, $free_search = "", $status = "all", $standby = -1, $acl = false, $total = false, $id_agent = 0) {
27	$sql = "";
28	$alerts = array();
29
30	//----------- Group ------------------------------------------------
31	if ($id_group != 0) {
32		if ($acl !== false) {
33			$groups = users_get_groups (false, $acl, false);
34
35			if (array_key_exists($id_group, $groups)) {
36				$group_query = " AND t3.id_grupo = " . $id_group . " ";
37			}
38			else {
39				//Set to fail the query
40				$group_query = " AND 1=0 ";
41			}
42		}
43		else {
44			$group_query = " AND t3.id_grupo = " . $id_group . " ";
45		}
46	}
47	else {
48		if ($acl !== false) {
49			$groups = users_get_groups (false, $acl, false);
50
51			$id_groups = array_keys($groups);
52
53			$group_query = " AND t3.id_grupo IN (" . implode(',', $id_groups) . ") ";
54		}
55		else {
56			$group_query = "";
57		}
58	}
59
60	//------------ Status ----------------------------------------------
61	switch ($status) {
62		case "notfired":
63			$status_query = ' AND t0.times_fired = 0 AND t0.disabled = 0';
64			break;
65		case "fired":
66			$status_query = ' AND t0.times_fired > 0 AND t0.disabled = 0';
67			break;
68		case "disabled":
69			$status_query = ' AND t0.disabled = 1';
70			break;
71		case "all_enabled":
72			$status_query = ' AND t0.disabled = 0';
73			break;
74		default:
75			$status_query = '';
76			break;
77	}
78
79	//----------- Standby ----------------------------------------------
80	$standby_query = '';
81	if ($standby != -1) {
82		$status_query .= ' AND t0.standby = ' . $standby . ' ';
83	}
84
85	//----------- Free search ------------------------------------------
86	$free_search = io_safe_input($free_search);
87
88	//----------- Make the query ---------------------------------------
89	if ($total) {
90		$sql = 'SELECT COUNT(*)';
91	}
92	else {
93		$sql = 'SELECT *, t2.nombre AS module_name,
94			t3.nombre AS agent_name, t1.name AS template_name,
95			t0.disabled AS alert_disabled ';
96	}
97	$sql .= '
98		FROM talert_template_modules AS t0
99		INNER JOIN talert_templates t1
100			ON t0.id_alert_template = t1.id
101		INNER JOIN tagente_modulo t2
102			ON t0.id_agent_module = t2.id_agente_modulo
103		INNER JOIN tagente t3
104			ON t2.id_agente = t3.id_agente
105		WHERE 1=1
106			' . $status_query . ' ' . $standby_query . ' ' . $group_query . '
107			AND (t1.name LIKE "%' . $free_search . '%"
108				OR t2.nombre LIKE "%' . $free_search . '%"
109				OR t3.nombre LIKE "%' . $free_search . '%")';
110
111	if ($id_agent != 0) {
112		$sql .= ' AND t3.id_agente = ' . $id_agent;
113	}
114
115	$row_alerts = db_get_all_rows_sql($sql);
116
117	if ($total) {
118		return reset($row_alerts[0]);
119	}
120	else {
121
122
123		return $row_alerts;
124	}
125}
126
127/**
128 * Get fired status from any alert of agent in group.
129 *
130 * @param integer $idGroup The ID of group.
131 * @param mixed $type The list of types to search or type. By default "alert_fired".
132 *
133 * @return mixed Return id if the group have any alert is fired or false is not.
134 */
135function alerts_get_event_status_group($idGroup, $type = "alert_fired", $query = 'AND 1=1') {
136	global $config;
137
138	$return = false;
139
140	$typeWhere = '';
141
142	if (!is_array($type)) {
143		$typeWhere = ' AND event_type = "' . $type . '" ';
144	}
145	else {
146		$temp = array();
147		foreach ($type as $item) {
148			$temp[] = '"' . $item . '"';
149		}
150
151		$typeWhere = ' AND event_type IN (' . implode(',', $temp) . ')';
152	}
153
154	$agents = agents_get_group_agents($idGroup, false, "lower", false);
155
156	$idAgents = array_keys($agents);
157
158	$result = db_get_all_rows_sql('SELECT id_evento
159		FROM tevento
160		WHERE estado = 0 AND id_agente IN (' . implode(',', $idAgents) . ') ' . $typeWhere . $query . '
161		ORDER BY id_evento DESC LIMIT 1');
162
163	if ($result === false) {
164		return false;
165	}
166
167	return $result[0]['id_evento'];
168}
169
170/**
171 * Insert in talert_commands a new command.
172 *
173 * @param string name command name to save in DB.
174 * @param string command String of command.
175 * @param mixed A single value or array of values to insert (can be a multiple amount of rows).
176 *
177 * @return mixed False in case of error or invalid values passed. Affected rows otherwise.
178 */
179function alerts_create_alert_command ($name, $command, $values = false) {
180	if (empty ($name))
181		return false;
182	if (empty ($command))
183		return false;
184	if (! is_array ($values))
185		$values = array ();
186	$values['name'] = $name;
187	$values['command'] = $command;
188
189	return @db_process_sql_insert ('talert_commands', $values);
190}
191
192/**
193 * Update a command in talert_commands.
194 *
195 * @param int Alert command Id.
196 * @param mixed Array of values to update.
197 *
198 * @return mixed False in case of error or invalid values passed. Affected rows otherwise
199 */
200function alerts_update_alert_command ($id_alert_command, $values) {
201	$id_alert_command = safe_int ($id_alert_command, 1);
202	if (empty ($id_alert_command))
203		return false;
204	if (! is_array ($values))
205		return false;
206
207	return (@db_process_sql_update ('talert_commands',
208		$values,
209		array ('id' => $id_alert_command))) !== false;
210}
211
212/**
213 * Delete a command in talert_commands.
214 *
215 * @param int Alert command Id.
216 *
217 * @return mixed False in case of error or invalid values passed. Affected rows otherwise
218 */
219function alerts_delete_alert_command ($id_alert_command) {
220	$id_alert_command = safe_int ($id_alert_command, 1);
221	if (empty ($id_alert_command))
222		return false;
223
224	return (@db_process_sql_delete ('talert_commands',
225		array ('id' => $id_alert_command))) !== false;
226}
227
228/**
229 * Get a command in talert_commands.
230 *
231 * @param int Alert command Id.
232 *
233 * @return mixed False in case of error or invalid values passed. All row of the selected command otherwise
234 */
235function alerts_get_alert_command ($id_alert_command) {
236	$id_alert_command = safe_int ($id_alert_command, 1);
237	if (empty ($id_alert_command))
238		return false;
239
240	return db_get_row ('talert_commands', 'id', $id_alert_command);
241}
242
243/**
244 * Get name of a command in talert_commands.
245 *
246 * @param int Alert command Id.
247 *
248 * @return mixed False in case of error or invalid values passed. Command name otherwise
249 */
250function alert_get_alert_command_name ($id_alert_command) {
251	$id_alert_command = safe_int ($id_alert_command, 1);
252	if (empty ($id_alert_command))
253		return false;
254
255	return db_get_value ('name', 'talert_commands', 'id', $id_alert_command);
256}
257
258/**
259 * Get command field of a command in talert_commands.
260 *
261 * @param int Alert command Id.
262 *
263 * @return mixed False in case of error or invalid values passed. Command field otherwise
264 */
265function alerts_get_alert_command_command ($id_alert_command) {
266	$id_alert_command = safe_int ($id_alert_command, 1);
267	if (empty ($id_alert_command))
268		return false;
269
270	return db_get_value ('command', 'talert_commands', 'id', $id_alert_command);
271}
272
273/**
274 * Get internal field of a command in talert_commands.
275 *
276 * @param int Alert command Id.
277 *
278 * @return mixed False in case of error or invalid values passed. Internal field otherwise
279 */
280function alerts_get_alert_command_internal ($id_alert_command) {
281	$id_alert_command = safe_int ($id_alert_command, 1);
282	if (empty ($id_alert_command))
283		return false;
284
285	return (bool) db_get_value ('internal', 'talert_commands', 'id', $id_alert_command);
286}
287
288/**
289 * Get description field of a command in talert_commands.
290 *
291 * @param int Alert command Id.
292 *
293 * @return mixed False in case of error or invalid values passed. Description field otherwise
294 */
295function alerts_get_alert_command_description ($id_alert_command) {
296	$id_alert_command = safe_int ($id_alert_command, 1);
297	if (empty ($id_alert_command))
298		return false;
299
300	return db_get_value ('description', 'talert_commands', 'id', $id_alert_command);
301}
302
303/**
304 * Creates a new alert action.
305 *
306 * @param string Name of the alert action
307 * @param int Id of the alert command associated
308 * @param mixed Other fields of the new alert or false.
309 *
310 * @return mixed Returns the id if success or false in case of fail.
311 */
312function alerts_create_alert_action ($name, $id_alert_command, $values = false) {
313	$id_alert_command = safe_int ($id_alert_command, 1);
314	if (empty ($id_alert_command))
315		return false;
316	if (empty ($name))
317		return false;
318
319	if (! is_array ($values))
320		$values = array ();
321	$values['name'] = $name;
322	$values['id_alert_command'] = (int) $id_alert_command;
323
324	return @db_process_sql_insert ('talert_actions', $values);
325}
326
327/**
328 * Updates an alert action.
329 *
330 * @param int Id of the alert action
331 * @param array Values to update.
332 *
333 * @return mixed Returns affected rows or false in case of fail.
334 */
335function alerts_update_alert_action ($id_alert_action, $values) {
336	$id_alert_action = safe_int ($id_alert_action, 1);
337	if (empty ($id_alert_action))
338		return false;
339	if (! is_array ($values))
340		return false;
341
342	return (@db_process_sql_update ('talert_actions',
343		$values,
344		array ('id' => $id_alert_action))) !== false;
345}
346
347/**
348 * Delete an alert action.
349 *
350 * @param int Id of the alert action
351 *
352 * @return mixed Returns affected rows or false in case of fail.
353 */
354function alerts_delete_alert_action ($id_alert_action) {
355	$id_alert_action = safe_int ($id_alert_action, 1);
356	if (empty ($id_alert_action))
357		return false;
358
359	return (@db_process_sql_delete ('talert_actions',
360		array ('id' => $id_alert_action))) !== false;
361}
362
363/**
364 * Clone an alert action.
365 *
366 * @param int Id of the original alert action
367 *
368 * @return mixed Id of the cloned action or false in case of fail.
369 */
370function alerts_clone_alert_action ($id_alert_action) {
371	$id_alert_action = safe_int ($id_alert_action, 1);
372	if (empty ($id_alert_action))
373		return false;
374
375	$action = alerts_get_alert_action($id_alert_action);
376
377	if (empty ($action))
378		return false;
379
380	unset($action['id']);
381
382	return alerts_create_alert_action ($action['name']." ".__('copy'), $action['id_alert_command'], $action);
383}
384
385/**
386 * Get all alert actions in Pandora DB.
387 *
388 * @param bool $only_names Return only names, by default is true.
389 * @param bool $acl Check the ACL, by default is false
390 *
391 * @return array The list of actions.
392 */
393function alerts_get_alert_actions ($only_names = true, $acl = false) {
394	$groups = users_get_groups(false, "AR", true);
395
396	if ($groups === false) {
397		$groups = array();
398	}
399	$id_groups = array_keys($groups);
400
401	$all_actions = db_get_all_rows_filter('talert_actions', array('id_group' => $id_groups));
402
403	if ($all_actions === false)
404		return array ();
405
406	if (! $only_names)
407		return $all_actions;
408
409	$actions = array ();
410	foreach ($all_actions as $action) {
411		$actions[$action['id']] = $action['name'];
412	}
413
414	return $actions;
415}
416
417/**
418 * Get actions alerts filtered.
419 *
420 * @param bool Return all fields or not.
421 * @param variant String with SQL filter or false in case you don't want to filter.
422 *
423 * @return mixed A matrix with all the values returned from the SQL statement or
424 * false in case of empty result
425 */
426function alerts_get_alert_actions_filter ($only_names = true, $filter = false) {
427
428	if (!$filter)
429		$all_actions = db_get_all_rows_in_table ('talert_actions');
430	elseif (is_string($filter))
431		$all_actions = db_get_all_rows_filter ('talert_actions', $filter);
432	else
433		$all_actions = false;
434
435	if ($all_actions === false)
436		return array ();
437
438	if (! $only_names)
439		return $all_actions;
440
441	$actions = array ();
442	foreach ($all_actions as $action) {
443		$actions[$action['id']] = $action['name'];
444	}
445
446	return $actions;
447}
448
449/**
450 * Get action alert.
451 *
452 * @param int Id of the action alert.
453 *
454 * @return mixed An array with the result set of the action alert or
455 * false in case of empty result
456 */
457function alerts_get_alert_action ($id_alert_action) {
458	$id_alert_action = safe_int ($id_alert_action, 1);
459	if (empty ($id_alert_action))
460		return false;
461
462	return db_get_row ('talert_actions', 'id', $id_alert_action);
463}
464
465/**
466 * Get Id of the alert command associated with an alert action.
467 *
468 * @param int Id of the action alert.
469 *
470 * @return mixed Id of the action alert or
471 * false in case of empty result
472 */
473function alerts_get_alert_action_alert_command_id ($id_alert_action) {
474	return db_get_value ('id_alert_command', 'talert_actions',
475		'id', $id_alert_action);
476}
477
478/**
479 * Get alert command associated with an alert action.
480 *
481 * @param int Id of the action alert.
482 *
483 * @return mixed Result set of the action alert or
484 * false in case of empty result
485 */
486function alerts_get_alert_action_alert_command ($id_alert_action) {
487	$id_command = alerts_get_alert_action_alert_command_id ($id_alert_action);
488
489	return alerts_get_alert_command ($id_command);
490}
491
492/**
493 * Get field1 of an alert action.
494 *
495 * @param int Id of the action alert.
496 *
497 * @return mixed Field1 of the action alert or
498 * false in case of empty result
499 */
500function alerts_get_alert_action_field1 ($id_alert_action) {
501	return db_get_value ('field1', 'talert_actions', 'id', $id_alert_action);
502}
503
504/**
505 * Get field2 of an alert action.
506 *
507 * @param int Id of the action alert.
508 *
509 * @return mixed Field2 of the action alert or
510 * false in case of empty result
511 */
512function alerts_get_alert_action_field2 ($id_alert_action) {
513	return db_get_value ('field2', 'talert_actions', 'id', $id_alert_action);
514}
515
516/**
517 * Get field3 of an alert action.
518 *
519 * @param int Id of the action alert.
520 *
521 * @return mixed Field3 of the action alert or
522 * false in case of empty result
523 */
524function alerts_get_alert_action_field3 ($id_alert_action) {
525	return db_get_value ('field3', 'talert_actions', 'id', $id_alert_action);
526}
527
528/**
529 * Get name of an alert action.
530 *
531 * @param int Id of the action alert.
532 *
533 * @return mixed Name of the action alert or
534 * false in case of empty result
535 */
536function alerts_get_alert_action_name ($id_alert_action) {
537	return db_get_value ('name', 'talert_actions', 'id', $id_alert_action);
538}
539
540/**
541 * Get types of alert templates.
542 *
543 * @return array Types of alert templates.
544 */
545function alerts_get_alert_templates_types () {
546	$types = array ();
547
548	$types['regex'] = __('Regular expression');
549	$types['max_min'] = __('Max and min');
550	$types['max'] = __('Max.');
551	$types['min'] = __('Min.');
552	$types['equal'] = __('Equal to');
553	$types['not_equal'] = __('Not equal to');
554	$types['warning'] = __('Warning status');
555	$types['critical'] = __('Critical status');
556	$types['unknown'] = __('Unknown status');
557	$types['onchange'] = __('On Change');
558	$types['always'] = __('Always');
559
560	return $types;
561}
562
563/**
564 * Get type name of an alert template.
565 *
566 * @param string alert template type.
567 *
568 * @return string name of the alert template.
569 */
570function alerts_get_alert_templates_type_name ($type) {
571	$types = alerts_get_alert_templates_types ();
572
573	if (! isset ($type[$type]))
574		return __('Unknown');
575
576	return $types[$type];
577}
578
579/**
580 * Creates an alert template.
581 *
582 * @param string Name of the alert template.
583 * @param string Type of the alert template.
584 * @param mixed Array of alert template values or false.
585 *
586 * @return string name of the alert template.
587 */
588function alerts_create_alert_template ($name, $type, $values = false) {
589	if (empty ($name))
590		return false;
591	if (empty ($type))
592		return false;
593
594	if (! is_array ($values))
595		$values = array ();
596	$values['name'] = $name;
597	$values['type'] = $type;
598
599	switch ($type) {
600	/* TODO: Check values based on type, return false if failure */
601	}
602
603	return @db_process_sql_insert ('talert_templates', $values);
604}
605
606/**
607 * Updates an alert template.
608 *
609 * @param int Id of the alert template.
610 * @param array Array of alert template values.
611 *
612 * @return mixed Number of rows affected or false if something goes wrong.
613 */
614function alerts_update_alert_template ($id_alert_template, $values) {
615	$id_alert_template = safe_int ($id_alert_template, 1);
616
617	if (empty ($id_alert_template))
618		return false;
619	if (! is_array ($values))
620		return false;
621
622	return (@db_process_sql_update ('talert_templates',
623		$values,
624		array ('id' => $id_alert_template))) !== false;
625}
626
627/**
628 * Deletes an alert template.
629 *
630 * @param int Id of the alert template.
631 *
632 * @return mixed Number of rows affected or false if something goes wrong.
633 */
634function alerts_delete_alert_template ($id_alert_template) {
635	$id_alert_template = safe_int ($id_alert_template, 1);
636
637	if (empty ($id_alert_template))
638		return false;
639
640	return @db_process_sql_delete ('talert_templates', array ('id' => $id_alert_template));
641}
642
643/**
644 * Get a set of alert templates.
645 *
646 * @param mixed Array with filter conditions or false.
647 * @param mixed Array with a set of fields to retrieve or false.
648 *
649 * @return mixed Array with selected alert templates or false if something goes wrong.
650 */
651function alerts_get_alert_templates ($filter = false, $fields = false) {
652	global $config;
653
654	if (isset($filter['offset'])) {
655		$offset = $filter['offset'];
656		unset($filter['offset']);
657	}
658
659	if (isset($filter['limit'])) {
660		$limit = $filter['limit'];
661		unset($filter['limit']);
662	}
663
664	$templates_sql = @db_get_all_rows_filter ('talert_templates', $filter, $fields, 'AND', false, true);
665
666	switch ($config["dbtype"]) {
667		case "mysql":
668		case "postgresql":
669			$limit_sql = '';
670			if (isset($offset) && isset($limit)) {
671				$limit_sql = " LIMIT $offset, $limit ";
672			}
673			else {
674				$limit_sql = "";
675			}
676
677			$sql = sprintf("%s %s", $templates_sql, $limit_sql);
678
679			$alert_templates = db_get_all_rows_sql($sql);
680			break;
681		case "oracle":
682			$set = array();
683			if (isset($offset) && isset($limit)) {
684				$set['limit'] = $limit;
685				$set['offset'] = $offset;
686			}
687
688			$alert_templates = oracle_recode_query ($templates_sql, $set, 'AND', false);
689			break;
690	}
691	return $alert_templates;
692}
693
694/**
695 * Get one alert template.
696 *
697 * @param int Id of an alert template.
698 *
699 * @return mixed Selected alert template or false if something goes wrong.
700 */
701function alerts_get_alert_template ($id_alert_template) {
702	global $config;
703
704	$alert_templates = false;
705	$id_alert_template = safe_int ($id_alert_template, 1);
706
707	if (!empty ($id_alert_template)) {
708		switch ($config['dbtype']) {
709			case "mysql":
710			case "postgresql":
711				$alert_templates = db_get_row ('talert_templates', 'id', $id_alert_template);
712				break;
713			case "oracle":
714				$sql = "SELECT column_name
715						FROM user_tab_columns
716						WHERE table_name = 'TALERT_TEMPLATES'
717							AND column_name NOT IN ('TIME_FROM','TIME_TO')";
718				$fields_select = db_get_all_rows_sql($sql);
719
720				$column_names = array_map(function($item) {
721					return $item['column_name'];
722				}, $fields_select);
723				$column_names_str = implode(',', $column_names);
724
725				$sql = "SELECT $column_names_str,
726							to_char(time_from, 'hh24:mi:ss') AS time_from,
727							to_char(time_to, 'hh24:mi:ss') AS time_to
728						FROM talert_templates
729						WHERE id = $id_alert_template";
730				$alert_templates = db_get_row_sql($sql);
731				break;
732		}
733	}
734
735	return $alert_templates;
736}
737
738/**
739 * Get field1 of talert_templates table.
740 *
741 * @param int Id of an alert template.
742 *
743 * @return mixed Field1 field or false if something goes wrong.
744 */
745function alerts_get_alert_template_field1 ($id_alert_template) {
746	return db_get_value ('field1', 'talert_templates', 'id', $id_alert_template);
747}
748
749/**
750 * Get field2 of talert_templates table.
751 *
752 * @param int Id of an alert template.
753 *
754 * @return mixed Field2 field or false if something goes wrong.
755 */
756function alerts_get_alert_template_field2 ($id_alert_template) {
757	return db_get_value ('field2', 'talert_templates', 'id', $id_alert_template);
758}
759
760/**
761 * Get field3 of talert_templates table.
762 *
763 * @param int Id of an alert template.
764 *
765 * @return mixed Field3 field or false if something goes wrong.
766 */
767function alerts_get_alert_template_field3 ($id_alert_template) {
768	return db_get_value ('field3', 'talert_templates', 'id', $id_alert_template);
769}
770
771/**
772 * Get name of talert_templates table.
773 *
774 * @param int Id of an alert template.
775 *
776 * @return mixed Name field or false if something goes wrong.
777 */
778function alerts_get_alert_template_name ($id_alert_template) {
779	return db_get_value ('name', 'talert_templates', 'id', $id_alert_template);
780}
781
782/**
783 * Get description of talert_templates table.
784 *
785 * @param int Id of an alert template.
786 *
787 * @return mixed Description field or false if something goes wrong.
788 */
789function alerts_get_alert_template_description ($id_alert_template) {
790	return db_get_value ('description', 'talert_templates', 'id', $id_alert_template);
791}
792
793/**
794 * Get type of talert_templates table.
795 *
796 * @param int Id of an alert template.
797 *
798 * @return mixed Type field or false if something goes wrong.
799 */
800function alerts_get_alert_template_type ($id_alert_template) {
801	return db_get_value ('type', 'talert_templates', 'id', $id_alert_template);
802}
803
804/**
805 * Get type's name of alert template.
806 *
807 * @param int Id of an alert template.
808 *
809 * @return mixed Type's name of an alert template or false if something goes wrong.
810 */
811function alerts_get_alert_template_type_name ($id_alert_template) {
812	$type = alerts_get_alert_template_type ($id_alert_template);
813
814	return alerts_get_alert_templates_type_name ($type);
815}
816
817/**
818 * Get value of talert_templates table.
819 *
820 * @param int Id of an alert template.
821 *
822 * @return mixed Value field or false if something goes wrong.
823 */
824function alerts_get_alert_template_value ($id_alert_template) {
825	return db_get_value ('value', 'talert_templates', 'id', $id_alert_template);
826}
827
828/**
829 * Get max_value of talert_templates table.
830 *
831 * @param int Id of an alert template.
832 *
833 * @return mixed Max_value field or false if something goes wrong.
834 */
835function alerts_get_alert_template_max_value ($id_alert_template) {
836	return db_get_value ('max_value', 'talert_templates', 'id', $id_alert_template);
837}
838
839/**
840 * Get min_value of talert_templates table.
841 *
842 * @param int Id of an alert template.
843 *
844 * @return mixed Min_value field or false if something goes wrong.
845 */
846function alerts_get_alert_template_min_value ($id_alert_template) {
847	return db_get_value ('min_value', 'talert_templates', 'id', $id_alert_template);
848}
849
850/**
851 * Get alert_text of talert_templates table.
852 *
853 * @param int Id of an alert template.
854 *
855 * @return mixed Alert_text field or false if something goes wrong.
856 */
857function alerts_get_alert_template_alert_text ($id_alert_template) {
858	return db_get_value ('alert_text', 'talert_templates', 'id', $id_alert_template);
859}
860
861/**
862 * Get time_from of talert_templates table.
863 *
864 * @param int Id of an alert template.
865 *
866 * @return mixed Time_from field or false if something goes wrong.
867 */
868function alerts_get_alert_template_time_from ($id_alert_template) {
869	return db_get_value ('time_from', 'talert_templates', 'id', $id_alert_template);
870}
871
872/**
873 * Get time_to of talert_templates table.
874 *
875 * @param int Id of an alert template.
876 *
877 * @return mixed Time_to field or false if something goes wrong.
878 */
879function alerts_get_alert_template_time_to ($id_alert_template) {
880	return db_get_value ('time_to', 'talert_templates', 'id', $id_alert_template);
881}
882
883/**
884 * Get alert template in weekday format.
885 *
886 * @param int Id of an alert template.
887 *
888 * @return mixed Alert template in weekday format or false if something goes wrong.
889 */
890function alerts_get_alert_template_weekdays ($id_alert_template) {
891	$alert = alerts_get_alert_template ($id_alert_template);
892
893	if ($alert === false)
894		return false;
895
896	$retval = array ();
897	$days = array ('monday', 'tuesday', 'wednesday', 'thursday',
898		'friday', 'saturday', 'sunday');
899	foreach ($days as $day)
900		$retval[$day] = (bool) $alert[$day];
901
902	return $retval;
903}
904
905/**
906 * Get recovery_notify of talert_templates table.
907 *
908 * @param int Id of an alert template.
909 *
910 * @return mixed Recovery_notify field or false if something goes wrong.
911 */
912function alerts_get_alert_template_recovery_notify ($id_alert_template) {
913	return db_get_value ('recovery_notify', 'talert_templates', 'id', $id_alert_template);
914}
915
916/**
917 * Get field2_recovery of talert_templates table.
918 *
919 * @param int Id of an alert template.
920 *
921 * @return mixed Field2_recovery field or false if something goes wrong.
922 */
923function alerts_get_alert_template_field2_recovery ($id_alert_template) {
924	return db_get_value ('field2_recovery', 'talert_templates', 'id', $id_alert_template);
925}
926
927/**
928 * Get field3_recovery of talert_templates table.
929 *
930 * @param int Id of an alert template.
931 *
932 * @return mixed Field3_recovery field or false if something goes wrong.
933 */
934function alerts_get_alert_template_field3_recovery ($id_alert_template) {
935	return db_get_value ('field3_recovery', 'talert_templates', 'id', $id_alert_template);
936}
937
938/**
939 * Duplicates an alert template.
940 *
941 * @param int Id of an alert template.
942 *
943 * @return mixed Duplicates an alert template or false if something goes wrong.
944 */
945function alerts_duplicate_alert_template ($id_alert_template) {
946	$template = alerts_get_alert_template ($id_alert_template);
947
948	if ($template === false)
949		return false;
950
951	$name = io_safe_input(__('Copy of') . ' ') . $template['name'];
952	$type = $template['type'];
953
954	$size = count ($template) / 2;
955	for ($i = 0; $i < $size; $i++) {
956		unset ($template[$i]);
957	}
958	unset ($template['name']);
959	unset ($template['id']);
960	unset ($template['type']);
961	$template['value'] = safe_sql_string ($template['value']);
962
963	return alerts_create_alert_template ($name, $type, $template);
964}
965
966/**
967 * Creates an alert associated to a module.
968 *
969 * @param int Id of an alert template.
970 *
971 * @return mixed Alert associated to a module or false if something goes wrong.
972 */
973function alerts_create_alert_agent_module ($id_agent_module, $id_alert_template, $values = false) {
974	if (empty ($id_agent_module))
975		return false;
976	if (empty ($id_alert_template))
977		return false;
978
979	if (! is_array ($values))
980		$values = array ();
981	$values['id_agent_module'] = (int) $id_agent_module;
982	$values['id_alert_template'] = (int) $id_alert_template;
983	$values['last_reference'] = time();
984
985	return @db_process_sql_insert ('talert_template_modules', $values);
986}
987
988/**
989 * Updates an alert associated to a module.
990 *
991 * @param int Id of an alert template.
992 * @param array Values of the update.
993 *
994 * @return mixed Affected rows or false if something goes wrong.
995 */
996function alerts_update_alert_agent_module ($id_alert_agent_module, $values) {
997	if (empty ($id_agent_module))
998		return false;
999	if (! is_array ($values))
1000		return false;
1001
1002	return (@db_process_sql_update ('talert_template_modules',
1003		$values,
1004		array ('id' => $id_alert_template))) !== false;
1005}
1006
1007/**
1008 * Deletes an alert associated to a module.
1009 *
1010 * @param int Id of an alert template.
1011 * @param mixed Array with filter conditions to delete.
1012 *
1013 * @return mixed Affected rows or false if something goes wrong.
1014 */
1015function alerts_delete_alert_agent_module ($id_alert_agent_module, $filter = false) {
1016	if (empty ($id_alert_agent_module) && ! is_array ($filter))
1017		return false;
1018
1019	if (! is_array ($filter))
1020		$filter = array ();
1021	if ($id_alert_agent_module)
1022		$filter['id'] = $id_alert_agent_module;
1023
1024	// Get the modules of the fired alerts that will be deleted to update counts
1025	$filter_get = $filter;
1026
1027	$filter_get['group'] = 'id_agent_module';
1028	$filter_get['times_fired'] = '>0';
1029
1030	$fired_alert_modules = db_get_all_rows_filter('talert_template_modules', $filter_get, array('id_agent_module', 'COUNT(*) alerts'));
1031
1032	/*
1033	The deletion of actions from talert_template_module_actions,
1034	it is automatily because the data base this table have
1035	a foreing key and delete on cascade.
1036	*/
1037	if (@db_process_sql_delete ('talert_template_modules', $filter) !== false) {
1038		return true;
1039	}
1040
1041	return false;
1042}
1043
1044/**
1045 * Get alert associated to a module.
1046 *
1047 * @param int Id of an alert template.
1048 * @param mixed Array with filter conditions to delete.
1049 *
1050 * @return mixed Affected rows or false if something goes wrong.
1051 */
1052function alerts_get_alert_agent_module ($id_alert_agent_module) {
1053	$id_alert_agent_module = safe_int ($id_alert_agent_module, 0);
1054
1055	if (empty ($id_alert_agent_module))
1056		return false;
1057
1058	return db_get_row ('talert_template_modules', 'id', $id_alert_agent_module);
1059}
1060
1061/**
1062 * Get alert associated to a module.
1063 *
1064 * @param int Id of an alert template.
1065 * @param bool Disabled or not.
1066 * @param mixed Filter conditions or false.
1067 * @param mixed Array with fields to retrieve or false.
1068 *
1069 * @return mixed Affected rows or false if something goes wrong.
1070 */
1071function alerts_get_alerts_agent_module ($id_agent_module, $disabled = false, $filter = false, $fields = false) {
1072	$id_alert_agent_module = safe_int ($id_agent_module, 0);
1073
1074	if (! is_array ($filter))
1075		$filter = array ();
1076	if (! $disabled)
1077		$filter['disabled'] = 0;
1078	$filter['id_agent_module'] = (int) $id_agent_module;
1079
1080	return db_get_all_rows_filter ('talert_template_modules',
1081		$filter, $fields);
1082}
1083
1084/**
1085 * Get alert associated to a module (only id and name fields).
1086 *
1087 * @param int Id of an alert template.
1088 * @param bool Disabled or not.
1089 *
1090 * @return mixed Affected rows or false if something goes wrong.
1091 */
1092function alerts_get_alerts_module_name ($id_agent_module, $disabled = false) {
1093	$id_alert_agent_module = safe_int ($id_agent_module, 0);
1094
1095	$sql = sprintf ('SELECT a.id, b.name
1096		FROM talert_template_modules AS a, talert_templates AS b
1097		WHERE a.id=b.id AND a.id_agent_module = %d AND a.disabled = %d',
1098		$id_agent_module, (int)$disabled);
1099
1100	return db_process_sql($sql);
1101}
1102
1103
1104/**
1105 * Get disabled field of talert_template_modules table.
1106 *
1107 * @param int Id of an alert associated to a module.
1108 *
1109 * @return mixed Disabled field or false if something goes wrong.
1110 */
1111function alerts_get_alert_agent_module_disabled ($id_alert_agent_module) {
1112	$id_alert_agent_module = safe_int ($id_alert_agent_module, 0);
1113
1114	return db_get_value ('disabled', 'talert_template_modules', 'id',
1115		$id_alert_agent_module);
1116}
1117
1118/**
1119 * Force execution of an alert associated to a module.
1120 *
1121 * @param int Id of an alert associated to a module.
1122 *
1123 * @return mixed Affected rows or false if something goes wrong.
1124 */
1125function alerts_agent_module_force_execution ($id_alert_agent_module) {
1126	$id_alert_agent_module = safe_int ($id_alert_agent_module, 0);
1127
1128	return (@db_process_sql_update ('talert_template_modules',
1129		array ('force_execution' => 1),
1130		array ('id' => $id_alert_agent_module))) !== false;
1131}
1132
1133/**
1134 * Disable/Enable an alert associated to a module.
1135 *
1136 * @param int Id of an alert associated to a module.
1137 * @param bool Whether to enable or disable an alert.
1138 *
1139 * @return mixed Affected rows or false if something goes wrong.
1140 */
1141function alerts_agent_module_disable ($id_alert_agent_module, $disabled) {
1142	$id_alert_agent_module = safe_int ($id_alert_agent_module, 0);
1143
1144	return (@db_process_sql_update ('talert_template_modules',
1145		array ('disabled' => (bool) $disabled),
1146		array ('id' => $id_alert_agent_module))) !== false;
1147}
1148
1149/**
1150 * Disable/Enable stanby of an alert associated to a module.
1151 *
1152 * @param int Id of an alert associated to a module.
1153 * @param bool Whether to enable or disable stanby of an alert.
1154 *
1155 * @return mixed Affected rows or false if something goes wrong.
1156 */
1157function alerts_agent_module_standby ($id_alert_agent_module, $standby) {
1158	$id_alert_agent_module = safe_int ($id_alert_agent_module, 0);
1159
1160	return (@db_process_sql_update ('talert_template_modules',
1161		array ('standby' => (bool) $standby),
1162		array ('id' => $id_alert_agent_module))) !== false;
1163}
1164
1165/**
1166 * Get last fired of an alert associated to a module.
1167 *
1168 * @param int Id of an alert associated to a module.
1169 *
1170 * @return mixed Affected rows or false if something goes wrong.
1171 */
1172function alerts_get_alerts_agent_module_last_fired ($id_alert_agent_module) {
1173	$id_alert_agent_module = safe_int ($id_alert_agent_module, 1);
1174
1175	return db_get_value ('last_fired', 'talert_template_modules', 'id',
1176		$id_alert_agent_module);
1177}
1178
1179/**
1180 * Add an action to an alert associated to a module.
1181 *
1182 * @param int Id of an alert associated to a module.
1183 * @param int Id of an alert.
1184 * @param mixed Options of the action.
1185 *
1186 * @return mixed Affected rows or false if something goes wrong.
1187 */
1188function alerts_add_alert_agent_module_action ($id_alert_template_module, $id_alert_action, $options = false) {
1189	global $config;
1190
1191	if (empty ($id_alert_template_module))
1192		return false;
1193	if (empty ($id_alert_action))
1194		return false;
1195
1196	$values = array ();
1197	$values['id_alert_template_module'] = (int) $id_alert_template_module;
1198	$values['id_alert_action'] = (int) $id_alert_action;
1199	$values['fires_max'] = 0;
1200	$values['fires_min'] = 0;
1201	$values['module_action_threshold'] = 0;
1202	if ($options) {
1203		$max = 0;
1204		$min = 0;
1205		if (isset ($options['fires_max']))
1206			$values['fires_max'] = $options['fires_max'];
1207		if (isset ($options['fires_min']))
1208			$values['fires_min'] = $options['fires_min'];
1209		if (isset ($options['module_action_threshold']))
1210			$values['module_action_threshold'] = (int) $options['module_action_threshold'];
1211	}
1212
1213	switch ($config["dbtype"]) {
1214		case "mysql":
1215		case "postgresql":
1216			return (@db_process_sql_insert(
1217				'talert_template_module_actions', $values)) !== false;
1218			break;
1219		case "oracle":
1220			return (@db_process_sql_insert(
1221				'talert_template_module_actions', $values, false)) !== false;
1222			break;
1223	}
1224}
1225
1226/**
1227 * Delete an action to an alert associated to a module.
1228 *
1229 * @param int Id of an alert associated to a module.
1230 *
1231 * @return mixed Affected rows or false if something goes wrong.
1232 */
1233function alerts_delete_alert_agent_module_action ($id_alert_agent_module_action) {
1234	if (empty ($id_alert_agent_module_action))
1235		return false;
1236
1237	return (@db_process_sql_delete ('talert_template_module_actions',
1238		array ('id' => $id_alert_agent_module_action))) !== false;
1239}
1240
1241/**
1242 * Get actions of an alert associated to a module.
1243 *
1244 * @param int Id of an alert associated to a module.
1245 * @param mixed Array with fields to retrieve or false.
1246 *
1247 * @return mixed Actions associated or false if something goes wrong.
1248 */
1249function alerts_get_alert_agent_module_actions ($id_alert_agent_module, $fields = false) {
1250	if (empty ($id_alert_agent_module))
1251		return false;
1252
1253	$actions = db_get_all_rows_filter ('talert_template_module_actions',
1254		array ('id_alert_template_module' => $id_alert_agent_module),
1255		$fields);
1256
1257	if ($actions === false)
1258		return array ();
1259	if ($fields !== false)
1260		return $actions;
1261
1262	$retval = array ();
1263	foreach ($actions as $element) {
1264		$action = alerts_get_alert_action ($element['id_alert_action']);
1265		$action['fires_min'] = $element['fires_min'];
1266		$action['fires_max'] = $element['fires_max'];
1267		$action['module_action_threshold'] = $element['module_action_threshold'];
1268
1269		if (isset($element['id']))
1270			$retval[$element['id']] = $action;
1271	}
1272
1273	return $retval;
1274}
1275
1276/**
1277 *  Validates an alert id or an array of alert id's.
1278 *
1279 * @param mixed Array of alerts ids or single id.
1280 * @param bool Whether to check ACLs
1281 *
1282 * @return bool True if it was successful, false otherwise.
1283 */
1284function alerts_validate_alert_agent_module ($id_alert_agent_module, $noACLs = false) {
1285	global $config;
1286
1287	include_once ("include/functions_events.php");
1288
1289	$alerts = safe_int ($id_alert_agent_module, 1);
1290
1291	if (empty ($alerts)) {
1292		return false;
1293	}
1294
1295	$alerts = (array) $alerts;
1296
1297	foreach ($alerts as $id) {
1298		$alert = alerts_get_alert_agent_module ($id);
1299		$agent_id = modules_get_agentmodule_agent ($alert["id_agent_module"]);
1300		$group_id = agents_get_agent_group ($agent_id);
1301		$critical_instructions = db_get_value('critical_instructions', 'tagente_modulo', 'id_agente_modulo', $agent_id);
1302		$warning_instructions = db_get_value('warning_instructions', 'tagente_modulo', 'id_agente_modulo', $agent_id);
1303		$unknown_instructions = db_get_value('unknown_instructions', 'tagente_modulo', 'id_agente_modulo', $agent_id);
1304
1305		if (!$noACLs) {
1306			if (! check_acl ($config['id_user'], $group_id, "AW")) {
1307				continue;
1308			}
1309		}
1310		$result = db_process_sql_update ('talert_template_modules',
1311			array ('times_fired' => 0,
1312				'internal_counter' => 0),
1313			array ('id' => $id));
1314
1315
1316		if ($result > 0) {
1317			// Update fired alert count on the agent
1318			db_process_sql(sprintf('UPDATE tagente SET update_alert_count=1 WHERE id_agente = %d', $agent_id));
1319
1320			events_create_event ("Manual validation of alert for ".
1321				alerts_get_alert_template_description ($alert["id_alert_template"]),
1322				$group_id, $agent_id, 1, $config["id_user"],
1323				"alert_manual_validation", 1, $alert["id_agent_module"],
1324				$id, $critical_instructions, $warning_instructions, $unknown_instructions);
1325		}
1326		elseif ($result === false) {
1327			return false;
1328		}
1329	}
1330	return true;
1331}
1332
1333/**
1334 * Copy an alert defined in a module agent to other module agent.
1335 *
1336 * This function avoid duplicated insertion.
1337 *
1338 * @param int Source agent module id.
1339 * @param int Detiny agent module id.
1340 *
1341 * @return New alert id on success. Existing alert id if it already exists.
1342 * False on error.
1343 */
1344function alerts_copy_alert_module_to_module ($id_agent_alert, $id_destiny_module) {
1345	global $config;
1346
1347	$alert = alerts_get_alert_agent_module ($id_agent_alert);
1348	if ($alert === false)
1349		return false;
1350
1351	$alerts = alerts_get_alerts_agent_module ($id_destiny_module, false,
1352		array ('id_alert_template' => $alert['id_alert_template']));
1353	if (! empty ($alerts)) {
1354		return $alerts[0]['id'];
1355	}
1356
1357	/* PHP copy arrays on assignment */
1358	$new_alert = array ();
1359	$new_alert['id_agent_module'] = (int) $id_destiny_module;
1360	$new_alert['id_alert_template'] = $alert['id_alert_template'];
1361
1362	switch ($config["dbtype"]) {
1363		case "mysql":
1364		case "postgresql":
1365			$id_new_alert = @db_process_sql_insert (
1366				'talert_template_modules', $new_alert);
1367			break;
1368		case "oracle":
1369			$id_new_alert = @db_process_sql_insert (
1370				'talert_template_modules', $new_alert, false);
1371			break;
1372	}
1373
1374	if ($id_new_alert === false) {
1375		return false;
1376	}
1377
1378	$actions = alerts_get_alert_agent_module_actions ($id_agent_alert);
1379	if (empty ($actions))
1380		return $id_new_alert;
1381
1382	foreach ($actions as $action) {
1383		$result = alerts_add_alert_agent_module_action ($id_new_alert, $action['id'],
1384			array ('fires_min' => $action['fires_min'],
1385				'fires_max' => $action['fires_max']));
1386		if ($result === false)
1387			return false;
1388	}
1389
1390	return $id_new_alert;
1391}
1392
1393/**
1394 * Get agents with an specific alert template.
1395 *
1396 * @param int Id of the alert template.
1397 * @param int Id of the group of agents.
1398 * @param mixed Array with filter conditions or false.
1399 * @param mixed Array with fields to retrieve or false.
1400 *
1401 * @return mixed Affected rows or false is something goes wrong.
1402 */
1403function alerts_get_agents_with_alert_template ($id_alert_template, $id_group, $filter = false, $fields = false, $id_agents = false) {
1404	global $config;
1405
1406	if (empty ($id_alert_template))
1407		return false;
1408
1409	if (! is_array ($filter))
1410		$filter = array ();
1411	$filter[] = 'tagente_modulo.id_agente_modulo = talert_template_modules.id_agent_module';
1412	$filter[] = 'tagente_modulo.id_agente = tagente.id_agente';
1413	$filter['id_alert_template'] = $id_alert_template;
1414	$filter['tagente_modulo.disabled'] = '<> 1';
1415	$filter['delete_pending'] = '<> 1';
1416
1417	if (empty ($id_agents)) {
1418		switch ($config["dbtype"]) {
1419			case "mysql":
1420				$filter['`tagente`.id_agente'] = array_keys (agents_get_group_agents ($id_group, false, "none"));
1421				break;
1422			case "postgresql":
1423			case "oracle":
1424				$filter['tagente.id_agente'] = array_keys (agents_get_group_agents ($id_group, false, "none"));
1425				break;
1426		}
1427	}
1428	else {
1429		switch ($config["dbtype"]) {
1430			case "mysql":
1431				$filter['`tagente`.id_agente'] = $id_agents;
1432				break;
1433			case "postgresql":
1434			case "oracle":
1435				$filter['tagente.id_agente'] = $id_agents;
1436				break;
1437		}
1438	}
1439
1440	return db_get_all_rows_filter ('tagente, tagente_modulo, talert_template_modules',
1441		$filter, $fields);
1442}
1443
1444/**
1445 * Get type name for alerts (e-mail, text, internal, ...) based on type number
1446 *
1447 * @param int id_alert Alert type id.
1448 *
1449 * @return string Type name of the alert.
1450 */
1451function get_alert_type ($id_type) {
1452	return (string) db_get_value ('name', 'talert_templates', 'id', (int) $id_type);
1453}
1454
1455/**
1456 * Get all the fired of alerts happened in an Agent during a period of time.
1457 *
1458 * The returned alerts will be in the time interval ($date - $period, $date]
1459 *
1460 * @param int $id_agent Agent id to get events.
1461 * @param int $period Period of time in seconds to get events.
1462 * @param int $date Beginning date to get events.
1463 *
1464 * @return array An array with all the events happened.
1465 */
1466function get_agent_alert_fired ($id_agent, $id_alert, $period, $date = 0) {
1467	if (!is_numeric ($date)) {
1468		$date = strtotime ($date);
1469	}
1470	if (empty ($date)) {
1471		$date = get_system_time ();
1472	}
1473
1474	$datelimit = $date - $period;
1475
1476	$sql = sprintf ('SELECT timestamp
1477		FROM tevento
1478		WHERE id_agente = %d AND utimestamp > %d
1479			AND utimestamp <= %d
1480			AND id_alert_am = %d
1481		ORDER BY timestamp DESC', $id_agent, $datelimit, $date, $id_alert);
1482
1483	return db_get_all_rows_sql ($sql);
1484}
1485
1486/**
1487 * Get all the fired of alerts happened in an Agent module during a period of time.
1488 *
1489 * The returned alerts will be in the time interval ($date - $period, $date]
1490 *
1491 * @param int $id_agent_module Agent module id to get events.
1492 * @param int $period Period of time in seconds to get events.
1493 * @param int $date Beginning date to get events.
1494 *
1495 * @return array An array with all the events happened.
1496 */
1497function get_module_alert_fired ($id_agent_module, $id_alert, $period, $date = 0) {
1498
1499	if (!is_numeric ($date)) {
1500		$date = strtotime ($date);
1501	}
1502	if (empty ($date)) {
1503		$date = get_system_time ();
1504	}
1505
1506	$datelimit = $date - $period;
1507
1508	$sql = sprintf ('SELECT timestamp
1509		FROM tevento
1510		WHERE id_agentmodule = %d AND utimestamp > %d
1511			AND utimestamp <= %d
1512			AND id_alert_am = %d
1513		ORDER BY timestamp DESC', $id_agent_module, $datelimit, $date, $id_alert);
1514
1515	return db_get_all_rows_sql ($sql);
1516}
1517
1518/**
1519 * Get all the times an alerts fired during a period.
1520 *
1521 * @param int Alert module id.
1522 * @param int Period timed to check from date
1523 * @param int Date to check (current time by default)
1524 *
1525 * @return int The number of times an alert fired.
1526 */
1527function get_alert_fires_in_period ($id_alert_module, $period, $date = 0) {
1528	global $config;
1529
1530	if (!$date)
1531		$date = get_system_time ();
1532
1533	$datelimit = $date - $period;
1534
1535	switch ($config["dbtype"]) {
1536		case "mysql":
1537			$sql = sprintf ("SELECT COUNT(`id_agentmodule`)
1538				FROM `tevento`
1539				WHERE `event_type` = 'alert_fired'
1540					AND `id_alert_am` = %d
1541					AND `utimestamp` > %d
1542					AND `utimestamp` <= %d",
1543				$id_alert_module, $datelimit, $date);
1544			break;
1545		case "postgresql":
1546		case "oracle":
1547			$sql = sprintf ("SELECT COUNT(id_agentmodule)
1548				FROM tevento
1549				WHERE event_type = 'alert_fired'
1550					AND id_alert_am = %d
1551					AND utimestamp > %d
1552					AND utimestamp <= %d",
1553				$id_alert_module, $datelimit, $date);
1554			break;
1555	}
1556
1557	return (int) db_get_sql ($sql);
1558}
1559
1560/**
1561 * Get all the alerts defined in a group.
1562 *
1563 * It gets all the alerts of all the agents on a given group.
1564 *
1565 * @param int $id_group Group id to check.
1566 *
1567 * @return array An array with alerts dictionaries defined in a group.
1568 */
1569function get_group_alerts($id_group, $filter = '', $options = false,
1570	$where = '', $allModules = false, $orderby = false,
1571	$idGroup = false, $count = false, $strict_user = false, $tag = false) {
1572
1573	global $config;
1574
1575	$group_query = '';
1576	if (!empty($idGroup)) {
1577		$group_query = ' AND id_grupo = ' . $idGroup;
1578	}
1579
1580	if (is_array($filter)) {
1581		$disabled = $filter['disabled'];
1582		if (isset($filter['standby'])) {
1583			$filter = $group_query . ' AND talert_template_modules.standby = "'.$filter['standby'].'"';
1584		}
1585		else {
1586			$filter = $group_query;
1587		}
1588	}
1589	else {
1590		$filter = $group_query;
1591		$disabled = $filter;
1592	}
1593
1594	switch ($disabled) {
1595		case "notfired":
1596			$filter .= ' AND times_fired = 0 AND talert_template_modules.disabled = 0';
1597			break;
1598		case "fired":
1599			$filter .= ' AND times_fired > 0 AND talert_template_modules.disabled = 0';
1600			break;
1601		case "disabled":
1602			$filter .= ' AND talert_template_modules.disabled = 1';
1603			break;
1604		case "all_enabled":
1605			$filter .= ' AND talert_template_modules.disabled = 0';
1606			break;
1607		default:
1608			$filter .= '';
1609			break;
1610	}
1611
1612	if ($tag) {
1613		$filter .= ' AND (id_agent_module IN (SELECT id_agente_modulo FROM ttag_module WHERE id_tag IN ('.$tag.')))';
1614	}
1615	if (is_array ($options)) {
1616		$filter .= db_format_array_where_clause_sql ($options);
1617	}
1618
1619
1620	if ($id_group !== false) {
1621		$groups = users_get_groups($config["id_user"], "AR");
1622
1623		if ($id_group != 0) {
1624			if (is_array($id_group)) {
1625				if (in_array(0, $id_group)) {
1626					$id_group = 0;
1627				}
1628			}
1629
1630			if (is_array($id_group)) {
1631				if (empty($id_group)) {
1632					$subQuery = 'SELECT id_agente_modulo
1633						FROM tagente_modulo
1634						WHERE 1 = 0';
1635				}
1636				else {
1637					$subQuery = 'SELECT id_agente_modulo
1638						FROM tagente_modulo
1639						WHERE delete_pending = 0
1640							AND id_agente IN (SELECT id_agente
1641								FROM tagente
1642								WHERE
1643									id_grupo IN (' . implode(',', $id_group) . '))';
1644
1645				}
1646			}
1647			else {
1648				$subQuery = 'SELECT id_agente_modulo
1649					FROM tagente_modulo
1650					WHERE delete_pending = 0
1651						AND id_agente IN (SELECT id_agente
1652							FROM tagente WHERE id_grupo = ' . $idGroup . ')';
1653			}
1654		}
1655		else {
1656			//ALL GROUP
1657			$subQuery = 'SELECT id_agente_modulo
1658				FROM tagente_modulo WHERE delete_pending = 0';
1659		}
1660
1661		if ($strict_user) {
1662			$groups = users_get_groups($config["id_user"]);
1663
1664			if ($idGroup !== 0) {
1665				$where_tags = tags_get_acl_tags($config['id_user'], $idGroup, 'AR', 'module_condition', 'AND', 'tagente_modulo', true, array(), true);
1666			} else {
1667				$where_tags = tags_get_acl_tags($config['id_user'], array_keys($groups), 'AR', 'module_condition', 'AND', 'tagente_modulo', true, array(), true);
1668			}
1669
1670			// If there are any errors add imposible condition
1671			if (in_array($where_tags, array(ERR_WRONG_PARAMETERS, ERR_ACL))) {
1672				$subQuery .= ' AND 1 = 0';
1673			}
1674			else {
1675				$subQuery .= $where_tags;
1676			}
1677		}
1678	}
1679	else {
1680		if ($allModules)
1681			$disabled = '';
1682		else
1683			$disabled = 'WHERE disabled = 0';
1684
1685		$subQuery = 'SELECT id_agente_modulo
1686			FROM tagente_modulo ' . $disabled;
1687	}
1688
1689	$orderbyText = '';
1690	if ($orderby !== false) {
1691		if (is_array($orderby)) {
1692			$orderbyText = sprintf("ORDER BY %s", $orderby['field'], $orderby['order']);
1693		}
1694		else {
1695			$orderbyText = sprintf("ORDER BY %s", $orderby);
1696		}
1697	}
1698
1699	$selectText = 'talert_template_modules.*, t2.nombre AS agent_module_name, t3.nombre AS agent_name, t4.name AS template_name';
1700	if ($count !== false) {
1701		$selectText = 'COUNT(talert_template_modules.id) AS count';
1702	}
1703
1704	$sql = sprintf ("SELECT %s
1705		FROM talert_template_modules
1706			INNER JOIN tagente_modulo t2
1707				ON talert_template_modules.id_agent_module = t2.id_agente_modulo
1708			INNER JOIN tagente t3
1709				ON t2.id_agente = t3.id_agente
1710			INNER JOIN talert_templates t4
1711				ON talert_template_modules.id_alert_template = t4.id
1712		WHERE id_agent_module in (%s) %s %s %s",
1713	$selectText, $subQuery, $where, $filter, $orderbyText);
1714	$alerts = db_get_all_rows_sql ($sql);
1715
1716	if ($alerts === false)
1717		return array ();
1718
1719	if ($count !== false) {
1720		return $alerts[0]['count'];
1721	}
1722	else {
1723		return $alerts;
1724	}
1725}
1726
1727/**
1728 * Get all the alerts fired during a period, given a list of alerts.
1729 *
1730 * @param array A list of alert modules to check. See get_alerts_in_group()
1731 * @param int Period of time to check fired alerts.
1732 * @param int Beginning date to check fired alerts in UNIX format (current date by default)
1733 *
1734 * @return array An array with the alert id as key and the number of times
1735 * the alert was fired (only included if it was fired).
1736 */
1737function get_alerts_fired ($alerts, $period = 0, $date = 0) {
1738	if (! $date)
1739		$date = get_system_time ();
1740
1741	$datelimit = $date - $period;
1742
1743	$alerts_fired = array ();
1744	$agents = array ();
1745
1746	foreach ($alerts as $alert) {
1747		if (isset($alert['id'])) {
1748			$fires = get_alert_fires_in_period($alert['id'],
1749				$period, $date);
1750			if (! $fires) {
1751				continue;
1752			}
1753			$alerts_fired[$alert['id']] = $fires;
1754		}
1755	}
1756
1757	return $alerts_fired;
1758}
1759
1760/**
1761 * Get the last time an alert fired during a period.
1762 *
1763 * @param int Alert agent module id.
1764 * @param int Period timed to check from date
1765 * @param int Date to check (current date by default)
1766 *
1767 * @return int The last time an alert fired. It's an UNIX timestamp.
1768 */
1769function get_alert_last_fire_timestamp_in_period ($id_alert_module, $period, $date = 0) {
1770	global $config;
1771
1772	if ($date == 0) {
1773		$date = get_system_time ();
1774	}
1775	$datelimit = $date - $period;
1776
1777	switch ($config["dbtype"]) {
1778		case "mysql":
1779			$sql = sprintf ("SELECT MAX(`utimestamp`)
1780				FROM `tevento`
1781				WHERE `event_type` = 'alert_fired'
1782					AND `id_alert_am` = %d
1783					AND `utimestamp` > %d
1784					AND `utimestamp` <= %d",
1785				$id_alert_module, $datelimit, $date);
1786			break;
1787		case "postgresql":
1788		case "oracle":
1789			$sql = sprintf ("SELECT MAX(utimestamp)
1790				FROM tevento
1791				WHERE event_type = 'alert_fired'
1792					AND id_alert_am = %d
1793					AND utimestamp > %d
1794					AND utimestamp <= %d",
1795				$id_alert_module, $datelimit, $date);
1796			break;
1797	}
1798
1799	return db_get_sql ($sql);
1800}
1801
1802/**
1803 * Insert in talert_special_days a new special day.
1804 *
1805 * @param date of special day.
1806 * @param same day of the week.
1807 * @param mixed A single value or array of values to insert (can be a multiple a mount of rows).
1808 *
1809 * @return mixed False in case of error or invalid values passed. Affected rows otherwise.
1810 */
1811function alerts_create_alert_special_day ($date, $same_day, $values = false) {
1812	if (empty ($date))
1813		return false;
1814	if (empty ($same_day))
1815		return false;
1816
1817	if (! is_array ($values))
1818		$values = array ();
1819
1820	global $config;
1821	$date_db = '';
1822
1823	switch ($config['dbtype']) {
1824		case "mysql":
1825			$date_db = 'date';
1826			break;
1827		case "oracle":
1828			$date_db = '"date"';
1829			break;
1830	}
1831
1832	$values[$date_db] = $date;
1833	$values['same_day'] = $same_day;
1834
1835	return @db_process_sql_insert ('talert_special_days', $values);
1836}
1837
1838/**
1839 * Update a special day in talert_special_days.
1840 *
1841 * @param int special day Id.
1842 * @param mixed Array of values to update.
1843 *
1844 * @return mixed False in case of error or invalid values passed. Affected rows otherwise
1845 */
1846function alerts_update_alert_special_day ($id_special_day, $values) {
1847	$id_special_day = safe_int ($id_special_day, 1);
1848
1849	if (empty ($id_special_day))
1850		return false;
1851	if (! is_array ($values))
1852		return false;
1853
1854	return (@db_process_sql_update ('talert_special_days',
1855		$values,
1856		array ('id' => $id_special_day))) !== false;
1857}
1858
1859/**
1860 * Delete a special day in talert_special_days.
1861 *
1862 * @param int special day Id.
1863 *
1864 * @return mixed False in case of error or invalid values passed. Affected rows otherwise
1865 */
1866function alerts_delete_alert_special_day ($id_special_day) {
1867	$id_special_day = safe_int ($id_special_day, 1);
1868
1869	if (empty ($id_special_day))
1870		return false;
1871
1872	return (@db_process_sql_delete ('talert_special_days',
1873		array ('id' => $id_special_day))) !== false;
1874}
1875
1876/**
1877 * Get a special day in talert_special_days.
1878 *
1879 * @param int special day Id.
1880 *
1881 * @return mixed False in case of error or invalid values passed. All row of the selected command otherwise
1882 */
1883function alerts_get_alert_special_day ($id_special_day) {
1884	$id_special_day = safe_int ($id_special_day, 1);
1885
1886	if (empty ($id_special_day))
1887		return false;
1888
1889	return db_get_row ('talert_special_days', 'id', $id_special_day);
1890}
1891
1892/**
1893 * Get number of alert fired that an action is executed. Only fot non default alerts
1894 *
1895 * @param mixed action
1896 *
1897 * @return mixed array with numeric indexes and 0|1 values for not executing or executing.
1898 * Returned 'everytime' for always situations
1899 * Returned $escalation['greater_than'] = VALUE for 'min - infinite' situations
1900 */
1901function alerts_get_action_escalation($action) {
1902	$escalation = array();
1903
1904	if ($action['fires_min'] == 0 && $action['fires_max'] == 0) {
1905		$escalation = 'everytime';
1906	}
1907	else if($action['fires_min'] == $action['fires_max']) {
1908		for($i=1;$i<$action['fires_min'];$i++) {
1909			$escalation[$i] = 0;
1910		}
1911		$escalation[$action['fires_max']] = 1;
1912	}
1913	else if($action['fires_min'] < $action['fires_max']) {
1914		for($i=1;$i<=$action['fires_max'];$i++) {
1915			if ($i <= $action['fires_min']) {
1916				$escalation[$i] = 0;
1917			}
1918			else {
1919				$escalation[$i] = 1;
1920			}
1921		}
1922	}
1923	else if($action['fires_min'] > $action['fires_max']) {
1924		$escalation['greater_than'] = $action['fires_min'];
1925	}
1926
1927	return $escalation;
1928}
1929
1930
1931/**
1932 * Get escalation of all the actions
1933 *
1934 * @param mixed Actions of an alert
1935 * @param mixed Default action of an alert
1936 *
1937 * @return mixed Actions array including the default action and the escalation of each action
1938 */
1939function alerts_get_actions_escalation($actions, $default_action = 0) {
1940	$escalation = array();
1941	foreach($actions as $kaction => $action) {
1942		$escalation[$kaction] = alerts_get_action_escalation($action);
1943	}
1944
1945	$default_escalation = alerts_get_default_action_escalation($default_action, $escalation);
1946	$escalation = array(0 => $default_escalation) + $escalation;
1947
1948	$escalation = alerts_normalize_actions_escalation($escalation);
1949
1950	// Join the actions with the default action
1951	$actions = array(0 => $default_action) + $actions;
1952
1953	// Add the escalation values to the actions array
1954	foreach(array_keys($actions) as $kaction) {
1955		$actions[$kaction]['escalation'] = $escalation[$kaction];
1956	}
1957
1958	return $actions;
1959}
1960
1961/**
1962 * Get escalation of default action. A default action will be executed when the alert is fired and
1963 * no other action is executed
1964 *
1965 * @param mixed Default action of the alert
1966 * @param mixed Escalation of all the other actions
1967 *
1968 * @return mixed Array with the escalation of the default alert
1969 */
1970function alerts_get_default_action_escalation($default_action, $escalation) {
1971	if ($default_action === 0) {
1972		return array();
1973	}
1974
1975	$busy_times = array();
1976	$busy_greater_than = -1;
1977	foreach($escalation as $action_escalation) {
1978		if ($action_escalation == 'everytime') {
1979			return 'never';
1980		}
1981		else if (isset($action_escalation['greater_than'])) {
1982			if ($busy_greater_than == -1 || $action_escalation['greater_than'] < $busy_greater_than) {
1983				$busy_greater_than = $action_escalation['greater_than'];
1984			}
1985		}
1986		else {
1987			foreach($action_escalation as $k => $v) {
1988				if (!isset($busy_times[$k])) {
1989					$busy_times[$k] = 0;
1990				}
1991
1992				$busy_times[$k] += $v;
1993			}
1994		}
1995	}
1996
1997	// Set to 1 the busy executions
1998	// Set to 2 the min - infinite situations
1999	foreach($busy_times as $k => $v) {
2000		if ($busy_greater_than != -1) {
2001			if ($k == ($busy_greater_than + 1)) {
2002				$busy_times[$k] = 2;
2003			}
2004			else if ($k > ($busy_greater_than + 1)) {
2005				unset($busy_times[$k]);
2006			}
2007		}
2008		else if ($v > 1) {
2009			$busy_times[$k] = 1;
2010		}
2011	}
2012
2013	// Fill gaps from last busy to greater than
2014	if ($busy_greater_than != -1) {
2015		for($i=(count($busy_times)+1);$i<=$busy_greater_than;$i++) {
2016			$busy_times[$i] = 0;
2017		}
2018		$busy_times[$i] = 2;
2019	}
2020
2021	// Set as default execution the not busy times
2022	$default_escalation = array();
2023	foreach($busy_times as $k => $v) {
2024		switch($v) {
2025			case 0:
2026				$default_escalation[$k] = 1;
2027				break;
2028			default:
2029				$default_escalation[$k] = 0;
2030				break;
2031		}
2032
2033		// Last element
2034		if ($k == count($busy_times)) {
2035			switch($v) {
2036				case 2:
2037					if ($default_escalation[$k] == 0) {
2038						unset($default_escalation[$k]);
2039					}
2040					break;
2041				default:
2042					$default_escalation[$k+1] = 1;
2043					break;
2044			}
2045		}
2046	}
2047
2048	if (empty($busy_times)) {
2049		if ($busy_greater_than == -1) {
2050			$default_escalation = 'everytime';
2051		}
2052		else {
2053			for($i=1;$i<=$busy_greater_than;$i++) {
2054				$default_escalation[$i] = 1;
2055			}
2056		}
2057	}
2058
2059	return $default_escalation;
2060}
2061
2062/**
2063 * Normalize escalation to have same number of elements setting all
2064 * of them the same number of elements
2065 *
2066 * @param mixed Escalation of the alerts
2067 *
2068 * @return mixed Escalation of the alerts with same number of elements
2069 * */
2070function alerts_normalize_actions_escalation($escalation) {
2071	$max_elements = 0;
2072	$any_greater_than = false;
2073	foreach($escalation as $k => $v) {
2074		if (is_array($v) && isset($v['greater_than'])) {
2075			$escalation[$k] = array();
2076			for($i=1;$i<$v['greater_than'];$i++) {
2077				$escalation[$k][$i] = 0;
2078			}
2079			$escalation[$k][$v['greater_than']] = 2;
2080			$any_greater_than = true;
2081		}
2082
2083		$n = count($escalation[$k]);
2084		if ($n > $max_elements) {
2085			$max_elements = $n;
2086		}
2087	}
2088
2089	if ($max_elements == 1 || !$any_greater_than) {
2090		$nelements = $max_elements;
2091	}
2092	else {
2093		$nelements = $max_elements+1;
2094	}
2095
2096	foreach($escalation as $k => $v) {
2097		if ($v == 'everytime') {
2098			$escalation[$k] = array_fill(1, $nelements, 1);
2099			$escalation[$k][$max_elements] = 2;
2100		}
2101		else if ($v == 'never') {
2102			$escalation[$k] = array_fill(1, $nelements, 0);
2103		}
2104		else {
2105			$fill_value = 0;
2106			for($i=1;$i<=$nelements;$i++) {
2107				if (!isset($escalation[$k][$i])) {
2108					$escalation[$k][$i] = $fill_value;
2109				}
2110				else if ($escalation[$k][$i] == 2) {
2111					$fill_value = 1;
2112					$escalation[$k][$i] = 0;
2113				}
2114			}
2115		}
2116	}
2117
2118	return $escalation;
2119}
2120
2121?>
2122