logger = $logManager->getLogger(self::class); } /** * @return Generator */ public function createDates( Import $import, array $timeIntervals, bool $canceled ): Generator { foreach ($timeIntervals as $date) { $dates = $this->createDate($import, $date, $canceled); if (!$dates instanceof Generator) { return null; } foreach ($dates as $createdDate) { yield $createdDate; } } } /** * @return Generator|null */ private function createDate( Import $import, array $date, bool $canceled ): ?Generator { if ($this->isDateSingleDate($date)) { $this->logger->info('Is single date', ['date' => $date]); return $this->createSingleDate($date, $canceled); } if ($this->isDateInterval($date)) { $this->logger->info('Is interval date', ['date' => $date]); return $this->createDateFromInterval($import, $date, $canceled); } return null; } private function isDateSingleDate(array $date): bool { $frequency = $date['freq'] ?? ''; $start = $date['start'] ?? ''; return $frequency === '' && $start !== ''; } 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; } /** * @return Generator */ private function createSingleDate( array $date, bool $canceled ): Generator { if (new DateTimeImmutable($date['start']) > $this->getToday()) { yield Date::createFromDestinationDataDate($date, $canceled); } } /** * @return Generator|null */ private function createDateFromInterval( Import $import, array $date, bool $canceled ): ?Generator { $date = $this->ensureRepeatUntil($import, $date); if ($date['freq'] == 'Daily') { return $this->createDailyDates($date, $canceled); } if ($date['freq'] == 'Weekly') { return $this->createWeeklyDates($date, $canceled); } return null; } private function ensureRepeatUntil( Import $import, array $date ): array { if (empty($date['repeatUntil']) === false) { return $date; } $date['repeatUntil'] = $this->getToday()->modify($import->getRepeatUntil())->format('c'); $this->logger->info('Interval did not provide repeatUntil.', ['newRepeat' => $date['repeatUntil']]); return $date; } /** * @return Generator */ private function createDailyDates( array $date, bool $canceled ): Generator { $today = $this->getToday(); $timeZone = new DateTimeZone($date['tz']); $start = new DateTimeImmutable($date['start'], $timeZone); $end = new DateTimeImmutable($date['end'], $timeZone); $until = new DateTimeImmutable($date['repeatUntil'], $timeZone); $period = new DatePeriod($start, new DateInterval('P1D'), $until); foreach ($period as $day) { $day = $day->setTimezone($timeZone); if ($day < $today) { $this->logger->debug('Date was in the past.', ['day' => $day]); continue; } yield $this->createDateFromStartAndEnd( $day, $start, $end, $canceled ); } } /** * @return Generator */ private function createWeeklyDates( array $date, bool $canceled ): Generator { $today = $this->getToday(); $timeZone = new DateTimeZone($date['tz']); $start = new DateTimeImmutable($date['start'], $timeZone); $end = new DateTimeImmutable($date['end'], $timeZone); $until = new DateTimeImmutable($date['repeatUntil'], $timeZone); foreach ($date['weekdays'] as $day) { $dateToUse = $start->modify($day); $dateToUse = $dateToUse->setTime((int)$start->format('H'), (int)$start->format('i')); $period = new DatePeriod($dateToUse, new DateInterval('P1W'), $until); foreach ($period as $day) { $day = $day->setTimezone($timeZone); if ($day < $today) { $this->logger->debug('Date was in the past.', ['day' => $day]); continue; } yield $this->createDateFromStartAndEnd( $day, $start, $end, $canceled ); } } } private function createDateFromStartAndEnd( DateTimeImmutable $dateToUse, DateTimeImmutable $start, DateTimeImmutable $end, bool $canceled ): Date { return Date::createFromDestinationData( $dateToUse->setTime((int)$start->format('H'), (int)$start->format('i')), $dateToUse->setTime((int)$end->format('H'), (int)$end->format('i')), $canceled ); } private function getToday(): DateTimeImmutable { $today = $this->context->getPropertyFromAspect('date', 'full', new DateTimeImmutable()); if (!$today instanceof DateTimeImmutable) { $today = new DateTimeImmutable(); } return $today->modify('midnight'); } }