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