From 4088b81c5c871de9872c5dd55da818b08c409bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lehrke?= Date: Thu, 19 Nov 2009 10:13:17 +0000 Subject: [PATCH] Impoved support for recurrences if device timezone differs from event timezone --- calendar/inc/class.calendar_ical.inc.php | 41 +++++++---------------- calendar/inc/class.calendar_so.inc.php | 42 +++++++++++++++++++++--- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index ae0b8f1580..668ce732c4 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -100,6 +100,13 @@ class calendar_ical extends calendar_boupdate */ var $tzid = null; + /** + * Cached timezone data + * + * @var array id => data + */ + protected static $tz_cache = array(); + /** * Device CTCap Properties * @@ -384,30 +391,8 @@ class calendar_ical extends calendar_boupdate // dont use "virtual" exceptions created by participant status for GroupDAV or file export if (!in_array($this->productManufacturer,array('file','groupdav'))) { - $participants = $this->so->get_participants($event['id'], 0); - - // Check if the stati for all participants are identical for all recurrences - foreach ($participants as $uid => $attendee) - { - switch ($attendee['type']) - { - case 'u': // account - case 'c': // contact - case 'e': // email address - $recurrences = $this->so->get_recurrences($event['id'], $uid); - foreach ($recurrences as $rdate => $recur_status) - { - if ($rdate && $recur_status != $recurrences[0]) - { - // Every distinct status results in an exception - $days[] = $rdate; - } - } - break; - default: // We don't handle the rest - break; - } - } + $tz_id = ($tzid != $event['tzid'] ? $tzid : null); + $days = $this->so->get_recurrence_exceptions($event, $tz_id); } if (is_array($event['recur_exception'])) { @@ -687,13 +672,11 @@ class calendar_ical extends calendar_boupdate { $time = new egw_time($time,egw_time::$server_timezone); } - static $timezone; - static $timezone_tzid; - if (is_null($timezone) || $timezone_tzid != $tzid) + if (!isset(self::$tz_cache[$tzid])) { - $timezone = calendar_timezones::DateTimeZone($timezone_tzid = $tzid); + self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); } - $time->setTimezone($timezone); + $time->setTimezone(self::$tz_cache[$tzid]); $params['TZID'] = $tzid; return $time->format('Ymd\THis'); diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index 51942a1344..8f30ec5bee 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -90,6 +90,14 @@ class calendar_so */ const STATUS_SORT = "CASE cal_status WHEN 'U' THEN 1 WHEN 'T' THEN 2 WHEN 'A' THEN 3 WHEN 'R' THEN 4 ELSE 0 END ASC"; + /** + * Cached timezone data + * + * @var array id => data + */ + protected static $tz_cache = array(); + + /** * Constructor of the socal class */ @@ -1433,16 +1441,30 @@ ORDER BY cal_user_type, cal_usre_id * Gets the exception days of a given recurring event caused by * irregular participant stati * - * @param array $event Recurring Event. + * @param array $event Recurring Event. + * @param string tz_id=null timezone for exports (null for event's timezone) * * @return array Array of exception days (false for non-recurring events). */ - function get_recurrence_exceptions(&$event) + function get_recurrence_exceptions(&$event, $tz_id=null) { $cal_id = (int) $event['id']; if (!$cal_id || $event['recur_type'] == MCAL_RECUR_NONE) return false; $days = array(); + $first_start = $recur_start = ''; + + if (!empty($tz_id)) + { + // set export timezone + if(!isset(self::$tz_cache[$tz_id])) + { + self::$tz_cache[$tz_id] = calendar_timezones::DateTimeZone($tz_id); + } + $starttime = new egw_time($event['start'], egw_time::$server_timezone); + $starttime->setTimezone(self::$tz_cache[$tz_id]); + $first_start = $starttime->format('His'); + } $participants = $this->get_participants($event['id'], 0); @@ -1457,10 +1479,20 @@ ORDER BY cal_user_type, cal_usre_id $recurrences = $this->get_recurrences($event['id'], $uid); foreach ($recurrences as $recur_date => $recur_status) { - if ($recur_date && $recur_status != $recurrences[0]) + if ($recur_date) { - // Every distinct status results in an exception - $days[] = $recur_date; + if (!empty($tz_id)) + { + $time = new egw_time($recur_date, egw_time::$server_timezone); + $time->setTimezone(self::$tz_cache[$tz_id]); + $recur_start = $time->format('His'); + } + if ($recur_status != $recurrences[0] + || !empty($tz_id) && $first_start != $recur_start) + { + // Every distinct status or starttime results in an exception + $days[] = $recur_date; + } } } break;