GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( a3c5fc...13d483 )
by Dragos
11:38
created

BusinessHours::getClosestInterval()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 18

Duplication

Lines 19
Ratio 67.86 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 19
loc 28
rs 8.8571
cc 3
eloc 18
nc 3
nop 1
1
<?php
2
3
namespace Speicher210\BusinessHours;
4
5
use Speicher210\BusinessHours\Day\DayInterface;
6
use Speicher210\BusinessHours\Day\Time\TimeBuilder;
7
8
/**
9
 * Default implementation of BusinessHoursInterface.
10
 */
11
class BusinessHours implements BusinessHoursInterface
12
{
13
    /**
14
     * The days.
15
     *
16
     * @var DayInterface[]
17
     */
18
    protected $days;
19
20
    /**
21
     * The time zone.
22
     *
23
     * @var \DateTimeZone
24
     */
25
    protected $timezone;
26
27
    /**
28
     * Constructor.
29
     *
30
     * @param DayInterface[] $days
31
     * @param \DateTimeZone|null $timezone
32
     */
33
    public function __construct(array $days, \DateTimeZone $timezone = null)
34
    {
35
        $this->setDays($days);
36
        $this->timezone = $timezone ?: new \DateTimeZone(date_default_timezone_get());
37
    }
38
39
    /**
40
     * Get the days.
41
     *
42
     * @return DayInterface[]
43
     */
44
    public function getDays()
45
    {
46
        return array_values($this->days);
47
    }
48
49
    /**
50
     * Add a set of days.
51
     *
52
     * @param DayInterface[] $days The days.
53
     * @throws \InvalidArgumentException If no days are passed.
54
     */
55
    public function setDays(array $days)
56
    {
57
        if (empty($days)) {
58
            throw new \InvalidArgumentException('At least one day must be added.');
59
        }
60
61
        $this->days = [];
62
63
        foreach ($days as $day) {
64
            $this->addDay($day);
65
        }
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function within(\DateTime $date)
72
    {
73
        $tmpDate = clone $date;
74
        $tmpDate->setTimezone($this->timezone);
75
76
        if (null !== $day = $this->getDay((int)$tmpDate->format('N'))) {
77
            return $day->isWithinOpeningHours(TimeBuilder::fromDate($tmpDate));
78
        }
79
80
        return false;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function getNextChangeDateTime(\DateTime $date = null)
87
    {
88
        if ($date === null) {
89
            $date = new \DateTime('now', $this->timezone);
90
        }
91
92
        $dateInterval = $this->closestDateInterval($date);
93
94
        if ($this->within($date)) {
95
            return ($date == $dateInterval->getStart()) ? $dateInterval->getStart() : $dateInterval->getEnd();
96
        } else {
97
            return $dateInterval->getStart();
98
        }
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function closestDateInterval(\DateTime $date)
105
    {
106
        $tmpDate = clone $date;
107
        $tmpDate->setTimezone($this->timezone);
108
109
        return $this->getClosestInterval($tmpDate);
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function jsonSerialize()
116
    {
117
        return array(
118
            'days' => $this->days,
119
            'timezone' => $this->timezone->getName(),
120
        );
121
    }
122
123
    /**
124
     * Get the closest business hours date interval after the given date.
125
     *
126
     * @param \DateTime $date
127
     * @return DateTimeInterval
128
     */
129
    private function getClosestDateIntervalAfter(\DateTime $date)
130
    {
131
        $tmpDate = clone $date;
132
        $dayOfWeek = (int)$tmpDate->format('N');
133
        $time = TimeBuilder::fromDate($tmpDate);
134
135 View Code Duplication
        if (null !== $day = $this->getDay($dayOfWeek)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
136
            if (null !== $closestTime = $day->getClosestOpeningHoursInterval($time)) {
137
                $intervalStart = clone $tmpDate;
138
                $intervalEnd = clone $tmpDate;
139
140
                $intervalStart->setTime(
141
                    $closestTime->getStart()->getHours(),
142
                    $closestTime->getStart()->getMinutes(),
143
                    $closestTime->getStart()->getSeconds()
144
                );
145
                $intervalEnd->setTime(
146
                    $closestTime->getEnd()->getHours(),
147
                    $closestTime->getEnd()->getMinutes(),
148
                    $closestTime->getEnd()->getSeconds()
149
                );
150
151
                return new DateTimeInterval($intervalStart, $intervalEnd);
152
            }
153
        }
154
155
        $tmpDate = $this->getDateAfter($tmpDate);
156
157
        $closestDay = $this->getClosestDayBefore((int)$tmpDate->format('N'));
158
159
        $openingTime = $closestDay->getOpeningTime();
160
        $closestTime = $closestDay->getClosestOpeningHoursInterval($openingTime);
161
162
        $intervalStart = clone $tmpDate;
163
        $intervalEnd = clone $tmpDate;
164
165
        $intervalStart->setTime(
166
            $closestTime->getStart()->getHours(),
167
            $closestTime->getStart()->getMinutes(),
168
            $closestTime->getStart()->getSeconds()
169
        );
170
        $intervalEnd->setTime(
171
            $closestTime->getEnd()->getHours(),
172
            $closestTime->getEnd()->getMinutes(),
173
            $closestTime->getEnd()->getSeconds()
174
        );
175
176
        return new DateTimeInterval($intervalStart, $intervalEnd);
177
    }
178
179
    /**
180
     * Get the business hours date after the given date (excluding holidays).
181
     *
182
     * @param \DateTime $date
183
     * @return \DateTime
184
     */
185
    private function getDateAfter(\DateTime $date)
186
    {
187
        $tmpDate = clone $date;
188
        $tmpDate->modify('+1 day');
189
190
        $dayOfWeek = (int)$tmpDate->format('N');
191
        $closestDay = $this->getClosestDayAfter($dayOfWeek);
192
193
        if ($closestDay->getDayOfWeek() !== $dayOfWeek) {
194
            $tmpDate->modify(sprintf('next %s', $closestDay->getDayOfWeekName()));
195
        }
196
197
        return $tmpDate;
198
    }
199
200
    /**
201
     * Get the closest interval endpoint after the given date.
202
     *
203
     * @param \DateTime $date
204
     * @return DateTimeInterval
205
     */
206
    private function getClosestInterval(\DateTime $date)
207
    {
208
        $tmpDate = clone $date;
209
        $dayOfWeek = (int)$tmpDate->format('N');
210
        $time = TimeBuilder::fromDate($tmpDate);
211
212 View Code Duplication
        if (null !== $day = $this->getDay($dayOfWeek)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
            if (null !== $closestTime = $day->getClosestOpeningHoursInterval($time)) {
214
                $intervalStart = clone $tmpDate;
215
                $intervalEnd = clone $tmpDate;
216
217
                $intervalStart->setTime(
218
                    $closestTime->getStart()->getHours(),
219
                    $closestTime->getStart()->getMinutes(),
220
                    $closestTime->getStart()->getSeconds()
221
                );
222
                $intervalEnd->setTime(
223
                    $closestTime->getEnd()->getHours(),
224
                    $closestTime->getEnd()->getMinutes(),
225
                    $closestTime->getEnd()->getSeconds()
226
                );
227
228
                return new DateTimeInterval($intervalStart, $intervalEnd);
229
            }
230
        }
231
232
        return $this->getClosestDateIntervalAfter($date);
233
    }
234
235
    /**
236
     * Get the closest business hours day before a given day number (including it).
237
     *
238
     * @param integer $dayNumber
239
     * @return DayInterface|null
240
     */
241
    private function getClosestDayBefore($dayNumber)
242
    {
243
        if (null !== $day = $this->getDay($dayNumber)) {
244
            return $day;
245
        }
246
247
        return $this->getDayBefore($dayNumber);
248
    }
249
250
    /**
251
     * Get the closest business hours day after a given day number (including it).
252
     *
253
     * @param integer $dayNumber
254
     * @return DayInterface|null
255
     */
256
    private function getClosestDayAfter($dayNumber)
257
    {
258
        if (null !== $day = $this->getDay($dayNumber)) {
259
            return $day;
260
        }
261
262
        return $this->getDayAfter($dayNumber);
263
    }
264
265
    /**
266
     * Get the business hours day before the day number.
267
     *
268
     * @param integer $dayNumber
269
     * @return DayInterface|null
270
     */
271 View Code Duplication
    private function getDayBefore($dayNumber)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
272
    {
273
        $tmpDayNumber = $dayNumber;
274
275
        for ($i = 0; $i < 6; $i++) {
276
            $tmpDayNumber = (DayInterface::WEEK_DAY_MONDAY === $tmpDayNumber) ? DayInterface::WEEK_DAY_SUNDAY : --$tmpDayNumber;
277
278
            if (null !== $day = $this->getDay($tmpDayNumber)) {
279
                return $day;
280
            }
281
        }
282
283
        return $this->getDay($dayNumber);
284
    }
285
286
    /**
287
     * Get the business hours day after the day number.
288
     *
289
     * @param integer $dayNumber
290
     * @return DayInterface|null
291
     */
292 View Code Duplication
    private function getDayAfter($dayNumber)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
293
    {
294
        $tmpDayNumber = $dayNumber;
295
296
        for ($i = 0; $i < 6; $i++) {
297
            $tmpDayNumber = (DayInterface::WEEK_DAY_SUNDAY === $tmpDayNumber) ? DayInterface::WEEK_DAY_MONDAY : ++$tmpDayNumber;
298
299
            if (null !== $day = $this->getDay($tmpDayNumber)) {
300
                return $day;
301
            }
302
        }
303
304
        return $this->getDay($dayNumber);
305
    }
306
307
    /**
308
     * Get the day corresponding to the day number.
309
     *
310
     * @param integer $dayNumber
311
     * @return DayInterface|null
312
     */
313
    private function getDay($dayNumber)
314
    {
315
        return isset($this->days[$dayNumber]) ? $this->days[$dayNumber] : null;
316
    }
317
318
    /**
319
     * Add a day.
320
     *
321
     * @param DayInterface $day The day.
322
     */
323
    private function addDay(DayInterface $day)
324
    {
325
        $this->days[$day->getDayOfWeek()] = $day;
326
    }
327
}
328