I never came up with a way to do it without a cronjob, but I can save you a little time making one -- here's the PHP script to do it. I have this set in cron to run 4 times a day.
Code:
#!/usr/bin/php
<?
/*
this script is meant to be run periodically by cron.
It needs to be run as user ZIMBRA.
It needs to run on PHP 4, because that's what the Zimbra server has on it
Dave Reed, eSpeakers
dreed -at- espeakers.com
*/
define ('GET_USERLIST', 'nice zmprov gaa');
define ('GET_CALENDARS', 'nice zmmailbox -z -m mbox gaf');
define ('SYNC_CALENDAR', 'nice zmmailbox -z -m mbox syncFolder calname');
define ('EVENT_CAL_IDENTIFIER', 'www.espeakers.com'); //use this to single out only certain calendars for update
define('LOGFILE', '/opt/zimbra/contrib/logs/update_calendars_log.txt');
$logfile = fopen(LOGFILE, 'w+');
fwrite($logfile, 'STARTING AT '.date('n-j-Y H:i')."\n\n");
//get a list of all the users on the system
exec(GET_USERLIST, $mailboxes);
fwrite($logfile, '(about to operate on '.count($mailboxes).' accounts)'."\n\n");
//iterate over each user's mailbox and update any event calendar feeds
foreach ($mailboxes as $mailbox) {
echo "looking through user $mailbox...\n";
fwrite($logfile, "looking through user $mailbox...\n");
$x = preg_replace('/mbox/', $mailbox, GET_CALENDARS);
$lines = array(); //the exec on the next line will append to lines, so we need to clear it out first
exec($x,$lines);
//go thru all the user's mailboxes, looking for an iCalendar feed
foreach ($lines as $line) {
//the calendar names always start with a 'slash' character
if (preg_match('/(\/.*)/i', $line, $matches)) {
$s = $matches[0];
if (strpos($s, EVENT_CAL_IDENTIFIER)) {
//we've got a match that should get synched
if (preg_match('/(.*)\s\(/i', $s, $matches)) {
$calname = trim($matches[1]);
$x = preg_replace(array('/mbox/', '/calname/'), array(escapeshellarg($mailbox), escapeshellarg($calname)), SYNC_CALENDAR);
fwrite($logfile, " reloading calendar: $calname\n");
shell_exec($x);
}
}
}
}
}
fwrite($logfile, "\n\nDONE at ".date('n-j-Y H:i')."\n\n");
fclose($logfile);
?>