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
Pull Request — master (#132)
by Kyle
01:47
created

OpeningHoursForDay::previousOpen()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
dl 11
loc 11
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\OpeningHours;
4
5
use Countable;
6
use Generator;
7
use ArrayAccess;
8
use ArrayIterator;
9
use IteratorAggregate;
10
use Spatie\OpeningHours\Helpers\Arr;
11
use Spatie\OpeningHours\Helpers\DataTrait;
12
use Spatie\OpeningHours\Exceptions\NonMutableOffsets;
13
use Spatie\OpeningHours\Exceptions\OverlappingTimeRanges;
14
15
class OpeningHoursForDay implements ArrayAccess, Countable, IteratorAggregate
16
{
17
    use DataTrait;
18
19
    /** @var \Spatie\OpeningHours\TimeRange[] */
20
    protected $openingHours = [];
21
22
    public static function fromStrings(array $strings)
23
    {
24
        if (isset($strings['hours'])) {
25
            return static::fromStrings($strings['hours'])->setData($strings['data'] ?? null);
26
        }
27
28
        $openingHoursForDay = new static();
29
30
        if (isset($strings['data'])) {
31
            $openingHoursForDay->setData($strings['data'] ?? null);
32
            unset($strings['data']);
33
        }
34
35
        uasort($strings, function ($a, $b) {
36
            return strcmp(static::getHoursFromRange($a), static::getHoursFromRange($b));
37
        });
38
39
        $timeRanges = Arr::map($strings, function ($string) {
40
            return TimeRange::fromDefinition($string);
41
        });
42
43
        $openingHoursForDay->guardAgainstTimeRangeOverlaps($timeRanges);
44
45
        $openingHoursForDay->openingHours = $timeRanges;
46
47
        return $openingHoursForDay;
48
    }
49
50
    public function isOpenAt(Time $time)
51
    {
52
        foreach ($this->openingHours as $timeRange) {
53
            if ($timeRange->containsTime($time)) {
54
                return true;
55
            }
56
        }
57
58
        return false;
59
    }
60
61
    public function isOpenAtNight(Time $time)
62
    {
63
        foreach ($this->openingHours as $timeRange) {
64
            if ($timeRange->containsNightTime($time)) {
65
                return true;
66
            }
67
        }
68
69
        return false;
70
    }
71
72
    /**
73
     * @param callable[] $filters
74
     * @param bool       $reverse
75
     *
76
     * @return Time|bool
77
     */
78
    public function openingHoursFilter(array $filters, bool $reverse = false)
79
    {
80
        foreach (($reverse ? array_reverse($this->openingHours) : $this->openingHours) as $timeRange) {
81
            foreach ($filters as $filter) {
82
                if ($result = $filter($timeRange)) {
83
                    reset($timeRange);
84
85
                    return $result;
86
                }
87
            }
88
        }
89
90
        return false;
91
    }
92
93
    /**
94
     * @param Time $time
95
     *
96
     * @return bool|Time
97
     */
98
    public function nextOpen(Time $time)
99
    {
100
        return $this->openingHoursFilter([
101
            function ($timeRange) use ($time) {
102
                return $this->findOpenInFreeTime($time, $timeRange);
103
            },
104
        ]);
105
    }
106
107
    /**
108
     * @param Time $time
109
     *
110
     * @return bool|TimeRange
111
     */
112
    public function nextOpenRange(Time $time)
113
    {
114
        return $this->openingHoursFilter([
115
            function ($timeRange) use ($time) {
116
                return $this->findRangeInFreeTime($time, $timeRange);
117
            },
118
        ]);
119
    }
120
121
    /**
122
     * @param Time $time
123
     *
124
     * @return bool|Time
125
     */
126 View Code Duplication
    public function nextClose(Time $time)
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...
127
    {
128
        return $this->openingHoursFilter([
129
            function ($timeRange) use ($time) {
130
                return $this->findCloseInWorkingHours($time, $timeRange);
131
            },
132
            function ($timeRange) use ($time) {
133
                return $this->findCloseInFreeTime($time, $timeRange);
134
            },
135
        ]);
136
    }
137
138
    /**
139
     * @param Time $time
140
     *
141
     * @return bool|TimeRange
142
     */
143 View Code Duplication
    public function nextCloseRange(Time $time)
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...
144
    {
145
        return $this->openingHoursFilter([
146
            function ($timeRange) use ($time) {
147
                return $this->findCloseRangeInWorkingHours($time, $timeRange);
148
            },
149
            function ($timeRange) use ($time) {
150
                return $this->findRangeInFreeTime($time, $timeRange);
151
            },
152
        ]);
153
    }
154
155
    /**
156
     * @param Time $time
157
     *
158
     * @return bool|Time
159
     */
160 View Code Duplication
    public function previousOpen(Time $time)
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...
161
    {
162
        return $this->openingHoursFilter([
163
            function ($timeRange) use ($time) {
164
                return $this->findPreviousOpenInFreeTime($time, $timeRange);
165
            },
166
            function ($timeRange) use ($time) {
167
                return $this->findOpenInWorkingHours($time, $timeRange);
168
            },
169
        ], true);
170
    }
171
172
    /**
173
     * @param Time $time
174
     *
175
     * @return bool|TimeRange
176
     */
177
    public function previousOpenRange(Time $time)
178
    {
179
        return $this->openingHoursFilter([
180
            function ($timeRange) use ($time) {
181
                return $this->findRangeInFreeTime($time, $timeRange);
182
            },
183
        ], true);
184
    }
185
186
    /**
187
     * @param Time $time
188
     *
189
     * @return bool|Time
190
     */
191
    public function previousClose(Time $time)
192
    {
193
        return $this->openingHoursFilter([
194
            function ($timeRange) use ($time) {
195
                return $this->findPreviousCloseInWorkingHours($time, $timeRange);
196
            },
197
        ], true);
198
    }
199
200
    /**
201
     * @param Time $time
202
     *
203
     * @return bool|TimeRange
204
     */
205
    public function previousCloseRange(Time $time)
206
    {
207
        return $this->openingHoursFilter([
208
            function ($timeRange) use ($time) {
209
                return $this->findPreviousRangeInFreeTime($time, $timeRange);
210
            },
211
        ], true);
212
    }
213
214
    protected function findRangeInFreeTime(Time $time, TimeRange $timeRange)
215
    {
216
        if ($timeRange->start()->isAfter($time)) {
0 ignored issues
show
Documentation introduced by
$time is of type object<Spatie\OpeningHours\Time>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
217
            return $timeRange;
218
        }
219
    }
220
221
    protected function findOpenInFreeTime(Time $time, TimeRange $timeRange)
222
    {
223
        $range = $this->findRangeInFreeTime($time, $timeRange);
224
225
        if ($range) {
226
            return $range->start();
227
        }
228
    }
229
230
    protected function findOpenRangeInWorkingHours(Time $time, TimeRange $timeRange)
231
    {
232
        if ($timeRange->start()->isBefore($time)) {
0 ignored issues
show
Documentation introduced by
$time is of type object<Spatie\OpeningHours\Time>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
233
            return $timeRange;
234
        }
235
    }
236
237
    protected function findOpenInWorkingHours(Time $time, TimeRange $timeRange)
238
    {
239
        $range = $this->findOpenRangeInWorkingHours($time, $timeRange);
240
241
        if ($range) {
242
            return $range->start();
243
        }
244
    }
245
246
    protected function findCloseInWorkingHours(Time $time, TimeRange $timeRange)
247
    {
248
        if ($timeRange->containsTime($time)) {
249
            return $timeRange->end();
250
        }
251
    }
252
253
    protected function findCloseRangeInWorkingHours(Time $time, TimeRange $timeRange)
254
    {
255
        if ($timeRange->containsTime($time)) {
256
            return $timeRange;
257
        }
258
    }
259
260
    protected function findCloseInFreeTime(Time $time, TimeRange $timeRange)
261
    {
262
        $range = $this->findRangeInFreeTime($time, $timeRange);
263
264
        if ($range) {
265
            return $range->end();
266
        }
267
    }
268
269
    protected function findPreviousRangeInFreeTime(Time $time, TimeRange $timeRange)
270
    {
271
        if ($timeRange->end()->isBefore($time)) {
0 ignored issues
show
Documentation introduced by
$time is of type object<Spatie\OpeningHours\Time>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
272
            return $timeRange;
273
        }
274
    }
275
276
    protected function findPreviousOpenInFreeTime(Time $time, TimeRange $timeRange)
277
    {
278
        $range = $this->findPreviousRangeInFreeTime($time, $timeRange);
279
280
        if ($range) {
281
            return $range->start();
282
        }
283
    }
284
285
    protected function findPreviousCloseInWorkingHours(Time $time, TimeRange $timeRange)
286
    {
287
        $end = $timeRange->end();
288
289
        if ($end->isBefore($time)) {
0 ignored issues
show
Documentation introduced by
$time is of type object<Spatie\OpeningHours\Time>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
290
            return $end;
291
        }
292
    }
293
294
    protected static function getHoursFromRange($range)
295
    {
296
        return strval((is_array($range)
297
            ? ($range['hours'] ?? array_values($range)[0] ?? null)
298
            : null
299
        ) ?: $range);
300
    }
301
302
    public function offsetExists($offset): bool
303
    {
304
        return isset($this->openingHours[$offset]);
305
    }
306
307
    public function offsetGet($offset)
308
    {
309
        return $this->openingHours[$offset];
310
    }
311
312
    public function offsetSet($offset, $value)
313
    {
314
        throw NonMutableOffsets::forClass(static::class);
315
    }
316
317
    public function offsetUnset($offset)
318
    {
319
        unset($this->openingHours[$offset]);
320
    }
321
322
    public function count(): int
323
    {
324
        return count($this->openingHours);
325
    }
326
327
    public function getIterator()
328
    {
329
        return new ArrayIterator($this->openingHours);
330
    }
331
332
    /**
333
     * @param Time $time
334
     *
335
     * @return TimeRange[]
336
     */
337
    public function forTime(Time $time): Generator
338
    {
339
        foreach ($this as $range) {
340
            /* @var TimeRange $range */
341
342
            if ($range->containsTime($time)) {
343
                yield $range;
344
            }
345
        }
346
    }
347
348
    /**
349
     * @param Time $time
350
     *
351
     * @return TimeRange[]
352
     */
353
    public function forNightTime(Time $time): Generator
354
    {
355
        foreach ($this as $range) {
356
            /* @var TimeRange $range */
357
358
            if ($range->containsNightTime($time)) {
359
                yield $range;
360
            }
361
        }
362
    }
363
364
    public function isEmpty(): bool
365
    {
366
        return empty($this->openingHours);
367
    }
368
369
    public function map(callable $callback): array
370
    {
371
        return Arr::map($this->openingHours, $callback);
372
    }
373
374
    protected function guardAgainstTimeRangeOverlaps(array $openingHours)
375
    {
376
        foreach (Arr::createUniquePairs($openingHours) as $timeRanges) {
377
            if ($timeRanges[0]->overlaps($timeRanges[1])) {
378
                throw OverlappingTimeRanges::forRanges($timeRanges[0], $timeRanges[1]);
379
            }
380
        }
381
    }
382
383
    public function __toString()
384
    {
385
        $values = [];
386
        foreach ($this->openingHours as $openingHour) {
387
            $values[] = (string) $openingHour;
388
        }
389
390
        return implode(',', $values);
391
    }
392
}
393