Passed
Push — master ( 495efb...ace576 )
by Brian
06:14 queued 01:46
created

CronExpression_DayOfWeekField::isSatisfiedBy()   C

Complexity

Conditions 16
Paths 18

Size

Total Lines 76
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 44
c 1
b 0
f 0
nc 18
nop 2
dl 0
loc 76
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Day of week field.  Allows: * / , - ? L #
5
 *
6
 * Days of the week can be represented as a number 0-7 (0|7 = Sunday)
7
 * or as a three letter string: SUN, MON, TUE, WED, THU, FRI, SAT.
8
 *
9
 * 'L' stands for "last". It allows you to specify constructs such as
10
 * "the last Friday" of a given month.
11
 *
12
 * '#' is allowed for the day-of-week field, and must be followed by a
13
 * number between one and five. It allows you to specify constructs such as
14
 * "the second Friday" of a given month.
15
 *
16
 * @author Michael Dowling <[email protected]>
17
 */
18
class CronExpression_DayOfWeekField extends CronExpression_AbstractField
19
{
20
    /**
21
     * {@inheritdoc}
22
     */
23
    public function isSatisfiedBy(DateTime $date, $value)
24
    {
25
        if ($value == '?') {
26
            return true;
27
        }
28
29
        // Convert text day of the week values to integers
30
        $value = str_ireplace(
31
            array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'),
32
            range(0, 6),
33
            $value
34
        );
35
36
        $currentYear = $date->format('Y');
37
        $currentMonth = $date->format('m');
38
        $lastDayOfMonth = $date->format('t');
39
40
        // Find out if this is the last specific weekday of the month
41
        if (strpos($value, 'L')) {
42
            $weekday = str_replace('7', '0', substr($value, 0, strpos($value, 'L')));
43
            $tdate = clone $date;
44
            $tdate->setDate($currentYear, $currentMonth, $lastDayOfMonth);
0 ignored issues
show
Bug introduced by
$currentMonth of type string is incompatible with the type integer expected by parameter $month of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
            $tdate->setDate($currentYear, /** @scrutinizer ignore-type */ $currentMonth, $lastDayOfMonth);
Loading history...
Bug introduced by
$lastDayOfMonth of type string is incompatible with the type integer expected by parameter $day of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
            $tdate->setDate($currentYear, $currentMonth, /** @scrutinizer ignore-type */ $lastDayOfMonth);
Loading history...
Bug introduced by
$currentYear of type string is incompatible with the type integer expected by parameter $year of DateTime::setDate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
            $tdate->setDate(/** @scrutinizer ignore-type */ $currentYear, $currentMonth, $lastDayOfMonth);
Loading history...
45
            while ($tdate->format('w') != $weekday) {
46
                $tdate->setDate($currentYear, $currentMonth, --$lastDayOfMonth);
47
            }
48
49
            return $date->format('j') == $lastDayOfMonth;
50
        }
51
52
        // Handle # hash tokens
53
        if (strpos($value, '#')) {
54
            list($weekday, $nth) = explode('#', $value);
55
            // Validate the hash fields
56
            if ($weekday < 1 || $weekday > 5) {
57
                throw new InvalidArgumentException("Weekday must be a value between 1 and 5. {$weekday} given");
58
            }
59
            if ($nth > 5) {
60
                throw new InvalidArgumentException('There are never more than 5 of a given weekday in a month');
61
            }
62
            // The current weekday must match the targeted weekday to proceed
63
            if ($date->format('N') != $weekday) {
64
                return false;
65
            }
66
67
            $tdate = clone $date;
68
            $tdate->setDate($currentYear, $currentMonth, 1);
69
            $dayCount = 0;
70
            $currentDay = 1;
71
            while ($currentDay < $lastDayOfMonth + 1) {
72
                if ($tdate->format('N') == $weekday) {
73
                    if (++$dayCount >= $nth) {
74
                        break;
75
                    }
76
                }
77
                $tdate->setDate($currentYear, $currentMonth, ++$currentDay);
78
            }
79
80
            return $date->format('j') == $currentDay;
81
        }
82
83
        // Handle day of the week values
84
        if (strpos($value, '-')) {
85
            $parts = explode('-', $value);
86
            if ($parts[0] == '7') {
87
                $parts[0] = '0';
88
            } elseif ($parts[1] == '0') {
89
                $parts[1] = '7';
90
            }
91
            $value = implode('-', $parts);
92
        }
93
94
        // Test to see which Sunday to use -- 0 == 7 == Sunday
95
        $format = in_array(7, str_split($value)) ? 'N' : 'w';
96
        $fieldValue = $date->format($format);
97
98
        return $this->isSatisfied($fieldValue, $value);
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function increment(DateTime $date, $invert = false)
105
    {
106
        if ($invert) {
107
            $date->modify('-1 day');
108
            $date->setTime(23, 59, 0);
109
        } else {
110
            $date->modify('+1 day');
111
            $date->setTime(0, 0, 0);
112
        }
113
114
        return $this;
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function validate($value)
121
    {
122
        return (bool) preg_match('/[\*,\/\-0-9A-Z]+/', $value);
123
    }
124
}
125