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 (#46)
by
unknown
01:19
created

OpeningHours::setRecurringExceptionsForDates()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
dl 12
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 1
nop 1
1
<?php
2
3
namespace Spatie\OpeningHours;
4
5
use DateTime;
6
use DateTimeZone;
7
use DateTimeInterface;
8
use Spatie\OpeningHours\Helpers\Arr;
9
use Spatie\OpeningHours\Exceptions\Exception;
10
use Spatie\OpeningHours\Exceptions\InvalidDate;
11
use Spatie\OpeningHours\Exceptions\InvalidDayName;
12
13
class OpeningHours
14
{
15
    /** @var \Spatie\OpeningHours\Day[] */
16
    protected $openingHours = [];
17
18
    /** @var array */
19
    protected $exceptions = [];
20
21
    /** @var array */
22
    protected $recurring_exceptions = [];
23
24
    /** @var DateTimeZone|null */
25
    protected $timezone = null;
26
27
    public function __construct($timezone = null)
28
    {
29
        $this->timezone = $timezone ? new DateTimeZone($timezone) : null;
30
31
        $this->openingHours = Day::mapDays(function () {
32
            return new OpeningHoursForDay();
33
        });
34
    }
35
36
    /**
37
     * @param array $data
38
     *
39
     * @return static
40
     */
41
    public static function create(array $data)
42
    {
43
        return (new static())->fill($data);
44
    }
45
46
    /**
47
     * @param array $data
48
     *
49
     * @return bool
50
     */
51
    public static function isValid(array $data): bool
52
    {
53
        try {
54
            static::create($data);
55
56
            return true;
57
        } catch (Exception $exception) {
58
            return false;
59
        }
60
    }
61
62
    public function fill(array $data)
63
    {
64
        list($openingHours, $exceptions, $recurring_exceptions) = $this->parseOpeningHoursAndExceptions($data);
65
66
        foreach ($openingHours as $day => $openingHoursForThisDay) {
67
            $this->setOpeningHoursFromStrings($day, $openingHoursForThisDay);
68
        }
69
70
        $this->setExceptionsFromStrings($exceptions);
71
        $this->setRecurringExceptionsForDates($recurring_exceptions);
72
73
        return $this;
74
    }
75
76
    public function forWeek(): array
77
    {
78
        return $this->openingHours;
79
    }
80
81
    public function forDay(string $day): OpeningHoursForDay
82
    {
83
        $day = $this->normalizeDayName($day);
84
85
        return $this->openingHours[$day];
86
    }
87
88
    public function forDate(DateTimeInterface $date): OpeningHoursForDay
89
    {
90
        $date = $this->applyTimezone($date);
91
92
        return $this->recurring_exceptions[$date->format('m-d')] ?? ($this->exceptions[$date->format('Y-m-d')] ?? $this->forDay(Day::onDateTime($date)));
93
    }
94
95
    public function exceptions(): array
96
    {
97
        return $this->exceptions;
98
    }
99
100
    public function recurringExceptions(): array
101
    {
102
        return $this->recurring_exceptions;
103
    }
104
105
    public function isOpenOn(string $day): bool
106
    {
107
        return count($this->forDay($day)) > 0;
108
    }
109
110
    public function isClosedOn(string $day): bool
111
    {
112
        return ! $this->isOpenOn($day);
113
    }
114
115
    public function isOpenAt(DateTimeInterface $dateTime): bool
116
    {
117
        $dateTime = $this->applyTimezone($dateTime);
118
119
        $openingHoursForDay = $this->forDate($dateTime);
120
121
        return $openingHoursForDay->isOpenAt(Time::fromDateTime($dateTime));
122
    }
123
124
    public function isClosedAt(DateTimeInterface $dateTime): bool
125
    {
126
        return ! $this->isOpenAt($dateTime);
127
    }
128
129
    public function isOpen(): bool
130
    {
131
        return $this->isOpenAt(new DateTime());
132
    }
133
134
    public function isClosed(): bool
135
    {
136
        return $this->isClosedAt(new DateTime());
137
    }
138
139
    public function nextOpen(DateTimeInterface $dateTime): DateTime
140
    {
141
        $openingHoursForDay = $this->forDate($dateTime);
142
        $nextOpen = $openingHoursForDay->nextOpen(Time::fromDateTime($dateTime));
143
144
        while ($nextOpen == false) {
145
            $dateTime
146
                ->modify('+1 day')
147
                ->setTime(0, 0, 0);
148
149
            $openingHoursForDay = $this->forDate($dateTime);
150
151
            $nextOpen = $openingHoursForDay->nextOpen(Time::fromDateTime($dateTime));
152
        }
153
154
        $nextDateTime = $nextOpen->toDateTime();
155
        $dateTime->setTime($nextDateTime->format('G'), $nextDateTime->format('i'), 0);
156
157
        return $dateTime;
158
    }
159
160
    public function regularClosingDays(): array
161
    {
162
        return array_keys($this->filter(function (OpeningHoursForDay $openingHoursForDay) {
163
            return $openingHoursForDay->isEmpty();
164
        }));
165
    }
166
167
    public function regularClosingDaysISO(): array
168
    {
169
        return Arr::map($this->regularClosingDays(), [Day::class, 'toISO']);
170
    }
171
172
    public function exceptionalClosingDates(): array
173
    {
174
        $dates = array_keys($this->filterExceptions(function (OpeningHoursForDay $openingHoursForDay, $date) {
0 ignored issues
show
Unused Code introduced by
The parameter $date is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
175
            return $openingHoursForDay->isEmpty();
176
        }));
177
178
        return Arr::map($dates, function ($date) {
179
            return DateTime::createFromFormat('Y-m-d', $date);
180
        });
181
    }
182
183
    public function setTimezone($timezone)
184
    {
185
        $this->timezone = new DateTimeZone($timezone);
186
    }
187
188
    protected function parseOpeningHoursAndExceptions(array $data): array
189
    {
190
        $exceptions = Arr::pull($data, 'exceptions', []);
191
        $recurring_exceptions = Arr::pull($data, 'recurring_exceptions', []);
192
        $openingHours = [];
193
194
        foreach ($data as $day => $openingHoursData) {
195
            $openingHours[$this->normalizeDayName($day)] = $openingHoursData;
196
        }
197
198
        return [$openingHours, $exceptions, $recurring_exceptions];
199
    }
200
201
    protected function setOpeningHoursFromStrings(string $day, array $openingHours)
202
    {
203
        $day = $this->normalizeDayName($day);
204
205
        $this->openingHours[$day] = OpeningHoursForDay::fromStrings($openingHours);
206
    }
207
208 View Code Duplication
    protected function setExceptionsFromStrings(array $exceptions)
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...
209
    {
210
        $this->exceptions = Arr::map($exceptions, function (array $openingHours, string $date) {
211
            $dateTime = DateTime::createFromFormat('Y-m-d', $date);
212
213
            if ($dateTime === false || $dateTime->format('Y-m-d') !== $date) {
214
                throw InvalidDate::invalidDate($date);
215
            }
216
217
            return OpeningHoursForDay::fromStrings($openingHours);
218
        });
219
    }
220
221 View Code Duplication
    protected function setRecurringExceptionsForDates(array $recurring_exceptions)
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...
222
    {
223
        $this->recurring_exceptions = Arr::map($recurring_exceptions, function (array $openingsHours, string $date) {
224
            $dateTime = DateTime::createFromFormat('m-d', $date);
225
226
            if ($dateTime === false || $dateTime->format('m-d') !== $date) {
227
                throw InvalidDate::invalidDate($date);
228
            }
229
230
            return OpeningHoursForDay::fromStrings($openingsHours);
231
        });
232
    }
233
234
    protected function normalizeDayName(string $day)
235
    {
236
        $day = strtolower($day);
237
238
        if (! Day::isValid($day)) {
239
            throw new InvalidDayName();
240
        }
241
242
        return $day;
243
    }
244
245
    protected function applyTimezone(DateTimeInterface $date)
246
    {
247
        if ($this->timezone) {
248
            $date = $date->setTimezone($this->timezone);
249
        }
250
251
        return $date;
252
    }
253
254
    public function filter(callable $callback): array
255
    {
256
        return Arr::filter($this->openingHours, $callback);
257
    }
258
259
    public function map(callable $callback): array
260
    {
261
        return Arr::map($this->openingHours, $callback);
262
    }
263
264
    public function flatMap(callable $callback): array
265
    {
266
        return Arr::flatMap($this->openingHours, $callback);
267
    }
268
269
    public function filterExceptions(callable $callback): array
270
    {
271
        return Arr::filter($this->exceptions, $callback);
272
    }
273
274
    public function mapExceptions(callable $callback): array
275
    {
276
        return Arr::map($this->exceptions, $callback);
277
    }
278
279
    public function flatMapExceptions(callable $callback): array
280
    {
281
        return Arr::flatMap($this->exceptions, $callback);
282
    }
283
284
    public function filterRecurringExceptions(callable $callback): array
285
    {
286
        return Arr::filter($this->recurring_exceptions, $callback);
287
    }
288
289
    public function mapRecurringExceptions(callable $callback): array
290
    {
291
        return Arr::map($this->recurring_exceptions, $callback);
292
    }
293
294
    public function flatMapRecurringExceptions(callable $callback): array
295
    {
296
        return Arr::flatMap($this->recurring_exceptions, $callback);
297
    }
298
299
    public function asStructuredData(): array
300
    {
301 View Code Duplication
        $regularHours = $this->flatMap(function (OpeningHoursForDay $openingHoursForDay, string $day) {
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...
302
            return $openingHoursForDay->map(function (TimeRange $timeRange) use ($day) {
303
                return [
304
                    '@type' => 'OpeningHoursSpecification',
305
                    'dayOfWeek' => ucfirst($day),
306
                    'opens' => (string) $timeRange->start(),
307
                    'closes' => (string) $timeRange->end(),
308
                ];
309
            });
310
        });
311
312
        $exceptions = $this->flatMapExceptions(function (OpeningHoursForDay $openingHoursForDay, string $date) {
313 View Code Duplication
            if ($openingHoursForDay->isEmpty()) {
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...
314
                return [[
315
                    '@type' => 'OpeningHoursSpecification',
316
                    'opens' => '00:00',
317
                    'closes' => '00:00',
318
                    'validFrom' => $date,
319
                    'validThrough' => $date,
320
                ]];
321
            }
322
323 View Code Duplication
            return $openingHoursForDay->map(function (TimeRange $timeRange) use ($date) {
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...
324
                return [
325
                    '@type' => 'OpeningHoursSpecification',
326
                    'opens' => $timeRange->start(),
327
                    'closes' => $timeRange->end(),
328
                    'validFrom' => $date,
329
                    'validThrough' => $date,
330
                ];
331
            });
332
        });
333
334
        $recurring_exceptions = $this->flatMapRecurringExceptions(function (OpeningHoursForDay $openingHoursForDay, string $date) {
335 View Code Duplication
            if ($openingHoursForDay->isEmpty()) {
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...
336
                return [[
337
                    '@type' => 'OpeningHoursSpecification',
338
                    'opens' => '00:00',
339
                    'closes' => '00:00',
340
                    'validFrom' => $date,
341
                    'validThrough' => $date,
342
                ]];
343
            }
344
        });
345
346
        return array_merge($regularHours, $exceptions, $recurring_exceptions);
347
    }
348
}
349