1: <?php
2:
3: namespace Cron;
4:
5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
18: class DayOfWeekField extends AbstractField
19: {
20: public function isSatisfiedBy(\DateTime $date, $value)
21: {
22: if ($value == '?') {
23: return true;
24: }
25:
26:
27: $value = $this->convertLiterals($value);
28:
29: $currentYear = $date->format('Y');
30: $currentMonth = $date->format('m');
31: $lastDayOfMonth = $date->format('t');
32:
33:
34: if (strpos($value, 'L')) {
35: $weekday = str_replace('7', '0', substr($value, 0, strpos($value, 'L')));
36: $tdate = clone $date;
37: $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth);
38: while ($tdate->format('w') != $weekday) {
39: $tdate->setDate($currentYear, $currentMonth, --$lastDayOfMonth);
40: }
41:
42: return $date->format('j') == $lastDayOfMonth;
43: }
44:
45:
46: if (strpos($value, '#')) {
47: list($weekday, $nth) = explode('#', $value);
48:
49:
50: if ($weekday === '0') {
51: $weekday = 7;
52: }
53:
54:
55: if ($weekday < 0 || $weekday > 7) {
56: throw new \InvalidArgumentException("Weekday must be a value between 0 and 7. {$weekday} given");
57: }
58: if ($nth > 5) {
59: throw new \InvalidArgumentException('There are never more than 5 of a given weekday in a month');
60: }
61:
62: if ($date->format('N') != $weekday) {
63: return false;
64: }
65:
66: $tdate = clone $date;
67: $tdate->setDate($currentYear, $currentMonth, 1);
68: $dayCount = 0;
69: $currentDay = 1;
70: while ($currentDay < $lastDayOfMonth + 1) {
71: if ($tdate->format('N') == $weekday) {
72: if (++$dayCount >= $nth) {
73: break;
74: }
75: }
76: $tdate->setDate($currentYear, $currentMonth, ++$currentDay);
77: }
78:
79: return $date->format('j') == $currentDay;
80: }
81:
82:
83: if (strpos($value, '-')) {
84: $parts = explode('-', $value);
85: if ($parts[0] == '7') {
86: $parts[0] = '0';
87: } elseif ($parts[1] == '0') {
88: $parts[1] = '7';
89: }
90: $value = implode('-', $parts);
91: }
92:
93:
94: $format = in_array(7, str_split($value)) ? 'N' : 'w';
95: $fieldValue = $date->format($format);
96:
97: return $this->isSatisfied($fieldValue, $value);
98: }
99:
100: public function increment(\DateTime $date, $invert = false)
101: {
102: if ($invert) {
103: $date->modify('-1 day');
104: $date->setTime(23, 59, 0);
105: } else {
106: $date->modify('+1 day');
107: $date->setTime(0, 0, 0);
108: }
109:
110: return $this;
111: }
112:
113: public function validate($value)
114: {
115: $value = $this->convertLiterals($value);
116: return (bool) preg_match('/^(\*|[0-7](L?|#[1-5]))([\/\,\-][0-7]+)*$/', $value);
117: }
118:
119: private function convertLiterals($string)
120: {
121: return str_ireplace(
122: array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'),
123: range(0, 6),
124: $string
125: );
126: }
127: }
128: