FilterFactory::checkNthDayArgs()   B
last analyzed

Complexity

Conditions 10
Paths 5

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 10

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
ccs 10
cts 10
cp 1
rs 7.2765
cc 10
eloc 9
nc 5
nop 3
crap 10

How to fix   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
namespace iansltx\BusinessDays;
4
5
/**
6
 * Class FilterFactory
7
 *
8
 * Builds filter functions based on dynamic input
9
 *
10
 * @package iansltx\BusinessDays
11
 */
12
class FilterFactory
13
{
14
    /**
15
     * Returns a filter that returns true if the day and month match,
16
     * false otherwise; the month is represented as an integer (January
17
     * is 1, December is 12)
18
     *
19
     * @param int $month
20
     * @param int $day
21
     * @return callable
22
     * @throws \OutOfBoundsException|\InvalidArgumentException
23
     */
24 30
    public static function monthAndDay($month, $day)
25
    {
26 30
        static::checkMonthAndDayArgs($month, $day);
27
28
        return function(\DateTimeInterface $dt) use ($month, $day) {
29 22
            return (int) $dt->format('m') === $month && (int) $dt->format('d') === $day;
30 22
        };
31
    }
32
33
    /**
34
     * Returns a filter that returns true if the day, month and day of week
35
     * match, false otherwise; the month and day of week are represented as
36
     * integers (January is 1, December is 12, Sunday is 0, Saturday is 6)
37
     *
38
     * @param int $month
39
     * @param int $day
40
     * @param int $day_of_week
41
     * @return callable
42
     * @throws \OutOfBoundsException|\InvalidArgumentException
43
     */
44 22
    public static function monthAndDayOnDayOfWeek($month, $day, $day_of_week)
45
    {
46 22
        static::checkMonthAndDayArgs($month, $day);
47
48 16
        if (!is_int($day_of_week)) {
49 2
            throw new \InvalidArgumentException('$day_of_week must be an integer');
50
        }
51
52 14
        if ($day_of_week < 0 || $day_of_week > 6) {
53 2
            throw new \OutOfBoundsException('$day_of_week must be 0-6');
54
        }
55
56
        return function(\DateTimeInterface $dt) use ($month, $day, $day_of_week) {
57 12
            return (int) $dt->format('m') === $month && (int) $dt->format('d') === $day &&
58 12
                    (int) $dt->format('w') === $day_of_week;
59 12
        };
60
    }
61
62
    /**
63
     * Returns a filter that returns true if the date is the Nth (e.g. 4rd)
64
     * day (e.g. Thursday, as an integer where Sunday is 0 and Saturday is 6)
65
     * of a given month (as an integer where January is 1 and December is 12)
66
     *
67
     * @param int $n
68
     * @param int $day_of_week
69
     * @param int $month
70
     * @return callable
71
     * @throws \OutOfBoundsException|\InvalidArgumentException
72
     */
73 34
    public static function nthDayOfWeekOfMonth($n, $day_of_week, $month)
74
    {
75 34
        static::checkNthDayArgs($n, $day_of_week, $month);
76
77 26
        $lowerBound = ($n - 1) * 7;
78 26
        $upperBound = $n * 7;
79
80 26
        return function(\DateTimeInterface $dt) use ($month, $day_of_week, $lowerBound, $upperBound) {
81 26
            if ((int) $dt->format('m') !== $month) {
82 20
                return false;
83
            }
84
85 24
            return ((int) $dt->format('w')) === $day_of_week &&
86 24
                    $dt->format('d') > $lowerBound && $dt->format('d') <= $upperBound;
87 26
        };
88
    }
89
90
    /**
91
     * Does type and bounds checks for nThDayOfWeekOfMonth()
92
     *
93
     * @param $n
94
     * @param $day_of_week
95
     * @param $month
96
     */
97 34
    protected static function checkNthDayArgs($n, $day_of_week, $month)
98
    {
99 34
        if (!is_int($n) || !is_int($day_of_week) || !is_int($month)) {
100 2
            throw new \InvalidArgumentException('$n, $day_of_week and $month must be integers');
101
        }
102
103 32
        if ($n < 1 || $n > 5) {
104 2
            throw new \OutOfBoundsException('$n must be 1-5');
105
        }
106
107 30
        if ($day_of_week < 0 || $day_of_week > 6) {
108 2
            throw new \OutOfBoundsException('$day_of_week must be 0-6');
109
        }
110
111 28
        if ($month < 1 || $month > 12) {
112 2
            throw new \OutOfBoundsException('$month must be 1-12');
113
        }
114 26
    }
115
116
    /**
117
     * Does type and bounds checks for monthAndDay()
118
     *
119
     * @param $month
120
     * @param $day
121
     */
122 52
    protected static function checkMonthAndDayArgs($month, $day)
123
    {
124 52
        if (!is_int($month) || !is_int($day)) {
125 2
            throw new \InvalidArgumentException('$month and $day must be integers');
126
        }
127
128 50
        if ($month < 1 || $month > 12) {
129 4
            throw new \OutOfBoundsException('$month must be 1-12');
130
        }
131
132 46
        if ($day < 1 || $day > 31) {
133 4
            throw new \OutOfBoundsException('$day must be a valid day of the month');
134
        }
135
136 42
        if ((in_array($month, [4, 6, 9, 11]) && $day > 30) || ((int) $month === 2 && $day > 29)) {
137 4
            throw new \OutOfBoundsException('Day ' . $day . ' does not exist in month ' . $month);
138
        }
139 38
    }
140
}
141