2022-04-21 08:07:25 +02:00
|
|
|
<?php
|
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2023-11-09 10:27:43 +01:00
|
|
|
namespace WerkraumMedia\Events\Service\DestinationDataImportService;
|
2022-04-21 08:07:25 +02:00
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
use DateInterval;
|
|
|
|
use DatePeriod;
|
|
|
|
use DateTimeImmutable;
|
|
|
|
use DateTimeZone;
|
|
|
|
use Generator;
|
|
|
|
use Psr\Log\LoggerInterface;
|
2022-07-07 09:03:31 +02:00
|
|
|
use TYPO3\CMS\Core\Context\Context;
|
2023-01-05 10:01:13 +01:00
|
|
|
use TYPO3\CMS\Core\Log\LogManager;
|
2023-11-09 10:27:43 +01:00
|
|
|
use WerkraumMedia\Events\Domain\Model\Date;
|
2024-11-04 14:30:18 +01:00
|
|
|
use WerkraumMedia\Events\Domain\Model\Import;
|
2022-04-21 08:07:25 +02:00
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
final class DatesFactory
|
2022-04-21 08:07:25 +02:00
|
|
|
{
|
2023-11-27 10:04:42 +01:00
|
|
|
private readonly LoggerInterface $logger;
|
2023-01-05 10:01:13 +01:00
|
|
|
|
2022-07-07 09:03:31 +02:00
|
|
|
public function __construct(
|
2023-11-27 10:04:42 +01:00
|
|
|
private readonly Context $context,
|
2023-01-05 10:01:13 +01:00
|
|
|
LogManager $logManager
|
2022-07-07 09:03:31 +02:00
|
|
|
) {
|
2023-11-27 10:04:42 +01:00
|
|
|
$this->logger = $logManager->getLogger(self::class);
|
2022-07-07 09:03:31 +02:00
|
|
|
}
|
|
|
|
|
2022-04-21 08:07:25 +02:00
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
public function createDates(
|
2024-11-04 14:30:18 +01:00
|
|
|
Import $import,
|
2022-04-21 08:07:25 +02:00
|
|
|
array $timeIntervals,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): Generator {
|
2022-04-21 08:07:25 +02:00
|
|
|
foreach ($timeIntervals as $date) {
|
2024-11-04 14:30:18 +01:00
|
|
|
$dates = $this->createDate($import, $date, $canceled);
|
2023-11-27 10:04:42 +01:00
|
|
|
if (!$dates instanceof Generator) {
|
2022-04-21 08:07:25 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($dates as $createdDate) {
|
|
|
|
yield $createdDate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>|null
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
private function createDate(
|
2024-11-04 14:30:18 +01:00
|
|
|
Import $import,
|
2022-04-21 08:07:25 +02:00
|
|
|
array $date,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): ?Generator {
|
2022-04-21 08:07:25 +02:00
|
|
|
if ($this->isDateSingleDate($date)) {
|
2023-01-05 10:01:13 +01:00
|
|
|
$this->logger->info('Is single date', ['date' => $date]);
|
2022-04-21 08:07:25 +02:00
|
|
|
return $this->createSingleDate($date, $canceled);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->isDateInterval($date)) {
|
2023-01-05 10:01:13 +01:00
|
|
|
$this->logger->info('Is interval date', ['date' => $date]);
|
2024-11-04 14:30:18 +01:00
|
|
|
return $this->createDateFromInterval($import, $date, $canceled);
|
2022-04-21 08:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function isDateSingleDate(array $date): bool
|
|
|
|
{
|
2022-04-25 07:47:47 +02:00
|
|
|
$frequency = $date['freq'] ?? '';
|
|
|
|
$start = $date['start'] ?? '';
|
|
|
|
|
|
|
|
return $frequency === ''
|
|
|
|
&& $start !== '';
|
2022-04-21 08:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function isDateInterval(array $date): bool
|
|
|
|
{
|
|
|
|
$frequency = $date['freq'] ?? '';
|
|
|
|
|
|
|
|
if ($frequency == 'Daily' && empty($date['weekdays'])) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($frequency == 'Weekly' && !empty($date['weekdays'])) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
private function createSingleDate(
|
|
|
|
array $date,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): Generator {
|
|
|
|
if (new DateTimeImmutable($date['start']) > $this->getToday()) {
|
2022-04-21 08:07:25 +02:00
|
|
|
yield Date::createFromDestinationDataDate($date, $canceled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>|null
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
private function createDateFromInterval(
|
2024-11-04 14:30:18 +01:00
|
|
|
Import $import,
|
2022-04-21 08:07:25 +02:00
|
|
|
array $date,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): ?Generator {
|
2024-11-04 14:30:18 +01:00
|
|
|
$date = $this->ensureRepeatUntil($import, $date);
|
2023-01-05 10:01:13 +01:00
|
|
|
|
2022-04-21 08:07:25 +02:00
|
|
|
if ($date['freq'] == 'Daily') {
|
|
|
|
return $this->createDailyDates($date, $canceled);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($date['freq'] == 'Weekly') {
|
|
|
|
return $this->createWeeklyDates($date, $canceled);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2024-11-04 14:30:18 +01:00
|
|
|
private function ensureRepeatUntil(
|
|
|
|
Import $import,
|
|
|
|
array $date
|
|
|
|
): array {
|
2023-01-05 10:01:13 +01:00
|
|
|
if (empty($date['repeatUntil']) === false) {
|
|
|
|
return $date;
|
|
|
|
}
|
|
|
|
|
2024-11-04 14:30:18 +01:00
|
|
|
$date['repeatUntil'] = $this->getToday()->modify($import->getRepeatUntil())->format('c');
|
2023-01-05 10:01:13 +01:00
|
|
|
$this->logger->info('Interval did not provide repeatUntil.', ['newRepeat' => $date['repeatUntil']]);
|
|
|
|
|
|
|
|
return $date;
|
|
|
|
}
|
|
|
|
|
2022-04-21 08:07:25 +02:00
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
private function createDailyDates(
|
|
|
|
array $date,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): Generator {
|
2022-04-21 08:07:25 +02:00
|
|
|
$today = $this->getToday();
|
2023-11-27 10:04:42 +01:00
|
|
|
$timeZone = new DateTimeZone($date['tz']);
|
|
|
|
$start = new DateTimeImmutable($date['start'], $timeZone);
|
|
|
|
$end = new DateTimeImmutable($date['end'], $timeZone);
|
|
|
|
$until = new DateTimeImmutable($date['repeatUntil'], $timeZone);
|
2022-04-21 08:07:25 +02:00
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
$period = new DatePeriod($start, new DateInterval('P1D'), $until);
|
2022-08-29 14:44:36 +02:00
|
|
|
foreach ($period as $day) {
|
|
|
|
$day = $day->setTimezone($timeZone);
|
|
|
|
if ($day < $today) {
|
2023-01-05 10:01:13 +01:00
|
|
|
$this->logger->debug('Date was in the past.', ['day' => $day]);
|
2022-04-21 08:07:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-07-07 14:10:49 +02:00
|
|
|
yield $this->createDateFromStartAndEnd(
|
2022-08-29 14:44:36 +02:00
|
|
|
$day,
|
2022-04-21 08:07:25 +02:00
|
|
|
$start,
|
2022-07-07 14:10:49 +02:00
|
|
|
$end,
|
2022-04-21 08:07:25 +02:00
|
|
|
$canceled
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-11-27 10:04:42 +01:00
|
|
|
* @return Generator<Date>
|
2022-04-21 08:07:25 +02:00
|
|
|
*/
|
|
|
|
private function createWeeklyDates(
|
|
|
|
array $date,
|
|
|
|
bool $canceled
|
2023-11-27 10:04:42 +01:00
|
|
|
): Generator {
|
2022-04-21 08:07:25 +02:00
|
|
|
$today = $this->getToday();
|
2023-11-27 10:04:42 +01:00
|
|
|
$timeZone = new DateTimeZone($date['tz']);
|
|
|
|
$start = new DateTimeImmutable($date['start'], $timeZone);
|
|
|
|
$end = new DateTimeImmutable($date['end'], $timeZone);
|
|
|
|
$until = new DateTimeImmutable($date['repeatUntil'], $timeZone);
|
2022-04-21 08:07:25 +02:00
|
|
|
|
|
|
|
foreach ($date['weekdays'] as $day) {
|
2022-08-29 14:44:36 +02:00
|
|
|
$dateToUse = $start->modify($day);
|
2023-06-07 08:56:42 +02:00
|
|
|
$dateToUse = $dateToUse->setTime((int)$start->format('H'), (int)$start->format('i'));
|
2022-08-29 14:44:36 +02:00
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
$period = new DatePeriod($dateToUse, new DateInterval('P1W'), $until);
|
2022-08-29 14:44:36 +02:00
|
|
|
foreach ($period as $day) {
|
|
|
|
$day = $day->setTimezone($timeZone);
|
|
|
|
if ($day < $today) {
|
2023-01-05 10:01:13 +01:00
|
|
|
$this->logger->debug('Date was in the past.', ['day' => $day]);
|
2022-04-21 08:07:25 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-07-07 14:10:49 +02:00
|
|
|
yield $this->createDateFromStartAndEnd(
|
2022-08-29 14:44:36 +02:00
|
|
|
$day,
|
2022-04-21 08:07:25 +02:00
|
|
|
$start,
|
2022-07-07 14:10:49 +02:00
|
|
|
$end,
|
2022-04-21 08:07:25 +02:00
|
|
|
$canceled
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-07 14:10:49 +02:00
|
|
|
private function createDateFromStartAndEnd(
|
2023-11-27 10:04:42 +01:00
|
|
|
DateTimeImmutable $dateToUse,
|
|
|
|
DateTimeImmutable $start,
|
|
|
|
DateTimeImmutable $end,
|
2022-04-21 08:07:25 +02:00
|
|
|
bool $canceled
|
|
|
|
): Date {
|
|
|
|
return Date::createFromDestinationData(
|
2023-06-07 08:56:42 +02:00
|
|
|
$dateToUse->setTime((int)$start->format('H'), (int)$start->format('i')),
|
|
|
|
$dateToUse->setTime((int)$end->format('H'), (int)$end->format('i')),
|
2022-04-21 08:07:25 +02:00
|
|
|
$canceled
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-11-27 10:04:42 +01:00
|
|
|
private function getToday(): DateTimeImmutable
|
2022-04-21 08:07:25 +02:00
|
|
|
{
|
2023-11-27 10:04:42 +01:00
|
|
|
$today = $this->context->getPropertyFromAspect('date', 'full', new DateTimeImmutable());
|
|
|
|
if (!$today instanceof DateTimeImmutable) {
|
|
|
|
$today = new DateTimeImmutable();
|
2022-07-07 09:03:31 +02:00
|
|
|
}
|
|
|
|
|
2022-07-13 15:58:05 +02:00
|
|
|
return $today->modify('midnight');
|
2022-04-21 08:07:25 +02:00
|
|
|
}
|
|
|
|
}
|