From c2f74d0c7291a1c292afbca3d18d75e16c90105f Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Sat, 8 Oct 2011 18:40:29 +0000 Subject: [PATCH] * CalDAV: fixed wrong VTIMEZONE component generated (has to be in UTC), probably fixes bug #2984: Problem with VTIMEZONE component generated for NZ --- calendar/inc/class.calendar_ical.inc.php | 43 ++++------------- calendar/inc/class.calendar_timezones.inc.php | 46 +++++++++++++++++++ infolog/inc/class.infolog_ical.inc.php | 20 +------- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index a39cc0db1b..ec71a3cd90 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -228,7 +228,7 @@ class calendar_ical extends calendar_boupdate } $vcal = new Horde_iCalendar; - $vcal->setAttribute('PRODID','-//eGroupWare//NONSGML eGroupWare Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'. + $vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'. strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang'])); $vcal->setAttribute('VERSION', $version); if ($method) $vcal->setAttribute('METHOD', $method); @@ -354,42 +354,15 @@ class calendar_ical extends calendar_boupdate if ($tzid && $tzid != 'UTC' && !in_array($tzid,$vtimezones_added)) { // check if we have vtimezone component data for tzid of event, if not default to user timezone (default to server tz) - if (!($vtimezone = calendar_timezones::tz2id($tzid,'component'))) + if (calendar_timezones::add_vtimezone($vcal, $tzid) || + !in_array($tzid = egw_time::$user_timezone->getName(), $vtimezones_added) && + calendar_timezones::add_vtimezone($vcal, $tzid)) { - error_log(__METHOD__."() unknown TZID='$tzid', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!"); - $vtimezone = calendar_timezones::tz2id($tzid=egw_time::$user_timezone->getName(),'component'); - $tzid = null; - } - if (!isset(self::$tz_cache[$tzid])) - { - self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); - } - //error_log("in_array('$tzid',\$vtimezones_added)=".array2string(in_array($tzid,$vtimezones_added)).", component=$vtimezone");; - if (!in_array($tzid,$vtimezones_added)) - { - // $vtimezone is a string with a single VTIMEZONE component, afaik Horde_iCalendar can not add it directly - // --> we have to parse it and let Horde_iCalendar add it again - $horde_vtimezone = Horde_iCalendar::newComponent('VTIMEZONE',$container=false); - $horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE'); - // DTSTART must be in local time! - $standard = $horde_vtimezone->findComponent('STANDARD'); - if (is_a($standard, 'Horde_iCalendar')) - { - $dtstart = $standard->getAttribute('DTSTART'); - $dtstart = new egw_time($dtstart, egw_time::$server_timezone); - $dtstart->setTimezone(self::$tz_cache[$tzid]); - $standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); - } - $daylight = $horde_vtimezone->findComponent('DAYLIGHT'); - if (is_a($daylight, 'Horde_iCalendar')) - { - $dtstart = $daylight->getAttribute('DTSTART'); - $dtstart = new egw_time($dtstart, egw_time::$server_timezone); - $dtstart->setTimezone(self::$tz_cache[$tzid]); - $daylight->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); - } - $vcal->addComponent($horde_vtimezone); $vtimezones_added[] = $tzid; + if (!isset(self::$tz_cache[$tzid])) + { + self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); + } } } if ($this->productManufacturer != 'file' && $this->uidExtension) diff --git a/calendar/inc/class.calendar_timezones.inc.php b/calendar/inc/class.calendar_timezones.inc.php index 39e0282d5d..d1daceb26c 100644 --- a/calendar/inc/class.calendar_timezones.inc.php +++ b/calendar/inc/class.calendar_timezones.inc.php @@ -319,6 +319,52 @@ class calendar_timezones '

'.self::import_tz_aliases()."

\n", lang('Update timezones'),true); } + + /** + * Add VTIMEZONE component to VCALENDAR + * + * @param Horde_iCalendar $vcal + * @param string $tzid + * @return boolean false if no vtimezone component available, true on success + */ + public static function add_vtimezone($vcal, $tzid) + { + include_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php'; + // checking type of $val, now we included the object definition (no need to always include it!) + if (!$vcal instanceof Horde_iCalendar) + { + throw new egw_exception_wrong_parameter(__METHOD__.'('.array2string($val).", '$tzid') no Horde_iCalendar!"); + } + // check if we have vtimezone component data for $tzid + if (!($vtimezone = calendar_timezones::tz2id($tzid, 'component'))) + { + return false; + } + // $vtimezone is a string with a single VTIMEZONE component, afaik Horde_iCalendar can not add it directly + // --> we have to parse it and let Horde_iCalendar add it again + $horde_vtimezone = Horde_iCalendar::newComponent('VTIMEZONE',$container=false); + $horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE'); + // DTSTART must be in UTC time + $standard = $horde_vtimezone->findComponent('STANDARD'); + if (is_a($standard, 'Horde_iCalendar')) + { + $dtstart = $standard->getAttribute('DTSTART'); + $dtstart = new egw_time($dtstart, egw_time::$server_timezone); + $dtstart->setTimezone('UTC'); + $standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); + } + $daylight = $horde_vtimezone->findComponent('DAYLIGHT'); + if (is_a($daylight, 'Horde_iCalendar')) + { + $dtstart = $daylight->getAttribute('DTSTART'); + $dtstart = new egw_time($dtstart, egw_time::$server_timezone); + $dtstart->setTimezone('UTC'); + $daylight->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); + } + $vcal->addComponent($horde_vtimezone); + + return true; + } } /* if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == __FILE__) // some tests diff --git a/infolog/inc/class.infolog_ical.inc.php b/infolog/inc/class.infolog_ical.inc.php index 5934a6ca3e..0e9330e8c8 100644 --- a/infolog/inc/class.infolog_ical.inc.php +++ b/infolog/inc/class.infolog_ical.inc.php @@ -177,32 +177,16 @@ class infolog_ical extends infolog_bo if ($tzid && $tzid != 'UTC') { // check if we have vtimezone component data for tzid of event, if not default to user timezone (default to server tz) - if (!($vtimezone = calendar_timezones::tz2id($tzid,'component'))) + if (!calendar_timezones::add_vtimezone($vcal, $tzid)) { error_log(__METHOD__."() unknown TZID='$tzid', defaulting to user timezone '".egw_time::$user_timezone->getName()."'!"); - $vtimezone = calendar_timezones::tz2id($tzid=egw_time::$user_timezone->getName(),'component'); + calendar_timezones::add_vtimezone($vcal, $tzid=egw_time::$user_timezone->getName()); $tzid = null; } if (!isset(self::$tz_cache[$tzid])) { self::$tz_cache[$tzid] = calendar_timezones::DateTimeZone($tzid); } - // $vtimezone is a string with a single VTIMEZONE component, afaik Horde_iCalendar can not add it directly - // --> we have to parse it and let Horde_iCalendar add it again - $horde_vtimezone = Horde_iCalendar::newComponent('VTIMEZONE',$container=false); - $horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE'); - // DTSTART must be in local time! - $standard = $horde_vtimezone->findComponent('STANDARD'); - $dtstart = $standard->getAttribute('DTSTART'); - $dtstart = new egw_time($dtstart, egw_time::$server_timezone); - $dtstart->setTimezone(self::$tz_cache[$tzid]); - $standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); - $daylight = $horde_vtimezone->findComponent('DAYLIGHT'); - $dtstart = $daylight->getAttribute('DTSTART'); - $dtstart = new egw_time($dtstart, egw_time::$server_timezone); - $dtstart->setTimezone(self::$tz_cache[$tzid]); - $daylight->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false); - $vcal->addComponent($horde_vtimezone); } $vevent = Horde_iCalendar::newComponent('VTODO',$vcal);