Andrew's Web Libraries (AWL)
Loading...
Searching...
No Matches
vCalendar.php
1<?php
21require_once('vComponent.php');
22
23class vCalendar extends vComponent {
24
35 private $primary_component;
36 private $timezones;
37 private $organizer;
38 private $attendees;
39 private $schedule_agent;
40 private $rendered;
41
52 function __construct($content=null) {
53 $this->contained_type = null;
54 $this->primary_component = null;
55 $this->timezones = array();
56 if ( empty($content) || is_array($content) ) {
57 parent::__construct();
58 $this->SetType('VCALENDAR');
59 $this->AddProperty('PRODID', '-//davical.org//NONSGML AWL Calendar//EN');
60 $this->AddProperty('VERSION', '2.0');
61 $this->AddProperty('CALSCALE', 'GREGORIAN');
62 if ( !empty($content) ) {
63 foreach( $content AS $k => $v ) {
64 $this->AddProperty($k,$v);
65 }
66 }
67 }
68 else {
69 parent::__construct($content);
70 $components = $this->GetComponents();
71 if(isset($components) && count($components) > 0){
72 foreach( $components AS $k => $comp ) {
73 if ( $comp->GetType() == 'VTIMEZONE' ) {
74 $this->AddTimeZone($comp, true);
75 }
76 else if ( empty($this->contained_type) ) {
77 $this->contained_type = $comp->GetType();
78 $this->primary_component = $comp;
79 }
80 }
81 }
82
83 if ( !isset($this->contained_type) && !empty($this->timezones) ) {
84 $this->contained_type = 'VTIMEZONE';
85 $this->primary_component = reset($this->timezones);
86 }
87 }
88 }
89
90
94 function AddTimeZone(vComponent $vtz, $in_components=false) {
95 $tzid = $vtz->GetPValue('TZID');
96 if ( empty($tzid) ) {
97 dbg_error_log('ERROR','Ignoring invalid VTIMEZONE with no TZID parameter!');
98 dbg_log_array('LOG', 'vTimezone', $vtz, true);
99 return;
100 }
101 $this->timezones[$tzid] = $vtz;
102 if ( !$in_components ) $this->AddComponent($vtz);
103 }
104
105
111 function GetTimeZone( $tzid ) {
112 if ( empty($this->timezones[$tzid]) ) return null;
113 return $this->timezones[$tzid];
114 }
115
116
121 function GetOrganizer() {
122 if ( !isset($this->organizer) ) {
123 $organizers = $this->GetPropertiesByPath('/VCALENDAR/*/ORGANIZER');
124 $organizer = (count($organizers) > 0 ? $organizers[0] : false);
125 $this->organizer = (empty($organizer) ? false : $organizer );
126 if ( $this->organizer ) {
127 $this->schedule_agent = $organizer->GetParameterValue('SCHEDULE-AGENT');
128 if ( empty($schedule_agent) ) $this->schedule_agent = 'SERVER';
129 }
130 }
131 return $this->organizer;
132 }
133
134
139 function GetScheduleAgent() {
140 if ( !isset($this->schedule_agent) ) $this->GetOrganizer();
141 return $this->schedule_agent;
142 }
143
144
148 function GetAttendees() {
149 if ( !isset($this->attendees) ) {
150 $this->attendees = array();
151 $attendees = $this->GetPropertiesByPath('/VCALENDAR/*/ATTENDEE');
152 $wr_attendees = $this->GetPropertiesByPath('/VCALENDAR/*/X-WR-ATTENDEE');
153 if ( count ( $wr_attendees ) > 0 ) {
154 dbg_error_log( 'PUT', 'Non-compliant iCal request. Using X-WR-ATTENDEE property' );
155 foreach( $wr_attendees AS $k => $v ) {
156 $attendees[] = $v;
157 }
158 }
159 $this->attendees = $attendees;
160 }
161 return $this->attendees;
162 }
163
164
165
171 function UpdateAttendeeStatus( $email, vProperty $statusProperty ) {
172 foreach($this->GetComponents() AS $ck => $v ) {
173 if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
174 $new_attendees = array();
175 foreach( $v->GetProperties() AS $p ) {
176 if ( $p->Name() == 'ATTENDEE' ) {
177 if ( $p->Value() == $email || $p->Value() == 'mailto:'.$email ) {
178 $new_attendees[] = $statusProperty;
179 }
180 else {
181 $new_attendees[] = clone($p);
182 }
183 }
184 }
185 $v->SetProperties($new_attendees,'ATTENDEE');
186 $this->attendees = null;
187 $this->rendered = null;
188 }
189 }
190 }
191
192
193
198 function UpdateOrganizerStatus( vProperty $statusProperty ) {
199 $this->rendered = null;
200 foreach($this->GetComponents() AS $ck => $v ) {
201 if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
202 $v->SetProperties(array($statusProperty), 'ORGANIZER');
203 $this->organizer = null;
204 $this->rendered = null;
205 }
206 }
207 }
208
209
210
220 function StartFilter( $filters ) {
221 dbg_error_log('vCalendar', ':StartFilter we have %d filters to test', count($filters) );
222
223 if ( count($filters) != 1 ) return false;
224
225 $tag = $filters[0]->GetNSTag();
226 $name = $filters[0]->GetAttribute("name");
227 if ( $tag != "urn:ietf:params:xml:ns:caldav:comp-filter" || $name != 'VCALENDAR' ) return false;
228 return $this->TestFilter($filters[0]->GetContent());
229 }
230
231
238 function GetOlsonName( vComponent $vtz ) {
239 $tzstring = $vtz->GetPValue('TZID');
240 $tzid = olson_from_tzstring($tzstring);
241 if ( !empty($tzid) ) return $tzid;
242
243 $tzstring = $vtz->GetPValue('X-LIC-LOCATION');
244 $tzid = olson_from_tzstring($tzstring);
245 if ( !empty($tzid) ) return $tzid;
246
247 $tzcdo = $vtz->GetPValue('X-MICROSOFT-CDO-TZID');
248 if ( empty($tzcdo) ) return null;
249 switch( $tzcdo ) {
254 case 0: return('UTC');
255 case 1: return('Europe/London');
256 case 2: return('Europe/Lisbon');
257 case 3: return('Europe/Paris');
258 case 4: return('Europe/Berlin');
259 case 5: return('Europe/Bucharest');
260 case 6: return('Europe/Prague');
261 case 7: return('Europe/Athens');
262 case 8: return('America/Brasilia');
263 case 9: return('America/Halifax');
264 case 10: return('America/New_York');
265 case 11: return('America/Chicago');
266 case 12: return('America/Denver');
267 case 13: return('America/Los_Angeles');
268 case 14: return('America/Anchorage');
269 case 15: return('Pacific/Honolulu');
270 case 16: return('Pacific/Apia');
271 case 17: return('Pacific/Auckland');
272 case 18: return('Australia/Brisbane');
273 case 19: return('Australia/Adelaide');
274 case 20: return('Asia/Tokyo');
275 case 21: return('Asia/Singapore');
276 case 22: return('Asia/Bangkok');
277 case 23: return('Asia/Kolkata');
278 case 24: return('Asia/Muscat');
279 case 25: return('Asia/Tehran');
280 case 26: return('Asia/Baghdad');
281 case 27: return('Asia/Jerusalem');
282 case 28: return('America/St_Johns');
283 case 29: return('Atlantic/Azores');
284 case 30: return('America/Noronha');
285 case 31: return('Africa/Casablanca');
286 case 32: return('America/Argentina/Buenos_Aires');
287 case 33: return('America/La_Paz');
288 case 34: return('America/Indiana/Indianapolis');
289 case 35: return('America/Bogota');
290 case 36: return('America/Regina');
291 case 37: return('America/Tegucigalpa');
292 case 38: return('America/Phoenix');
293 case 39: return('Pacific/Kwajalein');
294 case 40: return('Pacific/Fiji');
295 case 41: return('Asia/Magadan');
296 case 42: return('Australia/Hobart');
297 case 43: return('Pacific/Guam');
298 case 44: return('Australia/Darwin');
299 case 45: return('Asia/Shanghai');
300 case 46: return('Asia/Novosibirsk');
301 case 47: return('Asia/Karachi');
302 case 48: return('Asia/Kabul');
303 case 49: return('Africa/Cairo');
304 case 50: return('Africa/Harare');
305 case 51: return('Europe/Moscow');
306 case 53: return('Atlantic/Cape_Verde');
307 case 54: return('Asia/Yerevan');
308 case 55: return('America/Panama');
309 case 56: return('Africa/Nairobi');
310 case 58: return('Asia/Yekaterinburg');
311 case 59: return('Europe/Helsinki');
312 case 60: return('America/Godthab');
313 case 61: return('Asia/Rangoon');
314 case 62: return('Asia/Kathmandu');
315 case 63: return('Asia/Irkutsk');
316 case 64: return('Asia/Krasnoyarsk');
317 case 65: return('America/Santiago');
318 case 66: return('Asia/Colombo');
319 case 67: return('Pacific/Tongatapu');
320 case 68: return('Asia/Vladivostok');
321 case 69: return('Africa/Ndjamena');
322 case 70: return('Asia/Yakutsk');
323 case 71: return('Asia/Dhaka');
324 case 72: return('Asia/Seoul');
325 case 73: return('Australia/Perth');
326 case 74: return('Asia/Riyadh');
327 case 75: return('Asia/Taipei');
328 case 76: return('Australia/Sydney');
329
330 case 57: // null
331 case 52: // null
332 default: // null
333 }
334 return null;
335 }
336
337
343 function Confidential() {
344 static $keep_properties = array( 'DTSTAMP'=>1, 'DTSTART'=>1, 'RRULE'=>1, 'DURATION'=>1, 'DTEND'=>1, 'DUE'=>1, 'UID'=>1, 'CLASS'=>1, 'TRANSP'=>1, 'CREATED'=>1, 'LAST-MODIFIED'=>1 );
345 static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
346 $this->MaskComponents(array( 'VTIMEZONE'=>1, 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 ), false);
347 $this->MaskProperties($keep_properties, $resource_components );
348 if ( isset($this->rendered) ) unset($this->rendered);
349 foreach( $this->GetComponents() AS $comp ) {
350 if ( isset($resource_components[$comp->GetType()] ) ) {
351 if ( isset($comp->rendered) ) unset($comp->rendered);
352 $comp->AddProperty( 'SUMMARY', translate('Busy') );
353 }
354 }
355
356 return $this;
357 }
358
359
363 function GetItip($method, $attendee_value ) {
364 $iTIP = clone($this);
365 static $keep_properties = array( 'DTSTART'=>1, 'DURATION'=>1, 'DTEND'=>1, 'DUE'=>1, 'UID'=>1,
366 'SEQUENCE'=>1, 'ORGANIZER'=>1, 'ATTENDEE'=>1 );
367 static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
368 $iTIP->MaskComponents($resource_components, false);
369 $iTIP->MaskProperties($keep_properties, $resource_components );
370 $iTIP->AddProperty('METHOD',$method);
371 if ( isset($iTIP->rendered) ) unset($iTIP->rendered);
372 if ( !empty($attendee_value) ) {
373 $iTIP->attendees = array();
374 foreach( $iTIP->GetComponents() AS $comp ) {
375 if ( isset($resource_components[$comp->GetType()] ) ) {
376 foreach( $comp->GetProperties() AS $k=> $property ) {
377 switch( $property->Name() ) {
378 case 'ATTENDEE':
379 if ( $property->Value() == $attendee_value )
380 $iTIP->attendees[] = $property->ClearParameters(array('CUTYPE'=>true, 'SCHEDULE-STATUS'=>true));
381 else
382 $comp->clearPropertyAt($k);
383 break;
384 }
385 }
386 $comp->AddProperty('DTSTAMP', date('Ymd\THis\Z'));
387 }
388 }
389 }
390
391 return $iTIP;
392 }
393
394
398 function GetUID() {
399 if ( empty($this->primary_component) ) return null;
400 return $this->primary_component->GetPValue('UID');
401
402 }
403
404
409 function SetUID( $newUid ) {
410 if ( empty($this->primary_component) ) return;
411 $this->primary_component->SetProperties( array( new vProperty('UID', $newUid) ), 'UID');
412 }
413
414}
UpdateAttendeeStatus( $email, vProperty $statusProperty)
AddTimeZone(vComponent $vtz, $in_components=false)
Definition vCalendar.php:94
__construct($content=null)
Definition vCalendar.php:52
UpdateOrganizerStatus(vProperty $statusProperty)
GetTimeZone( $tzid)
GetOlsonName(vComponent $vtz)
StartFilter( $filters)
SetUID( $newUid)
GetScheduleAgent()
GetItip($method, $attendee_value)
AddComponent( $new_component)
AddProperty( $new_property, $value=null, $parameters=null)
GetPValue( $type)
MaskComponents( $keep, $recursive=true)
GetPropertiesByPath( $path)
MaskProperties( $keep, $component_list=null)
GetComponents( $type=null, $normal_match=true)
SetType( $type)
TestFilter( $filters)