Skip to content

Commit dd78539

Browse files
authored
Merge pull request #237 from spatie/feature/structured-data
Improve createFromStructuredData()
2 parents 78578d8 + 793b060 commit dd78539

6 files changed

+424
-93
lines changed

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,31 @@ Checks if the business is closed right now.
421421
$openingHours->isClosed();
422422
```
423423

424+
#### `OpeningHours::isAlwaysOpen(): bool`
425+
426+
Checks if the business is open 24/7, has no exceptions and no filters.
427+
428+
```php
429+
if ($openingHours->isAlwaysOpen()) {
430+
echo 'This business is open all day long every day.';
431+
}
432+
```
433+
434+
#### `OpeningHours::isAlwaysClosed(): bool`
435+
436+
Checks if the business is never open, has no exceptions and no filters.
437+
438+
`OpeningHours` accept empty array or list with every week day empty with no prejudices.
439+
440+
If it's not a valid state in your domain, you should use this method to throw an exception
441+
or show an error.
442+
443+
```php
444+
if ($openingHours->isAlwaysClosed()) {
445+
throw new RuntimeException('Opening hours missing');
446+
}
447+
```
448+
424449
#### `OpeningHours::nextOpen`
425450

426451
```php

src/OpeningHours.php

+42-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use Spatie\OpeningHours\Helpers\DataTrait;
2121
use Spatie\OpeningHours\Helpers\DateTimeCopier;
2222
use Spatie\OpeningHours\Helpers\DiffTrait;
23-
use ValueError;
2423

2524
class OpeningHours
2625
{
@@ -128,9 +127,15 @@ public static function createFromStructuredData(
128127
string|DateTimeZone|null $timezone = null,
129128
string|DateTimeZone|null $outputTimezone = null,
130129
): self {
131-
$parser = new OpeningHoursSpecificationParser($structuredData);
132-
133-
return new static($parser->getOpeningHours(), $timezone, $outputTimezone);
130+
return new static(
131+
array_merge(
132+
// https://schema.org/OpeningHoursSpecification allows overflow by default
133+
['overflow' => true],
134+
OpeningHoursSpecificationParser::create($structuredData)->getOpeningHours(),
135+
),
136+
$timezone,
137+
$outputTimezone,
138+
);
134139
}
135140

136141
/**
@@ -213,7 +218,7 @@ public static function isValid(array $data): bool
213218
static::create($data);
214219

215220
return true;
216-
} catch (Exception|ValueError) {
221+
} catch (Exception) {
217222
return false;
218223
}
219224
}
@@ -891,6 +896,11 @@ protected function getDateWithTimezone(DateTimeInterface $date, ?DateTimeZone $t
891896
return $date;
892897
}
893898

899+
/**
900+
* Returns opening hours for the days that match a given condition as an array.
901+
*
902+
* @return OpeningHoursForDay[]
903+
*/
894904
public function filter(callable $callback): array
895905
{
896906
return Arr::filter($this->openingHours, $callback);
@@ -906,6 +916,11 @@ public function flatMap(callable $callback): array
906916
return Arr::flatMap($this->openingHours, $callback);
907917
}
908918

919+
/**
920+
* Returns opening hours for the exceptions that match a given condition as an array.
921+
*
922+
* @return OpeningHoursForDay[]
923+
*/
909924
public function filterExceptions(callable $callback): array
910925
{
911926
return Arr::filter($this->exceptions, $callback);
@@ -921,6 +936,14 @@ public function flatMapExceptions(callable $callback): array
921936
return Arr::flatMap($this->exceptions, $callback);
922937
}
923938

939+
/** Checks that opening hours for every day of the week matches a given condition */
940+
public function every(callable $callback): bool
941+
{
942+
return $this->filter(
943+
static fn (OpeningHoursForDay $day) => ! $callback($day),
944+
) === [];
945+
}
946+
924947
public function asStructuredData(
925948
string $format = TimeDataContainer::TIME_FORMAT,
926949
DateTimeZone|string|null $timezone = null,
@@ -965,6 +988,20 @@ static function (OpeningHoursForDay $openingHoursForDay, string $date) use ($for
965988
return array_merge($regularHours, $exceptions);
966989
}
967990

991+
public function isAlwaysClosed(): bool
992+
{
993+
return $this->exceptions === [] && $this->filters === [] && $this->every(
994+
static fn (OpeningHoursForDay $day) => $day->isEmpty(),
995+
);
996+
}
997+
998+
public function isAlwaysOpen(): bool
999+
{
1000+
return $this->exceptions === [] && $this->filters === [] && $this->every(
1001+
static fn (OpeningHoursForDay $day) => ((string) $day) === '00:00-24:00',
1002+
);
1003+
}
1004+
9681005
private static function filterHours(array $data, array $excludedKeys): Generator
9691006
{
9701007
foreach ($data as $key => $value) {

0 commit comments

Comments
 (0)