1: <?php
2: /**
3: * Horde_Scheduler_cron:: Sort of a cron replacement in a PHP cli
4: * script.
5: *
6: * Date Syntax Examples.
7: *
8: * Remember:
9: * - Whitespace (space, tab, newline) delimited fields
10: * - Single values, sets, ranges, wildcards
11: *
12: * SECOND MINUTE HOUR DAY MONTH
13: * * * * * * (every second)
14: * 0,30 * * * * (every 30 seconds)
15: * 0 0,10,20,30,40,50 * * * (every 10 minutes)
16: * 0 0 * * * (beginning of every hour)
17: * 0 0 0,6,12,18 * * (at midnight, 6am, noon, 6pm)
18: * 0 0 0 1-7&Fri * (midnight, first Fri of the month)
19: * 0 0 0 1-7!Fri * (midnight, first Mon-Thu,Sat-Sun of the month)
20: *
21: *
22: * Example usage:
23: *
24: * @set_time_limit(0);
25: * $cron = Horde_Scheduler::factory('Cron');
26: *
27: * // Run this command every 5 minutes.
28: * $cron->addTask('perl somescript.pl', '0 0,5,10,15,20,25,30,35,40,45,50,55 * * *');
29: *
30: * // Run this command midnight of the first Friday of odd numbered months.
31: * $cron->addTask('php -q somescript.php', '0 0 0 1-7&Fri 1,3,5,7,9,11');
32: *
33: * // Also run this command midnight of the second Thursday and Saturday of the even numbered months.
34: * $cron->addTask('php -q somescript.php', '0 0 0 8-15&Thu,8-15&Sat 2,4,6,8,10,12');
35: *
36: * $cron->run();
37: *
38: * @author Ryan Flynn <ryan@ryanflynn.com>
39: * @author Chuck Hagenbuch <chuck@horde.org>
40: * @package Scheduler
41: */
42: class Horde_Scheduler_Cron extends Horde_Scheduler
43: {
44: /**
45: * TODO
46: *
47: * @var array
48: */
49: protected $_tasks = array();
50:
51: /**
52: * Every time a task is added it will get a fresh uid even if
53: * immediately removed.
54: *
55: * @var integer
56: */
57: var $_counter = 1;
58:
59: /**
60: */
61: public function addTask($cmd, $rules)
62: {
63: $ds = new Horde_Scheduler_Cron_Date($rules);
64:
65: $this->_counter++;
66:
67: $this->_tasks[] =
68: array(
69: 'uid' => $this->_counter,
70: 'rules' => $ds,
71: 'cmd' => $cmd
72: );
73:
74: return $this->_counter;
75: }
76:
77: /**
78: */
79: public function removeTask($uid)
80: {
81: $count = count($this->_tasks);
82: for ($i = 0; $i < $count; $i++) {
83: if ($this->_tasks['uid'] == $uid) {
84: $found = $i;
85: array_splice($this->_tasks, $i);
86: return $i;
87: }
88: }
89:
90: return 0;
91: }
92:
93: /**
94: */
95: public function run()
96: {
97: if (!count($this->_tasks)) {
98: exit("horde-crond: Nothing to schedule; exiting.\n");
99: }
100:
101: while (true) {
102: $t = time();
103:
104: // Check each task.
105: foreach ($this->_tasks as $task) {
106: if ($task['rules']->nowMatches()) {
107: $this->runcmd($task);
108: }
109: }
110:
111: // Wait until the next second.
112: while (time() == $t) {
113: $this->sleep(100000);
114: }
115: }
116: }
117:
118: /**
119: */
120: public function runcmd(&$task)
121: {
122: Horde::logMessage('runcmd(): ' . $task['cmd'] . ' run by ' . $task['uid'], 'INFO');
123: return shell_exec($task['cmd']);
124: }
125:
126: }
127: