mirror of
https://github.com/werkraum-media/thuecat.git
synced 2024-12-05 03:26: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;
|
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||||
|
|
||||||
|
use WerkraumMedia\ThueCat\Domain\TimingFormat;
|
||||||
|
|
||||||
class OpeningHour
|
class OpeningHour
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -91,12 +93,12 @@ class OpeningHour
|
||||||
|
|
||||||
public function getOpens(): string
|
public function getOpens(): string
|
||||||
{
|
{
|
||||||
return $this->formatTiming($this->opens);
|
return TimingFormat::format($this->opens);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCloses(): string
|
public function getCloses(): string
|
||||||
{
|
{
|
||||||
return $this->formatTiming($this->closes);
|
return TimingFormat::format($this->closes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDaysOfWeek(): array
|
public function getDaysOfWeek(): array
|
||||||
|
@ -158,35 +160,4 @@ class OpeningHour
|
||||||
|
|
||||||
return $days;
|
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);
|
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
|
public function __toString(): string
|
||||||
{
|
{
|
||||||
return $this->serialized;
|
return $this->serialized;
|
||||||
|
|
|
@ -103,11 +103,27 @@ abstract class Place extends Base
|
||||||
return $this->openingHours;
|
return $this->openingHours;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMergedOpeningHours(): ?MergedOpeningHours
|
||||||
|
{
|
||||||
|
if ($this->openingHours === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $this->openingHours->getMerged();
|
||||||
|
}
|
||||||
|
|
||||||
public function getSpecialOpeningHours(): ?OpeningHours
|
public function getSpecialOpeningHours(): ?OpeningHours
|
||||||
{
|
{
|
||||||
return $this->specialOpeningHours;
|
return $this->specialOpeningHours;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMergedSpecialOpeningHours(): ?MergedOpeningHours
|
||||||
|
{
|
||||||
|
if ($this->specialOpeningHours === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $this->specialOpeningHours->getMerged();
|
||||||
|
}
|
||||||
|
|
||||||
public function getParkingFacilitiesNearBy(): ObjectStorage
|
public function getParkingFacilitiesNearBy(): ObjectStorage
|
||||||
{
|
{
|
||||||
return $this->parkingFacilityNearBy;
|
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;
|
namespace WerkraumMedia\ThueCat\Service;
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Context\Context;
|
interface DateBasedFilter
|
||||||
|
|
||||||
class 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.
|
* 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(
|
public function filterOutPreviousDates(
|
||||||
array $listToFilter,
|
array $listToFilter,
|
||||||
callable $provideDate
|
callable $provideDate
|
||||||
): array {
|
): array;
|
||||||
$referenceDate = $this->context->getPropertyFromAspect('date', 'full');
|
|
||||||
|
|
||||||
return array_filter($listToFilter, function($elementToFilter) use ($referenceDate, $provideDate) {
|
|
||||||
$objectDate = $provideDate($elementToFilter);
|
|
||||||
return $objectDate === null || $objectDate >= $referenceDate;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
public: true
|
||||||
|
|
||||||
WerkraumMedia\ThueCat\Service\DateBasedFilter:
|
WerkraumMedia\ThueCat\Service\DateBasedFilter:
|
||||||
|
class: 'WerkraumMedia\ThueCat\Service\DateBasedFilter\FilterBasedOnTypo3Context'
|
||||||
public: true
|
public: true
|
||||||
|
|
||||||
'cache.thuecat_fetchdata':
|
'cache.thuecat_fetchdata':
|
||||||
|
|
|
@ -54,6 +54,19 @@ Features
|
||||||
``Streetcar``.
|
``Streetcar``.
|
||||||
These can be used with ``f:translate`` ViewHelper to provide proper none technical labels.
|
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
|
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;
|
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Model\Frontend;
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
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\ParkingFacility;
|
||||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction;
|
use WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction
|
* @covers \WerkraumMedia\ThueCat\Domain\Model\Frontend\TouristAttraction
|
||||||
|
@ -100,4 +105,190 @@ class TouristAttractionTest extends TestCase
|
||||||
],
|
],
|
||||||
], $subject->getDistanceToPublicTransport());
|
], $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' => 'Daniel Siepmann',
|
||||||
'author_email' => 'coding@daniel-siepmann.de',
|
'author_email' => 'coding@daniel-siepmann.de',
|
||||||
'author_company' => '',
|
'author_company' => '',
|
||||||
'version' => '1.3.1',
|
'version' => '1.3.0',
|
||||||
'constraints' => [
|
'constraints' => [
|
||||||
'depends' => [
|
'depends' => [
|
||||||
'core' => '',
|
'core' => '',
|
||||||
|
|
Loading…
Reference in a new issue