Skip to content

Commit

Permalink
Merge pull request #237 from spatie/feature/structured-data
Browse files Browse the repository at this point in the history
Improve createFromStructuredData()
  • Loading branch information
kylekatarnls committed Nov 25, 2023
2 parents 78578d8 + 793b060 commit dd78539
Show file tree
Hide file tree
Showing 6 changed files with 424 additions and 93 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,31 @@ Checks if the business is closed right now.
$openingHours->isClosed();
```

#### `OpeningHours::isAlwaysOpen(): bool`

Checks if the business is open 24/7, has no exceptions and no filters.

```php
if ($openingHours->isAlwaysOpen()) {
echo 'This business is open all day long every day.';
}
```

#### `OpeningHours::isAlwaysClosed(): bool`

Checks if the business is never open, has no exceptions and no filters.

`OpeningHours` accept empty array or list with every week day empty with no prejudices.

If it's not a valid state in your domain, you should use this method to throw an exception
or show an error.

```php
if ($openingHours->isAlwaysClosed()) {
throw new RuntimeException('Opening hours missing');
}
```

#### `OpeningHours::nextOpen`

```php
Expand Down
47 changes: 42 additions & 5 deletions src/OpeningHours.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use Spatie\OpeningHours\Helpers\DataTrait;
use Spatie\OpeningHours\Helpers\DateTimeCopier;
use Spatie\OpeningHours\Helpers\DiffTrait;
use ValueError;

class OpeningHours
{
Expand Down Expand Up @@ -128,9 +127,15 @@ public static function createFromStructuredData(
string|DateTimeZone|null $timezone = null,
string|DateTimeZone|null $outputTimezone = null,
): self {
$parser = new OpeningHoursSpecificationParser($structuredData);

return new static($parser->getOpeningHours(), $timezone, $outputTimezone);
return new static(
array_merge(
// https://schema.org/OpeningHoursSpecification allows overflow by default
['overflow' => true],
OpeningHoursSpecificationParser::create($structuredData)->getOpeningHours(),
),
$timezone,
$outputTimezone,
);
}

/**
Expand Down Expand Up @@ -213,7 +218,7 @@ public static function isValid(array $data): bool
static::create($data);

return true;
} catch (Exception|ValueError) {
} catch (Exception) {
return false;
}
}
Expand Down Expand Up @@ -891,6 +896,11 @@ protected function getDateWithTimezone(DateTimeInterface $date, ?DateTimeZone $t
return $date;
}

/**
* Returns opening hours for the days that match a given condition as an array.
*
* @return OpeningHoursForDay[]
*/
public function filter(callable $callback): array
{
return Arr::filter($this->openingHours, $callback);
Expand All @@ -906,6 +916,11 @@ public function flatMap(callable $callback): array
return Arr::flatMap($this->openingHours, $callback);
}

/**
* Returns opening hours for the exceptions that match a given condition as an array.
*
* @return OpeningHoursForDay[]
*/
public function filterExceptions(callable $callback): array
{
return Arr::filter($this->exceptions, $callback);
Expand All @@ -921,6 +936,14 @@ public function flatMapExceptions(callable $callback): array
return Arr::flatMap($this->exceptions, $callback);
}

/** Checks that opening hours for every day of the week matches a given condition */
public function every(callable $callback): bool
{
return $this->filter(
static fn (OpeningHoursForDay $day) => ! $callback($day),
) === [];
}

public function asStructuredData(
string $format = TimeDataContainer::TIME_FORMAT,
DateTimeZone|string|null $timezone = null,
Expand Down Expand Up @@ -965,6 +988,20 @@ static function (OpeningHoursForDay $openingHoursForDay, string $date) use ($for
return array_merge($regularHours, $exceptions);
}

public function isAlwaysClosed(): bool
{
return $this->exceptions === [] && $this->filters === [] && $this->every(
static fn (OpeningHoursForDay $day) => $day->isEmpty(),
);
}

public function isAlwaysOpen(): bool
{
return $this->exceptions === [] && $this->filters === [] && $this->every(
static fn (OpeningHoursForDay $day) => ((string) $day) === '00:00-24:00',
);
}

private static function filterHours(array $data, array $excludedKeys): Generator
{
foreach ($data as $key => $value) {
Expand Down
Loading

0 comments on commit dd78539

Please sign in to comment.