| [ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 3 require_once 'Horde/Scheduler.php'; 4 require_once 'Horde/String.php'; 5 6 /** 7 * Horde_Scheduler_cron:: Sort of a cron replacement in a PHP cli 8 * script. 9 * 10 * Date Syntax Examples. 11 * 12 * Remember: 13 * - Whitespace (space, tab, newline) delimited fields 14 * - Single values, sets, ranges, wildcards 15 * 16 * SECOND MINUTE HOUR DAY MONTH 17 * * * * * * (every second) 18 * 0,30 * * * * (every 30 seconds) 19 * 0 0,10,20,30,40,50 * * * (every 10 minutes) 20 * 0 0 * * * (beginning of every hour) 21 * 0 0 0,6,12,18 * * (at midnight, 6am, noon, 6pm) 22 * 0 0 0 1-7&Fri * (midnight, first Fri of the month) 23 * 0 0 0 1-7!Fri * (midnight, first Mon-Thu,Sat-Sun of the month) 24 * 25 * 26 * Example usage: 27 * 28 * @set_time_limit(0); 29 * require_once 'Horde/Scheduler.php'; 30 * $cron = &Horde_Scheduler::singleton('cron'); 31 * 32 * // Run this command every 5 minutes. 33 * $cron->addTask('perl somescript.pl', '0 0,5,10,15,20,25,30,35,40,45,50,55 * * *'); 34 * 35 * // Run this command midnight of the first Friday of odd numbered months. 36 * $cron->addTask('php -q somescript.php', '0 0 0 1-7&Fri 1,3,5,7,9,11'); 37 * 38 * // Also run this command midnight of the second Thursday and Saturday of the even numbered months. 39 * $cron->addTask('php -q somescript.php', '0 0 0 8-15&Thu,8-15&Sat 2,4,6,8,10,12'); 40 * 41 * $cron->run(); 42 * 43 * $Horde: framework/Scheduler/Scheduler/cron.php,v 1.13.10.3 2005/10/18 11:01:26 jan Exp $ 44 * 45 * @author Ryan Flynn <ryan@ryanflynn.com> 46 * @author Chuck Hagenbuch <chuck@horde.org> 47 * @package Horde_Scheduler 48 */ 49 class Horde_Scheduler_cron extends Horde_Scheduler { 50 51 var $_tasks = array(); 52 53 /** 54 * Every time a task is added it will get a fresh uid even if 55 * immediately removed. 56 */ 57 var $_counter = 1; 58 59 function addTask($cmd, $rules) 60 { 61 $ds = &new Horde_Scheduler_cronDate($rules); 62 63 $this->_counter++; 64 65 $this->_tasks[] = 66 array( 67 'uid' => $this->_counter, 68 'rules' => $ds, 69 'cmd' => $cmd 70 ); 71 72 return $this->_counter; 73 } 74 75 function removeTask($uid) 76 { 77 $count = count($this->_tasks); 78 for ($i = 0; $i < $count; $i++) { 79 if ($this->_tasks['uid'] == $uid) { 80 $found = $i; 81 array_splice($this->_tasks, $i); 82 return $i; 83 } 84 } 85 86 return 0; 87 } 88 89 function run() 90 { 91 if (!count($this->_tasks)) { 92 exit("crond: Nothing to schedule; exiting.\n"); 93 } 94 95 while (true) { 96 $t = time(); 97 98 // Check each task. 99 foreach ($this->_tasks as $task) { 100 if ($task['rules']->nowMatches()) { 101 $this->runcmd($task); 102 } 103 } 104 105 // Wait until the next second. 106 while (time() == $t) { 107 $this->sleep(100000); 108 } 109 } 110 } 111 112 function runcmd(&$task) 113 { 114 Horde::logMessage('Horde_Scheduler_Cron::runcmd(): ' . $task['cmd'] . ' run by ' . $task['uid'], __FILE__, __LINE__, PEAR_LOG_INFO); 115 return shell_exec($task['cmd']); 116 } 117 118 } 119 120 /** 121 * @package Horde_Scheduler 122 */ 123 class Horde_Scheduler_cronDate { 124 125 var $legalDays = array('MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'); 126 127 var $sec; 128 var $min; 129 var $hour; 130 var $day; 131 var $month; 132 133 function Horde_Scheduler_cronDate($raw) 134 { 135 $this->parse(String::upper($raw)); 136 } 137 138 function nowMatches() 139 { 140 return $this->scheduledAt(time()); 141 } 142 143 function scheduledAt($ts = null) 144 { 145 if ($ts === null) { 146 $ts = time(); 147 } 148 return ($this->monthMatches($ts) && 149 $this->monthMatches($ts) && 150 $this->dayMatches($ts) && 151 $this->hourMatches($ts) && 152 $this->minMatches($ts) && 153 $this->secMatches($ts)); 154 } 155 156 function monthMatches($ts) 157 { 158 if ($this->month == '*') { 159 return true; 160 } 161 162 $currentmonth = '-' . date('n', $ts) . '-'; 163 164 return (bool)strpos($this->month, $currentmonth); 165 } 166 167 function dayMatches($ts) 168 { 169 if (!empty($this->day['value']) && $this->day['value'] == '*') { 170 return true; 171 } 172 173 $currentdaynum = '-' . date('j', $ts) . '-'; 174 $currentdaytxt = String::upper(date('D')); 175 176 foreach ($this->day as $day) { 177 if (@strpos($day['not'], $currentdaytxt) === false) { 178 $v1 = (@strpos($day['value'], $currentdaynum) !== false); 179 $v2 = (@strpos($day['and'], $currentdaytxt) !== false); 180 181 if (!empty($day['and']) && ($v1 && $v2)) { 182 return true; 183 } elseif (empty($day['and']) && $v1) { 184 return true; 185 } 186 } 187 } 188 189 return false; 190 } 191 192 function hourMatches($ts) 193 { 194 if ($this->hour == '*') { 195 return true; 196 } 197 198 $currenthour = '-' . date('G', $ts) . '-'; 199 200 return (strpos($this->hour, $currenthour) !== false); 201 } 202 203 function minMatches($ts) 204 { 205 if ($this->min == '*') { 206 return true; 207 } 208 209 $currentmin = '-' . intval(date('i', $ts)) . '-'; 210 211 return (strpos($this->min, $currentmin) !== false); 212 } 213 214 function secMatches($ts) 215 { 216 if ($this->sec == '*') { 217 return true; 218 } 219 220 $currentsec = '-' . intval(date('s', $ts)) . '-'; 221 222 return (strpos($this->sec, $currentsec) !== false); 223 } 224 225 function parse($str) 226 { 227 $s = array(); 228 229 list($s['sec'], $s['min'], $s['hour'], $s['day'], $s['month']) = preg_split('|[\n\t ]+|', $str); 230 231 foreach ($s as $k => $v) { 232 if (strpos($v, '*') !== false) { 233 $s[$k] = array('*'); 234 } elseif (!$this->generallyDecentSyntax($v)) { 235 die("Illegal syntax in '$v'\n"); 236 } else { 237 $s[$k] = explode(',', $s[$k]); 238 } 239 } 240 241 if ($s['sec'][0] == '*') { 242 $this->sec = '*'; 243 } else { 244 for ($i = 0; $i < sizeof($s['sec']); $i++) { 245 if ($this->isRange($s['sec'][$i])) { 246 $s['sec'][$i] = $this->expandRange($this->rangeVals($s['sec'][$i])); 247 } 248 } 249 $this->sec = '-' . join('-', $s['sec']) . '-'; 250 } 251 252 if ($s['min'][0] == '*') { 253 $this->min = '*'; 254 } else { 255 for ($i = 0; $i < sizeof($s['min']); $i++) { 256 if ($this->isRange($s['min'][$i])) { 257 $s['min'][$i] = $this->expandRange($this->rangeVals($s['min'][$i])); 258 } 259 } 260 $this->min = '-' . join('-', $s['min']) . '-'; 261 } 262 263 if ($s['hour'][0] == '*') { 264 $this->hour = '*'; 265 } else { 266 for ($i = 0; $i < sizeof($s['hour']); $i++) { 267 if ($this->isRange($s['hour'][$i])) { 268 $s['hour'][$i] = $this->expandRange($this->rangeVals($s['hour'][$i])); 269 } 270 } 271 $this->hour = '-' . join('-', $s['hour']) . '-'; 272 } 273 274 if ($s['day'][0] == '*') { 275 $this->day = '*'; 276 } else { 277 for ($i = 0; $i < sizeof($s['day']); $i++) { 278 $tmp = array(); 279 if (($char = $this->isCond($s['day'][$i])) !== false) { 280 if ($char == '&') { 281 list($tmp['value'], $tmp['and']) = explode($char, $s['day'][$i]); 282 if ($this->isRange($tmp['and'])) { 283 $tmp['and'] = $this->expandRange($this->rangeVals($tmp['and'])); 284 } 285 } else { 286 list($tmp['value'], $tmp['not']) = explode($char, $s['day'][$i]); 287 if ($this->isRange($tmp['not'])) { 288 $tmp['not'] = $this->expandRange($this->rangeVals($tmp['not'])); 289 } 290 } 291 } else { 292 $tmp = array('value' => $s['day'][$i]); 293 } 294 295 $s['day'][$i] = $tmp; 296 297 if ($this->isRange($s['day'][$i]['value'])) { 298 $s['day'][$i]['value'] = $this->expandRange($this->rangeVals($s['day'][$i]['value'])); 299 } 300 } 301 302 $this->day = $s['day']; 303 } 304 305 if ($s['month'][0] == '*') { 306 $this->month = '*'; 307 } else { 308 for ($i = 0; $i < sizeof($s['month']); $i++) { 309 if ($this->isRange($s['month'][$i])) { 310 $s['month'][$i] = $this->expandRange($this->rangeVals($s['month'][$i])); 311 } 312 } 313 $this->month = '-' . join('-', $s['month']) . '-'; 314 } 315 } 316 317 function isCond($s) 318 { 319 if (strpos($s, '&') !== false) { 320 return '&'; 321 } elseif (strpos($s, '!') !== false) { 322 return '!'; 323 } else { 324 return false; 325 } 326 } 327 328 function isRange($s) 329 { 330 return preg_match('/^\w+\-\w+/', $s); 331 } 332 333 function isCondRange($s) 334 { 335 return (isCond($s) && isRange($s)); 336 } 337 338 function isCondVal($s) 339 { 340 return (isCond($s) && !isRange($s)); 341 } 342 343 function rangeVals($s) 344 { 345 return explode('-', $s); 346 } 347 348 function expandRange($l, $h = '') 349 { 350 // Expand range from 1-5 -> '-1-2-3-4-5-'. 351 if (is_array($l)) { 352 $h = $l[1]; 353 $l = $l[0]; 354 } 355 356 if ($this->isDigit($l)) { 357 if (!$this->isDigit($h)) { 358 die("Invalid value '$h' in range '$l-$h'"); 359 } 360 361 // Currently there is no possible reason to need to do a 362 // range beyond 0-59 for anything. 363 if ($l < 0) { 364 $l = 0; 365 } elseif ($l > 59) { 366 $l = 59; 367 } 368 369 if ($h < 0) { 370 $h = 0; 371 } elseif ($h > 59) { 372 $h = 59; 373 } 374 375 if ($l > $h) { 376 $tmp = $l; 377 $l = $h; 378 $h = $tmp; 379 unset($tmp); 380 } 381 382 // For some reason range() doesn't work w/o the explicit 383 // intval() calls. 384 return '-' . join('-', range(intval($l), intval($h))) . '-'; 385 } else { 386 // Invalid. 387 die("Invalid value '$l' in range '$l-$h'"); 388 } 389 } 390 391 function dayValue($s) 392 { 393 for ($i = 0; $i < count($this->legalDays); $i++) { 394 if ($this->legalDays[$i] == $s) { 395 return $i; 396 } 397 } 398 399 return -1; 400 } 401 402 function isDigit($s) 403 { 404 return preg_match('/^\d+$/', $s); 405 } 406 407 function isAlpha($s) 408 { 409 return $this->isLegalDay($s); 410 } 411 412 function isLegalDay($s) 413 { 414 return in_array($s, $this->legalDays); 415 } 416 417 function generallyDecentSyntax($s) 418 { 419 return ($s == '*' || 420 preg_match('/^\d+(-\d+)?([!&][A-Z\*]+(-[A-Z\*]+)?)?(,\d+(-\d+)?([!&][A-Z\*]+(-[A-Z\*]+)?)?)*$/', $s)); 421 } 422 423 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |