| 
     
      
      
      From: <par...@us...> - 2010-04-15 17:53:26
      
     
   | 
Update of /cvsroot/phpicalendar/phpicalendar/functions In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv8424/functions Modified Files: date_functions.php ical_parser.php Log Message: Performance improvements (especially for remote calendars) and some style cleanups Index: date_functions.php =================================================================== RCS file: /cvsroot/phpicalendar/phpicalendar/functions/date_functions.php,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** date_functions.php 13 Apr 2010 15:45:47 -0000 1.58 --- date_functions.php 15 Apr 2010 17:53:18 -0000 1.59 *************** *** 5,30 **** ! // get remote file last modification date (returns unix timestamp) ! function remote_filemtime($url) { ! $fp = fopen($url, 'r'); ! if (!$fp) return 0; ! $metadata = stream_get_meta_data($fp); ! fclose($fp); ! $unixtime = 0; ! foreach ($metadata['wrapper_data'] as $response) { ! // case: redirection ! // WARNING: does not handle relative redirection ! if (substr(strtolower($response), 0, 10) == 'location: ') { ! return GetRemoteLastModified(substr($response, 10)); ! } ! // case: last-modified ! else if (substr(strtolower($response), 0, 15) == 'last-modified: ') { ! $unixtime = strtotime(substr($response, 15)); ! break; } } ! return $unixtime; } --- 5,103 ---- ! /* ! * Get remote file last modification date (returns unix timestamp) ! * Supports HTTPS, HTTP basic authentication, and location: redirects ! * FIXME: Basic auth should not be sent over unencrypted connections ! * unless an HTTP 401 Unauthorized is returned ! */ ! function remote_filemtime($url, $recurse = 0) { ! // We hate infinite loops! ! if (++$recurse > 5) return 0; ! ! // Caching the remote mtime is a Really Good Idea. ! static $remote_files = array(); ! if (isset($remote_files[$url])) return $remote_files[$url]; ! $uri = parse_url($url); ! $uri['proto'] = ( ! (isset($uri['proto']) && ($uri['proto'] == 'https')) ? ! 'ssl://' : ! '' ! ); ! $uri['port'] = isset($uri['port']) ? $uri['port'] : 80; ! $path = ( ! (isset($uri['path']) || isset($uri['query'])) ? ! (@$uri['path'] . @$uri['query']) : ! '/' ! ); ! $auth = ( ! (isset($uri['user']) || isset($uri['pass'])) ? ! ('Authentication: Basic ' . base64_encode(@$uri['user'] . ':' . @$uri['pass']) . "\r\n") : ! '' ! ); ! ! $handle = @fsockopen($uri['proto'] . $uri['host'], $uri['port']); ! if (!$handle) { ! $remote_files[$url] = 0; ! return 0; ! } ! ! fputs($handle, "HEAD {$path} HTTP/1.1\r\nHost: {$uri['host']}\r\n{$auth}Connection: close\r\n\r\n"); ! $headers = array(); ! while (!feof($handle)) { ! $line = trim(fgets($handle, 1024)); ! if (empty($line)) break; ! $headers[] = $line; ! } ! fclose($handle); ! ! $result = 0; ! array_shift($headers); ! foreach ($headers as $header) { ! list($key, $value) = explode(':', $header, 2); ! $value = trim($value); ! ! switch (strtolower(trim($key))) { ! case 'location': // Redirect ! $result = remote_filemtime(resolve_path($url, $value), $recurse); ! break; ! ! case 'last-modified': // Got it! ! $result = strtotime($value); ! break; } } ! $remote_files[$url] = $result; ! return $result; ! } ! ! /* ! * Resolve relative paths ! * Utility function for remote_filemtime() ! */ ! function resolve_path($url, $rel_path) { ! $uri = parse_url($url); ! ! $uri['proto'] = (isset($uri['proto']) ? $uri['proto'] : 'http://'); ! $uri['port'] = (isset($uri['port']) ? (':' . $uri['port']) : ''); ! $auth = ( ! (isset($uri['user']) || isset($uri['pass'])) ? ! (urlencode(@$uri['user']) . ':' . urlencode(@$uri['pass']) . '@') : ! '' ! ); ! ! if (parse_url($rel_path) === false) { ! // Path is relative to this domain ! $rel_path = str_replace('\\', '/', $rel_path); ! ! if ($rel_path{0} == '/') ! return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $rel_path; ! ! return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $uri['path'] . '/' . $rel_path; ! } ! ! // Path is absolute ! return $rel_path; } *************** *** 236,243 **** if (ereg('<([[:alpha:]]+://)([^<>[:space:]]+)>',$event_text,$matches)) { $full_event_text = $matches[1] . $matches[2]; ! $event_text = $matches[2]; } else { $full_event_text = $event_text; ! $event_text = strip_tags($event_text, '<b><i><u><img>'); } --- 309,316 ---- if (ereg('<([[:alpha:]]+://)([^<>[:space:]]+)>',$event_text,$matches)) { $full_event_text = $matches[1] . $matches[2]; ! $event_text = $matches[2]; } else { $full_event_text = $event_text; ! $event_text = strip_tags($event_text, '<b><i><u><img>'); } Index: ical_parser.php =================================================================== RCS file: /cvsroot/phpicalendar/phpicalendar/functions/ical_parser.php,v retrieving revision 1.258 retrieving revision 1.259 diff -C2 -d -r1.258 -r1.259 *** ical_parser.php 13 Apr 2010 20:13:51 -0000 1.258 --- ical_parser.php 15 Apr 2010 17:53:18 -0000 1.259 *************** *** 9,15 **** // reading the file if it's allowed $parse_file = true; ! if ($phpiCal_config->save_parsed_cals == 'yes') { if (sizeof ($cal_filelist) > 1) { $parsedcal = $phpiCal_config->tmp_dir.'/parsedcal-'.urlencode($cpath.'::'.$phpiCal_config->ALL_CALENDARS_COMBINED).'-'.$this_year; if (file_exists($parsedcal)) { --- 9,17 ---- // reading the file if it's allowed + $realcal_mtime = time(); $parse_file = true; ! if ($phpiCal_config->save_parsed_cals == 'yes') { if (sizeof ($cal_filelist) > 1) { + // This is a special case for "all calendars combined" $parsedcal = $phpiCal_config->tmp_dir.'/parsedcal-'.urlencode($cpath.'::'.$phpiCal_config->ALL_CALENDARS_COMBINED).'-'.$this_year; if (file_exists($parsedcal)) { *************** *** 18,43 **** fclose($fd); $master_array = unserialize($contents); - $z=1; $y=0; if (sizeof($master_array['-4']) == (sizeof($cal_filelist))) { foreach ($master_array['-4'] as $temp_array) { ! $mtime = $master_array['-4'][$z]['mtime']; ! $fname = $master_array['-4'][$z]['filename']; ! $wcalc = $master_array['-4'][$z]['webcal']; ! ! if ($wcalc == 'no') $realcal_mtime = filemtime($fname); ! else $realcal_mtime = remote_filemtime($fname); ! if ($mtime == $realcal_mtime) { $y++; } - $z++; } foreach ($master_array['-3'] as $temp_array) { if (isset($temp_array) && $temp_array !='') $caldisplaynames[] = $temp_array; } if ($y == sizeof($cal_filelist)) { if ($master_array['-1'] == 'valid cal file') { $parse_file = false; $calendar_name = $master_array['calendar_name']; --- 20,65 ---- fclose($fd); $master_array = unserialize($contents); $y=0; + // Check the calendars' last-modified time to determine if any need to be re-parsed if (sizeof($master_array['-4']) == (sizeof($cal_filelist))) { foreach ($master_array['-4'] as $temp_array) { ! $mtime = $temp_array['mtime']; ! $fname = $temp_array['filename']; ! $wcalc = $temp_array['webcal']; ! ! if ($wcalc == 'no') { ! /* ! * Getting local file mtime is "fairly cheap" ! * (disk I/O is expensive, but *much* cheaper than going to the network for remote files) ! */ ! $realcal_mtime = filemtime($fname); ! } ! else if ((time() - $mtime) >= $phpiCal_config->webcal_hours * 60 * 60) { ! /* ! * We limit remote file mtime checks based on the magic webcal_hours config variable ! * This allows highly volatile web calendars to be cached for a period of time before ! * downloading them again ! */ ! $realcal_mtime = remote_filemtime($fname); ! } ! else { ! // This is our fallback, for the case where webcal_hours is taking effect ! $realcal_mtime = $mtime; ! } ! // If this calendar is up-to-date, the $y magic number will be incremented... ! if ($mtime >= $realcal_mtime) { $y++; } } + foreach ($master_array['-3'] as $temp_array) { if (isset($temp_array) && $temp_array !='') $caldisplaynames[] = $temp_array; } + // And the $y magic number is used here to determine if all calendars are up-to-date if ($y == sizeof($cal_filelist)) { if ($master_array['-1'] == 'valid cal file') { + // At this point, all calendars are up-to-date, so we can simply used the pre-parsed data $parse_file = false; $calendar_name = $master_array['calendar_name']; *************** *** 47,64 **** } } ! if ($parse_file == true) unset($master_array); } else { foreach ($cal_filelist as $filename) { - if (substr($filename, 0, 7) == 'http://' || substr($filename, 0, 8) == 'https://' || substr($filename, 0, 9) == 'webcal://') { - $realcal_mtime = remote_filemtime($filename); - } - else { - $realcal_mtime = filemtime($filename); - } - $parsedcal = $phpiCal_config->tmp_dir.'/parsedcal-'.urlencode($cpath.'::'.$cal_filename).'-'.$this_year; if (file_exists($parsedcal)) { $parsedcal_mtime = filemtime($parsedcal); ! if ($realcal_mtime == $parsedcal_mtime) { $fd = fopen($parsedcal, 'r'); $contents = fread($fd, filesize($parsedcal)); --- 69,91 ---- } } ! if ($parse_file == true) { ! // We need to re-parse at least one calendar, so unset master_array ! unset($master_array); ! } } else { foreach ($cal_filelist as $filename) { $parsedcal = $phpiCal_config->tmp_dir.'/parsedcal-'.urlencode($cpath.'::'.$cal_filename).'-'.$this_year; if (file_exists($parsedcal)) { $parsedcal_mtime = filemtime($parsedcal); ! ! if (((time() - $parsedcal_mtime) >= $phpiCal_config->webcal_hours * 60 * 60) && ! (substr($filename, 0, 7) == 'http://' || substr($filename, 0, 8) == 'https://' || substr($filename, 0, 9) == 'webcal://')) { ! $realcal_mtime = remote_filemtime($filename); ! } ! else { ! $realcal_mtime = $parsedcal_mtime; ! } ! ! if ($parsedcal_mtime >= $realcal_mtime) { $fd = fopen($parsedcal, 'r'); $contents = fread($fd, filesize($parsedcal)); *************** *** 96,108 **** $filename = $cal_httpPrefix; $master_array['-4'][$calnumber]['webcal'] = 'yes'; ! $actual_mtime = @remote_filemtime($filename); } else { ! $actual_mtime = @filemtime($filename); } ! include(BASE.'functions/parse/parse_tzs.php'); ! $ifile = @fopen($filename, "r"); if ($ifile == FALSE) exit(error($lang['l_error_cantopen'], $filename)); $nextline = fgets($ifile, 1024); --- 123,136 ---- $filename = $cal_httpPrefix; $master_array['-4'][$calnumber]['webcal'] = 'yes'; ! $actual_mtime = remote_filemtime($filename); } else { ! $actual_mtime = filemtime($filename); } ! $is_std = false; ! $is_daylight = false; ! $ifile = @fopen($filename, 'r'); if ($ifile == FALSE) exit(error($lang['l_error_cantopen'], $filename)); $nextline = fgets($ifile, 1024); *************** *** 121,135 **** $line = $nextline; $nextline = fgets($ifile, 1024); ! $nextline = ereg_replace("[\r\n]", "", $nextline); #handle continuation lines that start with either a space or a tab (MS Outlook) ! while (isset($nextline{0}) && ($nextline{0} == " " || $nextline{0} == "\t")) { $line = $line . substr($nextline, 1); $nextline = fgets($ifile, 1024); ! $nextline = ereg_replace("[\r\n]", "", $nextline); } ! $line = str_replace('\n',"\n",$line); ! $line = str_replace('\t',"\t",$line); $line = trim(stripslashes($line)); switch ($line) { case 'BEGIN:VFREEBUSY': case 'BEGIN:VEVENT': --- 149,201 ---- $line = $nextline; $nextline = fgets($ifile, 1024); ! $nextline = ereg_replace("[\r\n]", '', $nextline); #handle continuation lines that start with either a space or a tab (MS Outlook) ! while (isset($nextline{0}) && ($nextline{0} == ' ' || $nextline{0} == "\t")) { $line = $line . substr($nextline, 1); $nextline = fgets($ifile, 1024); ! $nextline = ereg_replace("[\r\n]", '', $nextline); } ! $line = str_replace('\n', "\n", $line); ! $line = str_replace('\t', "\t", $line); $line = trim(stripslashes($line)); switch ($line) { + // Begin VTIMEZONE Parsing + // + case 'BEGIN:VTIMEZONE': + unset($tz_name, $offset_from, $offset_to, $tz_id); + break; + case 'BEGIN:STANDARD': + unset ($offset_s); + $is_std = true; + $is_daylight = false; + break; + case 'END:STANDARD': + $offset_s = $offset_to; + $is_std = false; + break; + case 'BEGIN:DAYLIGHT': + unset ($offset_d); + $is_daylight = true; + $is_std = false; + break; + case 'END:DAYLIGHT': + $offset_d = $offset_to; + $is_daylight = false; + break; + case 'END:VTIMEZONE': + if (!isset($offset_d) && isset($offset_s)) $offset_d = $offset_s; + $tz_array[$tz_id] = array( + 0 => @$offset_s, + 1 => @$offset_d, + 'dt_start' => @$begin_daylight, + 'st_start' => @$begin_std, + 'st_name' => @$st_name, + 'dt_name' => @$dt_name + + ); #echo "<pre>$tz_id"; print_r($tz_array[$tz_id]);echo"</pre>"; + break; + + // Begin VFREEBUSY/VEVENT Parsing + // case 'BEGIN:VFREEBUSY': case 'BEGIN:VEVENT': *************** *** 176,181 **** case 'END:VFREEBUSY': case 'END:VEVENT': ! include BASE."functions/parse/end_vevent.php"; break; case 'END:VTODO': if (($vtodo_priority == '') && ($status == 'COMPLETED')) { --- 242,250 ---- case 'END:VFREEBUSY': case 'END:VEVENT': ! include BASE.'functions/parse/end_vevent.php'; break; + + // Begin VTODO Parsing + // case 'END:VTODO': if (($vtodo_priority == '') && ($status == 'COMPLETED')) { *************** *** 234,237 **** --- 303,309 ---- $description = ''; break; + + // Begin VALARM Parsing + // case 'BEGIN:VALARM': $valarm_set = TRUE; *************** *** 252,256 **** switch ($property) { ! // Start VTODO Parsing // --- 324,345 ---- switch ($property) { ! // Start TZ Parsing ! // ! case 'TZID': ! $tz_id = $data; ! break; ! case 'TZOFFSETFROM': ! $offset_from = $data; ! break; ! case 'TZOFFSETTO': ! $offset_to = $data; ! break; ! case 'TZNAME': ! if ($is_std) $st_name = $data; ! if ($is_daylight) $dt_name = $data; ! break; ! // ! // End TZ Parsing ! // Start VTODO Parsing // *************** *** 287,291 **** break; // ! // End VTODO Parsing case 'DTSTART': --- 376,380 ---- break; // ! // End VTODO Parsing case 'DTSTART': *************** *** 293,303 **** $start_unixtime = $datetime[0]; $start_date = $datetime[1]; ! $start_time = $datetime[2]; ! $allday_start = $datetime[3]; ! $start_tz = $datetime[4]; ! preg_match ('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})/', $data, $regs); ! $vevent_start_date = $regs[1] . $regs[2] . $regs[3]; ! $day_offset = dayCompare($start_date, $vevent_start_date); ! #echo date("Ymd Hi", $start_unixtime)." $start_date $start_time $vevent_start_date $day_offset<br>"; break; --- 382,399 ---- $start_unixtime = $datetime[0]; $start_date = $datetime[1]; ! if ($is_std || $is_daylight) { ! $year = substr($start_date, 0, 4); ! if ($is_std) $begin_std[$year] = $data; ! if ($is_daylight) $begin_daylight[$year] = $data; ! } ! else { ! $start_time = $datetime[2]; ! $allday_start = $datetime[3]; ! $start_tz = $datetime[4]; ! preg_match ('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})/', $data, $regs); ! $vevent_start_date = $regs[1] . $regs[2] . $regs[3]; ! $day_offset = dayCompare($start_date, $vevent_start_date); ! #echo date("Ymd Hi", $start_unixtime)." $start_date $start_time $vevent_start_date $day_offset<br>"; ! } break; *************** *** 311,315 **** case 'EXDATE': ! $data = split(",", $data); foreach ($data as $exdata) { $exdata = str_replace('T', '', $exdata); --- 407,411 ---- case 'EXDATE': ! $data = split(',', $data); foreach ($data as $exdata) { $exdata = str_replace('T', '', $exdata); *************** *** 425,433 **** break; case 'ATTENDEE': ! $email = preg_match("/mailto:(.*)/i", $data, $matches1); ! $name = preg_match("/CN=([^;]*)/i", $field, $matches2); ! $rsvp = preg_match("/RSVP=([^;]*)/i", $field, $matches3); ! $partstat = preg_match("/PARTSTAT=([^;]*)/i", $field, $matches4); ! $role = preg_match("/ROLE=([^;]*)/i", $field, $matches5); $email = ($email ? $matches1[1] : ''); --- 521,529 ---- break; case 'ATTENDEE': ! $email = preg_match('/mailto:(.*)/i', $data, $matches1); ! $name = preg_match('/CN=([^;]*)/i', $field, $matches2); ! $rsvp = preg_match('/RSVP=([^;]*)/i', $field, $matches3); ! $partstat = preg_match('/PARTSTAT=([^;]*)/i', $field, $matches4); ! $role = preg_match('/ROLE=([^;]*)/i', $field, $matches5); $email = ($email ? $matches1[1] : ''); *************** *** 448,453 **** break; case 'ORGANIZER': ! $email = preg_match("/mailto:(.*)/i", $data, $matches1); ! $name = preg_match("/CN=([^;]*)/i", $field, $matches2); $email = ($email ? $matches1[1] : ''); --- 544,549 ---- break; case 'ORGANIZER': ! $email = preg_match('/mailto:(.*)/i', $data, $matches1); ! $name = preg_match('/CN=([^;]*)/i', $field, $matches2); $email = ($email ? $matches1[1] : '');  |