Back to index

awl  0.53
vCalendar.php
Go to the documentation of this file.
00001 <?php
00021 require_once('vComponent.php');
00022 
00023 class vCalendar extends vComponent {
00024 
00034   private $contained_type;
00035   private $primary_component;
00036   private $timezones;
00037   private $organizer;
00038   private $attendees;
00039   private $schedule_agent;
00040   
00051   function __construct($content=null) {
00052     $this->contained_type = null;
00053     $this->primary_component = null;
00054     $this->timezones = array();
00055     if ( empty($content) || is_array($content) ) {
00056       parent::__construct();
00057       $this->SetType('VCALENDAR');
00058       $this->AddProperty('PRODID', '-//davical.org//NONSGML AWL Calendar//EN');
00059       $this->AddProperty('VERSION', '2.0');
00060       $this->AddProperty('CALSCALE', 'GREGORIAN');
00061       if ( !empty($content) ) {
00062         foreach( $content AS $k => $v ) {
00063           $this->AddProperty($k,$v);
00064         }
00065       }
00066     }
00067     else {
00068       parent::__construct($content);
00069       foreach( $this->components AS $k => $comp ) {
00070         if ( $comp->GetType() == 'VTIMEZONE' ) {
00071           $this->AddTimeZone($comp, true);
00072         }
00073         else if ( empty($this->contained_type) ) {
00074           $this->contained_type = $comp->GetType();
00075           $this->primary_component = $comp;
00076         }
00077       }
00078       if ( !isset($this->contained_type) && !empty($this->timezones) )
00079         $this->contained_type = 'VTIMEZONE';
00080     }
00081   }
00082 
00083   
00087   function AddTimeZone(vComponent $vtz, $in_components=false) {
00088     $tzid = $vtz->GetPValue('TZID');
00089     if ( empty($tzid) ) {
00090       dbg_error_log('ERROR','Ignoring invalid VTIMEZONE with no TZID parameter!');
00091       dbg_log_array('LOG', 'vTimezone', $vtz, true);
00092       return;
00093     }
00094     $this->timezones[$tzid] = $vtz;
00095     if ( !$in_components ) $this->AddComponent($vtz);
00096   }
00097 
00098   
00104   function GetTimeZone( $tzid ) {
00105     if ( empty($this->timezones[$tzid]) ) return null;
00106     return $this->timezones[$tzid];
00107   }
00108 
00109 
00114   function GetOrganizer() {
00115     if ( !isset($this->organizer) ) {
00116       $organizers = $this->GetPropertiesByPath('/VCALENDAR/*/ORGANIZER');
00117       $organizer = (count($organizers) > 0 ? $organizers[0] : false);
00118       $this->organizer = (empty($organizer) ? false : $organizer );
00119       if ( $this->organizer ) {
00120         $this->schedule_agent = $organizer->GetParameterValue('SCHEDULE-AGENT');
00121         if ( empty($schedule_agent) ) $this->schedule_agent = 'SERVER';
00122       }
00123     }
00124     return $this->organizer;
00125   }
00126 
00127   
00132   function GetScheduleAgent() {
00133     if ( !isset($this->schedule_agent) ) $this->GetOrganizer();
00134     return $this->schedule_agent;
00135   }
00136 
00137   
00141   function GetAttendees() {
00142     if ( !isset($this->attendees) ) {
00143       $attendees = $this->GetPropertiesByPath('/VCALENDAR/*/ATTENDEE');
00144       $wr_attendees = $this->GetPropertiesByPath('/VCALENDAR/*/X-WR-ATTENDEE');
00145       if ( count ( $wr_attendees ) > 0 ) {
00146         dbg_error_log( 'PUT', 'Non-compliant iCal request.  Using X-WR-ATTENDEE property' );
00147         foreach( $wr_attendees AS $k => $v ) {
00148           $attendees[] = $v;
00149         }
00150       }
00151       $this->attendees = $attendees;
00152     }
00153     return $this->attendees;
00154   }
00155 
00156   
00157  
00163   function UpdateAttendeeStatus( $email, vProperty $statusProperty ) {
00164     foreach($this->components AS $ck => $v ) {
00165       if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
00166         $new_attendees = array();
00167         foreach( $v->properties AS $p ) {
00168           if ( $p->Name() == 'ATTENDEE' ) {
00169             if ( $p->Value() == $email || $p->Value() == 'mailto:'.$email ) {
00170               $new_attendees[] = $statusProperty;
00171             }
00172             else {
00173               $new_attendees[] = clone($p);
00174             }
00175           }
00176         }
00177         $v->SetProperties($new_attendees,'ATTENDEE');
00178         $this->attendees = null;
00179         $this->rendered = null;
00180       }
00181     }
00182   }
00183 
00184 
00185  
00190   function UpdateOrganizerStatus( vProperty $statusProperty ) {
00191     $this->rendered = null;
00192     foreach($this->components AS $ck => $v ) {
00193       if ($v->GetType() == 'VEVENT' || $v->GetType() == 'VTODO' ) {
00194         foreach( $v->properties AS $pk => $p ) {
00195           if ( $p->Name() == 'ORGANIZER' ) {
00196             $v->properties[$pk] = $statusProperty;
00197             $v->rendered = null;
00198             unset($this->organizer);
00199           }
00200         }
00201       }
00202     }
00203   }
00204 
00205 
00206  
00216   function StartFilter( $filters ) {
00217     dbg_error_log('vCalendar', ':StartFilter we have %d filters to test', count($filters) );
00218 
00219     if ( count($filters) != 1 ) return false;
00220     
00221     $tag = $filters[0]->GetNSTag();
00222     $name = $filters[0]->GetAttribute("name");
00223     if ( $tag != "urn:ietf:params:xml:ns:caldav:comp-filter" || $name != 'VCALENDAR' ) return false;
00224     return $this->TestFilter($filters[0]->GetContent());
00225   }
00226 
00227   
00234   function GetOlsonName( vComponent $vtz ) {
00235     $tzstring = $vtz->GetProperty('TZID');
00236     $tzid = olson_from_tzstring($tzstring);
00237     if ( !empty($tzid) ) return $tzid;
00238     
00239     $tzstring = $vtz->GetProperty('X-LIC-LOCATION');
00240     $tzid = olson_from_tzstring($tzstring);
00241     if ( !empty($tzid) ) return $tzid;
00242     
00243     $tzcdo =  $vtz->GetProperty('X-MICROSOFT-CDO-TZID');
00244     if ( empty($tzcdo) ) return null;
00245     switch( $tzcdo ) {
00250       case 0:    return('UTC');
00251       case 1:    return('Europe/London');
00252       case 2:    return('Europe/Lisbon');
00253       case 3:    return('Europe/Paris');
00254       case 4:    return('Europe/Berlin');
00255       case 5:    return('Europe/Bucharest');
00256       case 6:    return('Europe/Prague');
00257       case 7:    return('Europe/Athens');
00258       case 8:    return('America/Brasilia');
00259       case 9:    return('America/Halifax');
00260       case 10:   return('America/New_York');
00261       case 11:   return('America/Chicago');
00262       case 12:   return('America/Denver');
00263       case 13:   return('America/Los_Angeles');
00264       case 14:   return('America/Anchorage');
00265       case 15:   return('Pacific/Honolulu');
00266       case 16:   return('Pacific/Apia');
00267       case 17:   return('Pacific/Auckland');
00268       case 18:   return('Australia/Brisbane');
00269       case 19:   return('Australia/Adelaide');
00270       case 20:   return('Asia/Tokyo');
00271       case 21:   return('Asia/Singapore');
00272       case 22:   return('Asia/Bangkok');
00273       case 23:   return('Asia/Kolkata');
00274       case 24:   return('Asia/Muscat');
00275       case 25:   return('Asia/Tehran');
00276       case 26:   return('Asia/Baghdad');
00277       case 27:   return('Asia/Jerusalem');
00278       case 28:   return('America/St_Johns');
00279       case 29:   return('Atlantic/Azores');
00280       case 30:   return('America/Noronha');
00281       case 31:   return('Africa/Casablanca');
00282       case 32:   return('America/Argentina/Buenos_Aires');
00283       case 33:   return('America/La_Paz');
00284       case 34:   return('America/Indiana/Indianapolis');
00285       case 35:   return('America/Bogota');
00286       case 36:   return('America/Regina');
00287       case 37:   return('America/Tegucigalpa');
00288       case 38:   return('America/Phoenix');
00289       case 39:   return('Pacific/Kwajalein');
00290       case 40:   return('Pacific/Fiji');
00291       case 41:   return('Asia/Magadan');
00292       case 42:   return('Australia/Hobart');
00293       case 43:   return('Pacific/Guam');
00294       case 44:   return('Australia/Darwin');
00295       case 45:   return('Asia/Shanghai');
00296       case 46:   return('Asia/Novosibirsk');
00297       case 47:   return('Asia/Karachi');
00298       case 48:   return('Asia/Kabul');
00299       case 49:   return('Africa/Cairo');
00300       case 50:   return('Africa/Harare');
00301       case 51:   return('Europe/Moscow');
00302       case 53:   return('Atlantic/Cape_Verde');
00303       case 54:   return('Asia/Yerevan');
00304       case 55:   return('America/Panama');
00305       case 56:   return('Africa/Nairobi');
00306       case 58:   return('Asia/Yekaterinburg');
00307       case 59:   return('Europe/Helsinki');
00308       case 60:   return('America/Godthab');
00309       case 61:   return('Asia/Rangoon');
00310       case 62:   return('Asia/Kathmandu');
00311       case 63:   return('Asia/Irkutsk');
00312       case 64:   return('Asia/Krasnoyarsk');
00313       case 65:   return('America/Santiago');
00314       case 66:   return('Asia/Colombo');
00315       case 67:   return('Pacific/Tongatapu');
00316       case 68:   return('Asia/Vladivostok');
00317       case 69:   return('Africa/Ndjamena');
00318       case 70:   return('Asia/Yakutsk');
00319       case 71:   return('Asia/Dhaka');
00320       case 72:   return('Asia/Seoul');
00321       case 73:   return('Australia/Perth');
00322       case 74:   return('Asia/Riyadh');
00323       case 75:   return('Asia/Taipei');
00324       case 76:   return('Australia/Sydney');
00325 
00326       case 57: // null
00327       case 52: // null
00328       default: // null
00329     }
00330     return null;
00331   }   
00332 
00333   
00339   function Confidential() {
00340     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 );
00341     static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
00342     $this->MaskComponents(array( 'VTIMEZONE'=>1, 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 ), false);
00343     $this->MaskProperties($keep_properties, $resource_components );
00344     if ( isset($this->rendered) ) unset($this->rendered);
00345     foreach( $this->components AS $comp ) {
00346       if ( isset($resource_components[$comp->GetType()] ) ) {
00347         if ( isset($comp->rendered) ) unset($comp->rendered);
00348         $comp->AddProperty( 'SUMMARY', translate('Busy') );
00349       }
00350     }
00351 
00352     return $this;
00353   }
00354 
00355 
00359   function GetItip($method, $attendee_value ) {
00360     $iTIP = clone($this);
00361     static $keep_properties = array( 'DTSTART'=>1, 'DURATION'=>1, 'DTEND'=>1, 'DUE'=>1, 'UID'=>1,
00362                                      'SEQUENCE'=>1, 'ORGANIZER'=>1, 'ATTENDEE'=>1 );
00363     static $resource_components = array( 'VEVENT'=>1, 'VTODO'=>1, 'VJOURNAL'=>1 );
00364     $iTIP->MaskComponents($resource_components, false);
00365     $iTIP->MaskProperties($keep_properties, $resource_components );
00366     $iTIP->AddProperty('METHOD',$method);
00367     if ( isset($iTIP->rendered) ) unset($iTIP->rendered);
00368     if ( !empty($attendee_value) ) {
00369       $iTIP->attendees = array();
00370       foreach( $iTIP->components AS $comp ) {
00371         if ( isset($resource_components[$comp->type] ) ) {
00372           foreach( $comp->properties AS $k=> $property ) {
00373             switch( $property->Name() ) {
00374               case 'ATTENDEE':
00375                 if ( $property->Value() == $attendee_value )
00376                   $iTIP->attendees[] = $property;
00377                 else
00378                   unset($comp->properties[$k]);
00379                 break;
00380               case 'SEQUENCE':
00381                 $property->Value( $property->Value() + 1);
00382                 break;
00383             }
00384           }
00385           $comp->AddProperty('DTSTAMP', date('Ymd\THis\Z'));
00386         }
00387       }
00388     }
00389     
00390     return $iTIP;
00391   }
00392 
00393 
00397   function GetUID() {
00398     if ( empty($this->primary_component) ) return null;
00399     return $this->primary_component->GetPValue('UID');
00400     
00401   }
00402 
00403 
00408   function SetUID( $newUid ) {
00409     if ( empty($this->primary_component) ) return;
00410     $this->primary_component->SetProperties( array( new vProperty('UID', $newUid) ), 'UID');
00411   }
00412   
00413 }