Fix missing events on edges of the view time range (when client timezone is different than server tz) (T698)
This commit is contained in:
parent
c67e78de61
commit
a0ca17fb36
6 changed files with 64 additions and 18 deletions
|
@ -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)
|
public function list_events($start, $end, $search = null, $virtual = 1, $query = array(), $filter_query = null)
|
||||||
{
|
{
|
||||||
// convert to DateTime for comparisons
|
// convert to DateTime for comparisons
|
||||||
|
// #5190: make the range a little bit wider
|
||||||
|
// to workaround possible timezone differences
|
||||||
try {
|
try {
|
||||||
$start = new DateTime('@'.$start);
|
$start = new DateTime('@' . ($start - 12 * 3600));
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
$start = new DateTime('@0');
|
$start = new DateTime('@0');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$end = new DateTime('@'.$end);
|
$end = new DateTime('@' . ($end + 12 * 3600));
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
$end = new DateTime('today +10 years');
|
$end = new DateTime('today +10 years');
|
||||||
|
|
|
@ -50,6 +50,7 @@ class kolab_storage_cache
|
||||||
protected $order_by = null;
|
protected $order_by = null;
|
||||||
protected $limit = null;
|
protected $limit = null;
|
||||||
protected $error = 0;
|
protected $error = 0;
|
||||||
|
protected $server_timezone;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +85,7 @@ class kolab_storage_cache
|
||||||
$this->enabled = $rcmail->config->get('kolab_cache', false);
|
$this->enabled = $rcmail->config->get('kolab_cache', false);
|
||||||
$this->folders_table = $this->db->table_name('kolab_folders');
|
$this->folders_table = $this->db->table_name('kolab_folders');
|
||||||
$this->cache_refresh = get_offset_sec($rcmail->config->get('kolab_cache_refresh', '12h'));
|
$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) {
|
if ($this->enabled) {
|
||||||
// always read folder cache and lock state from DB master
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,27 +34,27 @@ class kolab_storage_cache_event extends kolab_storage_cache
|
||||||
{
|
{
|
||||||
$sql_data = parent::_serialize($object);
|
$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['dtstart'] = $this->_convert_datetime($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['dtend'] = $this->_convert_datetime($object['end']);
|
||||||
|
|
||||||
// extend date range for recurring events
|
// extend date range for recurring events
|
||||||
if ($object['recurrence'] && $object['_formatobj']) {
|
if ($object['recurrence'] && $object['_formatobj']) {
|
||||||
$recurrence = new kolab_date_recurrence($object['_formatobj']);
|
$recurrence = new kolab_date_recurrence($object['_formatobj']);
|
||||||
$dtend = $recurrence->end() ?: new DateTime('now +10 years');
|
$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
|
// extend start/end dates to spawn all exceptions
|
||||||
if (is_array($object['exceptions'])) {
|
if (is_array($object['exceptions'])) {
|
||||||
foreach ($object['exceptions'] as $exception) {
|
foreach ($object['exceptions'] as $exception) {
|
||||||
if (is_a($exception['start'], 'DateTime')) {
|
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']) {
|
if ($exstart < $sql_data['dtstart']) {
|
||||||
$sql_data['dtstart'] = $exstart;
|
$sql_data['dtstart'] = $exstart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_a($exception['end'], 'DateTime')) {
|
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']) {
|
if ($exend > $sql_data['dtend']) {
|
||||||
$sql_data['dtend'] = $exend;
|
$sql_data['dtend'] = $exend;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,19 @@
|
||||||
class kolab_storage_cache_freebusy extends kolab_storage_cache
|
class kolab_storage_cache_freebusy extends kolab_storage_cache
|
||||||
{
|
{
|
||||||
protected $extra_cols = array('dtstart','dtend');
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -25,4 +25,18 @@ class kolab_storage_cache_journal extends kolab_storage_cache
|
||||||
{
|
{
|
||||||
protected $extra_cols = array('dtstart','dtend');
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -32,12 +32,10 @@ class kolab_storage_cache_task extends kolab_storage_cache
|
||||||
*/
|
*/
|
||||||
protected function _serialize($object)
|
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'] = $this->_convert_datetime($object['start']);
|
||||||
$sql_data['dtstart'] = is_object($object['start']) ? $object['start']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['start']);
|
$sql_data['dtend'] = $this->_convert_datetime($object['due']);
|
||||||
if ($object['due'])
|
|
||||||
$sql_data['dtend'] = is_object($object['due']) ? $object['due']->format(self::DB_DATE_FORMAT) : date(self::DB_DATE_FORMAT, $object['due']);
|
|
||||||
|
|
||||||
return $sql_data;
|
return $sql_data;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue