diff --git a/calendar/ical_test.php b/calendar/ical_test.php index b76ccb9161..92a9dfd4f3 100755 --- a/calendar/ical_test.php +++ b/calendar/ical_test.php @@ -25,14 +25,17 @@ $vcalendar = $vcal->read($contents); - echo "Product ID = ".$vcalendar->prodid."
\n"; - echo "Method = ".$vcalendar->method."
\n"; - echo "Version = ".$vcalendar->version."
\n"; + echo "Product ID = ".$vcalendar->prodid->value."
\n"; + echo "Method = ".$vcalendar->method->value."
\n"; + echo "Version = ".$vcalendar->version->value."
\n"; for($i=0;$ievent);$i++) { echo "
\nEVENT
\n"; - echo "Summary = ".$vcalendar->event[$i]->summary."
\n"; + if($vcalendar->event[$i]->calscale->value) + { + echo "Calscale = ".$vcalendar->event[$i]->calscale->value."
\n"; + } if($vcalendar->event[$i]->description->value) { echo "Description (Value) = ".$vcalendar->event[$i]->description->value."
\n"; @@ -41,10 +44,28 @@ { echo "Description (Alt Rep) = ".$vcalendar->event[$i]->description->altrep."
\n"; } - echo "Location = ".$vcalendar->event[$i]->location."
\n"; + if($vcalendar->event[$i]->summary->value) + { + echo "Summary = ".$vcalendar->event[$i]->summary->value."
\n"; + } + if(!empty($vcalendar->event[$i]->comment)) + { + for($j=0;$jevent[$i]->comment);$j++) + { + echo "Comment = ".$vcalendar->event[$i]->comment[$j]->value."
\n"; + } + } + if($vcalendar->event[$i]->location->value) + { + echo "Location = ".$vcalendar->event[$i]->location->value."
\n"; + } echo "Sequence = ".$vcalendar->event[$i]->sequence."
\n"; echo "Date Start : ".$phpgw->common->show_date(mktime($vcalendar->event[$i]->dtstart->hour,$vcalendar->event[$i]->dtstart->min,$vcalendar->event[$i]->dtstart->sec,$vcalendar->event[$i]->dtstart->month,$vcalendar->event[$i]->dtstart->mday,$vcalendar->event[$i]->dtstart->year) - $phpgw->calendar->datatime->tz_offset)."
\n"; - echo "Class = ".$vcal->switch_class($vcalendar->event[$i]->class)."
\n"; + if($vcalendar->event[$i]->rrule) + { + echo "Recurrence : Frequency = ".$vcalendar->event[$i]->rrule->freq." Count = ".$vcalendar->event[$i]->rrule->count."
\n"; + } + echo "Class = ".$vcalendar->event[$i]->class->value."
\n"; echo "Organizer = ".$vcalendar->event[$i]->organizer->mailto->user.'@'.$vcalendar->event[$i]->organizer->mailto->host."
\n"; if($vcalendar->event[$i]->organizer->dir) { @@ -70,7 +91,10 @@ for($i=0;$itodo);$i++) { echo "
\nTODO
\n"; - echo "Summary = ".$vcalendar->todo[$i]->summary."
\n"; + if($vcalendar->todo[$i]->summary->value) + { + echo "Summary = ".$vcalendar->todo[$i]->summary->value."
\n"; + } if($vcalendar->todo[$i]->description->value) { echo "Description (Value) = ".$vcalendar->todo[$i]->description->value."
\n"; @@ -79,15 +103,18 @@ { echo "Description (Alt Rep) = ".$vcalendar->todo[$i]->description->altrep."
\n"; } - echo "Location = ".$vcalendar->todo[$i]->location."
\n"; + if($vcalendar->event[$i]->location->value) + { + echo "Location = ".$vcalendar->todo[$i]->location->value."
\n"; + } echo "Sequence = ".$vcalendar->todo[$i]->sequence."
\n"; echo "Date Start : ".$phpgw->common->show_date(mktime($vcalendar->todo[$i]->dtstart->hour,$vcalendar->todo[$i]->dtstart->min,$vcalendar->todo[$i]->dtstart->sec,$vcalendar->todo[$i]->dtstart->month,$vcalendar->todo[$i]->dtstart->mday,$vcalendar->todo[$i]->dtstart->year) - $phpgw->calendar->datatime->tz_offset)."
\n"; - echo "Class = ".$vcal->switch_class($vcalendar->todo[$i]->class)."
\n"; + echo "Class = ".$vcalendar->todo[$i]->class->value."
\n"; } include(PHPGW_APP_INC.'/../setup/setup.inc.php'); - $vcal->set_var($vcalendar,'prodid','-//phpGroupWare//phpGroupWare '.$setup_info['calendar']['version'].' MIMEDIR//'.strtoupper($phpgw_info['user']['preferences']['common']['lang'])); + $vcal->set_var($vcalendar->prodid,'value','-//phpGroupWare//phpGroupWare '.$setup_info['calendar']['version'].' MIMEDIR//'.strtoupper($phpgw_info['user']['preferences']['common']['lang'])); echo "


\n"; echo nl2br($vcal->build_vcal($vcalendar)); $phpgw->common->phpgw_footer(); diff --git a/calendar/inc/class.vCalendar.inc.php b/calendar/inc/class.vCalendar.inc.php index bbb494217a..9627020ec1 100755 --- a/calendar/inc/class.vCalendar.inc.php +++ b/calendar/inc/class.vCalendar.inc.php @@ -82,6 +82,12 @@ class vCalendar_time var $allday = False; } +class class_geo +{ + var $lat; + var $lon; +} + class rrule { var $freq; @@ -98,6 +104,7 @@ class class_text var $fmttype; var $encoding; var $altrep; + var $language; var $value; } @@ -108,17 +115,31 @@ class vCalendar_item var $organizer; var $dtstart; var $dtend; - var $location; - var $transp = OPAQUE; - var $sequence; - var $attach; - var $uid; var $dtstamp; + var $due; + var $created; + var $last_modified; + var $completed; + var $duration; + var $freebusy; + var $location; + var $categories; + var $transp; + var $sequence; + var $percent_complete; + var $attach; + var $calscale; + var $tzid; + var $uid; var $description; + var $comment; var $summary; + var $status; var $priority; - var $class = PUBLIC; + var $class; var $rrule; + var $resources; + var $request_status; } class vCal @@ -127,6 +148,7 @@ class vCal var $version; var $method; var $event = Array(); + var $todo = Array(); } class vCalendar @@ -134,62 +156,289 @@ class vCalendar var $vcal; var $event = Array(); var $todo = Array(); - - function splitdate($value) - { - $dtime = new vCalendar_time; - if(strpos($value,':')) - { - $pos = explode(':',$value); - $value = $pos[1]; - } - $dtime->year = intval(substr($value,0,4)); - $dtime->month = intval(substr($value,4,2)); - $dtime->mday = intval(substr($value,6,2)); - if(substr($value,8,1) == 'T') - { - $dtime->hour = intval(substr($value,9,2)); - $dtime->min = intval(substr($value,11,2)); - $dtime->sec = intval(substr($value,13,2)); - } - else - { - $dtime->hour = 0; - $dtime->min = 0; - $dtime->sec = 0; - } - return $dtime; - } + var $property; - function split_address($address) + /* + * Base Functions + */ + + function vCalendar() { - if(strpos(' '.$address,':')) - { - $parts = explode(':',$address); - $address = $parts[1]; - } - - $parts = explode('@',$address); - if(count($parts) == 2) - { - $temp_address = new mailto; - $temp_address->user = $parts[0]; - $temp_address->host = $parts[1]; - return $temp_address; - } - else - { - return False; - } + $this->property = Array( + 'dtstart' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'required', + 'vtodo' => 'optional', + 'vfreebusy'=> 'optional', + 'vtimezone'=> 'required' + ) + ), + 'dtend' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'optional', + 'vfreebusy'=> 'optional' + ) + ), + 'dtstamp' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'required', + 'vtodo' => 'required', + 'vjournal' => 'required', + 'vfreebusy'=> 'required' + ) + ), + 'due' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vtodo' => 'optional' + ) + ), + 'completed' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vtodo' => 'optional' + ) + ), + 'created' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'last_modified' => Array( + 'type' => 'date-time', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vtimezone'=> 'optional' + ) + ), + 'duration' => Array( + 'type' => 'duration', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vfreebusy'=> 'optional', + 'valarm' => 'optional' + ) + ), + 'freebusy' => Array( + 'type' => 'freebusy', + 'mangle'=> False, + 'state' => Array( + 'vfreebusy'=> 'optional' + ) + ), + 'attendee' => Array( + 'type' => 'cal-address', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'organizer' => Array( + 'type' => 'cal-address', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vfreebusy'=> 'optional' + ) + ), + 'rrule' => Array( + 'type' => 'recur', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vtimezone'=> 'optional' + ) + ), + 'comment' => Array( + 'type' => 'uri', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vtimezone'=> 'optional', + 'vfreebusy'=> 'optional' + ) + ), + 'summary' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'valarm' => 'optional' + ) + ), + 'resources' => Array( + 'type' => 'text', + 'mangle'=> False, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional' + ) + ), + 'description' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'valarm' => 'optional' + ) + ), + 'location' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional' + ) + ), + 'priority' => Array( + 'type' => 'integer', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional' + ) + ), + 'calscale' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'valarm' => 'optional' + ) + ), + 'transp' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional' + ) + ), + 'tzid' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vtimezone' => 'required' + ) + ), + 'geo' => Array( + 'type' => 'float', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional' + ) + ), + 'uid' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vfreebusy'=> 'optional' + ) + ), + 'percent_complete' => Array( + 'type' => 'integer', + 'mangle'=> True, + 'state' => Array( + 'vtodo' => 'optional' + ) + ), + 'sequence' => Array( + 'type' => 'integer', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'status' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'class' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'categories' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional' + ) + ), + 'request_status' => Array( + 'type' => 'text', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'vfreebusy'=> 'optional' + ) + ), + 'attach' => Array( + 'type' => 'uri', + 'mangle'=> True, + 'state' => Array( + 'vevent' => 'optional', + 'vtodo' => 'optional', + 'vjournal' => 'optional', + 'valarm' => 'optional' + ) + ) + ); } function set_var(&$event,$type,$value) { -// if($value != False) -// { - $type = strtolower(str_replace('-','_',$type)); - $event->$type = $value; -// } + $type = strtolower(str_replace('-','_',$type)); + $event->$type = $value; } function unfold(&$vcal_text,$current_line) @@ -206,7 +455,7 @@ class vCalendar $vcal_text[$i] = $vcal_text[$i + 1]; $i++; } - $next_line++; +// $next_line++; } } @@ -220,19 +469,6 @@ class vCalendar return str_replace('"','',$str); } - function strip_param($str) - { - $extra_param = explode(':',$str); - if(count($extra_param) == 1) - { - return $str; - } - else - { - return $extra_param[1]; - } - } - function split_param(&$return_value,$str,$check_equal) { if($check_equal) @@ -297,6 +533,92 @@ class vCalendar return $return_value; } + function from_text($str) + { + $str = str_replace("\\,",",",$str); + $str = str_replace("\\;",";",$str); + $str = str_replace("\\N","\n",$str); + $str = str_replace("\\n","\n",$str); + $str = str_replace("\\\\","\\",$str); + return $str; + } + + function to_text($str) + { + $str = str_replace("\\","\\\\",$str); + $str = str_replace(",","\\,",$str); + $str = str_replace(";","\\;",$str); + $str = str_replace("\n","\\n",$str); + return $str; + } + + function new_vcal() + { + return new vCal; + } + + /* + * Parse Functions + */ + + function parse_date($value) + { + $dtime = new vCalendar_time; + if(strpos($value,':')) + { + $pos = explode(':',$value); + $value = $pos[1]; + } + $dtime->year = intval(substr($value,0,4)); + $dtime->month = intval(substr($value,4,2)); + $dtime->mday = intval(substr($value,6,2)); + if(substr($value,8,1) == 'T') + { + $dtime->hour = intval(substr($value,9,2)); + $dtime->min = intval(substr($value,11,2)); + $dtime->sec = intval(substr($value,13,2)); + } + else + { + $dtime->hour = 0; + $dtime->min = 0; + $dtime->sec = 0; + } + return $dtime; + } + + function parse_address($address) + { + if(strpos(' '.$address,':')) + { + $parts = explode(':',$address); + $address = $parts[1]; + } + + $parts = explode('@',$address); + if(count($parts) == 2) + { + $temp_address = new mailto; + $temp_address->user = $parts[0]; + $temp_address->host = $parts[1]; + return $temp_address; + } + else + { + return False; + } + } + + function parse_geo(&$event,$value) + { + $return_value = $this->explode_param($value,'"',True); + if(count($return_value) == 2) + { + $event->lat = $return_value[0]; + $event->lon = $return_value[1]; + } + } + function parse_text(&$event,$value) { $return_value = $this->explode_param($value,'"',True); @@ -311,6 +633,7 @@ class vCalendar case 'altrep': case 'fmttype': case 'cid': + case 'language': $this->set_var($event,strtolower($type[0]),$type[1]); break; case 'encoding': @@ -319,17 +642,248 @@ class vCalendar case 'value': break; default: - $this->set_var($event,'value',$type[0]); + if($type[0] <> "\\n") + { + $this->set_var($event,'value',$type[0]); + } break; } } } - elseif($value <> '\n') + elseif($value <> "\\n") { $this->set_var($event,'value',$value); } } + function parse_attendee(&$event,$value) + { + $param = $this->explode_param($value,'"',True); + + for($j=0;$jstrip_quotes($param[$j+1]); + switch($type[0]) + { + case 'role': + $val = $this->switch_role($type[1]); + break; + case 'partstat': + $val = $this->switch_partstat($type[1]); + break; + case 'rsvp': + $val = $this->switch_rsvp($type[1]); + break; + case 'delegated-from': + case 'delegated-to': + case 'mailto': + $type[0] = str_replace('-','_',$type[0]); + $val = $this->parse_address($type[1]); + break; + case 'dir': + $val = $type[1]; + break; + default: + $val = $type[1]; + break; + } + $this->set_var($event,$type[0],$val); + } + } + + function parse_recurrence(&$event,$value) + { + $return_value = $this->explode_param($value,'"',True); + if(count($return_value) > 0) + { + for($i=0;$istrip_quotes($return_value[$i+1]); + $this->set_var($event,$type[0],$type[1]); + } + } + } + + /* + * Build-Card Functions + */ + + function out_organizer_attendee($event) + { + $str = ''; + if(!empty($event->cn) && $event->cn <> 'Unknown') + { + $str .= ';CN="'.$event->cn.'"'; + } + if(!empty($event->dir)) + { + $str .= ';DIR="'.str_replace('=','=3D',str_replace(' ','%20',$event->dir)).'"'; + } + if(!empty($event->role)) + { + $str .= ';ROLE='.$this->switch_role($event->role); + } + if(!empty($event->rsvp)) + { + $str .= ';RSVP='.$this->switch_rsvp($event->rsvp); + } + if(!empty($event->delegated_from->user) && !empty($event->delegated_from->host)) + { + $str .= ';DELEGATED-FROM="MAILTO:'.$event->delegated_from->user.'@'.$event->delegated_from->host.'"'; + } + if(!empty($event->delegated_to->user) && !empty($event->delegated_to->host)) + { + $str .= ';DELEGATED-TO="MAILTO:'.$event->delegated_to->user.'@'.$event->delegated_to->host.'"'; + } + if(!empty($event->mailto->user) && !empty($event->mailto->host)) + { + $str .= ':MAILTO:'.$event->mailto->user.'@'.$event->mailto->host; + } + return $str; + } + + function build_text($event,$mangle) + { + $str = ''; + if(!empty($event->cid)) + { + $str .= ';CID="'.$event->cid.'"'; + } + if(!empty($event->altrep)) + { + $str .= ';ALTREP="'.$event->altrep.'"'; + } + if(!empty($event->fmttype)) + { + $str .= ';FMTTYPE='.$event->fmttype; + } + if(!empty($event->encoding)) + { + $str .= ';ENCODING='.$this->switch_encoding($event->encoding); + } + if(!empty($event->value)) + { + if($mangle) + { + $event->value = $this->to_text($event->value); + } + $str .= ':'.$event->value; + } +// else +// { +// $str .= ':\n'; +// } + + return $str; + } + + function build_rrule($event) + { + $var = Array( + 'freq', + 'count', + 'wkst', + 'byday' + ); + for($i=0;$i{$var[$i]})) + { + $str[] = strtoupper($var[$i]).'='.$event->{$var[$i]}; + } + } + return implode($str,';'); + } + + function build_time($event) + { + return ':'.date('Ymd\THms\Z',mktime($event->year,$event->month,$event->mday,$event->hour,$event->min,$event->sec)); + } + + function build_card_internals($ical_item,$event) + { + reset($this->property); + while(list($key,$varray) = each($this->property)) + { + $value = $key; + $type = $varray['type']; + $mangle = $varray['mangle']; + $state = $varray['state'][$ical_item]; + if(@$state == 'optional' || @$state == 'required') + { + switch($type) + { + case 'date-time': + switch($value) + { + case 'last_modified': + $str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.gmdate('Ymd\THms\Z')); + break; + default: + if(!empty($event->$value)) + { + $str .= $this->fold(strtoupper($value).$this->build_time($event->$value)); + } + elseif($value == 'dtstamp' || $value == 'created') + { + $str .= $this->fold(strtoupper($value).':'.gmdate('Ymd\THms\Z')); + } + break; + } + break; + case 'uri': + if(!empty($event->$value)) + { + for($i=0;$i$value);$i++) + { + $str .= $this->fold(strtoupper($value).$this->build_text($event->{$value}[$i],$mangle)); + } + } + break; + case 'recur': + if(!empty($event->$value)) + { + $str .= $this->fold(strtoupper($value).':'.$this->build_rrule($event->$value)); + } + break; + case 'integer': + if(!empty($event->$value)) + { + $str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event->$value); + } + elseif($value == 'sequence' || $value == 'percent_complete') + { + $str .= $this->fold(strtoupper(str_replace('_','-',$value)).':0'); + } + break; + case 'float': + if(!empty($event->$value)) + { + $str .= $this->fold(strtoupper(str_replace('_','-',$value)).':'.$event->$value->lat.';'.$event->$value->lon); + } + break; + case 'text': + if(empty($event->$value) && $state == 'required') + { + return ''; + } + if(!empty($event->$value)) + { + $str .= $this->fold(strtoupper(str_replace('_','-',$value)).$this->build_text($event->$value,$mangle)); + } + break; + } + } + } + return $str; + } + + /* + * Switching Functions + */ + function switch_encoding($var) { if(gettype($var) == 'string') @@ -586,84 +1140,14 @@ class vCalendar } } - function parse_attendee(&$event,$value) - { - $param = $this->explode_param($value,'"',True); - - for($j=0;$jstrip_quotes($param[$j+1]); - switch($type[0]) - { - case 'role': - $val = $this->switch_role($type[1]); - break; - case 'partstat': - $val = $this->switch_partstat($type[1]); - break; - case 'rsvp': - $val = $this->switch_rsvp($type[1]); - break; - case 'delegated-from': - case 'delegated-to': - case 'mailto': - $type[0] = str_replace('-','_',$type[0]); - $val = $this->split_address($type[1]); - break; - case 'dir': - $val = $type[1]; - break; - default: - $val = $type[1]; - break; - } - $this->set_var($event,$type[0],$val); - } - } - - function parse_recurrence(&$event,$value) - { - $param = explode(';',$value); - for($j=0;$jstrip_quotes($type[1]); - $this->set_var($event,$type[0],$type[1]); - } - } - } - - function from_text($str) - { - $str = str_replace("\\,",",",$str); - $str = str_replace("\\;",";",$str); - $str = str_replace("\\N","\n",$str); - $str = str_replace("\\n","\n",$str); - $str = str_replace("\\\\","\\",$str); - return $str; - } - - function to_text($str) - { - $str = str_replace("\\","\\\\",$str); - $str = str_replace(",","\\,",$str); - $str = str_replace(";","\\;",$str); - $str = str_replace("\n","\\n",$str); - return $str; - } - - function new_vcal() - { - return new vCal; - } + /* + * The brunt of the class + */ function read($vcal_text) { $i = 0; + $mode = 'none'; while(chop($vcal_text[$i]) != '') { // if(strlen($vcal_text[$i]) > 75) @@ -675,6 +1159,8 @@ class vCalendar $vcal_text[$i] = str_replace("\r\n",'',$vcal_text[$i]); +// echo "TEXT : ".$vcal_text[$i]."
\n"; + // Example #1 //vcal_text[$i] = 'BEGIN:VCALENDAR' @@ -721,218 +1207,150 @@ class vCalendar $value = $vcal_text[$i]; } - switch($majortype) + $mtype = str_replace('-','_',$majortype); + + if($mtype == 'begin' || $mtype == 'end') { - case 'begin': - switch(strtolower($value)) - { - case 'vcalendar': - $vcal = $this->new_vcal(); - break; - case 'vevent': - case 'vtodo': - $event = new vCalendar_item; - $event->type = strtolower($value); - break; - } - break; - case 'prodid': - case 'version': - case 'method': - $this->set_var($vcal,$majortype,$value); - break; - case 'description': - $event->$majortype = new class_text; - $this->parse_text($event->$majortype,$this->from_text($value)); - break; - case 'location': - $this->set_var($event,$majortype,$this->from_text($value)); - break; - case 'attach': - $attach = new class_text; - $this->parse_text($attach,$value); - $event->attach[] = $attach; - unset($attach); - break; - case 'attendee': - $attendee = new attendee; - $this->parse_attendee($attendee,$value); - $event->attendee[] = $attendee; - unset($attendee); - break; - case 'organizer': - $event->$majortype = new attendee; - $this->parse_attendee($event->$majortype,$value); - break; - case 'end': - switch(strtolower($value)) - { - case 'vevent': - $this->event[] = $event; - unset($event); - break; - case 'vtodo': - $this->todo[] = $event; - unset($event); - break; - case 'vcalendar': - $this->vcal = $vcal; - $this->vcal->event = $this->event; - $this->vcal->todo = $this->todo; - break 2; - } - break; - case 'dtstart': - case 'dtend': - case 'dtstamp': - $this->set_var($event,$majortype,$this->splitdate($value)); - break; - case 'class': - $this->set_var($event,$majortype,$this->switch_class($value)); - break; - case 'transp': - $this->set_var($event,$majortype,$this->switch_transp($value)); - break; - case 'rrule': - $event->$majortype = new $majortype; - $this->parse_recurrence($event->$majortype,$value); - break; - default: - $this->set_var($event,$majortype,$value); - break; + $mode = 'none'; + } + + if($mode != 'none') + { + if(isset($this->property[$mtype])) + { + $state = @$this->property[$mtype]['state']["$mode"]; + } + else + { + $state = ''; + } + } + else + { + $state = 'required'; + } + + if($state == 'optional' || $state == 'required') + { + switch($mtype) + { + case 'begin': + switch(strtolower($value)) + { + case 'vcalendar': + $vcal = $this->new_vcal(); + break; + case 'vevent': + $mode = 'vevent'; + $event = new vCalendar_item; + $event->type = strtolower($value); + break; + case 'vtodo': + $mode = 'vtodo'; + $event = new vCalendar_item; + $event->type = strtolower($value); + break; + } + break; + case 'prodid': + case 'version': + case 'method': + $this->parse_text($vcal->$majortype,$this->from_text($value)); + break; + case 'geo': + $event->$majortype = new class_geo; + $this->parse_geo($event->$majortype,$value); + break; + case 'description': + case 'location': + case 'summary': + case 'calscale': + case 'tzid': + case 'transp': + case 'uid': + case 'class': + case 'status': + case 'categories': + case 'resources': + case 'request_status': + $event->$majortype = new class_text; + $this->parse_text($event->$majortype,$this->from_text($value)); + break; + case 'attach': + $attach = new class_text; + $this->parse_text($attach,$this->from_text($value)); + $event->attach[] = $attach; + unset($attach); + break; + case 'comment': + $comment = new class_text; + $this->parse_text($comment,$this->from_text($value)); + $event->comment[] = $comment; + unset($comment); + break; + case 'percent_complete': + $this->set_var($event,str_replace('-','_',$majortype),$value); + break; + case 'attendee': + $attendee = new attendee; + $this->parse_attendee($attendee,$value); + $event->attendee[] = $attendee; + unset($attendee); + break; + case 'organizer': + $event->$majortype = new attendee; + $this->parse_attendee($event->$majortype,$value); + break; + case 'due': + case 'completed': + case 'duration': + case 'freebusy': + case 'dtstart': + case 'dtend': + case 'dtstamp': + case 'created': + case 'last_modified': + $this->set_var($event,$majortype,$this->parse_date($value)); + break; + case 'rrule': + $event->$majortype = new $majortype; + $this->parse_recurrence($event->$majortype,$value); + break; + case 'end': + $mode = 'none'; + switch(strtolower($value)) + { + case 'vevent': + $this->event[] = $event; + unset($event); + break; + case 'vtodo': + $this->todo[] = $event; + unset($event); + break; + case 'vcalendar': + $this->vcal = $vcal; + $this->vcal->event = $this->event; + $this->vcal->todo = $this->todo; + break 2; + } + break; + default: + $this->set_var($event,$majortype,$value); + break; + } } $i++; } return $this->vcal; } - function out_organizer_attendee($event) - { - $str = ''; - if(!empty($event->cn) && $event->cn <> 'Unknown') - { - $str .= ';CN="'.$event->cn.'"'; - } - if(!empty($event->dir)) - { - $str .= ';DIR="'.str_replace('=','=3D',str_replace(' ','%20',$event->dir)).'"'; - } - if(!empty($event->role)) - { - $str .= ';ROLE='.$this->switch_role($event->role); - } - if(!empty($event->rsvp)) - { - $str .= ';RSVP='.$this->switch_rsvp($event->rsvp); - } - if(!empty($event->delegated_from->user) && !empty($event->delegated_from->host)) - { - $str .= ';DELEGATED-FROM="MAILTO:'.$event->delegated_from->user.'@'.$event->delegated_from->host.'"'; - } - if(!empty($event->delegated_to->user) && !empty($event->delegated_to->host)) - { - $str .= ';DELEGATED-TO="MAILTO:'.$event->delegated_to->user.'@'.$event->delegated_to->host.'"'; - } - if(!empty($event->mailto->user) && !empty($event->mailto->host)) - { - $str .= ':MAILTO:'.$event->mailto->user.'@'.$event->mailto->host; - } - return $str; - } - - function build_text($event) - { - $str = ''; - if(!empty($event->cid)) - { - $str .= ';CID="'.$event->cid.'"'; - } - if(!empty($event->altrep)) - { - $str .= ';ALTREP="'.$event->altrep.'"'; - } - if(!empty($event->fmttype)) - { - $str .= ';FMTTYPE='.$event->fmttype; - } - if(!empty($event->encoding)) - { - $str .= ';ENCODING='.$this->switch_encoding($event->encoding); - } - if(!empty($event->value)) - { - $str .= ':'.$this->to_text($event->value); - } - else - { - $str .= ':\n'; - } - - return $str; - } - - function build_card_internals($event) - { - $str = 'DTSART:'.sprintf("%4d%02d%02dT%02d%02d%02dZ",$event->dtstart->year,$event->dtstart->month,$event->dtstart->mday,$event->dtstart->hour,$event->dtstart->min,$event->dtstart->sec)."\r\n"; - $str .= 'DTEND:'.sprintf("%4d%02d%02dT%02d%02d%02dZ",$event->dtend->year,$event->dtend->month,$event->dtend->mday,$event->dtend->hour,$event->dtend->min,$event->dtend->sec)."\r\n"; -// Still need to build recurrence portion...... - iF(!empty($event->location)) - { - $str .= $this->fold('LOCATION:'.$this->to_text($event->location)); - } - else - { - $str .= 'LOCATION:\n'."\r\n"; - } - $str .= 'TRANSP:'.$this->switch_transp($event->transp)."\r\n"; - if(!empty($event->sequence)) - { - $str .= 'SEQUENCE:'.$event->sequence."\r\n"; - } - if(!empty($event->uid)) - { - $str .= $this->fold('UID:'.$event->uid); - } - $str .= 'DTSTAMP:'.gmdate('Ymd\THms\Z')."\r\n"; - if(!empty($event->description)) - { - $str .= $this->fold('DESCRIPTION'.$this->build_text($event->description)); - } - else - { - $str .= 'DESCRIPTION:\n'."\r\n"; - } - if(!empty($event->summary)) - { - $str .= $this->fold('SUMMARY:'.$event->summary); - } - else - { - $str .= 'SUMMARY:\n'."\r\n"; - } - if(!empty($event->priority)) - { - $str .= 'PRIORITY:'.$event->priority."\r\n"; - } - $str .= 'CLASS:'.$this->switch_class($event->class)."\r\n"; - - if(!empty($event->attach)) - { - for($i=0;$iattach);$i++) - { - $str .= $this->fold('ATTACH'.$this->build_text($event->atttach[$i])); - } - } - - return $str; - } - function build_vcal($vcal) { $str = 'BEGIN:VCALENDAR'."\r\n"; - $str .= 'PRODID:'.$vcal->prodid."\r\n"; - $str .= 'VERSION:'.$vcal->version."\r\n"; - $str .= 'METHOD:'.$vcal->method."\r\n"; + $str .= $this->fold('PRODID'.$this->build_text($vcal->prodid)); + $str .= $this->fold('VERSION'.$this->build_text($vcal->version)); + $str .= $this->fold('METHOD'.$this->build_text($vcal->method)); if($vcal->event) { for($i=0;$ievent);$i++) @@ -951,7 +1369,7 @@ class vCalendar { $str .= $this->fold('ORGANIZER'.$this->out_organizer_attendee($vcal->event[$i]->organizer)); } - $str .= $this->build_card_internals($vcal->event[$i]); + $str .= $this->build_card_internals('vevent',$vcal->event[$i]); $str .= 'END:VEVENT'."\r\n"; } } @@ -960,7 +1378,7 @@ class vCalendar for($i=0;$itodo);$i++) { $str .= 'BEGIN:VTODO'."\r\n"; - $str .= $this->build_card_internals($vcal->todo[$i]); + $str .= $this->build_card_internals('vtodo',$vcal->todo[$i]); $str .= 'END:VTODO'."\r\n"; } } diff --git a/calendar/inc/vcal1.ics b/calendar/inc/vcal1.ics index dd2935e167..aa77700061 100755 --- a/calendar/inc/vcal1.ics +++ b/calendar/inc/vcal1.ics @@ -8,8 +8,15 @@ ATTENDEE;CN="Jones Bill (IT)";ROLE=REQ-PARTICIPANT;RSVP=TRUE;DELEGATED-FROM="MAI ATTENDEE;CN="Smith Mary (PR)";ROLE=NON-PARTICIPANT;RSVP=FALSE:MAILTO:Mary.Smith@elsewhere.com ORGANIZER;DIR="ldap://host.com:6666/o=3DABC%20Industries,c=3DUS??(cn=3DJim%20Dolittle)":MAILTO:John.Doe@somewhere.com DTSTART:20010302T150000Z +RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH DTEND:20010302T153000Z LOCATION:Conference Room #2 +COMMENT:The meeting really needs to include both ourselves + and the customer. We can't hold this meeting without them. + As a matter of fact\, the venue for the meeting ought to be at + their site. - - John +COMMENT:I really don't think so. +RESOURCES:EASEL,PROJECTOR,VCR TRANSP:OPAQUE SEQUENCE:0 UID:023007208203E60074C5B7107A82E00803730C0D40A12C0042A2C001009384EA000F00B100 @@ -20,6 +27,7 @@ SUMMARY:Web Site Redesign PRIORITY:5 ATTACH;FMTTYPE=image/basic;ENCODING=BASE64:VALUE:TEST CLASS:PUBLIC +CATEGORIES:MEETING END:VEVENT BEGIN:VEVENT ATTENDEE;CN="Doe2 John (Marketing)";ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:John.Doe2@somewhere.com @@ -36,6 +44,8 @@ UID:023007208203E60074C5B7107A82E00803730C0D40A12C0042A2C001009384EA000F00B100 DTSTAMP:20010301T172412Z DESCRIPTION:\n SUMMARY:Web Site Redesign (2) +CALSCALE:GREGORIAN +GEO:37.386013;-122.082932 PRIORITY:2 CLASS:PRIVATE END:VEVENT @@ -56,14 +66,15 @@ DESCRIPTION:P DPD OLSEN\, JOHN SSGT 19 - 23 Mar 01 2476 Mr Marr (GS-11) \nA SUMMARY:Alternate - Front Desk Duty PRIORITY:5 CLASS:PUBLIC +STATUS:CANCELLED END:VEVENT BEGIN:VTODO DTSTART:20010301T160000Z -DTEND:20010301T163000Z LOCATION:My Desk\, or the conference room DTSTAMP:20010301T172312Z DESCRIPTION:\n SUMMARY:Prepare for tomrrow's meeting CLASS:PRIVATE +PERCENT-COMPLETE:30 END:VTODO END:VCALENDAR