dateFrom; $to = $this->dateTo; $hasFrom = null !== $from && '' !== $from; $hasTo = null !== $to && '' !== $to; // Neither supplied: the caller wants the full priced span, which the persisted prices define. if (!$hasFrom && !$hasTo) { return; } // A lone dateFrom would have to mean "from there to the end of the prices", a third mode // nobody asked for. Demand the pair instead of inventing a meaning for half of it. if (!$hasFrom || !$hasTo) { $context->buildViolation('dateFrom and dateTo must be supplied together.') ->atPath($hasFrom ? 'dateTo' : 'dateFrom') ->addViolation(); return; } $dateFrom = self::parseDate($from); $dateTo = self::parseDate($to); if (null === $dateFrom || null === $dateTo) { return; } if ($dateTo < $dateFrom) { $context->buildViolation('dateTo must not be before dateFrom.') ->atPath('dateTo') ->addViolation(); return; } if ($dateFrom->diff($dateTo)->days > self::MAX_RANGE_DAYS) { $context->buildViolation(sprintf('The date range must not exceed %d days.', self::MAX_RANGE_DAYS)) ->atPath('dateTo') ->addViolation(); } } /** * Null when the parameter was not supplied, which puts the request into full-span mode. */ public function dateFromDate(): ?\DateTimeImmutable { return $this->suppliedDate($this->dateFrom); } /** * Null when the parameter was not supplied, which puts the request into full-span mode. */ public function dateToDate(): ?\DateTimeImmutable { return $this->suppliedDate($this->dateTo); } private function suppliedDate(?string $value): ?\DateTimeImmutable { if (null === $value || '' === $value) { return null; } return self::parseDate($value) ?? throw new \LogicException('ContingentCalendarQuery must be validated before use.'); } private static function parseDate(string $value): ?\DateTimeImmutable { $date = \DateTimeImmutable::createFromFormat('!Y-m-d', $value); $errors = \DateTimeImmutable::getLastErrors(); if (false === $date || (false !== $errors && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) { return null; } return $date->format('Y-m-d') === $value ? $date : null; } }