<?php
/**
* @version	$Id: agent_eh.php 13934 2010-09-12 16:40:27Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class AgentEventHandler extends kDBEventHandler {

		/**
		 * Allows to override standart permission mapping
		 *
		 */
		function mapPermissions()
		{
			parent::mapPermissions();

			$permissions = Array (
				'OnMassCancel' => Array ('self' => 'add|edit'),
				'OnRunAgents' => Array ('self' => 'add|edit'),
			);

			$this->permMapping = array_merge($this->permMapping, $permissions);
		}

		/**
		 * Refreshes agents list in database based on cached data from unit configs
		 *
		 * @param kEvent $event
		 */
		function OnRefreshAgents(&$event)
		{
			$regular_events = $this->Application->EventManager->getRegularEvents(true);

			$object =& $event->getObject( Array ('skip_autoload' => true) );
			/* @var $object kDBItem */

			$processed_ids = Array ();
			foreach ($regular_events as $run_mode => $events) {
				foreach ($events as $agent_name => $agent_params) {
					$object->Load($agent_name, 'AgentName');

					if (!$object->isLoaded()) {
						$fields_hash = Array (
							'Event' => $agent_params['EventName'],
							'AgentName' => $agent_name,
							'AgentType' => AGENT_TYPE_SYSTEM,
							'Status' => array_key_exists('Status', $agent_params) ? $agent_params['Status'] : STATUS_ACTIVE,
							'RunInterval' => $agent_params['RunInterval'],
							'RunMode' => $run_mode,
						);

						$object->SetDBFieldsFromHash($fields_hash);
						$object->Create();
					}

					$processed_ids[] = $object->GetID();
				}
			}

			// delete all non-processed agents (ones, that were deleted from unit configs)
			$sql = 'SELECT ' . $object->IDField . '
					FROM ' . $object->TableName . '
					WHERE (AgentType = ' . AGENT_TYPE_SYSTEM . ') AND (' . $object->IDField . ' NOT IN (' . implode(',', $processed_ids) . '))';
			$delete_ids = $this->Conn->GetCol($sql);

			if ($delete_ids) {
				$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
				/* @var $temp_handler kTempTablesHandler */

				$temp_handler->DeleteItems($event->Prefix, $event->Special, $delete_ids);
			}

			$this->Application->removeObject($event->getPrefixSpecial());
		}

		/**
		 * Don't allow to delete other user's messages
		 *
		 * @param kEvent $event
		 */
		function customProcessing(&$event, $type)
		{
			if ($event->Name == 'OnMassDelete' && $type == 'before') {
				if ($this->Application->isDebugMode()) {
					// allow to delete system agents in debug mode
					return ;
				}

				$ids = $event->getEventParam('ids');
				if ($ids) {
					$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
					$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');

					$sql = 'SELECT ' . $id_field . '
							FROM ' . $table_name . '
							WHERE ' . $id_field . ' IN (' . implode(',', $ids) . ') AND AgentType <> ' . AGENT_TYPE_SYSTEM;
					$allowed_ids = $this->Conn->GetCol($sql);

					$event->setEventParam('ids', $allowed_ids);
				}
			}
		}

		/**
		 * Cancels agents, that are currenty running
		 *
		 * @param kEvent $event
		 */
		function OnMassCancel(&$event)
		{
			$ids = $this->StoreSelectedIDs($event);

			if ($ids) {
				$object =& $event->getObject( Array ('skip_autoload' => true) );
				/* @var $object kDBItem */

				foreach ($ids as $id) {
					$object->Load($id);

					if ($object->GetDBField('LastRunStatus') == AGENT_LAST_RUN_RUNNING) {
						// only changes status, doesn't affect currency running agents
						$object->SetDBField('LastRunStatus', AGENT_LAST_RUN_FAILED);
						$object->Update();
					}
				}
			}

			$this->clearSelectedIDs($event);
		}

		/**
		 * Runs selected agents
		 *
		 * @param kEvent $event
		 */
		function OnRunAgents(&$event)
		{
			$ids = $this->StoreSelectedIDs($event);

			if ($ids) {
				$object =& $event->getObject( Array ('skip_autoload' => true) );
				/* @var $object kDBItem */

				$where_clause = Array (
					$object->TableName . '.' . $object->IDField . ' IN (' . implode(',', $ids) . ')',
					$object->TableName . '.Status = ' . STATUS_ACTIVE,
					$object->TableName . '.LastRunStatus <> ' . AGENT_LAST_RUN_RUNNING,
				);

				$sql =	$object->GetSelectSQL() . '
						WHERE (' . implode(') AND (', $where_clause) . ')';
				$agents = $this->Conn->Query($sql);

				foreach ($agents as $agent_data) {
					$agent_data['EventName'] = $agent_data['Event'];
					$this->Application->EventManager->runAgent($agent_data);
				}
			}

			$this->clearSelectedIDs($event);
		}
	}