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 ( fec915...e674c5 )
by Sebastian
02:57
created

OpeningHours::setExceptionsFromStrings()   B

Complexity

Conditions 5
Paths 1

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 8
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 DateTimeZone|null */
22
    protected $timezone = null;
23
24
    public function __construct($timezone = null)
25
    {
26
        $this->timezone = $timezone ? new DateTimeZone($timezone) : null;
27
28
        $this->openingHours = Day::mapDays(function () {
29
            return new OpeningHoursForDay();
30
        });
31
    }
32
33
    /**
34
     * @param array $data
35
     *
36
     * @return static
37
     */
38
    public static function create(array $data)
39
    {
40
        return (new static())->fill($data);
41
    }
42
43
    /**
44
     * @param array $data
45
     *
46
     * @return bool
47
     */
48
    public static function isValid(array $data): bool
49
    {
50
        try {
51
            static::create($data);
52
53
            return true;
54
        } catch (Exception $exception) {
55
            return false;
56
        }
57
    }
58
59
    public function fill(array $data)
60
    {
61
        list($openingHours, $exceptions) = $this->parseOpeningHoursAndExceptions($data);
62
63
        foreach ($openingHours as $day => $openingHoursForThisDay) {
64
            $this->setOpeningHoursFromStrings($day, $openingHoursForThisDay);
65
        }
66
67
        $this->setExceptionsFromStrings($exceptions);
68
69
        return $this;
70
    }
71
72
    public function forWeek(): array
73
    {
74
        return $this->openingHours;
75
    }
76
77
    public function forDay(string $day): OpeningHoursForDay
78
    {
79
        $day = $this->normalizeDayName($day);
80
81
        return $this->openingHours[$day];
82
    }
83
84
    public function forDate(DateTimeInterface $date): OpeningHoursForDay
85
    {
86
        $date = $this->applyTimezone($date);
87
88
        return $this->exceptions[$date->format('Y-m-d')] ?? ($this->exceptions[$date->format('m-d')] ?? $this->forDay(Day::onDateTime($date)));
89
    }
90
91
    public function exceptions(): array
92
    {
93
        return $this->exceptions;
94
    }
95
96
    public function isOpenOn(string $day): bool
97
    {
98
        return count($this->forDay($day)) > 0;
99
    }
100
101
    public function isClosedOn(string $day): bool
102
    {
103
        return ! $this->isOpenOn($day);
104
    }
105
106
    public function isOpenAt(DateTimeInterface $dateTime): bool
107
    {
108
        $dateTime = $this->applyTimezone($dateTime);
109
110
        $openingHoursForDay = $this->forDate($dateTime);
111
112
        return $openingHoursForDay->isOpenAt(Time::fromDateTime($dateTime));
113
    }
114
115
    public function isClosedAt(DateTimeInterface $dateTime): bool
116
    {
117
        return ! $this->isOpenAt($dateTime);
118
    }
119
120
    public function isOpen(): bool
121
    {
122
        return $this->isOpenAt(new DateTime());
123
    }
124
125
    public function isClosed(): bool
126
    {
127
        return $this->isClosedAt(new DateTime());
128
    }
129
130
    public function nextOpen(DateTimeInterface $dateTime): DateTime
131
    {
132
        $openingHoursForDay = $this->forDate($dateTime);
133
        $nextOpen = $openingHoursForDay->nextOpen(Time::fromDateTime($dateTime));
134
135
        while ($nextOpen == false) {
136
            $dateTime
137
                ->modify('+1 day')
138
                ->setTime(0, 0, 0);
139
140
            $openingHoursForDay = $this->forDate($dateTime);
141
142
            $nextOpen = $openingHoursForDay->nextOpen(Time::fromDateTime($dateTime));
143
        }
144
145
        $nextDateTime = $nextOpen->toDateTime();
146
        $dateTime->setTime($nextDateTime->format('G'), $nextDateTime->format('i'), 0);
147
148
        return $dateTime;
149
    }
150
151
    public function regularClosingDays(): array
152
    {
153
        return array_keys($this->filter(function (OpeningHoursForDay $openingHoursForDay) {
154
            return $openingHoursForDay->isEmpty();
155
        }));
156
    }
157
158
    public function regularClosingDaysISO(): array
159
    {
160
        return Arr::map($this->regularClosingDays(), [Day::class, 'toISO']);
161
    }
162
163
    public function exceptionalClosingDates(): array
164
    {
165
        $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...
166
            return $openingHoursForDay->isEmpty();
167
        }));
168
169
        return Arr::map($dates, function ($date) {
170
            return DateTime::createFromFormat('Y-m-d', $date);
171
        });
172
    }
173
174
    public function setTimezone($timezone)
175
    {
176
        $this->timezone = new DateTimeZone($timezone);
177
    }
178
179
    protected function parseOpeningHoursAndExceptions(array $data): array
180
    {
181
        $exceptions = Arr::pull($data, 'exceptions', []);
182
        $openingHours = [];
183
184
        foreach ($data as $day => $openingHoursData) {
185
            $openingHours[$this->normalizeDayName($day)] = $openingHoursData;
186
        }
187
188
        return [$openingHours, $exceptions];
189
    }
190
191
    protected function setOpeningHoursFromStrings(string $day, array $openingHours)
192
    {
193
        $day = $this->normalizeDayName($day);
194
195
        $this->openingHours[$day] = OpeningHoursForDay::fromStrings($openingHours);
196
    }
197
198
    protected function setExceptionsFromStrings(array $exceptions)
199
    {
200
        $this->exceptions = Arr::map($exceptions, function (array $openingHours, string $date) {
201
            $recurring = DateTime::createFromFormat('m-d', $date);
202
203
            if ($recurring === false || $recurring->format('m-d') !== $date) {
204
                $dateTime = DateTime::createFromFormat('Y-m-d', $date);
205
206
                if ($dateTime === false || $dateTime->format('Y-m-d') !== $date) {
207
                    throw InvalidDate::invalidDate($date);
208
                }
209
            }
210
211
            return OpeningHoursForDay::fromStrings($openingHours);
212
        });
213
    }
214
215
    protected function normalizeDayName(string $day)
216
    {
217
        $day = strtolower($day);
218
219
        if (! Day::isValid($day)) {
220
            throw new InvalidDayName();
221
        }
222
223
        return $day;
224
    }
225
226
    protected function applyTimezone(DateTimeInterface $date)
227
    {
228
        if ($this->timezone) {
229
            $date = $date->setTimezone($this->timezone);
230
        }
231
232
        return $date;
233
    }
234
235
    public function filter(callable $callback): array
236
    {
237
        return Arr::filter($this->openingHours, $callback);
238
    }
239
240
    public function map(callable $callback): array
241
    {
242
        return Arr::map($this->openingHours, $callback);
243
    }
244
245
    public function flatMap(callable $callback): array
246
    {
247
        return Arr::flatMap($this->openingHours, $callback);
248
    }
249
250
    public function filterExceptions(callable $callback): array
251
    {
252
        return Arr::filter($this->exceptions, $callback);
253
    }
254
255
    public function mapExceptions(callable $callback): array
256
    {
257
        return Arr::map($this->exceptions, $callback);
258
    }
259
260
    public function flatMapExceptions(callable $callback): array
261
    {
262
        return Arr::flatMap($this->exceptions, $callback);
263
    }
264
265
    public function asStructuredData(): array
266
    {
267 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...
268
            return $openingHoursForDay->map(function (TimeRange $timeRange) use ($day) {
269
                return [
270
                    '@type' => 'OpeningHoursSpecification',
271
                    'dayOfWeek' => ucfirst($day),
272
                    'opens' => (string) $timeRange->start(),
273
                    'closes' => (string) $timeRange->end(),
274
                ];
275
            });
276
        });
277
278
        $exceptions = $this->flatMapExceptions(function (OpeningHoursForDay $openingHoursForDay, string $date) {
279
            if ($openingHoursForDay->isEmpty()) {
280
                return [[
281
                    '@type' => 'OpeningHoursSpecification',
282
                    'opens' => '00:00',
283
                    'closes' => '00:00',
284
                    'validFrom' => $date,
285
                    'validThrough' => $date,
286
                ]];
287
            }
288
289 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...
290
                return [
291
                    '@type' => 'OpeningHoursSpecification',
292
                    'opens' => $timeRange->start(),
293
                    'closes' => $timeRange->end(),
294
                    'validFrom' => $date,
295
                    'validThrough' => $date,
296
                ];
297
            });
298
        });
299
300
        return array_merge($regularHours, $exceptions);
301
    }
302
}
303