Viewing file: import_vcal.php (10.25 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php // Parse the vcal file and return the data hash. function parse_vcal($cal_file) { global $tz, $errormsg;
$vcal_data = array();
//echo "Parsing vcal file... <br />\n";
if (!$fd=@fopen($cal_file,"r")) { $errormsg .= "Can't read temporary file: $cal_file\n"; exit(); } else { // reflect the section where we are in the file: // VCALENDAR, TZ/DAYLIGHT, VEVENT, ALARM $state = "NONE"; $substate = "none"; // reflect the sub section $subsubstate = ""; // reflect the sub-sub section $error = false; $line = 0; $event = '';
while (!feof($fd) && !$error) { $line++; $buff = fgets($fd, 4096); $buff = chop($buff);
// parser debugging code... //echo "line = $line <br />"; //echo "state = $state <br />"; //echo "substate = $substate <br />"; //echo "subsubstate = $subsubstate <br />"; //echo "buff = " . htmlspecialchars ( $buff ) . "<br /><br />\n";
if ($state == "VEVENT") { if ( ! empty ( $subsubstate ) ) { if (preg_match("/^END:(.+)$/i", $buff, $match)) { if ( $match[1] == $subsubstate ) { $subsubstate = ''; } } else if ( $subsubstate == "VALARM" && preg_match ( "/TRIGGER:(.+)$/i", $buff, $match ) ) { //echo "Set reminder to $match[1]<br />"; //reminder time is $match[1] } } else if (preg_match("/^BEGIN:(.+)$/i", $buff, $match)) { $subsubstate = $match[1]; } // we suppose ":" is on the same line as property name, this can perhaps cause problems else if (preg_match("/^SUMMARY.*:(.+)$/i", $buff, $match)) { $substate = "summary"; $event[$substate] = $match[1]; } elseif (preg_match("/^DESCRIPTION:(.+)$/i", $buff, $match)) { $substate = "description"; $event[$substate] = $match[1]; } elseif (preg_match("/^DESCRIPTION;ENCODING=QUOTED-PRINTABLE:(.+)$/i", $buff, $match)) { // $substate = "description"; // $event[$substate] = quoted_printable_decode ( $match[1] ); $substate = "descriptionqp"; $event[$substate] = $match[1]; } elseif (preg_match("/^CLASS.*:(.+)$/i", $buff, $match)) { $substate = "class"; $event[$substate] = $match[1]; } elseif (preg_match("/^PRIORITY.*:(.+)$/i", $buff, $match)) { $substate = "priority"; $event[$substate] = $match[1]; } elseif (preg_match("/^DTSTART.*:(.+)$/i", $buff, $match)) { $substate = "dtstart"; $event[$substate] = $match[1]; } elseif (preg_match("/^DTEND.*:(.+)$/i", $buff, $match)) { $substate = "dtend"; $event[$substate] = $match[1]; } elseif (preg_match("/^RRULE.*:(.+)$/i", $buff, $match)) { $substate = "rrule"; $event[$substate] = $match[1]; } elseif (preg_match("/^EXDATE.*:(.+)$/i", $buff, $match)) { $substate = "exdate"; $event[$substate] = $match[1]; } elseif (preg_match("/^DALARM.*:(.+)$/i", $buff, $match)) { $substate = "dalarm"; $event[$substate] = $match[1]; } elseif (preg_match("/^CATEGORIES.*:(.+)$/i", $buff, $match)) { $substate = "categories"; $event[$substate] = $match[1]; } elseif (preg_match("/^UID.*:(.+)$/i", $buff, $match)) { $substate = "uid"; $event[$substate] = $match[1]; } elseif (preg_match("/^END:VEVENT$/i", $buff, $match)) { $state = "VCALENDAR"; $substate = "none"; $subsubstate = ''; if ($tmp_data = format_vcal($event)) $vcal_data[] = $tmp_data; // clear out data for new event $event = '';
// TODO: QUOTED-PRINTABLE descriptions
// folded lines } elseif (preg_match("/^[ ]{1}(.+)$/", $buff, $match)) { if ($substate != "none") { $event[$substate] .= $match[1]; } else { $errormsg .= "Error in file $cal_file line $line:<br />$buff\n"; $error = true; } // For unsupported properties } else { $substate = "none"; } } elseif ($state == "VCALENDAR") { if (preg_match("/^TZ.*:(.+)$/i", $buff, $match)) { $event['tz'] = $match[1]; } elseif (preg_match("/^DAYLIGHT.*:(.+)$/i", $buff, $match)) { $event['daylight'] = $match[1]; } elseif (preg_match("/^BEGIN:VEVENT$/i", $buff)) { $state = "VEVENT"; } elseif (preg_match("/^END:VCALENDAR$/i", $buff)) { $state = "NONE"; } } elseif ($state == "NONE") { if (preg_match("/^BEGIN:VCALENDAR$/i", $buff)) $state = "VCALENDAR"; else if (preg_match("/^BEGIN:ALARM$/i", $buff)) $state = "ALARM"; } } //End while fclose($fd); }
return $vcal_data; }
// Convert vcal format (yyyymmddThhmmssZ) to epoch time function vcaldate_to_timestamp($vdate,$plus_d = '0',$plus_m = '0', $plus_y = '0') { global $TZoffset;
$y = substr($vdate, 0, 4) + $plus_y; $m = substr($vdate, 4, 2) + $plus_m; $d = substr($vdate, 6, 2) + $plus_d; $H = substr($vdate, 9, 2); $M = substr($vdate, 11, 2); $S = substr($vdate, 13, 2); $Z = substr($vdate, 15, 1); if ($Z == 'Z') { $TS = gmmktime($H,$M,$S,$m,$d,$y); } else { // Problem here if server in different timezone $TS = mktime($H,$M,$S,$m,$d,$y); }
return $TS; }
// Put all vcal data into import hash structure function format_vcal($event) { // Start and end time $fevent['StartTime'] = vcaldate_to_timestamp($event['dtstart']); if ($fevent['StartTime'] == '-1') return false; $fevent['EndTime'] = vcaldate_to_timestamp($event['dtend']);
// Calculate duration in minutes $fevent['Duration'] = ($fevent['EndTime'] - $fevent['StartTime']) / 60; if ($fevent['Duration'] == '1440') { $fevent['Duration'] = '0'; $fevent['Untimed'] = 1; } //All day (untimed)
if (! empty($event['summary'])) $fevent['Summary'] = $event['summary']; if (! empty($event['description'])) $fevent['Description'] = $event['description']; if (! empty($event['descriptionqp'])) { $fevent['Description'] = quoted_printable_decode ( $event['descriptionqp'] ); // hack for mozilla sunbird's extra = signs $fevent['Description'] = preg_replace('/^=/', '', $fevent['Description']); $fevent['Description'] = str_replace("\n=", "\n", $fevent['Description']); } if (! empty($event['class'])) { $fevent['Private'] = preg_match("/private|confidential/i", $event['class']) ? '1' : '0'; } else { $fevent['Private'] = '0'; } if (! empty($fevent['UID'])) $fevent['UID'] = $event['uid'];
// Repeats // // vcal 1.0 repeats can be very complicated and the webcalendar doesn't // actually support all of the ways repeats can be specified. We will // focus on vcals dumped from Palm Desktop and Lotus Notes, which are simple // and the ones webcalendar should fully support. if (! empty($event['rrule'])) { //split into pieces $RR = explode(" ", $event['rrule']);
if (preg_match("/^D(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '1'; $fevent['Repeat']['Frequency'] = $match[1]; } elseif (preg_match("/^W(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '2'; $fevent['Repeat']['Frequency'] = $match[1]; $fevent['Repeat']['RepeatDays'] = rrule_repeat_days($RR); } elseif (preg_match("/^MP(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '3'; $fevent['Repeat']['Frequency'] = $match[1]; if ($RR[1] == '5+') { $fevent['Repeat']['Interval'] = '6'; // Last week (monthlyByDayR) } } elseif (preg_match("/^MD(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '4'; $fevent['Repeat']['Frequency'] = $match[1]; } elseif (preg_match("/^YM(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '5'; $fevent['Repeat']['Frequency'] = $match[1]; } elseif (preg_match("/^YD(.+)$/i", $RR[0], $match)) { $fevent['Repeat']['Interval'] = '5'; $fevent['Repeat']['Frequency'] = $match[1]; }
$end = end($RR);
// No end in Palm is 12-31-2031 if (($end != '20311231') && ($end != '#0')) { $fevent['Repeat']['EndTime'] = rrule_endtime($fevent['Repeat']['Interval'],$fevent['Repeat']['Frequency'],$event['dtstart'],$end); }
// Repeating exceptions? if (!empty($event['exdate'])) { $fevent['Repeat']['Exceptions'] = array(); $EX = explode(",", $event['exdate']); foreach ( $EX as $exdate ){ $fevent['Repeat']['Exceptions'][] = vcaldate_to_timestamp($exdate); } } } // end if rrule
// TODO // $fevent[Category]; // $fevent[AlarmSet]; // $fevent[AlarmAdvanceAmount]; // $fevent[AlarmAdvanceType];
return $fevent; }
// Figure out days of week for weekly repeats function rrule_repeat_days($RA) { $T = count($RA); $j = $T - 1; $sun = $mon = $tue = $wed = $thu = $fri = $sat = 'n'; for ($i = 1; $i < $j; $i++) { if ($RA[$i] == 'SU') { $sun = 'y'; } elseif ($RA[$i] == 'MO') { $mon = 'y'; } elseif ($RA[$i] == 'TU') { $tue = 'y'; } elseif ($RA[$i] == 'WE') { $wed = 'y'; } elseif ($RA[$i] == 'TH') { $thu = 'y'; } elseif ($RA[$i] == 'FR') { $fri = 'y'; } elseif ($RA[$i] == 'SA') { $sat = 'y'; } } return $sun.$mon.$tue.$wed.$thu.$fri.$sat; }
// Calculate repeating ending time function rrule_endtime($int,$freq,$start,$end) { // if # then we have to add the difference to the start time if (preg_match("/^#(.+)$/i", $end, $M)) { $T = $M[1] * $freq; $plus_d = $plus_m = $plus_y = '0'; if ($int == '1') { $plus_d = $T; } elseif ($int == '2') { $plus_d = $T * 7; } elseif ($int == '3') { $plus_m = $T; } elseif ($int == '4') { $plus_m = $T; } elseif ($int == '5') { $plus_y = $T; } elseif ($int == '6') { $plus_m = $T; } $endtime = vcaldate_to_timestamp($start,$plus_d,$plus_m,$plus_y);
// if we have the enddate } else { $endtime = vcaldate_to_timestamp($end); } return $endtime; } ?>
|