<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package clearFusionCMS
 * @copyright Copyright (c) 2012 - 2013 clearFusionCMS. All rights reserved.
 * @link http://clearfusioncms.com
 */

/**
 * cfTaskSnippets Class
 *
 * Class to create, manage and use task snippets.
 *
 * @package clearFusionCMS
 */
class cfTaskSnippets {

	/**
	 * The database object.
	 *
	 * @var flDb
	 */
	protected $db;

	/**
	 * Create the object.
	 *
	 * @param flDb $db The database to use.
	 */
	function __construct($db) {
		$this->db = $db;
	}

	/**
	 * Get the count of tasks.
	 *
	 * @param int $catId If given is limits the count to a category.
	 * @return int The number of custom fields.
	 */
	function getCount($catId = null) {
		if($catId !== null)
			return $this->db->fetchOne('SELECT COUNT(*) FROM cf_tasksnippets WHERE catid=?', $catId);
		else
			return $this->db->fetchOne('SELECT COUNT(*) FROM cf_tasksnippets');
	}

	/**
	 * Get the list of tasks that are in a category.
	 *
	 * @param int $catId The category id.
	 * @return array Array of tasks in the category.
	 */
	function getInCat($catId) {
		$r = array();
		$result = $this->db->query('SELECT taskid,taskname FROM cf_tasksnippets WHERE catid=? ORDER BY taskname', $catId);
		while($row = $result->fetch())
			$r[$row['taskid']] = $row['taskname'];
		return $r;
	}

	/**
	 * Moves all tasks from the deleted category to the root.
	 *
	 * @param int $catId ID of the category being deleted.
	 */
	function categoryDeleted($catId) {
		$this->db->query('UPDATE cf_tasksnippets SET catid=0 WHERE catid=?', $catId);
	}

	/**
	 * Get the data for a task.
	 *
	 * @param int $id ID of the snippet to get.
	 * @return array Assosiative array of data or false if failed to read.
	 */
	function getTask($id) {
		return $this->db->fetchRow('SELECT taskname,description,email,catid,updaterate,content FROM cf_tasksnippets WHERE taskid=?', $id);
	}

	/**
	 * Map the task rate to a system cron event.
	 *
	 * @param int $rate The task rate.
	 * @return string The event to use.
	 */
	function mapRateToEvent($rate) {
		$map = array(
			300 => 'system.cron5m',
			1800 => 'system.cron30m',
			3600 => 'system.cron1h',
			10800 => 'system.cron3h',
			21600 => 'system.cron6h',
			43200 => 'system.cron12h',
			86400 => 'system.cron1d'
		);
		return $map[$rate];
	}

	/**
	 * Create a task.
	 *
	 * @param string $name The name of the task.
	 * @param string $description The description of the task.
	 * @param string $content The content of the task.
	 * @param string $catId The category to add the element to.
	 * @param int $rate The rate to run the task at in seconds.
	 * @param string $email Optional email address.
	 * @return int ID of the new task; or false if failed.
	 */
	function createTask($name, $description, $content, $catId, $rate, $email) {
		if($this->db->insert('cf_tasksnippets', array('taskname' => $name, 'description' => $description, 'catid' => $catId, 'content' => preg_replace('/.*<\?php(.*)\?>.*$/s', '$1', $content), 'updaterate' => $rate, 'email' => $email))) {
			$id = $this->db->insertID();
			new flVariables('cfTask.' . $name, $this->db);
			clearFusionCMS::getEventManager()->addListener($this->mapRateToEvent($rate), 'cfTaskRunner', $name);
			return $id;
		}
		return false;
	}

	/**
	 * Update a task.
	 *
	 * @param int $id The id of the task to update.
	 * @param string $name The name of the task.
	 * @param string $description The description of the task.
	 * @param string $content The content of the task.
	 * @param string $catId The category to add the element to.
	 * @param int $rate The rate to run the task at in seconds.
	 * @param string $email Optional email address.
	 * @return bool true if worked; else false.
	 */
	function updateTask($id, $name, $description, $content, $catId, $rate, $email) {
		if(($d = $this->db->fetchRow('SELECT taskname,updaterate FROM cf_tasksnippets WHERE taskid=?', $id)) && $name != $d['taskname']) {
			$old = new flVariables('cfTask.' . $d['taskname'], $this->db);
			$old->deleteNamespace();
			new flVariables('cfTask.' . $name, $this->db);
		}

		if($d && ($rate != $d['updaterate'] || $name != $d['taskname'])) {
			clearFusionCMS::getEventManager()->removeListener($this->mapRateToEvent($d['updaterate']), 'cfTaskRunner', $d['taskname']);
			clearFusionCMS::getEventManager()->addListener($this->mapRateToEvent($rate), 'cfTaskRunner', $name);
		}

		return $this->db->update('cf_tasksnippets', array('taskname' => $name, 'description' => $description, 'catid' => $catId, 'content' => preg_replace('/.*<\?php(.*)\?>.*$/s', '$1', $content), 'updaterate' => $rate, 'email' => $email), 'taskid=?', $id);
	}

	/**
	 * Delete a task.
	 *
	 * @param int $id The id of the task to delete.
	 * @return bool true if worked; else false.
	 */
	function deleteTask($id) {
		if($d = $this->db->fetchRow('SELECT taskname,updaterate FROM cf_tasksnippets WHERE taskid=?', $id)) {
			clearFusionCMS::getEventManager()->removeListener($this->mapRateToEvent($d['updaterate']), 'cfTaskRunner', $d['taskname']);
			$old = new flVariables('cfTask.' . $d['taskname'], $this->db);
			$old->deleteNamespace();
		}

		return $this->db->delete('cf_tasksnippets', 'taskid=?', $id);
	}

	/**
	 * Run the named task.
	 *
	 * @param string $name The name of the task to run.
	 */
	function runTask($name) {
		if($d = $this->db->fetchRow('SELECT taskname,email,content FROM cf_tasksnippets WHERE taskname=?', $name)) {
			ob_start();
			$fn = create_function('$dataStore', $d['content']);
			$fn(new flVariables('cfTask.' . $d['taskname'], $this->db));
			$output = ob_get_clean();

			// If has email address & output then email it
			if(!empty($d['email']) && !empty($output)) {
				$mailer = clearFusionCMS::getMailer();
				$mailer->connect();
				$mailer->addRecipient($d['email'])
					->setTextBody($output)
					->setSubject('Output from task ' . $name . ' at site ' . clearFusionCMS::getSiteName())
					->send();
				$mailer->close();
			}
		}
	}
}
