SkipWhenTrait::getSkipWhenFilters()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace iansltx\BusinessDays;
4
5
use DateTimeImmutable;
6
use InvalidArgumentException;
7
use DateTime;
8
9
/**
10
 * Trait SkipWhenTrait
11
 *
12
 * Use this trait to include filter storage and a few convenience methods in
13
 * your date iteration classes. Includes a method to check whether, based on
14
 * the filters currently added, a bay is a business day or not.
15
 *
16
 * @package iansltx\BusinessDays
17
 */
18
trait SkipWhenTrait
19
{
20
    protected $skipWhen = [];
21
    protected $isImported = false;
22
23
    /**
24
     * @param callable $filter takes a DateTimeInterface, returns true if that date
25
     *  is not a business day (and should be skipped) and false if it is
26
     * @param string $filter_name a way to refer to the filter; for future use
27
     * @return $this
28
     */
29 20
    public function skipWhen($filter, $filter_name)
30
    {
31 20
        if (!is_bool(call_user_func($filter, new DateTimeImmutable()))) {
32 2
            throw new InvalidArgumentException('$filter must accept a \DateTimeInterface and return a boolean.');
33
        }
34
35 18
        $this->skipWhen[$filter_name] = $filter;
36 18
        return $this;
37
    }
38
39
    /**
40
     * Convenience method for adding a filter that marks Saturday and Sunday as
41
     * non-business days.
42
     *
43
     * @return $this
44
     */
45 18
    public function skipWhenWeekend()
46
    {
47 18
        $this->skipWhen['weekend'] = [StaticFilter::class, 'isWeekend'];
48 18
        return $this;
49
    }
50
51
    /**
52
     * Convenience method for adding a filter that marks a certain day/month as
53
     * a non-business day.
54
     *
55
     * @param int $month
56
     * @param int $day
57
     * @param null|string $name optional filter name rather than default of md_$month_$day
58
     * @return $this
59
     */
60 18
    public function skipWhenMonthAndDay($month, $day, $name = null)
61
    {
62 18
        $this->skipWhen[$name ?: 'md_' . $month . '_' . $day] =
63 18
            FilterFactory::monthAndDay($month, $day);
64 18
        return $this;
65
    }
66
67
    /**
68
     * Convenience method for adding a filter that marks the Nth (e.g. 4th) weekday
69
     * (e.g. Thursday, as an integer e.g. 4) of a given month (as an integer) as
70
     * a non-business day.
71
     *
72
     * @param int $n
73
     * @param int $day_of_week
74
     * @param int $month
75
     * @param null|string $name optional filter name rather than default of ndm_$n_$day_of_week_$month
76
     * @return $this
77
     */
78 18
    public function skipWhenNthDayOfWeekOfMonth($n, $day_of_week, $month, $name = null)
79
    {
80 18
        $this->skipWhen[$name ?: 'ndm_' . $n . '_' . $day_of_week . '_' . $month] =
81 18
            FilterFactory::nthDayOfWeekOfMonth($n, $day_of_week, $month);
82 18
        return $this;
83
    }
84
85
    /**
86
     * Returns an associative array of filters added via skipWhen()
87
     *
88
     * @return array
89
     */
90 2
    public function getSkipWhenFilters()
91
    {
92 2
        return $this->skipWhen;
93
    }
94
95
    /**
96
     * Replace all skip-when filters with the supplied set
97
     *
98
     * @param array $filters
99
     * @return $this
100
     */
101 22
    protected function replaceSkipWhen(array $filters = [])
102
    {
103 22
        $this->skipWhen = $filters;
104 22
        return $this;
105
    }
106
107
    /**
108
     * Returns the name of the first "skip when" filter that matches the
109
     * supplied date, or false if none match (i.e. $dt is a business day).
110
     *
111
     * @param DateTime $dt
112
     * @return false|string
113
     */
114 20
    protected function getSkippedBy(DateTime $dt)
115
    {
116 20
        foreach ($this->skipWhen as $name => $fn) {
117 18
            if (call_user_func($fn, $dt)) {
118 17
                return $name;
119
            }
120 10
        }
121
122 20
        return false;
123
    }
124
}
125