diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 19a03e15..9043b4a9 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -251,14 +251,16 @@ class kolab_calendar extends kolab_storage_folder_api public function list_events($start, $end, $search = null, $virtual = 1, $query = array(), $filter_query = null) { // convert to DateTime for comparisons + // #5190: make the range a little bit wider + // to workaround possible timezone differences try { - $start = new DateTime('@'.$start); + $start = new DateTime('@' . ($start - 12 * 3600)); } catch (Exception $e) { $start = new DateTime('@0'); } try { - $end = new DateTime('@'.$end); + $end = new DateTime('@' . ($end + 12 * 3600)); } catch (Exception $e) { $end = new DateTime('today +10 years'); diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php index 9f4533cc..bcc9ac3f 100644 --- a/plugins/libkolab/lib/kolab_storage_cache.php +++ b/plugins/libkolab/lib/kolab_storage_cache.php @@ -50,6 +50,7 @@ class kolab_storage_cache protected $order_by = null; protected $limit = null; protected $error = 0; + protected $server_timezone; /** @@ -84,6 +85,7 @@ class kolab_storage_cache $this->enabled = $rcmail->config->get('kolab_cache', false); $this->folders_table = $this->db->table_name('kolab_folders'); $this->cache_refresh = get_offset_sec($rcmail->config->get('kolab_cache_refresh', '12h')); + $this->server_timezone = new DateTimeZone(date_default_timezone_get()); if ($this->enabled) { // always read folder cache and lock state from DB master @@ -1145,4 +1147,19 @@ class kolab_storage_cache } } + /** + * Converts DateTime or unix timestamp into sql date format + * using server timezone. + */ + protected function _convert_datetime($datetime) + { + if (is_object($datetime)) { + $dt = clone $datetime; + $dt->setTimeZone($this->server_timezone); + return $dt->format(self::DB_DATE_FORMAT); + } + else if ($datetime) { + return date(self::DB_DATE_FORMAT, $datetime); + } + } } diff --git a/plugins/libkolab/lib/kolab_storage_cache_event.php b/plugins/libkolab/lib/kolab_storage_cache_event.php index e25bd899..ae9c693b 100644 --- a/plugins/libkolab/lib/kolab_storage_cache_event.php +++ b/plugins/libkolab/lib/kolab_storage_cache_event.php @@ -34,27 +34,27 @@ class kolab_storage_cache_event extends kolab_storage_cache { $sql_data = parent::_serialize($object); - $sql_data['dtstart'] = is_object($object['start']) ? $object['start']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['start']); - $sql_data['dtend'] = is_object($object['end']) ? $object['end']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['end']); + $sql_data['dtstart'] = $this->_convert_datetime($object['start']); + $sql_data['dtend'] = $this->_convert_datetime($object['end']); // extend date range for recurring events if ($object['recurrence'] && $object['_formatobj']) { $recurrence = new kolab_date_recurrence($object['_formatobj']); $dtend = $recurrence->end() ?: new DateTime('now +10 years'); - $sql_data['dtend'] = $dtend->format(self::DB_DATE_FORMAT); + $sql_data['dtend'] = $this->_convert_datetime($dtend); } // extend start/end dates to spawn all exceptions if (is_array($object['exceptions'])) { foreach ($object['exceptions'] as $exception) { if (is_a($exception['start'], 'DateTime')) { - $exstart = $exception['start']->format(self::DB_DATE_FORMAT); + $exstart = $this->_convert_datetime($exception['start']); if ($exstart < $sql_data['dtstart']) { $sql_data['dtstart'] = $exstart; } } if (is_a($exception['end'], 'DateTime')) { - $exend = $exception['end']->format(self::DB_DATE_FORMAT); + $exend = $this->_convert_datetime($exception['end']); if ($exend > $sql_data['dtend']) { $sql_data['dtend'] = $exend; } @@ -64,4 +64,4 @@ class kolab_storage_cache_event extends kolab_storage_cache return $sql_data; } -} \ No newline at end of file +} diff --git a/plugins/libkolab/lib/kolab_storage_cache_freebusy.php b/plugins/libkolab/lib/kolab_storage_cache_freebusy.php index d8ab554a..50e48042 100644 --- a/plugins/libkolab/lib/kolab_storage_cache_freebusy.php +++ b/plugins/libkolab/lib/kolab_storage_cache_freebusy.php @@ -23,5 +23,20 @@ class kolab_storage_cache_freebusy extends kolab_storage_cache { - protected $extra_cols = array('dtstart','dtend'); -} \ No newline at end of file + protected $extra_cols = array('dtstart','dtend'); + + /** + * Helper method to convert the given Kolab object into a dataset to be written to cache + * + * @override + */ + protected function _serialize($object) + { + $sql_data = parent::_serialize($object) + array('dtstart' => null, 'dtend' => null); + + $sql_data['dtstart'] = $this->_convert_datetime($object['start']); + $sql_data['dtend'] = $this->_convert_datetime($object['end']); + + return $sql_data; + } +} diff --git a/plugins/libkolab/lib/kolab_storage_cache_journal.php b/plugins/libkolab/lib/kolab_storage_cache_journal.php index a63577b7..766f1da1 100644 --- a/plugins/libkolab/lib/kolab_storage_cache_journal.php +++ b/plugins/libkolab/lib/kolab_storage_cache_journal.php @@ -24,5 +24,19 @@ class kolab_storage_cache_journal extends kolab_storage_cache { protected $extra_cols = array('dtstart','dtend'); - -} \ No newline at end of file + + /** + * Helper method to convert the given Kolab object into a dataset to be written to cache + * + * @override + */ + protected function _serialize($object) + { + $sql_data = parent::_serialize($object) + array('dtstart' => null, 'dtend' => null); + + $sql_data['dtstart'] = $this->_convert_datetime($object['start']); + $sql_data['dtend'] = $this->_convert_datetime($object['end']); + + return $sql_data; + } +} diff --git a/plugins/libkolab/lib/kolab_storage_cache_task.php b/plugins/libkolab/lib/kolab_storage_cache_task.php index 7bf5c798..8b714e63 100644 --- a/plugins/libkolab/lib/kolab_storage_cache_task.php +++ b/plugins/libkolab/lib/kolab_storage_cache_task.php @@ -32,13 +32,11 @@ class kolab_storage_cache_task extends kolab_storage_cache */ protected function _serialize($object) { - $sql_data = parent::_serialize($object) + array('dtstart' => null, 'dtend' => null); + $sql_data = parent::_serialize($object); - if ($object['start']) - $sql_data['dtstart'] = is_object($object['start']) ? $object['start']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['start']); - if ($object['due']) - $sql_data['dtend'] = is_object($object['due']) ? $object['due']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['due']); + $sql_data['dtstart'] = $this->_convert_datetime($object['start']); + $sql_data['dtend'] = $this->_convert_datetime($object['due']); return $sql_data; } -} \ No newline at end of file +}