diff --git a/inc/caldav-REPORT-sync-collection.php b/inc/caldav-REPORT-sync-collection.php index 2e641867..d32126fa 100644 --- a/inc/caldav-REPORT-sync-collection.php +++ b/inc/caldav-REPORT-sync-collection.php @@ -1,4 +1,14 @@ +* @copyright Morphoss Ltd - http://www.morphoss.com/ +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later +*/ + require("DAVResource.php"); $responses = array(); @@ -23,7 +33,7 @@ foreach( $props AS $k => $v ) { function display_status( $status_code ) { return sprintf( 'HTTP/1.1 %03d %s', intval($status_code), getStatusMessage($status_code) ); } - + $sql = "SELECT new_sync_token(?,?)"; $qry = new PgQuery($sql, $sync_token, $request->CollectionId()); if ( !$qry->Exec("REPORT",__LINE__,__FILE__) || $qry->rows <= 0 ) { @@ -38,31 +48,67 @@ SELECT *, 201 AS sync_status FROM collection LEFT JOIN caldav_data USING (collection_id) LEFT JOIN calendar_item USING (dav_id) WHERE collection.collection_id = ? + ORDER BY collection.collection_id, caldav_data.dav_id EOSQL; $qry = new PgQuery($sql, $request->CollectionId()); } else { $sql = << (SELECT modification_time FROM sync_tokens WHERE sync_token = ?) + AND sync_time > (SELECT modification_time FROM sync_tokens WHERE sync_token = ?) + ORDER BY collection.collection_id, sync_changes.dav_id, sync_changes.sync_time EOSQL; $qry = new PgQuery($sql, $request->CollectionId(), $sync_token); } +$last_dav_id = -1; +$first_status = 0; + if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) { while( $object = $qry->Fetch() ) { - $resultset = array( - new XMLElement( 'href', ConstructURL($object->dav_name) ), - new XMLElement( 'status', display_status($object->sync_status) ) - ); - if ( $status != 404 ) { - $dav_resource = new DAVResource($object); - $resultset = array_merge( $resultset, $dav_resource->GetPropStat($proplist) ); - } - $responses[] = new XMLElement( 'sync-response', $resultset ); + if ( $object->dav_id == $last_dav_id ) { + /** The complex case: this is the second or subsequent for this dav_id */ + if ( $object->sync_status == 404 ) { + if ( $first_action == 201 ) { + array_pop($responses); + $last_dav_id = -1; + $first_status = 0; + } + else { + array_pop($responses); + $resultset = array( + new XMLElement( 'href', ConstructURL($object->dav_name) ), + new XMLElement( 'status', display_status($object->sync_status) ) + ); + $responses[] = new XMLElement( 'sync-response', $resultset ); + $first_status = 404; + } + } + /** Else: + * the object existed at start and we have multiple modifications, + * or, + * the object didn't exist at start and we have subsequent modifications, + * but: + * in either case we simply stick with our first report. + */ + } + else { + /** The simple case: this is the first one for this dav_id */ + $resultset = array( + new XMLElement( 'href', ConstructURL($object->dav_name) ), + new XMLElement( 'status', display_status($object->sync_status) ) + ); + if ( $object->sync_status != 404 ) { + $dav_resource = new DAVResource($object); + $resultset = array_merge( $resultset, $dav_resource->GetPropStat($proplist) ); + } + $responses[] = new XMLElement( 'sync-response', $resultset ); + $first_status = $object->sync_status; + $last_dav_id = $object->dav_id; + } } $responses[] = new XMLElement( 'sync-token', $new_token ); }