1: <?php
2: declare(strict_types=1);
3:
4: namespace om;
5:
6: use ArrayObject;
7:
8: /**
9: * Copyright (c) Roman Ožana (https://ozana.cz)
10: *
11: * @license BSD-3-Clause
12: * @author Roman Ožana <roman@ozana.cz>
13: * @extends ArrayObject<int, array<string, mixed>>
14: *
15: * @deprecated 5.0, removed in 5.5 at the latest; use om\ICal\Calendar::events() and occurrencesBetween(), see UPGRADING.md
16: */
17: class EventsList extends ArrayObject {
18: /**
19: * Return array of Events
20: */
21: public function getArrayCopy(): array {
22: return array_values(parent::getArrayCopy());
23: }
24:
25: /**
26: * Sort in place, oldest dates first. Missing dates sort last.
27: */
28: public function sorted(): EventsList {
29: return $this->sortByStart(true);
30: }
31:
32: /**
33: * Sort in place, newest dates first. Missing dates sort last.
34: */
35: public function reversed(): EventsList {
36: return $this->sortByStart(false);
37: }
38:
39: /**
40: * Stable sort by DTSTART; each timestamp is calculated only once.
41: */
42: private function sortByStart(bool $ascending): EventsList {
43: $events = parent::getArrayCopy();
44: $timestamps = [];
45: $undated = [];
46: foreach ($events as $key => $event) {
47: $start = $event['DTSTART'] ?? null;
48: if ($start === null) {
49: $undated[] = $key;
50: } else {
51: $timestamps[$key] = $this->dtTimestamp($start);
52: }
53: }
54: $ascending ? asort($timestamps, SORT_NUMERIC) : arsort($timestamps, SORT_NUMERIC);
55:
56: $sorted = [];
57: foreach ([...array_keys($timestamps), ...$undated] as $key) {
58: $sorted[$key] = $events[$key];
59: }
60: $this->exchangeArray($sorted);
61: return $this;
62: }
63:
64: /**
65: * Normalize a DTSTART value to an integer timestamp for stable comparisons.
66: */
67: private function dtTimestamp(mixed $value): int {
68: if ($value instanceof \DateTimeInterface) {
69: return $value->getTimestamp();
70: }
71: if (is_int($value) || is_float($value) || is_numeric($value)) {
72: return (int) $value;
73: }
74: $ts = strtotime((string) $value);
75: return $ts === false ? 0 : $ts;
76: }
77:
78: }
79: