<?php
!function_exists('readover') && exit('Forbidden');

/**
 * 任務系統調度中心
 * @2009-11-23
 * 
 * @package Task
 */
class PW_Task {
	var $_db = null;
	var $_tasks = array();
	var $_interval = 6; /*每6小時通過一次*/
	var $_runInterval = 12; /*任務運行間隔每12小時*/
	var $_filename = 'tasks.php';
	var $_cache = false;
	var $_openVerity = true; /*是否開啟時間限制*/
	var $_timestamp = null;
	var $_hour = 3600;
	function PW_Task() {
		global $db, $timestamp;
		$this->_db = & $db;
		$this->_timestamp = $timestamp;
	}
	/**
	 * 運行任務
	 */
	function run() {
		if ($this->verify()) {
			$this->doTask();
		}
		return true;
	}
	/**
	 * 執行任務
	 */
	function doTask() {
		$tasks = $this->gets();
		if (!$tasks) {
			return null;
		}
		foreach($tasks as $task) {
			$this->tasklist($task['task']);
		}
	}
	/**
	 * 任務列表
	 */
	function tasklist($task) {
		switch ($task) {
			case 'alteradver':
				$this->alterAdver();
				break;

			default:
				break;
		}
		return true;;
	}
	/**
	 * 任務一︰廣告到期提醒任務
	 */
	function alterAdver() {
		list($id, $name, $task, $next) = array_values($this->getDefaultTask('alteradver'));
		$class = $this->_loadTask($task);
		$finish = $class->run();
		if ($finish) {
			$this->update($id, $name, $task, $next);
		}
		return true;
	}
	/**
	 * 單任務檢查
	 */
	function check($id, $name, $task, $next) {
		$tasks = $this->get($id);
		if (!$tasks) {
			$next = $this->_timestamp + $next;
			$this->add($id, $name, $task, $next);
			return true;
		}
		if ($tasks['next'] <= $this->_timestamp) {
			return true;
		}
		return false;
	}
	/**
	 * 系統任務默認設置
	 */
	function getDefaultTask($k) {
		$current = $this->_timestamp;
		$next = $current + $this->_interval * $this->_hour; /*默認設置間隔時間*/
		$tasks = array(
			'alteradver' => array(
				'id' => 1,
				'name' => '廣告到期提醒',
				'task' => 'alteradver',
				'next' => $next
			)
		);
		return $tasks[$k];
	}
	/**
	 * 增加一條任務記錄
	 */
	function add($id, $name, $task, $next) {
		$this->_db->update("INSERT INTO pw_task" . " SET " . S::sqlSingle(array(
			'id' => ($id) ? $id : '',
			'name' => $name,
			'task' => $task,
			'count' => 1,
			'last' => $this->_timestamp,
			'next' => $next,
			'ctime' => $this->_timestamp,
		)));
	}
	/**
	 * 更新一條任務記錄
	 */
	function update($id, $name, $task, $next) {
		$this->_db->update("UPDATE pw_task SET count=count+1," . S::sqlSingle(array(
			'name' => $name,
			'task' => $task,
			'last' => $this->_timestamp,
			'next' => $next,
		)) . " WHERE id=" . S::sqlEscape($id));
	}
	/**
	 * 獲取需要執行的任務列表
	 */
	function gets($current = null) {
		$current = $current ? $current : $this->_timestamp;
		$current = intval($current);
		if ($current < 1) {
			return array();
		}
		$result = array();
		$query = $this->_db->query("SELECT * FROM pw_task WHERE next<=" . $current);
		while ($rs = $this->_db->fetch_array($query)) {
			$result[$rs['id']] = $rs;
		}
		return $result;
	}
	/**
	 * 獲取單條任務信息
	 */
	function get($id) {
		$id = intval($id);
		if ($id < 1) {
			return array();
		}
		return $this->_db->get_one("SELECT * FROM pw_task WHERE id=" . $id);
	}
	/*驗證任務是否可以開始*/
	function verify() {
		if (!$this->_openVerity) {
			return true;
		}
		$current = $this->_timestamp;
		$configs = $this->getFileCache();
		if ($configs['next'] <= $current) {
			$this->setFileCache();
			return true;
		}
		return false;
	}
	/*獲取任務配置*/
	function taskConfig() {
		$current = $this->_timestamp;
		$interval = $this->_runInterval;
		$last = $current;
		$next = $current + $interval * $this->_hour;
		return array(
			'interval' => $interval,
			'last' => $last,
			'next' => $next
		);
	}
	/**
	 * 設置文件緩存
	 */
	function setFileCache() {
		$configs = $this->taskConfig();
		$tasks = "\$tasks=" . pw_var_export($configs) . ";";
		pwCache::setData($this->getCacheFileName(), "<?php\r\n" . $tasks . "\r\n?>");
		return $configs;
	}
	/**
	 * 獲取文件緩存
	 */
	function getFileCache() {
		if (!$this->_cache) {
			return $this->taskConfig(); /*not open cache*/
		}
		@include S::escapePath($this->getCacheFileName());
		if ($tasks) {
			return $tasks;
		}
		return $this->setFileCache();
	}
	/*獲取緩存文件路徑*/
	function getCacheFileName() {
		return D_P . "data/bbscache/" . $this->_filename;
	}
	/**
	 * 獲取任務文件類
	 */
	function _loadTask($name) {
		static $classes = array();
		$name = strtolower($name);
		$filename = R_P . "lib/task/task/" . $name . ".task.php";
		if (!is_file($filename)) {
			return null;
		}
		$class = 'Task_' . ucfirst($name);
		if (isset($classes[$class])) {
			return $classes[$class];
		}
		include S::escapePath($filename);
		$classes[$class] = new $class();
		return $classes[$class];
	}
}
