mirror of
https://github.com/werkraum-media/thuecat.git
synced 2024-12-04 19:16:13 +01:00
Add merged opening hours (#104)
This allows to fetch merged opening hours instead of actually edited opening hours. They will be merged per valid time span. The data structure is a bit different as each time span has a list of week days, each with its own open and end. Relates: #10246
This commit is contained in:
parent
6a049366b9
commit
928f42e7fc
14 changed files with 639 additions and 92 deletions
103
Classes/Domain/Model/Frontend/MergedOpeningHour.php
Normal file
103
Classes/Domain/Model/Frontend/MergedOpeningHour.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||
|
||||
class MergedOpeningHour
|
||||
{
|
||||
/**
|
||||
* @var MergedOpeningHourWeekDay[]
|
||||
*/
|
||||
private $weekDays = [];
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable|null
|
||||
*/
|
||||
private $from;
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable|null
|
||||
*/
|
||||
private $through;
|
||||
|
||||
public function __construct(
|
||||
array $weekDays,
|
||||
?\DateTimeImmutable $from,
|
||||
?\DateTimeImmutable $through
|
||||
) {
|
||||
$this->weekDays = array_values($weekDays);
|
||||
$this->from = $from;
|
||||
$this->through = $through;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MergedOpeningHourWeekDay[]
|
||||
*/
|
||||
public function getWeekDays(): array
|
||||
{
|
||||
return $this->weekDays;
|
||||
}
|
||||
|
||||
public function getWeekDaysWithMondayFirstWeekDay(): array
|
||||
{
|
||||
return $this->sortWeekDays([
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
'Wednesday',
|
||||
'Thursday',
|
||||
'Friday',
|
||||
'Saturday',
|
||||
'Sunday',
|
||||
'PublicHolidays',
|
||||
]);
|
||||
}
|
||||
|
||||
public function getFrom(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->from;
|
||||
}
|
||||
|
||||
public function getThrough(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->through;
|
||||
}
|
||||
|
||||
private function sortWeekDays(array $sorting): array
|
||||
{
|
||||
$days = [];
|
||||
$weekDays = array_map(function (MergedOpeningHourWeekDay $weekDay) {
|
||||
return $weekDay->getDayOfWeek();
|
||||
}, $this->weekDays);
|
||||
|
||||
foreach ($sorting as $weekDay) {
|
||||
$position = array_search($weekDay, $weekDays);
|
||||
if ($position === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$days[] = $this->weekDays[$position];
|
||||
}
|
||||
|
||||
return $days;
|
||||
}
|
||||
}
|
69
Classes/Domain/Model/Frontend/MergedOpeningHourWeekDay.php
Normal file
69
Classes/Domain/Model/Frontend/MergedOpeningHourWeekDay.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||
|
||||
use WerkraumMedia\ThueCat\Domain\TimingFormat;
|
||||
|
||||
class MergedOpeningHourWeekDay
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $opens;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $closes;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dayOfWeek;
|
||||
|
||||
public function __construct(
|
||||
string $opens,
|
||||
string $closes,
|
||||
string $dayOfWeek
|
||||
) {
|
||||
$this->opens = $opens;
|
||||
$this->closes = $closes;
|
||||
$this->dayOfWeek = $dayOfWeek;
|
||||
}
|
||||
|
||||
public function getOpens(): string
|
||||
{
|
||||
return TimingFormat::format($this->opens);
|
||||
}
|
||||
|
||||
public function getCloses(): string
|
||||
{
|
||||
return TimingFormat::format($this->closes);
|
||||
}
|
||||
|
||||
public function getDayOfWeek(): string
|
||||
{
|
||||
return $this->dayOfWeek;
|
||||
}
|
||||
}
|
75
Classes/Domain/Model/Frontend/MergedOpeningHours.php
Normal file
75
Classes/Domain/Model/Frontend/MergedOpeningHours.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||
|
||||
class MergedOpeningHours implements \Iterator, \Countable
|
||||
{
|
||||
/**
|
||||
* @var MergedOpeningHour[]
|
||||
*/
|
||||
private $openingHours = [];
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $position = 0;
|
||||
|
||||
/**
|
||||
* @param MergedOpeningHour[] $openingHours
|
||||
*/
|
||||
public function __construct(array $openingHours)
|
||||
{
|
||||
$this->openingHours = array_values($openingHours);
|
||||
}
|
||||
|
||||
public function current(): MergedOpeningHour
|
||||
{
|
||||
return $this->openingHours[$this->position];
|
||||
}
|
||||
|
||||
public function next(): void
|
||||
{
|
||||
++$this->position;
|
||||
}
|
||||
|
||||
public function key(): int
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function valid(): bool
|
||||
{
|
||||
return isset($this->openingHours[$this->position]);
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->openingHours);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||
|
||||
use WerkraumMedia\ThueCat\Domain\TimingFormat;
|
||||
|
||||
class OpeningHour
|
||||
{
|
||||
/**
|
||||
|
@ -91,12 +93,12 @@ class OpeningHour
|
|||
|
||||
public function getOpens(): string
|
||||
{
|
||||
return $this->formatTiming($this->opens);
|
||||
return TimingFormat::format($this->opens);
|
||||
}
|
||||
|
||||
public function getCloses(): string
|
||||
{
|
||||
return $this->formatTiming($this->closes);
|
||||
return TimingFormat::format($this->closes);
|
||||
}
|
||||
|
||||
public function getDaysOfWeek(): array
|
||||
|
@ -158,35 +160,4 @@ class OpeningHour
|
|||
|
||||
return $days;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns timing in default format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function formatTiming(string $timing): string
|
||||
{
|
||||
$parts = $this->getTimingParts($timing);
|
||||
|
||||
if ($parts['hour'] === '' || $parts['minutes'] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $parts['hour'] . ':' . $parts['minutes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the string representationg of a time HH:MM:SS into an array.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function getTimingParts(string $string): array
|
||||
{
|
||||
$parts = explode(':', $string);
|
||||
return [
|
||||
'hour' => $parts[0] ?? '',
|
||||
'minutes' => $parts[1] ?? '',
|
||||
'seconds' => $parts[2] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,53 @@ class OpeningHours implements TypeInterface, \Iterator, \Countable
|
|||
return array_values($array);
|
||||
}
|
||||
|
||||
public function getMerged(): MergedOpeningHours
|
||||
{
|
||||
$weekDaysPerTimeSpan = [];
|
||||
foreach ($this as $hour) {
|
||||
$key = $this->buildKey($hour);
|
||||
if (isset($weekDaysPerTimeSpan[$key]) === false) {
|
||||
$weekDaysPerTimeSpan[$key] = [
|
||||
'from' => $hour->getFrom(),
|
||||
'through' => $hour->getThrough(),
|
||||
'weekDays' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$weekDays = array_map(function (string $dayOfWeek) use ($hour) {
|
||||
return new MergedOpeningHourWeekDay(
|
||||
$hour->getOpens(),
|
||||
$hour->getCloses(),
|
||||
$dayOfWeek
|
||||
);
|
||||
}, $hour->getDaysOfWeek());
|
||||
$weekDaysPerTimeSpan[$key]['weekDays'] = array_merge($weekDaysPerTimeSpan[$key]['weekDays'], $weekDays);
|
||||
}
|
||||
|
||||
$mergedOpeningHours = array_map(function (array $timeSpan) {
|
||||
return new MergedOpeningHour(
|
||||
$timeSpan['weekDays'],
|
||||
$timeSpan['from'],
|
||||
$timeSpan['through']
|
||||
);
|
||||
}, $weekDaysPerTimeSpan);
|
||||
|
||||
return new MergedOpeningHours($mergedOpeningHours);
|
||||
}
|
||||
|
||||
private function buildKey(OpeningHour $hour): string
|
||||
{
|
||||
$start = '';
|
||||
if ($hour->getFrom()) {
|
||||
$start = $hour->getFrom()->format('d.m.Y');
|
||||
}
|
||||
$end = '';
|
||||
if ($hour->getThrough()) {
|
||||
$end = $hour->getThrough()->format('d.m.Y');
|
||||
}
|
||||
return $start . '-' . $end;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->serialized;
|
||||
|
|
|
@ -103,11 +103,27 @@ abstract class Place extends Base
|
|||
return $this->openingHours;
|
||||
}
|
||||
|
||||
public function getMergedOpeningHours(): ?MergedOpeningHours
|
||||
{
|
||||
if ($this->openingHours === null) {
|
||||
return null;
|
||||
}
|
||||
return $this->openingHours->getMerged();
|
||||
}
|
||||
|
||||
public function getSpecialOpeningHours(): ?OpeningHours
|
||||
{
|
||||
return $this->specialOpeningHours;
|
||||
}
|
||||
|
||||
public function getMergedSpecialOpeningHours(): ?MergedOpeningHours
|
||||
{
|
||||
if ($this->specialOpeningHours === null) {
|
||||
return null;
|
||||
}
|
||||
return $this->specialOpeningHours->getMerged();
|
||||
}
|
||||
|
||||
public function getParkingFacilitiesNearBy(): ObjectStorage
|
||||
{
|
||||
return $this->parkingFacilityNearBy;
|
||||
|
|
58
Classes/Domain/TimingFormat.php
Normal file
58
Classes/Domain/TimingFormat.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Domain;
|
||||
|
||||
class TimingFormat
|
||||
{
|
||||
/**
|
||||
* Returns timing in default format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function format(string $timing): string
|
||||
{
|
||||
$parts = self::getTimingParts($timing);
|
||||
|
||||
if ($parts['hour'] === '' || $parts['minutes'] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $parts['hour'] . ':' . $parts['minutes'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the string representationg of a time HH:MM:SS into an array.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private static function getTimingParts(string $string): array
|
||||
{
|
||||
$parts = explode(':', $string);
|
||||
return [
|
||||
'hour' => $parts[0] ?? '',
|
||||
'minutes' => $parts[1] ?? '',
|
||||
'seconds' => $parts[2] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -23,35 +23,15 @@ declare(strict_types=1);
|
|||
|
||||
namespace WerkraumMedia\ThueCat\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
|
||||
class DateBasedFilter
|
||||
interface DateBasedFilter
|
||||
{
|
||||
/**
|
||||
* @var Context
|
||||
*/
|
||||
private $context;
|
||||
|
||||
public function __construct(
|
||||
Context $context
|
||||
) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all objects where the date is prior the reference date.
|
||||
*
|
||||
* The reference date is now.
|
||||
* The reference date depends on implementation.
|
||||
*/
|
||||
public function filterOutPreviousDates(
|
||||
array $listToFilter,
|
||||
callable $provideDate
|
||||
): array {
|
||||
$referenceDate = $this->context->getPropertyFromAspect('date', 'full');
|
||||
|
||||
return array_filter($listToFilter, function($elementToFilter) use ($referenceDate, $provideDate) {
|
||||
$objectDate = $provideDate($elementToFilter);
|
||||
return $objectDate === null || $objectDate >= $referenceDate;
|
||||
});
|
||||
}
|
||||
): array;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||
|
||||
class FilterBasedOnTypo3Context implements DateBasedFilter
|
||||
{
|
||||
/**
|
||||
* @var Context
|
||||
*/
|
||||
private $context;
|
||||
|
||||
public function __construct(
|
||||
Context $context
|
||||
) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all objects where the date is prior the reference date.
|
||||
*
|
||||
* The reference date is now.
|
||||
*/
|
||||
public function filterOutPreviousDates(
|
||||
array $listToFilter,
|
||||
callable $provideDate
|
||||
): array {
|
||||
$referenceDate = $this->context->getPropertyFromAspect('date', 'full', new \DateTimeImmutable());
|
||||
|
||||
return array_filter($listToFilter, function($elementToFilter) use ($referenceDate, $provideDate) {
|
||||
$objectDate = $provideDate($elementToFilter);
|
||||
return $objectDate === null || $objectDate >= $referenceDate;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ services:
|
|||
public: true
|
||||
|
||||
WerkraumMedia\ThueCat\Service\DateBasedFilter:
|
||||
class: 'WerkraumMedia\ThueCat\Service\DateBasedFilter\FilterBasedOnTypo3Context'
|
||||
public: true
|
||||
|
||||
'cache.thuecat_fetchdata':
|
||||
|
|
|
@ -54,6 +54,19 @@ Features
|
|||
``Streetcar``.
|
||||
These can be used with ``f:translate`` ViewHelper to provide proper none technical labels.
|
||||
|
||||
* Configure EXT:scheduler table garbage collection task to clean up import records.
|
||||
It is now possible to select the tables within the TYPO3 scheduler task to be cleaned up.
|
||||
|
||||
* Respect ``schema:givenName`` and ``schema:familyName`` of ``schema:author`` for media.
|
||||
We only respected ``schema:name`` until now.
|
||||
|
||||
* Provide new key ``copyrightAuthor`` holding the actual author for convenience.
|
||||
It will pick the ``author`` value falling back to ``license.author``.
|
||||
|
||||
* Provide new method to retrieve merged opening hours and merged special opening hours.
|
||||
The merge happens on the valid time span of each.
|
||||
The data structure is a bit different as different hours will be merged.
|
||||
|
||||
Fixes
|
||||
-----
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
1.3.1
|
||||
=====
|
||||
|
||||
Breaking
|
||||
--------
|
||||
|
||||
Nothing
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Configure EXT:scheduler table garbage collection task to clean up import records.
|
||||
It is now possible to select the tables within the TYPO3 scheduler task to be cleaned up.
|
||||
|
||||
* Respect ``schema:givenName`` and ``schema:familyName`` of ``schema:author`` for media.
|
||||
We only respected ``schema:name`` until now.
|
||||
|
||||
* Provide new key ``copyrightAuthor`` holding the actual author for convenience.
|
||||
It will pick the ``author`` value falling back to ``license.author``.
|
||||
|
||||
Fixes
|
||||
-----
|
||||
|
||||
Nothing
|
||||
|
||||
Tasks
|
||||
-----
|
||||
|
||||
Nothing
|
||||
|
||||
Deprecation
|
||||
-----------
|
||||
|
||||
Nothing
|
||||
|
|
@ -23,10 +23,15 @@ declare(strict_types=1);
|
|||
|
||||
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Model\Frontend;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\MergedOpeningHour;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\MergedOpeningHours;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\OpeningHours;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\ParkingFacility;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||
|
||||
/**
|
||||
* @covers \WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction
|
||||
|
@ -100,4 +105,190 @@ class TouristAttractionTest extends TestCase
|
|||
],
|
||||
], $subject->getDistanceToPublicTransport());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsMergedOpeningHours(): void
|
||||
{
|
||||
GeneralUtility::addInstance(DateBasedFilter::class, new class implements DateBasedFilter {
|
||||
public function filterOutPreviousDates(
|
||||
array $listToFilter,
|
||||
callable $provideDate
|
||||
): array {
|
||||
return $listToFilter;
|
||||
}
|
||||
});
|
||||
|
||||
$openingHours = new OpeningHours(json_encode([
|
||||
[
|
||||
'opens' => '12:00',
|
||||
'closes' => '14:00',
|
||||
'daysOfWeek' => [
|
||||
'Sunday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+2 days')->format('U'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'opens' => '10:00',
|
||||
'closes' => '16:00',
|
||||
'daysOfWeek' => [
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+2 days')->format('U'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'opens' => '13:00',
|
||||
'closes' => '15:00',
|
||||
'daysOfWeek' => [
|
||||
'Saturday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+3 days')->format('U'),
|
||||
],
|
||||
],
|
||||
]) ?: '');
|
||||
|
||||
$subject = new TouristAttraction();
|
||||
$subject->_setProperty('openingHours', $openingHours);
|
||||
|
||||
$result = $subject->getMergedOpeningHours();
|
||||
self::assertInstanceOf(MergedOpeningHours::class, $result);
|
||||
self::assertCount(2, $result);
|
||||
foreach ($result as $index => $mergedHour) {
|
||||
self::assertInstanceOf(MergedOpeningHour::class, $mergedHour);
|
||||
$today = (new \DateTimeImmutable())->format('Y-m-d');
|
||||
$inTwoDays = (new \DateTimeImmutable())->modify('+2 days')->format('Y-m-d');
|
||||
$inThreeDays = (new \DateTimeImmutable())->modify('+3 days')->format('Y-m-d');
|
||||
|
||||
if ($index === 0) {
|
||||
self::assertSame($today, $mergedHour->getFrom() ? $mergedHour->getFrom()->format('Y-m-d') : '');
|
||||
self::assertSame($inTwoDays, $mergedHour->getThrough() ? $mergedHour->getThrough()->format('Y-m-d') : '');
|
||||
self::assertCount(3, $mergedHour->getWeekDays());
|
||||
self::assertSame('Sunday', $mergedHour->getWeekDays()[0]->getDayOfWeek());
|
||||
self::assertSame('12:00', $mergedHour->getWeekDays()[0]->getOpens());
|
||||
self::assertSame('14:00', $mergedHour->getWeekDays()[0]->getCloses());
|
||||
self::assertSame('Monday', $mergedHour->getWeekDays()[1]->getDayOfWeek());
|
||||
self::assertSame('10:00', $mergedHour->getWeekDays()[1]->getOpens());
|
||||
self::assertSame('16:00', $mergedHour->getWeekDays()[1]->getCloses());
|
||||
self::assertSame('Tuesday', $mergedHour->getWeekDays()[2]->getDayOfWeek());
|
||||
self::assertSame('10:00', $mergedHour->getWeekDays()[2]->getOpens());
|
||||
self::assertSame('16:00', $mergedHour->getWeekDays()[2]->getCloses());
|
||||
} elseif ($index === 1) {
|
||||
self::assertSame($today, $mergedHour->getFrom() ? $mergedHour->getFrom()->format('Y-m-d') : '');
|
||||
self::assertSame($inThreeDays, $mergedHour->getThrough() ? $mergedHour->getThrough()->format('Y-m-d') : '');
|
||||
self::assertCount(1, $mergedHour->getWeekDays());
|
||||
self::assertSame('Saturday', $mergedHour->getWeekDays()[0]->getDayOfWeek());
|
||||
self::assertSame('13:00', $mergedHour->getWeekDays()[0]->getOpens());
|
||||
self::assertSame('15:00', $mergedHour->getWeekDays()[0]->getCloses());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsMergedSpecialOpeningHours(): void
|
||||
{
|
||||
GeneralUtility::addInstance(DateBasedFilter::class, new class implements DateBasedFilter {
|
||||
public function filterOutPreviousDates(
|
||||
array $listToFilter,
|
||||
callable $provideDate
|
||||
): array {
|
||||
return $listToFilter;
|
||||
}
|
||||
});
|
||||
|
||||
$openingHours = new OpeningHours(json_encode([
|
||||
[
|
||||
'opens' => '12:00',
|
||||
'closes' => '14:00',
|
||||
'daysOfWeek' => [
|
||||
'Sunday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+2 days')->format('U'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'opens' => '10:00',
|
||||
'closes' => '16:00',
|
||||
'daysOfWeek' => [
|
||||
'Monday',
|
||||
'Tuesday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+2 days')->format('U'),
|
||||
],
|
||||
],
|
||||
[
|
||||
'opens' => '13:00',
|
||||
'closes' => '15:00',
|
||||
'daysOfWeek' => [
|
||||
'Saturday',
|
||||
],
|
||||
'from' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->format('U'),
|
||||
],
|
||||
'through' => [
|
||||
'date' => '@' . (new \DateTimeImmutable())->modify('+3 days')->format('U'),
|
||||
],
|
||||
],
|
||||
]) ?: '');
|
||||
|
||||
$subject = new TouristAttraction();
|
||||
$subject->_setProperty('specialOpeningHours', $openingHours);
|
||||
|
||||
$result = $subject->getMergedSpecialOpeningHours();
|
||||
self::assertInstanceOf(MergedOpeningHours::class, $result);
|
||||
self::assertCount(2, $result);
|
||||
foreach ($result as $index => $mergedHour) {
|
||||
self::assertInstanceOf(MergedOpeningHour::class, $mergedHour);
|
||||
$today = (new \DateTimeImmutable())->format('Y-m-d');
|
||||
$inTwoDays = (new \DateTimeImmutable())->modify('+2 days')->format('Y-m-d');
|
||||
$inThreeDays = (new \DateTimeImmutable())->modify('+3 days')->format('Y-m-d');
|
||||
|
||||
if ($index === 0) {
|
||||
self::assertSame($today, $mergedHour->getFrom() ? $mergedHour->getFrom()->format('Y-m-d') : '');
|
||||
self::assertSame($inTwoDays, $mergedHour->getThrough() ? $mergedHour->getThrough()->format('Y-m-d') : '');
|
||||
self::assertCount(3, $mergedHour->getWeekDaysWithMondayFirstWeekDay());
|
||||
self::assertSame('Monday', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getDayOfWeek());
|
||||
self::assertSame('10:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getOpens());
|
||||
self::assertSame('16:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getCloses());
|
||||
self::assertSame('Tuesday', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[1]->getDayOfWeek());
|
||||
self::assertSame('10:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[1]->getOpens());
|
||||
self::assertSame('16:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[1]->getCloses());
|
||||
self::assertSame('Sunday', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[2]->getDayOfWeek());
|
||||
self::assertSame('12:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[2]->getOpens());
|
||||
self::assertSame('14:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[2]->getCloses());
|
||||
} elseif ($index === 1) {
|
||||
self::assertSame($today, $mergedHour->getFrom() ? $mergedHour->getFrom()->format('Y-m-d') : '');
|
||||
self::assertSame($inThreeDays, $mergedHour->getThrough() ? $mergedHour->getThrough()->format('Y-m-d') : '');
|
||||
self::assertCount(1, $mergedHour->getWeekDaysWithMondayFirstWeekDay());
|
||||
self::assertSame('Saturday', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getDayOfWeek());
|
||||
self::assertSame('13:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getOpens());
|
||||
self::assertSame('15:00', $mergedHour->getWeekDaysWithMondayFirstWeekDay()[0]->getCloses());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ $EM_CONF[$_EXTKEY] = [
|
|||
'author' => 'Daniel Siepmann',
|
||||
'author_email' => 'coding@daniel-siepmann.de',
|
||||
'author_company' => '',
|
||||
'version' => '1.3.1',
|
||||
'version' => '1.3.0',
|
||||
'constraints' => [
|
||||
'depends' => [
|
||||
'core' => '',
|
||||
|
|
Loading…
Reference in a new issue