<?php
/**
 * AgileBill - Open Billing Software
 *
 * This body of work is free software; you can redistribute it and/or
 * modify it under the terms of the Open AgileBill License
 * License as published at http://www.agileco.com/agilebill/license1-4.txt
 *
 * Originally authored by Tony Landis, AgileBill LLC
 *
 * Recent modifications by Deon George
 *
 * @author Deon George <deonATleenooksDOTnet>
 * @copyright 2009 Deon George
 * @link http://osb.leenooks.net
 *
 * @link http://www.agileco.com/
 * @copyright 2004-2008 Agileco, LLC.
 * @license http://www.agileco.com/agilebill/license1-4.txt
 * @author Tony Landis <tony@agileco.com>
 * @package AgileBill
 * @subpackage Module:Task
 */

/**
 * The main AgileBill Task Class
 *
 * @package AgileBill
 * @subpackage Module:Task
 * @todo Change the debug printing to use central debugging calls ie: C_alert
 */
class task extends OSB_module {
	# Schedule Task ID
	private $id = null;
	# Does this task need authorisation
	private $noauth = false;

	/**
	 * Run all scheduled tasks
	 *
	 * @uses cron;
	 */
	public function run_all() {
		include_once(PATH_INCLUDES.'cron/cron.inc.php');
		$cron = new cron;

		# Ensure that tasks complete and dont hang on running=1
		set_time_limit(2*60*60);

		# Loop through the tasks:
		foreach ($this->sql_GetRecords(array('where'=>'(running=0 OR running IS NULL) AND status=1')) as $result) {
			# Initialise the task
			$this->id = $result['id'];
			$this->noauth = false;

			if ($this->debug)
				printf("%s: Selecting Job [%s] (%s)\n",__METHOD__,$result['command'],$this->id);

			$task = array();
			$task['start']  = (int)$result['date_start'];
			$task['end']  = (int)$result['date_expire'];
			$task['lastrun']  = (int)$result['date_run'];
			$task['cron']  = sprintf('%s %s %s %s %s',
				$result['int_min'],
				$result['int_hour'],
				$result['int_month_day'],
				$result['int_month'],
				$result['int_week_day']);
			$task['now'] = (int)time();

			# Default the last run time, if it isnt set
			if (! $task['lastrun'] > 0)
				$task['lastrun'] = $task['now']-86400*365;

			# Verify it has not expired:
			if ($task['start'] <= $task['now'] || $task['start'] == '' || $task['start'] == '0') {
				# Verify it is past the start date:
				if ($task['end'] >= $task['now'] || $task['end'] == '' || $task['end'] == '0') {
					# Verify that it is time to run:
					if ($cron->due($task['lastrun'],$task['now'],$task['cron'])) {
						# Run the task:
						if ($this->debug)
							printf("%s: Running Job [%s] (%s)\n",__METHOD__,$result['command'],$this->id);

						$this->run($this->VAR);
					}
				}
			}
		}
	}

	/**
	 * Run a task
	 *
	 * @uses task_log
	 */
	public function run($VAR) {  
		global $VAR,$C_auth,$_ENV,$_SERVER,$_COOKIE,$C_list,$C_method;
		$db = &DB();

		# Check if we are on a console, we'll debug output if we are
		if (isset($_ENV['S']) ||
			(isset($_ENV['SESSIONNAME']) && $_ENV['SESSIONNAME'] == 'Console') ||
			(isset($_SERVER['SESSIONNAME']) && $_SERVER['SESSIONNAME'] == 'Console') ||
			(isset($_SERVER['CLIENTNAME']) && $_SERVER['CLIENTNAME'] == 'Console') ||
			empty($_COOKIE)) {

			$this->debug = true;
			$this->noauth = true;

		# Can this task be run without authorisation
		} elseif($C_auth->auth_method_by_name('task','run')) {
			$this->noauth = true;
		}

		if (! isset($this->id)) {
			if (isset($VAR['id']))
				$this->id = $VAR['id'];
			else
				return false;
		}

		# Get task details
		if (! $task = $this->sql_GetRecords(array('where'=>array('id'=>$this->id))))
			return false;
		$task = array_shift($task);

		# Record task running
		$db->Execute(sqlUpdate($db,'task',array('running'=>1),array('id'=>$this->id)));

		if ($this->debug)
			printf("%s: Running Task [%s]\n",__METHOD__,$task['command']);

		# Run task
		switch ($task['type']) {
			# Internal function
			case 0:
				$cm = explode(':',$task['command']);

				if ($this->noauth)
					$C_method->exe_noauth($cm[0],$cm[1]);
				else
					$C_method->exe($cm[0],$cm[1]);

				if ($C_method->result)
					$result = 1;
				else
					$result = 0;

				$message = isset($C_method->error) ? $C_method->error : '';

				break;

			# Run System Command:
			case 1:
				$message = `{$task['command']}`;
				$result = 1;
				break;

			default:
				printf('ERROR: Unknown task type [%s]',$result['type']);
		}

		# Update last run date & flip run toggle		 
		$db->Execute(sqlUpdate($db,'task',array('running'=>0,'date_run'=>time()),array('id'=>$this->id)));

		# Store task log if required
		if ($task['log'] && $C_list->is_installed('task_log')) { 
			include_once(PATH_MODULES.'task_log/task_log.inc.php');
			$tl = new task_log;

			$tl->add(array(
				'task_log_task_id'=>$this->id,
				'task_log_result'=>$result,
				'task_log_message'=>$message,
				'_page_current'=>isset($VAR['_page_current']) ? $VAR['_page_current'] : '',
				'_noredirect'=>1
			));
		}

		# If admin, print success message
		if (DEFAULT_ADMIN_THEME == SESS_THEME)  {
			global $C_translate,$C_debug;

			$C_debug->alert($C_translate->translate('true','',''));
		}
	}
}
?>