comparison plugins/libcalendaring/lib/Sabre/VObject/Component/VCalendar.php @ 4:888e774ee983

libcalendar plugin as distributed
author Charlie Root
date Sat, 13 Jan 2018 08:57:56 -0500
parents
children
comparison
equal deleted inserted replaced
3:f6fe4b6ae66a 4:888e774ee983
1 <?php
2
3 namespace Sabre\VObject\Component;
4
5 use Sabre\VObject;
6
7 /**
8 * The VCalendar component
9 *
10 * This component adds functionality to a component, specific for a VCALENDAR.
11 *
12 * @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
13 * @author Evert Pot (http://evertpot.com/)
14 * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
15 */
16 class VCalendar extends VObject\Document {
17
18 static $defaultName = 'VCALENDAR';
19
20 /**
21 * Returns a list of all 'base components'. For instance, if an Event has
22 * a recurrence rule, and one instance is overridden, the overridden event
23 * will have the same UID, but will be excluded from this list.
24 *
25 * VTIMEZONE components will always be excluded.
26 *
27 * @param string $componentName filter by component name
28 * @return array
29 */
30 public function getBaseComponents($componentName = null) {
31
32 $components = array();
33 foreach($this->children as $component) {
34
35 if (!$component instanceof VObject\Component)
36 continue;
37
38 if (isset($component->{'RECURRENCE-ID'}))
39 continue;
40
41 if ($componentName && $component->name !== strtoupper($componentName))
42 continue;
43
44 if ($component->name === 'VTIMEZONE')
45 continue;
46
47 $components[] = $component;
48
49 }
50
51 return $components;
52
53 }
54
55 /**
56 * If this calendar object, has events with recurrence rules, this method
57 * can be used to expand the event into multiple sub-events.
58 *
59 * Each event will be stripped from it's recurrence information, and only
60 * the instances of the event in the specified timerange will be left
61 * alone.
62 *
63 * In addition, this method will cause timezone information to be stripped,
64 * and normalized to UTC.
65 *
66 * This method will alter the VCalendar. This cannot be reversed.
67 *
68 * This functionality is specifically used by the CalDAV standard. It is
69 * possible for clients to request expand events, if they are rather simple
70 * clients and do not have the possibility to calculate recurrences.
71 *
72 * @param DateTime $start
73 * @param DateTime $end
74 * @return void
75 */
76 public function expand(\DateTime $start, \DateTime $end) {
77
78 $newEvents = array();
79
80 foreach($this->select('VEVENT') as $key=>$vevent) {
81
82 if (isset($vevent->{'RECURRENCE-ID'})) {
83 unset($this->children[$key]);
84 continue;
85 }
86
87
88 if (!$vevent->rrule) {
89 unset($this->children[$key]);
90 if ($vevent->isInTimeRange($start, $end)) {
91 $newEvents[] = $vevent;
92 }
93 continue;
94 }
95
96 $uid = (string)$vevent->uid;
97 if (!$uid) {
98 throw new \LogicException('Event did not have a UID!');
99 }
100
101 $it = new VObject\RecurrenceIterator($this, $vevent->uid);
102 $it->fastForward($start);
103
104 while($it->valid() && $it->getDTStart() < $end) {
105
106 if ($it->getDTEnd() > $start) {
107
108 $newEvents[] = $it->getEventObject();
109
110 }
111 $it->next();
112
113 }
114 unset($this->children[$key]);
115
116 }
117
118 foreach($newEvents as $newEvent) {
119
120 foreach($newEvent->children as $child) {
121 if ($child instanceof VObject\Property\DateTime &&
122 $child->getDateType() == VObject\Property\DateTime::LOCALTZ) {
123 $child->setDateTime($child->getDateTime(),VObject\Property\DateTime::UTC);
124 }
125 }
126
127 $this->add($newEvent);
128
129 }
130
131 // Removing all VTIMEZONE components
132 unset($this->VTIMEZONE);
133
134 }
135
136 /**
137 * Validates the node for correctness.
138 * An array is returned with warnings.
139 *
140 * Every item in the array has the following properties:
141 * * level - (number between 1 and 3 with severity information)
142 * * message - (human readable message)
143 * * node - (reference to the offending node)
144 *
145 * @return array
146 */
147 /*
148 public function validate() {
149
150 $warnings = array();
151
152 $version = $this->select('VERSION');
153 if (count($version)!==1) {
154 $warnings[] = array(
155 'level' => 1,
156 'message' => 'The VERSION property must appear in the VCALENDAR component exactly 1 time',
157 'node' => $this,
158 );
159 } else {
160 if ((string)$this->VERSION !== '2.0') {
161 $warnings[] = array(
162 'level' => 1,
163 'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
164 'node' => $this,
165 );
166 }
167 }
168 $version = $this->select('PRODID');
169 if (count($version)!==1) {
170 $warnings[] = array(
171 'level' => 2,
172 'message' => 'The PRODID property must appear in the VCALENDAR component exactly 1 time',
173 'node' => $this,
174 );
175 }
176 if (count($this->CALSCALE) > 1) {
177 $warnings[] = array(
178 'level' => 2,
179 'message' => 'The CALSCALE property must not be specified more than once.',
180 'node' => $this,
181 );
182 }
183 if (count($this->METHOD) > 1) {
184 $warnings[] = array(
185 'level' => 2,
186 'message' => 'The METHOD property must not be specified more than once.',
187 'node' => $this,
188 );
189 }
190
191 $allowedComponents = array(
192 'VEVENT',
193 'VTODO',
194 'VJOURNAL',
195 'VFREEBUSY',
196 'VTIMEZONE',
197 );
198 $allowedProperties = array(
199 'PRODID',
200 'VERSION',
201 'CALSCALE',
202 'METHOD',
203 );
204 $componentsFound = 0;
205 foreach($this->children as $child) {
206 if($child instanceof Component) {
207 $componentsFound++;
208 if (!in_array($child->name, $allowedComponents)) {
209 $warnings[] = array(
210 'level' => 1,
211 'message' => 'The ' . $child->name . " component is not allowed in the VCALENDAR component",
212 'node' => $this,
213 );
214 }
215 }
216 if ($child instanceof Property) {
217 if (!in_array($child->name, $allowedProperties)) {
218 $warnings[] = array(
219 'level' => 2,
220 'message' => 'The ' . $child->name . " property is not allowed in the VCALENDAR component",
221 'node' => $this,
222 );
223 }
224 }
225 }
226
227 if ($componentsFound===0) {
228 $warnings[] = array(
229 'level' => 1,
230 'message' => 'An iCalendar object must have at least 1 component.',
231 'node' => $this,
232 );
233 }
234
235 return array_merge(
236 $warnings,
237 parent::validate()
238 );
239
240 }
241 */
242
243 }
244