* CalDAV/CardDAV: fixed support for limited sync-collection report used eg. by Marten Gajdas Android apps

This commit is contained in:
Ralf Becker 2014-02-20 17:46:15 +00:00
parent 5949016faa
commit a9b6c6e9b4
6 changed files with 39 additions and 3 deletions

View File

@ -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

View File

@ -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'];
}

View File

@ -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']);

View File

@ -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))
{

View File

@ -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
{

View File

@ -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 =
' <D:response>
<D:href>'.htmlspecialchars($this->groupdav->base_uri.$this->groupdav->path).'</D:href>
<D:status>HTTP/1.1 507 Insufficient Storage</D:status>
<D:error><D:number-of-matches-within-limits/></D:error>
</D:response>
';
if ($this->groupdav->crrnd)
{
$error = str_replace(array('<D:', '</D:'), array('<', '</'), $error);
}
echo $error;
}
return $this->get_sync_token($path, $user, $this->sync_collection_token);
}