Révision 082b75eb
Ajouté par Assos Assos il y a environ 6 ans
drupal7/sites/all/modules/job_scheduler/JobSchedulerCronTab.inc | ||
---|---|---|
17 | 17 |
* I hate Sundays. |
18 | 18 |
*/ |
19 | 19 |
class JobSchedulerCronTab { |
20 |
// Original crontab elements |
|
20 |
|
|
21 |
/** |
|
22 |
* Original crontab elements. |
|
23 |
* |
|
24 |
* @var string |
|
25 |
*/ |
|
21 | 26 |
public $crontab; |
22 |
// Parsed numeric values indexed by type |
|
27 |
|
|
28 |
/** |
|
29 |
* Parsed numeric values indexed by type. |
|
30 |
* |
|
31 |
* @var string |
|
32 |
*/ |
|
23 | 33 |
public $cron; |
24 | 34 |
|
25 | 35 |
/** |
26 |
* Constructor |
|
36 |
* Constructor.
|
|
27 | 37 |
* |
28 | 38 |
* About crontab strings, see all about possible formats |
29 |
* http://linux.die.net/man/5/crontab |
|
39 |
* http://linux.die.net/man/5/crontab.
|
|
30 | 40 |
* |
31 |
* @param $crontab string
|
|
32 |
* Crontab text line: minute hour day-of-month month day-of-week |
|
41 |
* @param string $crontab
|
|
42 |
* Crontab text line: minute hour day-of-month month day-of-week.
|
|
33 | 43 |
*/ |
34 | 44 |
public function __construct($crontab) { |
35 | 45 |
$this->crontab = $crontab; |
... | ... | |
37 | 47 |
} |
38 | 48 |
|
39 | 49 |
/** |
40 |
* Parse full crontab string into an array of type => values |
|
50 |
* Parse full crontab string into an array of type => values.
|
|
41 | 51 |
* |
42 |
* Note this one is static and can be used to validate values |
|
52 |
* Note this one is static and can be used to validate values.
|
|
43 | 53 |
*/ |
44 | 54 |
public static function parse($crontab) { |
45 | 55 |
// Crontab elements, names match PHP date indexes (getdate) |
46 |
$keys = array('minutes', 'hours', 'mday', 'mon', 'wday'); |
|
47 |
// Replace multiple spaces by single space |
|
56 |
// Example: |
|
57 |
// $keys = array('minutes', 'hours', 'mday', 'mon', 'wday'); |
|
58 |
// Replace multiple spaces by single space. |
|
48 | 59 |
$crontab = preg_replace('/(\s+)/', ' ', $crontab); |
49 |
// Expand into elements and parse all |
|
60 |
// Expand into elements and parse all.
|
|
50 | 61 |
$values = explode(' ', trim($crontab)); |
51 | 62 |
return self::values($values); |
52 | 63 |
} |
53 | 64 |
|
54 | 65 |
/** |
55 |
* Parse array of values, check whether this is valid |
|
66 |
* Parse array of values, check whether this is valid.
|
|
56 | 67 |
*/ |
57 | 68 |
public static function values($array) { |
58 | 69 |
if (count($array) == 5) { |
... | ... | |
71 | 82 |
} |
72 | 83 |
|
73 | 84 |
/** |
74 |
* Find the next occurrence within the next year as unix timestamp |
|
85 |
* Find the next occurrence within the next year as unix timestamp. |
|
86 |
* |
|
87 |
* @param timestamp $start_time |
|
88 |
* Starting time. |
|
89 |
* @param int $limit |
|
90 |
* Default is 366. |
|
75 | 91 |
* |
76 |
* @param $start_time timestamp |
|
77 |
* Starting time |
|
92 |
* @codingStandardsIgnoreStart |
|
78 | 93 |
*/ |
79 | 94 |
public function nextTime($start_time = NULL, $limit = 366) { |
95 |
// @codingStandardsIgnoreEnd |
|
80 | 96 |
$start_time = isset($start_time) ? $start_time : time(); |
81 |
$start_date = getdate($start_time); // Get minutes, hours, mday, wday, mon, year |
|
97 |
// Get minutes, hours, mday, wday, mon, year. |
|
98 |
$start_date = getdate($start_time); |
|
82 | 99 |
if ($date = $this->nextDate($start_date, $limit)) { |
83 | 100 |
return mktime($date['hours'], $date['minutes'], 0, $date['mon'], $date['mday'], $date['year']); |
84 | 101 |
} |
... | ... | |
88 | 105 |
} |
89 | 106 |
|
90 | 107 |
/** |
91 |
* Find the next occurrence within the next year as a date array, |
|
108 |
* Find the next occurrence within the next year as a date array,. |
|
109 |
* |
|
110 |
* @param array $date |
|
111 |
* Date array with: 'mday', 'mon', 'year', 'hours', 'minutes'. |
|
112 |
* @param int $limit |
|
113 |
* Default is 366. |
|
92 | 114 |
* |
93 | 115 |
* @see getdate() |
94 | 116 |
* |
95 |
* @param $date |
|
96 |
* Date array with: 'mday', 'mon', 'year', 'hours', 'minutes' |
|
117 |
* @codingStandardsIgnoreStart |
|
97 | 118 |
*/ |
98 | 119 |
public function nextDate($date, $limit = 366) { |
120 |
// @codingStandardsIgnoreEnd |
|
99 | 121 |
$date['seconds'] = 0; |
100 |
// It is possible that the current date doesn't match |
|
122 |
// It is possible that the current date doesn't match.
|
|
101 | 123 |
if ($this->checkDay($date) && ($nextdate = $this->nextHour($date))) { |
102 | 124 |
return $nextdate; |
103 | 125 |
} |
... | ... | |
110 | 132 |
} |
111 | 133 |
|
112 | 134 |
/** |
113 |
* Check whether date's day is a valid one |
|
135 |
* Check whether date's day is a valid one.
|
|
114 | 136 |
*/ |
115 | 137 |
protected function checkDay($date) { |
116 | 138 |
foreach (array('wday', 'mday', 'mon') as $key) { |
... | ... | |
122 | 144 |
} |
123 | 145 |
|
124 | 146 |
/** |
125 |
* Find the next day from date that matches with cron parameters |
|
147 |
* Find the next day from date that matches with cron parameters.
|
|
126 | 148 |
* |
127 |
* Maybe it's possible that it's within the next years, maybe no day of a year matches all conditions. |
|
149 |
* Maybe it's possible that it's within the next years, maybe no day of a year |
|
150 |
* matches all conditions. |
|
128 | 151 |
* However, to prevent infinite loops we restrict it to the next year. |
129 | 152 |
*/ |
130 | 153 |
protected function nextDay($date, $limit = 366) { |
131 |
$i = 0; // Safety check, we love infinite loops... |
|
154 |
// Safety check, we love infinite loops... |
|
155 |
$i = 0; |
|
132 | 156 |
while ($i++ <= $limit) { |
133 | 157 |
// This should fix values out of range, like month > 12, day > 31.... |
134 | 158 |
// So we can trust we get the next valid day, can't we? |
... | ... | |
141 | 165 |
} |
142 | 166 |
} |
143 | 167 |
} |
168 |
|
|
144 | 169 |
/** |
145 |
* Find the next available hour within the same day |
|
170 |
* Find the next available hour within the same day.
|
|
146 | 171 |
*/ |
147 | 172 |
protected function nextHour($date) { |
148 | 173 |
$cron = $this->cron; |
... | ... | |
177 | 202 |
$string = self::translateNames($type, $string); |
178 | 203 |
} |
179 | 204 |
if ($string === '*') { |
180 |
// This means all possible values, return right away, no need to double check |
|
205 |
// This means all possible values, return right away, no need to double |
|
206 |
// check. |
|
181 | 207 |
return self::possibleValues($type); |
182 | 208 |
} |
183 | 209 |
elseif (strpos($string, '/')) { |
184 |
// Multiple. Example */2, for weekday will expand into 2, 4, 6 |
|
210 |
// Multiple. Example */2, for weekday will expand into 2, 4, 6.
|
|
185 | 211 |
list($values, $multiple) = explode('/', $string); |
186 | 212 |
$values = self::parseElement($type, $values); |
187 | 213 |
foreach ($values as $value) { |
... | ... | |
191 | 217 |
} |
192 | 218 |
} |
193 | 219 |
elseif (strpos($string, ',')) { |
194 |
// Now process list parts, expand into items, process each and merge back |
|
220 |
// Now process list parts, expand into items, process each and merge back.
|
|
195 | 221 |
$list = explode(',', $string); |
196 | 222 |
$range = array(); |
197 | 223 |
foreach ($list as $item) { |
... | ... | |
201 | 227 |
} |
202 | 228 |
} |
203 | 229 |
elseif (strpos($string, '-')) { |
204 |
// This defines a range. Example 1-3, will expand into 1,2,3 |
|
230 |
// This defines a range. Example 1-3, will expand into 1,2,3.
|
|
205 | 231 |
list($start, $end) = explode('-', $string); |
206 |
// Double check the range is within possible values |
|
232 |
// Double check the range is within possible values.
|
|
207 | 233 |
$range = range($start, $end); |
208 | 234 |
} |
209 | 235 |
elseif (is_numeric($string)) { |
210 |
// This looks like a single number, double check it's int |
|
211 |
$range = array((int)$string); |
|
236 |
// This looks like a single number, double check it's int.
|
|
237 |
$range = array((int) $string);
|
|
212 | 238 |
} |
213 | 239 |
|
214 |
// Return unique sorted values and double check they're within possible values |
|
240 |
// Return unique sorted values and double check they're within possible |
|
241 |
// values. |
|
215 | 242 |
if (!empty($range)) { |
216 | 243 |
$range = array_intersect(array_unique($range), self::possibleValues($type)); |
217 | 244 |
sort($range); |
218 |
// Sunday validation. We need cron values to match PHP values, thus week day 7 is not allowed, must be 0 |
|
245 |
// Sunday validation. We need cron values to match PHP values, thus week |
|
246 |
// day 7 is not allowed, must be 0. |
|
219 | 247 |
if ($type == 'wday' && in_array(7, $range)) { |
220 | 248 |
array_pop($range); |
221 | 249 |
array_unshift($range, 0); |
... | ... | |
223 | 251 |
return $range; |
224 | 252 |
} |
225 | 253 |
else { |
226 |
// No match found for this one, will produce an error with validation |
|
254 |
// No match found for this one, will produce an error with validation.
|
|
227 | 255 |
return array(); |
228 | 256 |
} |
229 | 257 |
} |
230 | 258 |
|
231 | 259 |
/** |
232 |
* Get values for each type |
|
260 |
* Get values for each type.
|
|
233 | 261 |
*/ |
234 | 262 |
public static function possibleValues($type) { |
235 | 263 |
switch ($type) { |
236 | 264 |
case 'minutes': |
237 | 265 |
return range(0, 59); |
266 |
|
|
238 | 267 |
case 'hours': |
239 | 268 |
return range(0, 23); |
269 |
|
|
240 | 270 |
case 'mday': |
241 | 271 |
return range(1, 31); |
272 |
|
|
242 | 273 |
case 'mon': |
243 | 274 |
return range(1, 12); |
275 |
|
|
244 | 276 |
case 'wday': |
245 |
// These are PHP values, not *nix ones |
|
277 |
// These are PHP values, not *nix ones.
|
|
246 | 278 |
return range(0, 6); |
247 | 279 |
|
248 | 280 |
} |
249 | 281 |
} |
250 | 282 |
|
251 | 283 |
/** |
252 |
* Replace element names by values |
|
284 |
* Replace element names by values.
|
|
253 | 285 |
*/ |
254 | 286 |
public static function translateNames($type, $string) { |
255 | 287 |
switch ($type) { |
256 | 288 |
case 'wday': |
257 | 289 |
$replace = array_merge( |
258 |
// Tricky, tricky, we need sunday to be zero at the beginning of a range, but 7 at the end |
|
259 |
array('-sunday' => '-7', '-sun' => '-7', 'sunday-' => '0-', 'sun-' => '0-'), |
|
260 |
array_flip(array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday')), |
|
290 |
// Tricky, tricky, we need sunday to be zero at the beginning of a |
|
291 |
// range, but 7 at the end. |
|
292 |
array( |
|
293 |
'-sunday' => '-7', |
|
294 |
'-sun' => '-7', |
|
295 |
'sunday-' => '0-', |
|
296 |
'sun-' => '0-', |
|
297 |
), |
|
298 |
array_flip(array( |
|
299 |
'sunday', |
|
300 |
'monday', |
|
301 |
'tuesday', |
|
302 |
'wednesday', |
|
303 |
'thursday', |
|
304 |
'friday', |
|
305 |
'saturday', |
|
306 |
)), |
|
261 | 307 |
array_flip(array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')) |
262 | 308 |
); |
263 | 309 |
break; |
310 |
|
|
264 | 311 |
case 'mon': |
265 | 312 |
$replace = array_merge( |
266 |
array_flip(array('nomonth1', 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december')), |
|
267 |
array_flip(array('nomonth2', 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec')), |
|
313 |
array_flip(array( |
|
314 |
'nomonth1', |
|
315 |
'january', |
|
316 |
'february', |
|
317 |
'march', |
|
318 |
'april', |
|
319 |
'may', |
|
320 |
'june', |
|
321 |
'july', |
|
322 |
'august', |
|
323 |
'september', |
|
324 |
'october', |
|
325 |
'november', |
|
326 |
'december', |
|
327 |
)), |
|
328 |
array_flip(array( |
|
329 |
'nomonth2', |
|
330 |
'jan', |
|
331 |
'feb', |
|
332 |
'mar', |
|
333 |
'apr', |
|
334 |
'may', |
|
335 |
'jun', |
|
336 |
'jul', |
|
337 |
'aug', |
|
338 |
'sep', |
|
339 |
'oct', |
|
340 |
'nov', |
|
341 |
'dec', |
|
342 |
)), |
|
268 | 343 |
array('sept' => 9) |
269 | 344 |
); |
270 | 345 |
break; |
... | ... | |
276 | 351 |
return strtr($string, $replace); |
277 | 352 |
} |
278 | 353 |
} |
354 |
|
|
279 | 355 |
} |
Formats disponibles : Unified diff
Weekly update of contrib modules