diff --git a/inc/inc.ClassScheduler.php b/inc/inc.ClassScheduler.php new file mode 100644 index 000000000..38aad78de --- /dev/null +++ b/inc/inc.ClassScheduler.php @@ -0,0 +1,74 @@ + + * @copyright 2018 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Class to represent a SchedulerTask + * + * This class provides some very basic methods to manage extensions. + * + * @category DMS + * @package SeedDMS + * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann + * @copyright 2011 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_Scheduler { + + /** + * Instanz of database + */ + protected $db; + + public function getTask($id) { /* {{{ */ + return SeedDMS_SchedulerTask::getInstance($id, $this->db); + } /* }}} */ + + public function getTasksByExtension($extname, $taskname) { /* {{{ */ + return SeedDMS_SchedulerTask::getInstancesByExtension($extname, $taskname, $this->db); + } /* }}} */ + + public function getTasks() { /* {{{ */ + return SeedDMS_SchedulerTask::getInstances($this->db); + } /* }}} */ + + public function addTask($extname, $taskname, $name, $description, $frequency, $disabled, $params) { /* {{{ */ + $db = $this->db; + if(!$extname) + return false; + if(!$taskname) + return false; + try { + $cron = Cron\CronExpression::factory($frequency); + } catch (Exception $e) { + return false; + } + $nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s'); + + $queryStr = "INSERT INTO `tblSchedulerTask` (`extension`, `task`, `name`, `description`, `frequency`, `disabled`, `params`, `nextrun`, `lastrun`) VALUES (".$db->qstr($extname).", ".$db->qstr($taskname).", ".$db->qstr($name).", ".$db->qstr($description).", ".$db->qstr($frequency).", ".intval($disabled).", ".$db->qstr(json_encode($params)).", '".$nextrun."', NULL)"; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $task = SeedDMS_SchedulerTask::getInstance($db->getInsertID('tblSchedulerTask'), $db); + + return $task; + } /* }}} */ + + function __construct($db) { + $this->db = $db; + } + +} diff --git a/inc/inc.ClassSchedulerTask.php b/inc/inc.ClassSchedulerTask.php new file mode 100644 index 000000000..45017dbc3 --- /dev/null +++ b/inc/inc.ClassSchedulerTask.php @@ -0,0 +1,278 @@ + + * @copyright 2018 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Class to represent a SchedulerTask + * + * This class provides some very basic methods to manage extensions. + * + * @category DMS + * @package SeedDMS + * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann + * @copyright 2011 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_SchedulerTask { + /** + * Instanz of database + */ + protected $db; + + /** + * @var integer unique id of task + */ + protected $_id; + + /** + * @var string name of task + */ + protected $_name; + + /** + * @var string description of task + */ + protected $_description; + + /** + * @var string extension of task + */ + protected $_extension; + + /** + * @var string task of task + */ + protected $_task; + + /** + * @var string frequency of task + */ + protected $_frequency; + + /** + * @var integer set if disabled + */ + protected $_disabled; + + /** + * @var integer last run + */ + protected $_lastrun; + + /** + * @var integer next run + */ + protected $_nextrun; + + public static function getInstance($id, $db) { /* {{{ */ + $queryStr = "SELECT * FROM `tblSchedulerTask` WHERE `id` = " . (int) $id; + $resArr = $db->getResultArray($queryStr); + if (is_bool($resArr) && $resArr == false) + return false; + if (count($resArr) != 1) + return null; + $row = $resArr[0]; + + $task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]); + $task->setDB($db); + + return $task; + } /* }}} */ + + public static function getInstances($db) { /* {{{ */ + $queryStr = "SELECT * FROM `tblSchedulerTask`"; + $resArr = $db->getResultArray($queryStr); + if (is_bool($resArr) && $resArr == false) + return false; + if (count($resArr) == 0) + return array(); + + $tasks = array(); + foreach($resArr as $row) { + $task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]); + $task->setDB($db); + $tasks[] = $task; + } + + return $tasks; + } /* }}} */ + + public static function getInstancesByExtension($extname, $taskname, $db) { /* {{{ */ + $queryStr = "SELECT * FROM `tblSchedulerTask` WHERE `extension` = '".$extname."' AND `task` = '".$taskname."'"; + $resArr = $db->getResultArray($queryStr); + if (is_bool($resArr) && $resArr == false) + return false; + if (count($resArr) == 0) + return array(); + + $tasks = array(); + foreach($resArr as $row) { + $task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]); + $task->setDB($db); + $tasks[] = $task; + } + + return $tasks; + } /* }}} */ + + function __construct($id, $name, $description, $extension, $task, $frequency, $disabled, $params, $nextrun, $lastrun) { + $this->_id = $id; + $this->_name = $name; + $this->_description = $description; + $this->_extension = $extension; + $this->_task = $task; + $this->_frequency = $frequency; + $this->_disabled = $disabled; + $this->_params = $params; + $this->_nextrun = $nextrun; + $this->_lastrun = $lastrun; + } + + public function setDB($db) { + $this->db = $db; + } + + public function getID() { + return $this->_id; + } + + public function getName() { + return $this->_name; + } + + public function setName($newName) { /* {{{ */ + $db = $this->db; + + $queryStr = "UPDATE `tblSchedulerTask` SET `name` =".$db->qstr($newName)." WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_name = $newName; + return true; + } /* }}} */ + + public function getDescription() { + return $this->_description; + } + + public function setDescription($newDescripion) { /* {{{ */ + $db = $this->db; + + $queryStr = "UPDATE `tblSchedulerTask` SET `description` =".$db->qstr($newDescripion)." WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_description = $newDescripion; + return true; + } /* }}} */ + + public function getExtension() { + return $this->_extension; + } + + public function getTask() { + return $this->_task; + } + + public function getFrequency() { + return $this->_frequency; + } + + public function setFrequency($newFrequency) { /* {{{ */ + $db = $this->db; + + try { + $cron = Cron\CronExpression::factory($newFrequency); + } catch (Exception $e) { + return false; + } + $nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s'); + + $queryStr = "UPDATE `tblSchedulerTask` SET `frequency` =".$db->qstr($newFrequency).", `nextrun` = '".$nextrun."' WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_frequency = $newFrequency; + $this->_nextrun = $nextrun; + return true; + } /* }}} */ + + public function getNextRun() { + return $this->_nextrun; + } + + public function getLastRun() { + return $this->_lastrun; + } + + public function getDisabled() { + return $this->_disabled; + } + + public function setDisabled($newDisabled) { /* {{{ */ + $db = $this->db; + + $queryStr = "UPDATE `tblSchedulerTask` SET `disabled` =".intval($newDisabled)." WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_disabled = $newDisable; + return true; + } /* }}} */ + + public function setParameter($newParams) { /* {{{ */ + $db = $this->db; + + $queryStr = "UPDATE `tblSchedulerTask` SET `parameter` =".json_encode($newParams)." WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_params = $newParams; + return true; + } /* }}} */ + + public function getParameter() { + return $this->_params; + } + + public function isDue() { + return $this->_nextrun < date('Y-m-d H:i:s'); + } + + public function updateLastNextRun() { + $db = $this->db; + + $lastrun = date('Y-m-d H:i:s'); + try { + $cron = Cron\CronExpression::factory($this->_frequency); + $nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s'); + } catch (Exception $e) { + $nextrun = null; + } + + $queryStr = "UPDATE `tblSchedulerTask` SET `lastrun`=".$db->qstr($lastrun).", `nextrun`=".($nextrun ? $db->qstr($nextrun) : "NULL")." WHERE `id` = " . $this->_id; + $res = $db->getResult($queryStr); + if (!$res) + return false; + + $this->_lastrun = $lastrun; + $this->_nextrun = $nextrun; + } +} diff --git a/inc/inc.ClassSchedulerTaskBase.php b/inc/inc.ClassSchedulerTaskBase.php new file mode 100644 index 000000000..c190096a9 --- /dev/null +++ b/inc/inc.ClassSchedulerTaskBase.php @@ -0,0 +1,37 @@ + +* All rights reserved +* +* This script is part of the SeedDMS project. The SeedDMS project is +* free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +/** + * Base class for scheduler task + * + * @author Uwe Steinmann + * @package SeedDMS + */ +class SeedDMS_SchedulerTaskBase { + public function execute($task, $dms) { + return true; + } +} + +?> diff --git a/inc/inc.Extension.php b/inc/inc.Extension.php index b5ba1c203..ceb491587 100644 --- a/inc/inc.Extension.php +++ b/inc/inc.Extension.php @@ -12,6 +12,7 @@ */ require "inc.ClassExtensionMgr.php"; +require_once "inc.ClassSchedulerTaskBase.php"; require_once "inc.ClassExtBase.php"; require_once "inc.Version.php"; require_once "inc.Utils.php"; diff --git a/inc/inc.Scheduler.php b/inc/inc.Scheduler.php new file mode 100644 index 000000000..e5c2e3aaa --- /dev/null +++ b/inc/inc.Scheduler.php @@ -0,0 +1,17 @@ + + * @copyright Copyright (C) 2018 Uwe Steinmann + * @version Release: @package_version@ + */ + +require_once "inc.ClassSchedulerTaskBase.php"; +require_once "inc.ClassScheduler.php"; +require_once "inc.ClassSchedulerTask.php"; + diff --git a/op/op.SchedulerTaskMgr.php b/op/op.SchedulerTaskMgr.php new file mode 100644 index 000000000..6904da2c7 --- /dev/null +++ b/op/op.SchedulerTaskMgr.php @@ -0,0 +1,107 @@ +isGuest()) { + UI::exitError(getMLText("admin_tools"),getMLText("access_denied")); +} + +if (isset($_POST["action"])) $action=$_POST["action"]; +else $action=NULL; + +$scheduler = new SeedDMS_Scheduler($dms->getDB()); + +// add new task --------------------------------------------------- +if ($action == "addtask") { /* {{{ */ + + /* Check if the form data comes for a trusted request */ + if(!checkFormKey('addtask')) { + UI::exitError(getMLText("admin_tools"),getMLText("invalid_request_token")); + } + + $extension = $_POST["extension"]; + $task = $_POST["task"]; + $name = $_POST["name"]; + $description = $_POST["description"]; + $frequency = $_POST["frequency"]; + $params = $_POST["params"]; + + $newtask = $scheduler->addTask($extension, $task, $name, $description, $frequency, 0, $params); + if ($newtask) { + } + else UI::exitError(getMLText("admin_tools"),getMLText("error_occured")); + + $taskid=$newtask->getID(); + + $session->setSplashMsg(array('type'=>'success', 'msg'=>getMLText('splash_add_task'))); + + add_log_line(".php&action=addtask&name=".$name); +} /* }}} */ + +// modify transmittal ---------------------------------------------------- +else if ($action == "edittask") { /* {{{ */ + + /* Check if the form data comes for a trusted request */ + if(!checkFormKey('edittask')) { + UI::exitError(getMLText("admin_tools"),getMLText("invalid_request_token")); + } + + if (!isset($_POST["taskid"]) || !is_numeric($_POST["taskid"]) || intval($_POST["taskid"])<1) { + UI::exitError(getMLText("admin_tools"),getMLText("invalid_task")); + } + + $taskid=$_POST["taskid"]; + $editedtask = $scheduler->getTask($taskid); + + if (!is_object($editedtask)) { + UI::exitError(getMLText("admin_tools"),getMLText("invalid_task")); + } + + $name = $_POST["name"]; + $description = $_POST["description"]; + $frequency = $_POST["frequency"]; + $disabled = isset($_POST["disabled"]) ? $_POST["disabled"] : 0; + $params = $_POST["params"]; + + if ($editedtask->getName() != $name) + $editedtask->setName($name); + if ($editedtask->getDescription() != $description) + $editedtask->setDescription($description); + $editedtask->setFrequency($frequency); + $editedtask->setDisabled($disabled); + $editedtask->setParameter($params); + + $session->setSplashMsg(array('type'=>'success', 'msg'=>getMLText('splash_edit_task'))); + add_log_line(".php&action=edittask&taskid=".$taskid); +} /* }}} */ + +header("Location:../out/out.SchedulerTaskMgr.php"); + diff --git a/out/out.SchedulerTaskMgr.php b/out/out.SchedulerTaskMgr.php new file mode 100644 index 000000000..14d95d766 --- /dev/null +++ b/out/out.SchedulerTaskMgr.php @@ -0,0 +1,67 @@ +$dms, 'user'=>$user)); +$accessop = new SeedDMS_AccessOperation($dms, $user, $settings); +if (!$accessop->check_view_access($view, $_GET)) { + UI::exitError(getMLText("admin_tools"),getMLText("access_denied")); +} + +if(isset($_GET['task'])) { + $taskname = $_GET['task']; +} else { + $taskname = ''; +} + +if(isset($_GET['extension'])) { + $extname = $_GET['extension']; +} else { + $extname = ''; +} + +if(isset($_GET['taskid'])) { + $taskid = $_GET['taskid']; +} else { + $taskid = 0; +} + +$scheduler = new SeedDMS_Scheduler($dms->getDB()); + +if($view) { + $view->setParam('scheduler', $scheduler); + $view->setParam('accessobject', $accessop); + $view->setParam('taskname', $taskname); + $view->setParam('extname', $extname); + $view->setParam('taskid', $taskid); + $view($_GET); + exit; +} + +?> diff --git a/utils/schedulercli.php b/utils/schedulercli.php new file mode 100644 index 000000000..b5e4a59cc --- /dev/null +++ b/utils/schedulercli.php @@ -0,0 +1,108 @@ +]\n"; + echo "\n"; + echo "Description:\n"; + echo " Check for scheduled tasks.\n"; + echo "\n"; + echo "Options:\n"; + echo " -h, --help: print usage information and exit.\n"; + echo " -v, --version: print version and exit.\n"; + echo " --config: set alternative config file.\n"; + echo " --mode: set mode of operation (run, check, list).\n"; +} /* }}} */ + +$version = "0.0.1"; +$shortoptions = "hvc"; +$longoptions = array('help', 'version', 'config:', 'mode:'); +if(false === ($options = getopt($shortoptions, $longoptions))) { + usage(); + exit(0); +} + +/* Print help and exit */ +if(isset($options['h']) || isset($options['help'])) { + usage(); + exit(0); +} + +/* Print version and exit */ +if(isset($options['v']) || isset($options['verŅ•ion'])) { + echo $version."\n"; + exit(0); +} + +/* Set alternative config file */ +if(isset($options['config'])) { + define('SEEDDMS_CONFIG_FILE', $options['config']); +} + +$mode = 'list'; +if(isset($options['mode'])) { + if(!in_array($options['mode'], array('run', 'check', 'list'))) { + usage(); + exit(1); + } + $mode = $options['mode']; +} + +include($myincpath."/inc/inc.Settings.php"); +include($myincpath."/inc/inc.Init.php"); +include($myincpath."/inc/inc.Extension.php"); +include($myincpath."/inc/inc.DBInit.php"); +include($myincpath."/inc/inc.Scheduler.php"); + +$scheduler = new SeedDMS_Scheduler($db); +$tasks = $scheduler->getTasks(); + +foreach($tasks as $task) { + if(is_object($taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()])) { + switch($mode) { + case "run": + if(method_exists($taskobj, 'execute')) { + if(!$task->getDisabled()) { + if($taskobj->execute($task, $dms)) { + $task->updateLastNextRun(); + } else { + echo "Execution of task failed, task has been disabled\n"; + $task->setDisabled(1); + } + } + } + break; + case "check": + echo "Checking ".$task->getExtension()."::".$task->getTask().":\n"; + if(!method_exists($taskobj, 'execute')) { + echo " Missing method execute()\n"; + } + if(get_parent_class($taskobj) != 'SeedDMS_SchedulerTaskBase') { + echo " wrong parent class\n"; + } + break; + case "list": + if(!$task->getDisabled()) { + if($task->isDue()) + echo "*"; + else + echo " "; + } else { + echo "-"; + } + echo " ".$task->getExtension()."::".$task->getTask().""; + echo " ".$task->getNextRun(); + echo "\n"; + break; + } + } + +} diff --git a/utils/seeddms-schedulercli b/utils/seeddms-schedulercli new file mode 100644 index 000000000..34bc8b219 --- /dev/null +++ b/utils/seeddms-schedulercli @@ -0,0 +1,6 @@ +#!/bin/sh +if [ -z ${SEEDDMS_HOME+x} ]; then + echo "Please set SEEDDMS_HOME before running this script"; + exit 1; +fi +php -f ${SEEDDMS_HOME}/utils/schedulercli.php -- "$@" diff --git a/views/bootstrap/class.SchedulerTaskMgr.php b/views/bootstrap/class.SchedulerTaskMgr.php new file mode 100644 index 000000000..8ada34273 --- /dev/null +++ b/views/bootstrap/class.SchedulerTaskMgr.php @@ -0,0 +1,315 @@ + + * @copyright Copyright (C) 2013 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Include parent class + */ +require_once("class.Bootstrap.php"); + +/** + * Class which outputs the html page for SchedulerTaskMgr view + * + * @category DMS + * @package SeedDMS + * @author Uwe Steinmann + * @copyright Copyright (C) 2013 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_View_SchedulerTaskMgr extends SeedDMS_Bootstrap_Style { + + function js() { /* {{{ */ + header('Content-Type: application/javascript'); +?> +$(document).ready( function() { + $('body').on('click', '.addtask', function(ev){ + ev.preventDefault(); + $('#editaddtask.ajax').trigger('update', {extension: $(this).data('extension'), task: $(this).data('task')}); + }); + $('body').on('click', '.listtasks', function(ev){ + ev.preventDefault(); + $('#listtasks.ajax').trigger('update', {extension: $(this).data('extension'), task: $(this).data('task')}); + }); + $('body').on('click', '.edittask', function(ev){ + ev.preventDefault(); + $('#editaddtask.ajax').trigger('update', {taskid: $(this).data('id'), action: $(this).data('action')}); + }); + $('#listtasks.ajax').trigger('update', {}); +}); +params['dms']; + $user = $this->params['user']; + $extname = $this->params['extname']; + $taskname = $this->params['taskname']; + if($extname && $taskname) { + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$extname][$taskname]; + if(method_exists($taskobj, 'getAdditionalParams')) + $additionalparams = $taskobj->getAdditionalParams(); + else + $additionalparams = null; +?> +
+ + + + +
+ +
+ :: +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+params['dms']; + $user = $this->params['user']; + $scheduler = $this->params['scheduler']; + $taskid = $this->params['taskid']; + + $task = $scheduler->getTask($taskid); + $taskobj = $GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]; +?> +
+ + + + + +
+ +
+ getExtension() ?>::getTask() ?> +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+getAdditionalParams()) { + foreach($additionalparams as $param) { + switch($param['type']) { + default: +?> +
+ +
+ +
+
+ +
+ +
+ +
+
+
+params['dms']; + $user = $this->params['user']; + $extname = $this->params['extname']; + $taskname = $this->params['taskname']; + $scheduler = $this->params['scheduler']; + + if($extname && $taskname) + $tasks = $scheduler->getTasksByExtension($extname, $taskname); + else + $tasks = $scheduler->getTasks(); + if(!$tasks) + return; + + $this->contentHeading(getMLText("scheduler_class_tasks")); + echo "\n"; + print "\n\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + foreach($tasks as $task) { + echo "getDisabled() ? " class=\"success\"" : "").">"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + echo "
".getMLText('scheduler_class')."".getMLText('task_name')."".getMLText('task_description')."".getMLText('task_frequency')."".getMLText('task_next_run')."".getMLText('task_last_run')."
"; + echo $task->getExtension()."::".$task->getTask(); + echo ""; + echo $task->getName(); + echo ""; + echo $task->getDescription(); + echo ""; + echo $task->getFrequency(); + echo ""; + echo $task->getNextRun(); + echo ""; + echo $task->getLastRun(); + echo ""; + print ""; + echo "
\n"; + } /* }}} */ + + function show() { /* {{{ */ + $dms = $this->params['dms']; + $user = $this->params['user']; + $extname = $this->params['extname']; + $taskname = $this->params['taskname']; + $scheduler = $this->params['scheduler']; + + $this->htmlStartPage(getMLText("admin_tools")); + $this->globalNavigation(); + $this->contentStart(); + $this->pageNavigation(getMLText("admin_tools"), "admin_tools"); + $this->contentHeading(getMLText("scheduler_task_manager")); +?> +
+
+\n"; + print "\n\n"; + print "".getMLText('scheduler_class')."\n"; + print "".getMLText('scheduler_class_description')."\n"; + print "".getMLText('scheduler_class_parameter')."\n"; + print "\n"; + print "\n"; + $errmsgs = array(); + foreach($GLOBALS['SEEDDMS_SCHEDULER']['tasks'] as $extname=>$tasks) { + foreach($tasks as $taskname=>$task) { + echo ""; + echo ""; + echo $extname."::".$taskname; + echo ""; + echo ""; + echo $task->getDescription(); + echo ""; + echo ""; + $params = $task->getAdditionalParams(); + foreach($params as $param) + $k[] = $param['name']; + echo implode(', ', $k); + echo ""; + echo ""; + print "
"; + $t = $scheduler->getTasksByExtension($extname, $taskname); + if($t) { + print ""; + } + print ""; + print "
"; + echo ""; + echo ""; + } + } + echo "\n"; +?> +
+
+
+
+
+
+ +contentEnd(); + $this->htmlEndPage(); + } /* }}} */ +} +?>