| 1: | <?php |
| 2: | declare(strict_types=1); |
| 3: | |
| 4: | namespace om; |
| 5: | |
| 6: | use DateInterval; |
| 7: | use DateTimeImmutable; |
| 8: | use DateTimeInterface; |
| 9: | use InvalidArgumentException; |
| 10: | |
| 11: | /** |
| 12: | * Configuration of {@see IcalParser}. |
| 13: | * |
| 14: | * @deprecated 5.0, removed in 5.5 at the latest; configure om\ICal::parser() instead, see UPGRADING.md |
| 15: | */ |
| 16: | class ParserOptions { |
| 17: | public function __construct( |
| 18: | /** |
| 19: | * Interval used to cap recurring events that have no defined end |
| 20: | * (RRULE without UNTIL or COUNT). This prevents infinite expansion |
| 21: | * when parsing such rules. |
| 22: | * |
| 23: | * - Format: DateInterval (e.g. new DateInterval('P3Y') for 3 years). |
| 24: | * - If set to null, recurring events will be limited by the current date. |
| 25: | */ |
| 26: | public ?DateInterval $untilInterval = new DateInterval('P3Y'), |
| 27: | |
| 28: | /** |
| 29: | * Skip old occurrences of recurring events that lack UNTIL/COUNT. |
| 30: | * |
| 31: | * - null: keep all occurrences since DTSTART. |
| 32: | * - DateInterval: occurrences older than (now - interval) are skipped, |
| 33: | * so a daily event starting in 1970 does not produce decades of history. |
| 34: | * |
| 35: | * Example: DTSTART=1970-01-01, today=2026-01-30, shiftEventDates=P1Y -> the first |
| 36: | * returned occurrence is on or after 2025-01-30. |
| 37: | */ |
| 38: | public ?DateInterval $shiftEventDates = null, |
| 39: | |
| 40: | /** |
| 41: | * Mapping of Windows timezones to IANA timezones. |
| 42: | * |
| 43: | * @var array<string, string>|null |
| 44: | */ |
| 45: | public ?array $windowsTimezones = null, |
| 46: | |
| 47: | /** |
| 48: | * The moment used as "now" for the limits above; null means the current time. |
| 49: | * Pass a fixed date to get reproducible results (for example in tests). |
| 50: | */ |
| 51: | public ?DateTimeInterface $now = null, |
| 52: | |
| 53: | /** |
| 54: | * Maximal number of occurrences expanded for a single event. |
| 55: | * Longer series are truncated (or rejected in strict mode). |
| 56: | */ |
| 57: | public int $maxOccurrences = 100000, |
| 58: | |
| 59: | /** |
| 60: | * When true, invalid recurrence rules and series exceeding maxOccurrences throw |
| 61: | * an exception. When false (default), an invalid RRULE is ignored, so the event |
| 62: | * keeps its DTSTART (plus RDATE), and a too long series is truncated. |
| 63: | */ |
| 64: | public bool $strict = false, |
| 65: | ) { |
| 66: | if ($maxOccurrences < 1) { |
| 67: | throw new InvalidArgumentException('maxOccurrences must be positive.'); |
| 68: | } |
| 69: | $this->windowsTimezones ??= require __DIR__ . '/WindowsTimezones.php'; |
| 70: | } |
| 71: | |
| 72: | public function now(): DateTimeImmutable { |
| 73: | return $this->now === null ? new DateTimeImmutable() : DateTimeImmutable::createFromInterface($this->now); |
| 74: | } |
| 75: | } |
| 76: |