1: <?php
2: declare(strict_types=1);
3:
4: namespace om;
5:
6: use DateTime;
7: use DateTimeInterface;
8: use Exception;
9:
10: /**
11: * Class taken from https://github.com/coopTilleuls/intouch-iCalendar.git (Recurrence.php)
12: * A wrapper for recurrence rules in iCalendar. Parses the given line and puts the
13: * recurrence rules in the correct field of this object.
14: * See http://tools.ietf.org/html/rfc2445 for more information. Page 39 and onward contains more
15: * information on the recurrence rules themselves. Page 116 and onward contains
16: * some great examples which were often used for testing.
17: *
18: * @author Steven Oxley
19: * @author Michael Kahn (C) 2013
20: * @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
21: *
22: * @deprecated 5.0, removed in 5.5 at the latest; use om\RRule\Rule, see UPGRADING.md
23: */
24: class Recurrence {
25: /** @var array<string, mixed> */
26: public array $rrule;
27: protected mixed $freq;
28: protected mixed $until;
29: protected mixed $count;
30: protected mixed $interval;
31: protected mixed $bysecond;
32: protected mixed $byminute;
33: protected mixed $byhour;
34: protected mixed $byday;
35: protected mixed $bymonthday;
36: protected mixed $byyearday;
37: protected mixed $byweekno;
38: protected mixed $bymonth;
39: protected mixed $bysetpos;
40: protected mixed $wkst;
41: /**
42: * A list of the properties that can have comma-separated lists for values.
43: */
44: /** @var list<string> */
45: protected array $listProperties = [
46: 'bysecond', 'byminute', 'byhour', 'byday', 'bymonthday',
47: 'byyearday', 'byweekno', 'bymonth', 'bysetpos',
48: ];
49:
50: /**
51: * Creates a recurrence object with a passed in line. Parses the line.
52: *
53: * @param array $rrule an om\icalparser row array which will be parsed to get the
54: * desired information.
55: * @param array<string, mixed> $rrule
56: */
57: public function __construct(array $rrule) {
58: $this->parseRrule($rrule);
59: }
60:
61: /**
62: * Parses an 'RRULE' array and sets the member variables of this object.
63: * Expects a string that looks like this: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=SU,TU,WE'
64: *
65: * @param array<string, mixed> $rrule
66: */
67: protected function parseRrule(array $rrule): void {
68: $this->rrule = $rrule;
69: //loop through the properties in the line and set their associated
70: //member variables
71: foreach ($this->rrule as $propertyName => $propertyValue) {
72: //need the lower-case name for setting the member variable
73: $propertyName = strtolower($propertyName);
74: // Preserve extensions in rrule without creating dynamic object properties.
75: if (!in_array($propertyName, ['freq', 'until', 'count', 'interval', 'wkst'], true)
76: && !in_array($propertyName, $this->listProperties, true)) {
77: continue;
78: }
79: //split up the list of values into an array (if it's a list)
80: if (in_array($propertyName, $this->listProperties, true)) {
81: $propertyValue = explode(',', $propertyValue);
82: }
83: $this->$propertyName = $propertyValue;
84: }
85: }
86:
87: /**
88: * Returns the frequency - corresponds to FREQ in RFC 2445.
89: *
90: * @return mixed string if the member has been set, false otherwise
91: */
92: public function getFreq(): mixed {
93: return $this->getMember('freq');
94: }
95:
96: /**
97: * Retrieves the desired member variable and returns it (if it's set)
98: *
99: * @param string $member name of the member variable
100: * @return mixed the variable value (if set), false otherwise
101: */
102: protected function getMember(string $member): mixed {
103: return $this->$member ?? false;
104: }
105:
106: /**
107: * Returns when the event will go until - corresponds to UNTIL in RFC 2445.
108: *
109: * @return mixed string if the member has been set, false otherwise
110: */
111: public function getUntil(): mixed {
112: return $this->getMember('until');
113: }
114:
115: /**
116: * Set the $until member
117: *
118: * @param string|int|DateTime $ts timestamp (int) / Valid DateTime format (string)
119: * @throws Exception
120: */
121: public function setUntil(string|int|DateTimeInterface $ts): void {
122: if (!$ts instanceof DateTimeInterface) {
123: $ts = is_int($ts) ? DateTime::createFromTimestamp($ts) : new DateTime($ts);
124: }
125:
126: $this->until = $ts->format('Ymd\THisO');
127: $this->rrule['until'] = $this->until;
128: }
129:
130: /**
131: * Returns the count of the times the event will occur (should only appear if 'until'
132: * does not appear) - corresponds to COUNT in RFC 2445.
133: *
134: * @return mixed string if the member has been set, false otherwise
135: */
136: public function getCount(): mixed {
137: return $this->getMember('count');
138: }
139:
140: /**
141: * Returns the interval - corresponds to INTERVAL in RFC 2445.
142: *
143: * @return mixed string if the member has been set, false otherwise
144: */
145: public function getInterval(): mixed {
146: return $this->getMember('interval');
147: }
148:
149: /**
150: * Returns the bysecond part of the event - corresponds to BYSECOND in RFC 2445.
151: *
152: * @return mixed string if the member has been set, false otherwise
153: */
154: public function getBySecond(): mixed {
155: return $this->getMember('bysecond');
156: }
157:
158: /**
159: * Returns the byminute information for the event - corresponds to BYMINUTE in RFC 2445.
160: *
161: * @return mixed string if the member has been set, false otherwise
162: */
163: public function getByMinute(): mixed {
164: return $this->getMember('byminute');
165: }
166:
167: /**
168: * Corresponds to BYHOUR in RFC 2445.
169: *
170: * @return mixed string if the member has been set, false otherwise
171: */
172: public function getByHour(): mixed {
173: return $this->getMember('byhour');
174: }
175:
176: /**
177: *Corresponds to BYDAY in RFC 2445.
178: *
179: * @return mixed string if the member has been set, false otherwise
180: */
181: public function getByDay(): mixed {
182: return $this->getMember('byday');
183: }
184:
185: /**
186: * Corresponds to BYMONTHDAY in RFC 2445.
187: *
188: * @return mixed string if the member has been set, false otherwise
189: */
190: public function getByMonthDay(): mixed {
191: return $this->getMember('bymonthday');
192: }
193:
194: /**
195: * Corresponds to BYYEARDAY in RFC 2445.
196: *
197: * @return mixed string if the member has been set, false otherwise
198: */
199: public function getByYearDay(): mixed {
200: return $this->getMember('byyearday');
201: }
202:
203: /**
204: * Corresponds to BYWEEKNO in RFC 2445.
205: *
206: * @return mixed string if the member has been set, false otherwise
207: */
208: public function getByWeekNo(): mixed {
209: return $this->getMember('byweekno');
210: }
211:
212: /**
213: * Corresponds to BYMONTH in RFC 2445.
214: *
215: * @return mixed string if the member has been set, false otherwise
216: */
217: public function getByMonth(): mixed {
218: return $this->getMember('bymonth');
219: }
220:
221: /**
222: * Corresponds to BYSETPOS in RFC 2445.
223: *
224: * @return mixed string if the member has been set, false otherwise
225: */
226: public function getBySetPos(): mixed {
227: return $this->getMember('bysetpos');
228: }
229:
230: /**
231: * Corresponds to WKST in RFC 2445.
232: *
233: * @return mixed string if the member has been set, false otherwise
234: */
235: public function getWkst(): mixed {
236: return $this->getMember('wkst');
237: }
238: }
239: