From a9b6c6e9b4845d59b647183409b06ddcb56c8c2a Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 20 Feb 2014 17:46:15 +0000 Subject: [PATCH] * CalDAV/CardDAV: fixed support for limited sync-collection report used eg. by Marten Gajdas Android apps --- .../inc/class.addressbook_groupdav.inc.php | 1 + calendar/inc/class.calendar_groupdav.inc.php | 5 ++++- calendar/inc/class.calendar_so.inc.php | 3 ++- infolog/inc/class.infolog_bo.inc.php | 6 ++++++ infolog/inc/class.infolog_groupdav.inc.php | 9 +++++++++ phpgwapi/inc/class.groupdav_handler.inc.php | 18 +++++++++++++++++- 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/addressbook/inc/class.addressbook_groupdav.inc.php b/addressbook/inc/class.addressbook_groupdav.inc.php index 6daa353d6f..0f9cf6fb3e 100644 --- a/addressbook/inc/class.addressbook_groupdav.inc.php +++ b/addressbook/inc/class.addressbook_groupdav.inc.php @@ -167,6 +167,7 @@ class addressbook_groupdav extends groupdav_handler if ($options['root']['name'] == 'sync-collection' && $this->bo->total > $nresults) { --$this->sync_collection_token; + $files['sync-token-params'][] = true; // tel get_sync_collection_token that we have more entries } } else diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index ab8a9a7bcd..bcdc33ed7c 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -197,6 +197,7 @@ class calendar_groupdav extends groupdav_handler } // process REPORT filters or multiget href's + $nresults = null; if (($id || $options['root']['name'] != 'propfind') && !$this->_report_filters($options, $filter, $id, $nresults)) { // return empty collection, as iCal under iOS 5 had problems with returning "404 Not found" status @@ -223,6 +224,7 @@ class calendar_groupdav extends groupdav_handler if (isset($nresults)) { + unset($filter['no_total']); // we need the total! $files['files'] = $this->propfind_callback($path, $filter, array(0, (int)$nresults)); // hack to support limit with sync-collection report: events are returned in modified ASC order (oldest first) @@ -231,6 +233,7 @@ class calendar_groupdav extends groupdav_handler if ($options['root']['name'] == 'sync-collection' && $this->bo->total > $nresults) { --$this->sync_collection_token; + $files['sync-token-params'][] = true; // tel get_sync_collection_token that we have more entries } } else @@ -333,7 +336,7 @@ class calendar_groupdav extends groupdav_handler } } // sync-collection report --> return modified of last contact as sync-token - if ($sync_collection_report) + if ($sync_collection) { $this->sync_collection_token = $event['modified']; } diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index 0f63fe5e63..9d38bdd614 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -695,7 +695,8 @@ class calendar_so $selects[$key]['cols'] = "DISTINCT $this->repeats_table.recur_type,range_end AS recur_enddate,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,".$this->db->to_varchar($this->cal_table.'.cal_id').",cal_start,cal_end,$this->user_table.cal_recur_date"; if (!$params['enum_recuring']) { - $selects[$key]['cols'] = str_replace('cal_start','MIN(cal_start) AS cal_start',$selects[$key]['cols']); + $selects[$key]['cols'] = str_replace(array('cal_start','cal_end'), + array('range_start AS cal_start','range_end AS cal_end'), $selects[$key]['cols']); } } if (!isset($param['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']); diff --git a/infolog/inc/class.infolog_bo.inc.php b/infolog/inc/class.infolog_bo.inc.php index 55da7be4b5..5d81eec47c 100644 --- a/infolog/inc/class.infolog_bo.inc.php +++ b/infolog/inc/class.infolog_bo.inc.php @@ -26,6 +26,11 @@ class infolog_bo * @var infolog_so */ var $so; + /** + * Total from last search call + * @var int + */ + var $total; var $vfs; var $vfs_basedir='/infolog'; /** @@ -1037,6 +1042,7 @@ class infolog_bo } $ret = $this->so->search($query); + $this->total = $query['total']; if (is_array($ret)) { diff --git a/infolog/inc/class.infolog_groupdav.inc.php b/infolog/inc/class.infolog_groupdav.inc.php index c7d56139f2..c2f5e008b9 100644 --- a/infolog/inc/class.infolog_groupdav.inc.php +++ b/infolog/inc/class.infolog_groupdav.inc.php @@ -193,6 +193,15 @@ class infolog_groupdav extends groupdav_handler if (isset($nresults)) { $files['files'] = $this->propfind_callback($path, $filter, array(0, (int)$nresults)); + + // hack to support limit with sync-collection report: contacts are returned in modified ASC order (oldest first) + // if limit is smaller then full result, return modified-1 as sync-token, so client requests next chunk incl. modified + // (which might contain further entries with identical modification time) + if ($options['root']['name'] == 'sync-collection' && $this->bo->total > $nresults) + { + --$this->sync_collection_token; + $files['sync-token-params'][] = true; // tel get_sync_collection_token that we have more entries + } } else { diff --git a/phpgwapi/inc/class.groupdav_handler.inc.php b/phpgwapi/inc/class.groupdav_handler.inc.php index 0142826cd8..bbbadea8f6 100644 --- a/phpgwapi/inc/class.groupdav_handler.inc.php +++ b/phpgwapi/inc/class.groupdav_handler.inc.php @@ -692,8 +692,24 @@ abstract class groupdav_handler * @param int $user parameter necessary to call getctag, if no $token specified * @return string */ - public function get_sync_collection_token($path, $user=null) + public function get_sync_collection_token($path, $user=null, $more_results=null) { + //error_log(__METHOD__."('$path', $user, more_results=$more_results) this->sync_collection_token=".$this->sync_collection_token); + if ($more_results) + { + $error = +' + '.htmlspecialchars($this->groupdav->base_uri.$this->groupdav->path).' + HTTP/1.1 507 Insufficient Storage + + +'; + if ($this->groupdav->crrnd) + { + $error = str_replace(array('get_sync_token($path, $user, $this->sync_collection_token); }