htdocs/modules/system/admin/autotasks/class/autotasks.php
<?php
/**
* ImpressCMS AUTOTASKS
*
* @copyright The ImpressCMS Project http://www.impresscms.org/
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU General Public License (GPL)
* @package Administration
* @subpackage Autotasks
* @since 1.2 alpha 2
* @author MekDrop <mekdrop@gmail.com>
* @version SVN: $Id: autotasks.php 12399 2014-01-25 17:02:01Z skenow $
*/
defined('ICMS_ROOT_PATH') || die('ImpressCMS root path not defined');
//error_reporting(E_ALL);
//ini_set('display_errors', '1');
icms_loadLanguageFile('system', 'autotasks', TRUE);
/**
* Task objects
*
* @package Administration
* @subpackage Autotasks
*/
class SystemAutoTasks extends icms_ipf_Object {
public $content = FALSE;
/**
* Constructor
*
* @param object $handler
*/
public function __construct(&$handler) {
parent::__construct($handler);
$this->quickInitVar('sat_id', XOBJ_DTYPE_INT, FALSE);
$this->quickInitVar('sat_lastruntime', XOBJ_DTYPE_INT, FALSE, _CO_ICMS_AUTOTASKS_LASTRUNTIME, NULL, 0);
$this->quickInitVar('sat_name', XOBJ_DTYPE_TXTBOX, TRUE, _CO_ICMS_AUTOTASKS_NAME, _CO_ICMS_AUTOTASKS_NAME_DSC);
$this->quickInitVar('sat_code', XOBJ_DTYPE_SOURCE, TRUE, _CO_ICMS_AUTOTASKS_CODE, _CO_ICMS_AUTOTASKS_CODE_DSC);
$this->quickInitVar('sat_repeat', XOBJ_DTYPE_INT, TRUE, _CO_ICMS_AUTOTASKS_REPEAT, _CO_ICMS_AUTOTASKS_REPEAT_DSC, 0);
$this->quickInitVar('sat_interval', XOBJ_DTYPE_INT, TRUE, _CO_ICMS_AUTOTASKS_INTERVAL, _CO_ICMS_AUTOTASKS_INTERVAL_DSC, 24 * 60);
$this->quickInitVar('sat_onfinish', XOBJ_DTYPE_INT, TRUE, _CO_ICMS_AUTOTASKS_ONFINISH, _CO_ICMS_AUTOTASKS_ONFINISH_DSC, 0);
$this->quickInitVar('sat_enabled', XOBJ_DTYPE_INT, TRUE, _CO_ICMS_AUTOTASKS_ENABLED, _CO_ICMS_AUTOTASKS_ENABLED_DSC, 1);
$this->quickInitVar('sat_type', XOBJ_DTYPE_TXTBOX, TRUE, _CO_ICMS_AUTOTASKS_TYPE, NULL, ':custom');
$this->quickInitVar('sat_addon_id', XOBJ_DTYPE_INT, FALSE);
$this->setControl('sat_name', 'text');
$this->setControl('sat_onfinish', 'yesno');
$this->setControl('sat_enabled', 'yesno');
$this->doHideFieldFromForm('sat_addon_id');
$this->doHideFieldFromForm('sat_type');
$this->doHideFieldFromForm('sat_lastruntime');
}
/**
* Get the last time a task was run and format it for display
* @return string
*/
public function getLastRunTimeForDisplay() {
if ($this->getVar('sat_lastruntime') < 1) {
return _CO_ICMS_AUTOTASKS_NOTYETRUNNED;
} else {
return formatTimestamp($this->getVar('sat_lastruntime'));
}
}
/**
* Get the recurrence for the task and format it for display
* @return string
*/
public function getRepeatForDisplay() {
if ($this->getVar('sat_repeat') < 1) {
return _CO_ICMS_AUTOTASKS_FOREVER;
} else {
return $this->getVar('sat_repeat');
}
}
/**
* Get the recur interval and format it for display
* @return string
*/
public function getIntervalForDisplay() {
$int = $this->getVar('sat_interval');
$day = (int) ($int / 60 / 24);
$hou = (int) (($int - $day * 24 * 60) / 60);
$min = (int) (($int - $day * 24 * 60) - $hou * 60);
$ret = '';
if ($day == 1) {
$ret .= _DAY . ' ';
} elseif ($day > 1) {
$ret .= sprintf(_DAYS, $day) . ' ';
}
if ($hou == 1) {
$ret .= _HOUR . ' ';
} elseif ($hou > 1) {
$ret .= sprintf(_HOURS, $hou) . ' ';
}
if ($min == 1) {
$ret .= _MINUTE;
} elseif ($min > 1) {
$ret .= sprintf(_MINUTES, $min);
}
return trim($ret);
}
/**
* Get the autotask type
*
* @param string $part
* @return string
*/
public function getType($part = NULL) {
$type = $this->getVar('sat_type');
if ($type[0] == ':') {
$type = substr($type, 1);
}
$type = explode('/', $type);
if ($part === NULL) return $type;
return $type[$part];
}
/**
* Format the type for display
* @return string
*/
public function getTypeForDisplay() {
return constant('_CO_ICMS_AUTOTASKS_TYPE_' . strtoupper($this->getType(0)));
}
/**
* Retrieve and format the enabled status of the task
* @return string
*/
public function getEnableForDisplay() {
return ($this->getVar('sat_enabled')==1) ? _YES : _NO;
}
/**
* Retrieve and format for display if the task will be deleted on completion
* @return string
*/
public function getOnFinishForDisplay() {
return ($this->getVar('sat_onfinish')==1) ? _YES : _NO;
}
/**
* Executes code attached to event
*
* @return bool
*/
public function exec() {
if (!$this->getVar('sat_enabled')) return FALSE;
if (((int) $this->getVar('sat_lastruntime') + (int) $this->getVar('sat_interval') * 60) > time()) return FALSE;
$code = $this->getVar('sat_code');
ignore_user_abort(TRUE);
if (substr($this->getVar('sat_type'), 0, 6) == 'addon/') {
$dirname = substr($this->getVar('sat_type'), 6);
if ($dirname == '') return FALSE;
// only execute autotasks for active modules
$module = icms::handler("icms_module")->getByDirname($dirname);
if ($module->getVar("isactive") != 1) return FALSE;
$dirname = ICMS_MODULES_PATH . '/' . $dirname;
$dirname = $dirname . '/' . $code;
$code = " require '" . $dirname . "';";
$is_bug = !(@highlight_string(file_get_contents($dirname), TRUE));
} else {
$is_bug = !(@highlight_string('<?' . 'php '. $code . ' return TRUE; ?' . '>', TRUE));
}
if ($is_bug) {
trigger_error(sprintf(_CO_ICMS_AUTOTASKS_SOURCECODE_ERROR, $code));
return FALSE;
}
eval($code);
$count = $this->getVar('sat_repeat');
if ($count > 0) {
if ($count == 1) {
if ($this->getVar('sat_onfinish')) {
// delete this task
$this->handler->delete($this);
return TRUE;
} else {
// disable this task
$this->setVar('sat_enabled', 0);
}
}
$count--;
$this->setVar('sat_repeat', $count);
}
$this->setVar('sat_lastruntime', time());
$this->handler->insert($this, TRUE);
return TRUE;
}
/**
* Custom form generation for autotasks
* @see icms_ipf_Object::getForm()
*/
public function getForm($form_caption, $form_name, $form_action = FALSE, $submit_button_caption = _CO_ICMS_SUBMIT, $cancel_js_action = FALSE, $captcha = FALSE) {
if ($this->getType(0)=='addon') {
$this->doHideFieldFromForm('sat_code');
$this->doHideFieldFromForm('sat_onfinish');
} else {
$this->doShowFieldOnForm('sat_code');
$this->doShowFieldOnForm('sat_onfinish');
}
return parent::getForm($form_caption, $form_name, $form_action, $submit_button_caption, $cancel_js_action, $captcha);
}
/**
* Determine if the user can delete the task and display a button
* @return mixed
*/
public function getDeleteButtonForDisplay() {
static $controller = NULL;
if ($this->getType(0) == 'addon') return;
if ($controller === NULL) $controller = new icms_ipf_Controller($this->handler);
return $controller->getDeleteItemLink($this, FALSE, TRUE, FALSE);
}
/**
* Retrieve name for display
* @return string
*/
public function getNameForDisplay() {
return $this->getVar('sat_name');
}
}
/**
* Handler for the autotask objects
*
* @package Administration
* @subpackage Autotasks
*/
class SystemAutotasksHandler extends icms_ipf_Handler {
private $_use_virtual_config = FALSE;
private $_virtual_config = array();
/**
* Constructor
*
* @param object $db Database object
*/
public function __construct($db) {
parent::__construct($db, 'autotasks', 'sat_id', 'sat_name', 'sat_code', 'system');
}
/**
* Enable virtual configuartion and set it
*
* @param array
*/
public function enableVirtualConfig(&$array) {
$this->_virtual_config = $array;
$this->_use_virtual_config = TRUE;
}
/**
* Get virtual configuration status
*
* @return bool
*/
public function isVirtualConfigEnabled() {
return $this->_use_virtual_config;
}
/**
* Disable virtual configuration
*/
public function disableVirtualConfig() {
$this->_use_virtual_config = FALSE;
}
/**
* Gets selected type current events for current user
*
* @param int $ type
* @return Object
*/
public function getTasks() {
$criteria = new icms_db_criteria_Compo();
$criteria->setSort('sat_lastruntime');
$criteria->setOrder('ASC');
$criteria->add( new icms_db_criteria_Item('(sat_lastruntime + sat_interval)', time(), '<=', NULL, "%s" ));
$criteria->add( new icms_db_criteria_Item('sat_repeat', 0, '>=', NULL, "'%s'"));
$criteria->add( new icms_db_criteria_Item('sat_enabled', 1));
$rez = $this->getObjects($criteria, FALSE);
return $rez;
}
/**
* Executes events
*
* @return array
*/
public function execTasks() {
$rez = array('all' => 0, 'ok' => 0);
if (!($tasks = $this->getTasks())) return $rez;
foreach ($tasks as $task) {
if ($task->exec()) {
$rez['ok']++;
}
$rez['all']++;
}
return $rez;
}
/**
* Get if current autotask handler needs execution
*
* @return TRUE
*/
public function needExecution() {
return $this->getCurrentSystemHandler()->needExecution();
}
/**
* Returns if all tasks was executed to do no more php lines processing
*
* @param bool
*/
public function needExit() {
return $this->getCurrentSystemHandler()->needExit();
}
/**
* Starts handler if needed
*/
public function startIfNeeded() {
$system = $this->getCurrentSystemHandler();
if ($system->needStart()) {
if ($system->canRun()) {
$system->start($this->getRealTasksRunningTime());
} else {
trigger_error("Can't start selected automated tasks handler.");
}
}
unset($system);
}
/**
* Tasks are executed in some times periods but not always exatcly the same
* as in administration. This will get real tasks execution interval.
*
* @return int
*/
public function getRealTasksRunningTime() {
$sql = 'SELECT MIN(sat_interval) INTV FROM ' . $this->db->prefix('system_autotasks') . ' WHERE sat_enabled = TRUE LIMIT 1';
if (!$result = $this->db->query($sql)) {
return 0;
}
$data = $this->db->fetchArray($result);
$interval = (int) $data['INTV'];
return ($interval == 0) ? strtotime('60 minutes') : $interval;
}
/**
* Get selected autotask system handler
*
* @param string system name
*
* @return AutomatedTasks
*/
public function getSelectedSystemHandler($name) {
if ("$name" == '') {
$name = 'internal';
}
$name = trim(strtolower($name));
require_once $this->getSystemHandlerFileName((string) $name);
$handler_name = 'IcmsAutoTasks' . ucfirst($name);
if (class_exists($handler_name)) {
$handler = new $handler_name($this);
} else {
trigger_error('Needed autotask handler not found!');
}
return $handler;
}
/**
* Gets system handler filename
*
* @param string name
* @return string
*/
private function getSystemHandlerFileName($name) {
return ICMS_PLUGINS_PATH . '/autotasks/' . $name . '.php';
}
/**
* Get system handler name from filename
*
* @param string filename
* @return string
*/
private function getSystemHandlerNameFromFileName($filename) {
return substr($filename, strlen(ICMS_PLUGINS_PATH . '/autotasks/'), -strlen('.php'));
}
/**
* Gets autotasks settings
*
* @return Array(ConfigObjectItems)
*/
public function getConfig() {
if ($this->isVirtualConfigEnabled()) {
return $this->_virtual_config;
}
//$old_handler_name = get_class($handler);
$config_handler = icms::handler('icms_config');
$config_atasks = $config_handler->getConfigsByCat(ICMS_CONF_AUTOTASKS);
return $config_atasks;
}
/**
* Get AutoTasks System
*
* @param bool force update handler
*
* @return AutomatedTasks
*/
public function getCurrentSystemHandler($forceUpdate = FALSE) {
static $handler = FALSE;
if ($forceUpdate || ($handler === FALSE)) {
$config_atasks = $this->getConfig();
$handler = $this->getSelectedSystemHandler($config_atasks['autotasks_system']);
}
return $handler;
}
/**
* Gets all avaible system handlers
*
* @param bool checkIfItIsAvaibleOnCurrentSystem
*
* @return array
*/
public function getSystemHandlersList($checkIfItIsAvaibleOnCurrentSystem = TRUE) {
static $ret = NULL;
if ($ret === NULL) {
$files = glob($this->getSystemHandlerFileName('*'));
$ret = FALSE;
foreach ($files as $file) {
$name = (string)$this->getSystemHandlerNameFromFileName((string) $file);
$handler = $this->getSelectedSystemHandler($name);
if (!$handler) continue;
if ($checkIfItIsAvaibleOnCurrentSystem && (!$handler->canRun())) {
continue;
}
$ret[] = $name;
}
}
sort($ret);
return $ret;
}
}