Skip to content

Commit 88abd08

Browse files
author
Jason Oster
committed
Performance improvements (especially for remote calendars) and some style cleanups
1 parent c1c6750 commit 88abd08

File tree

3 files changed

+237
-67
lines changed

3 files changed

+237
-67
lines changed

default_config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ private function __construct(){
5555
// Calendar Caching (decreases page load times)
5656
$this->save_parsed_cals = 'no'; // Saves a copy of the cal in /tmp after it's been parsed. Improves performance.
5757
$this->tmp_dir = '/tmp'; // The temporary directory on your system (/tmp is fine for UNIXes including Mac OS X). Any php-writable folder works.
58+
$this->webcal_hours = '24'; // Number of hours to cache webcals. Setting to '0' will always re-parse webcals if they've been modified.
5859

5960
// Webdav style publishing
6061
$this->phpicalendar_publishing = '0'; // Set to '1' to enable remote webdav style publish. See 'calendars/publish.php' for complete information;

functions/date_functions.php

Lines changed: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,101 @@
44
// functions for returning or comparing dates
55

66

7-
// get remote file last modification date (returns unix timestamp)
8-
function remote_filemtime($url) {
9-
$fp = fopen($url, 'r');
10-
if (!$fp) return 0;
11-
$metadata = stream_get_meta_data($fp);
12-
fclose($fp);
13-
14-
$unixtime = 0;
15-
foreach ($metadata['wrapper_data'] as $response) {
16-
// case: redirection
17-
// WARNING: does not handle relative redirection
18-
if (substr(strtolower($response), 0, 10) == 'location: ') {
19-
return GetRemoteLastModified(substr($response, 10));
20-
}
21-
// case: last-modified
22-
else if (substr(strtolower($response), 0, 15) == 'last-modified: ') {
23-
$unixtime = strtotime(substr($response, 15));
24-
break;
7+
/*
8+
* Get remote file last modification date (returns unix timestamp)
9+
* Supports HTTPS, HTTP basic authentication, and location: redirects
10+
* FIXME: Basic auth should not be sent over unencrypted connections
11+
* unless an HTTP 401 Unauthorized is returned
12+
*/
13+
function remote_filemtime($url, $recurse = 0) {
14+
// We hate infinite loops!
15+
if (++$recurse > 5) return 0;
16+
17+
// Caching the remote mtime is a Really Good Idea.
18+
static $remote_files = array();
19+
if (isset($remote_files[$url])) return $remote_files[$url];
20+
21+
$uri = parse_url($url);
22+
$uri['proto'] = (
23+
(isset($uri['proto']) && ($uri['proto'] == 'https')) ?
24+
'ssl://' :
25+
''
26+
);
27+
$uri['port'] = isset($uri['port']) ? $uri['port'] : 80;
28+
$path = (
29+
(isset($uri['path']) || isset($uri['query'])) ?
30+
(@$uri['path'] . @$uri['query']) :
31+
'/'
32+
);
33+
$auth = (
34+
(isset($uri['user']) || isset($uri['pass'])) ?
35+
('Authentication: Basic ' . base64_encode(@$uri['user'] . ':' . @$uri['pass']) . "\r\n") :
36+
''
37+
);
38+
39+
$handle = @fsockopen($uri['proto'] . $uri['host'], $uri['port']);
40+
if (!$handle) {
41+
$remote_files[$url] = 0;
42+
return 0;
43+
}
44+
45+
fputs($handle, "HEAD {$path} HTTP/1.1\r\nHost: {$uri['host']}\r\n{$auth}Connection: close\r\n\r\n");
46+
$headers = array();
47+
while (!feof($handle)) {
48+
$line = trim(fgets($handle, 1024));
49+
if (empty($line)) break;
50+
$headers[] = $line;
51+
}
52+
fclose($handle);
53+
54+
$result = 0;
55+
array_shift($headers);
56+
foreach ($headers as $header) {
57+
list($key, $value) = explode(':', $header, 2);
58+
$value = trim($value);
59+
60+
switch (strtolower(trim($key))) {
61+
case 'location': // Redirect
62+
$result = remote_filemtime(resolve_path($url, $value), $recurse);
63+
break;
64+
65+
case 'last-modified': // Got it!
66+
$result = strtotime($value);
67+
break;
2568
}
2669
}
2770

28-
return $unixtime;
71+
$remote_files[$url] = $result;
72+
return $result;
73+
}
74+
75+
/*
76+
* Resolve relative paths
77+
* Utility function for remote_filemtime()
78+
*/
79+
function resolve_path($url, $rel_path) {
80+
$uri = parse_url($url);
81+
82+
$uri['proto'] = (isset($uri['proto']) ? $uri['proto'] : 'http://');
83+
$uri['port'] = (isset($uri['port']) ? (':' . $uri['port']) : '');
84+
$auth = (
85+
(isset($uri['user']) || isset($uri['pass'])) ?
86+
(urlencode(@$uri['user']) . ':' . urlencode(@$uri['pass']) . '@') :
87+
''
88+
);
89+
90+
if (parse_url($rel_path) === false) {
91+
// Path is relative to this domain
92+
$rel_path = str_replace('\\', '/', $rel_path);
93+
94+
if ($rel_path{0} == '/')
95+
return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $rel_path;
96+
97+
return $uri['proto'] . '://' . $auth . $uri['host'] . $uri['port'] . $uri['path'] . '/' . $rel_path;
98+
}
99+
100+
// Path is absolute
101+
return $rel_path;
29102
}
30103

31104
// takes iCalendar 2 day format and makes it into 3 characters
@@ -235,10 +308,10 @@ function openevent($event_date, $time, $uid, $arr, $lines = 0, $length = 0, $lin
235308
# for iCal pseudo tag <http> comptability
236309
if (ereg('<([[:alpha:]]+://)([^<>[:space:]]+)>',$event_text,$matches)) {
237310
$full_event_text = $matches[1] . $matches[2];
238-
$event_text = $matches[2];
311+
$event_text = $matches[2];
239312
} else {
240313
$full_event_text = $event_text;
241-
$event_text = strip_tags($event_text, '<b><i><u><img>');
314+
$event_text = strip_tags($event_text, '<b><i><u><img>');
242315
}
243316

244317
if (!empty($link_class)) $link_class = ' class="'.$link_class.'"';

0 commit comments

Comments
 (0)