00001 <?php
00002
00015
00016
00017
00018 require(dirname(__FILE__) . '/includes/cliTool.inc.php');
00019
00021 define('TASKS_REGISTRY_FILE', Config::getVar('general', 'registry_dir') . '/scheduledTasks.xml');
00022
00023 import('scheduledTask.ScheduledTask');
00024 import('scheduledTask.ScheduledTaskDAO');
00025
00026 class runScheduledTasks extends CommandLineTool {
00027
00029 var $file;
00030
00032 var $taskDao;
00033
00040 function runScheduledTasks($argv = array()) {
00041 parent::CommandLineTool($argv);
00042
00043 if (isset($this->argv[0])) {
00044 $this->file = $this->argv[0];
00045 } else {
00046 $this->file = TASKS_REGISTRY_FILE;
00047 }
00048
00049 if (!file_exists($this->file) || !is_readable($this->file)) {
00050 printf("Tasks file \"%s\" does not exist or is not readable!\n", $this->file);
00051 exit(1);
00052 }
00053
00054 $this->taskDao = &DAORegistry::getDAO('ScheduledTaskDAO');
00055 }
00056
00060 function usage() {
00061 echo "Script to run a set of scheduled tasks\n"
00062 . "Usage: {$this->scriptName} [tasks_file]\n";
00063 }
00064
00068 function execute() {
00069 $this->parseTasks($this->file);
00070 }
00071
00076 function parseTasks($file) {
00077 $xmlParser = &new XMLParser();
00078 $tree = $xmlParser->parse($file);
00079
00080 if (!$tree) {
00081 $xmlParser->destroy();
00082 printf("Unable to parse file \"%s\"!\n", $file);
00083 exit(1);
00084 }
00085
00086 foreach ($tree->getChildren() as $task) {
00087 $className = $task->getAttribute('class');
00088
00089 $frequency = $task->getChildByName('frequency');
00090 if (isset($frequency)) {
00091 $canExecute = $this->checkFrequency($className, $frequency);
00092 } else {
00093
00094 $canExecute = true;
00095 }
00096
00097 if ($canExecute) {
00098 $this->executeTask($className, $this->getTaskArgs($task));
00099 }
00100 }
00101
00102 $xmlParser->destroy();
00103 }
00104
00110 function executeTask($className, $args) {
00111
00112 $pos = strrpos($className, '.');
00113 if ($pos === false) {
00114 $baseClassName = $className;
00115 } else {
00116 $baseClassName = substr($className, $pos+1);
00117 }
00118
00119
00120 import($className);
00121 $task = &new $baseClassName($args);
00122 $task->execute();
00123 $this->taskDao->updateLastRunTime($className);
00124 }
00125
00131 function getTaskArgs($task) {
00132 $args = array();
00133 $index = 0;
00134
00135 while(($arg = $task->getChildByName('arg', $index)) != null) {
00136 array_push($args, $arg->getValue());
00137 $index++;
00138 }
00139
00140 return $args;
00141 }
00142
00150 function checkFrequency($className, $frequency) {
00151 $isValid = true;
00152 $lastRunTime = $this->taskDao->getLastRunTime($className);
00153
00154
00155 $dayOfWeek = $frequency->getAttribute('dayofweek');
00156 if (isset($dayOfWeek)) {
00157 $isValid = $this->isInRange($dayOfWeek, (int)date('w'), $lastRunTime, 'day', strtotime('-1 week'));
00158 }
00159
00160 if ($isValid) {
00161
00162 $month = $frequency->getAttribute('month');
00163 if (isset($month)) {
00164 $isValid = $this->isInRange($month, (int)date('n'), $lastRunTime, 'month', strtotime('-1 year'));
00165 }
00166 }
00167
00168 if ($isValid) {
00169
00170 $day = $frequency->getAttribute('day');
00171 if (isset($day)) {
00172 $isValid = $this->isInRange($day, (int)date('j'), $lastRunTime, 'day', strtotime('-1 month'));
00173 }
00174 }
00175
00176 if ($isValid) {
00177
00178 $hour = $frequency->getAttribute('hour');
00179 if (isset($hour)) {
00180 $isValid = $this->isInRange($hour, (int)date('G'), $lastRunTime, 'hour', strtotime('-1 day'));
00181 }
00182 }
00183
00184 if ($isValid) {
00185
00186 $minute = $frequency->getAttribute('minute');
00187 if (isset($minute)) {
00188 $isValid = $this->isInRange($minute, (int)date('i'), $lastRunTime, 'min', strtotime('-1 hour'));
00189 }
00190 }
00191
00192 return $isValid;
00193 }
00194
00204 function isInRange($rangeStr, $currentValue, $lastTimestamp, $timeCompareStr, $cutoffTimestamp) {
00205 $isValid = false;
00206 $rangeArray = explode(',', $rangeStr);
00207
00208 if ($cutoffTimestamp > $lastTimestamp) {
00209
00210 $isValid = true;
00211 }
00212
00213 for ($i = 0, $count = count($rangeArray); !$isValid && ($i < $count); $i++) {
00214 if ($rangeArray[$i] == '*') {
00215
00216 $isValid = true;
00217
00218 } if (is_numeric($rangeArray[$i])) {
00219
00220 $isValid = ($currentValue == (int)$rangeArray[$i]);
00221
00222 } else if (preg_match('/^(\d*)\-(\d*)$/', $rangeArray[$i], $matches)) {
00223
00224 $isValid = $this->isInNumericRange($currentValue, (int)$matches[1], (int)$matches[2]);
00225
00226 } else if (preg_match('/^(.+)\/(\d+)$/', $rangeArray[$i], $matches)) {
00227
00228 $skipRangeStr = $matches[1];
00229 $skipFactor = (int)$matches[2];
00230
00231 if ($skipRangeStr == '*') {
00232 $isValid = true;
00233
00234 } else if (preg_match('/^(\d*)\-(\d*)$/', $skipRangeStr, $matches)) {
00235 $isValid = $this->isInNumericRange($currentValue, (int)$matches[1], (int)$matches[2]);
00236 }
00237
00238 if ($isValid) {
00239
00240 $isValid = (strtotime("-$skipFactor $timeCompareStr") > $lastTimestamp);
00241 }
00242 }
00243 }
00244
00245 return $isValid;
00246 }
00247
00255 function isInNumericRange($value, $min, $max) {
00256 return ($value >= $min && $value <= $max);
00257 }
00258
00259 }
00260
00261 $tool = &new runScheduledTasks(isset($argv) ? $argv : array());
00262 $tool->execute();
00263 ?>