*/ private const REPLY_FREQUENCIES = [ '1' => 1, '10' => 10, '30' => 30, '60' => 60, '120' => 120, '360' => 360, '720' => 720, '1440' => 1440, '2880' => 2880, '4320' => 4320, '5760' => 5760, '7200' => 7200, '8640' => 8640, '10080' => 10080, '11520' => 11520, '12960' => 12960, '14400' => 14400, '15840' => 15840, '17280' => 17280, '18720' => 18720, '20160' => 20160, ]; /** @param array $input @return array */ public static function validate(array $input, Settings $settings, bool $allowPastSchedule = false): array { $name = trim(str_replace(["\r\n", "\r", "\0"], ["\n", "\n", ''], (string)($input['name'] ?? ''))); if (str_contains($name, "\n")) { throw new InvalidArgumentException('Nazwa autorespondera nie może zawierać nowych linii.'); } if (strlen($name) > 255) { throw new InvalidArgumentException('Nazwa autorespondera jest za długa.'); } $subjectPrefix = trim((string)($input['subject_prefix'] ?? $input['subject'] ?? '')); if (str_contains($subjectPrefix, "\r") || str_contains($subjectPrefix, "\n")) { throw new InvalidArgumentException('Przedrostek tematu nie może zawierać nowych linii.'); } if (strlen($subjectPrefix) > $settings->maxSubjectBytes()) { throw new InvalidArgumentException('Przedrostek tematu jest za długi.'); } $body = str_replace(["\r\n", "\r", "\0"], ["\n", "\n", ''], (string)($input['body'] ?? '')); $body = trim($body); if ($body === '') { throw new InvalidArgumentException('Treść wiadomości jest wymagana.'); } if (strlen($body) > $settings->maxBodyBytes()) { throw new InvalidArgumentException('Treść wiadomości jest za długa.'); } $mode = $settings->scheduleMode(); $tz = new DateTimeZone($settings->timezone()); [$startTs, $startValue] = self::parseScheduleValue((string)($input['start_value'] ?? ''), $mode, $tz, true); [$endTs, $endValue] = self::parseScheduleValue((string)($input['end_value'] ?? ''), $mode, $tz, false); if (!$allowPastSchedule) { $today = (new DateTimeImmutable('today', $tz))->format('Y-m-d'); if (substr($startValue, 0, 10) < $today) { throw new InvalidArgumentException('Data rozpoczęcia nie może być wcześniejsza niż aktualna data.'); } if (substr($endValue, 0, 10) < $today) { throw new InvalidArgumentException('Data zakończenia nie może być wcześniejsza niż aktualna data.'); } } if ($endTs <= $startTs) { throw new InvalidArgumentException('Data zakończenia musi być późniejsza niż data rozpoczęcia.'); } $repeatMinutes = self::parseReplyFrequency((string)($input['reply_frequency'] ?? '1440')); return [ 'name' => $name, 'subject_prefix' => $subjectPrefix, 'body' => $body, 'schedule_mode' => $mode, 'timezone' => $settings->timezone(), 'start_value' => $startValue, 'end_value' => $endValue, 'start_ts' => $startTs, 'end_ts' => $endTs, 'enabled' => self::truthy($input['enabled'] ?? false), 'repeat_minutes' => $repeatMinutes, 'dynamic_scope' => $settings->dynamicMailboxScope(), ]; } private static function parseReplyFrequency(string $value): int { $value = trim(strtolower($value)); if (isset(self::REPLY_FREQUENCIES[$value])) { return self::REPLY_FREQUENCIES[$value]; } throw new InvalidArgumentException('Częstość odpowiedzi jest nieprawidłowa.'); } /** @return array{0:int,1:string} */ private static function parseScheduleValue(string $value, string $mode, DateTimeZone $tz, bool $start): array { $value = trim($value); if ($mode === 'exact_hour') { if (!preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}$/', $value)) { throw new InvalidArgumentException('Nieprawidłowa data lub godzina.'); } $dt = DateTimeImmutable::createFromFormat('!Y-m-d\TH:i', $value, $tz); if (!$dt) { throw new InvalidArgumentException('Nieprawidłowa data lub godzina.'); } return [$dt->getTimestamp(), $value]; } if (!preg_match('/^([0-9]{4}-[0-9]{2}-[0-9]{2})\|(morning|afternoon|evening)$/', $value, $m)) { throw new InvalidArgumentException('Nieprawidłowa data lub pora dnia.'); } $hour = ['morning' => 8, 'afternoon' => 13, 'evening' => 18][$m[2]]; if (!$start && $m[2] === 'evening') { $hour = 23; } $dt = DateTimeImmutable::createFromFormat('!Y-m-d H:i', $m[1] . ' ' . sprintf('%02d:00', $hour), $tz); if (!$dt) { throw new InvalidArgumentException('Nieprawidłowa data lub pora dnia.'); } return [$dt->getTimestamp(), $value]; } private static function truthy(mixed $value): bool { return in_array(strtolower((string)$value), ['1', 'true', 'yes', 'on'], true); } }