* @copyright Morphoss Ltd - http://www.morphoss.com/ * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later */ $responses = array(); /** * Build the array of properties to include in the report output */ $sync_tokens = $xmltree->GetPath('/DAV::sync-collection/DAV::sync-token'); $sync_token = $sync_tokens[0]->GetContent(); if ( !isset($sync_token) ) $sync_token = 0; $sync_token = intval($sync_token); dbg_error_log( 'sync', " sync-token: %s", $sync_token ); $props = $xmltree->GetElements('DAV::prop'); $v = $props[0]; $props = $v->GetContent(); $proplist = array(); foreach( $props AS $k => $v ) { $proplist[] = $v->GetTag(); } function display_status( $status_code ) { return sprintf( 'HTTP/1.1 %03d %s', intval($status_code), getStatusMessage($status_code) ); } $collection = new DAVResource( $request->path ); $params = array( ':collection_id' => $collection->GetProperty('collection_id'), ':sync_token' => $sync_token ); $sql = "SELECT new_sync_token( :sync_token, :collection_id)"; $qry = new AwlQuery($sql, $params); if ( !$qry->Exec("REPORT",__LINE__,__FILE__) || $qry->rows() <= 0 ) { $request->DoResponse( 500, translate("Database error") ); } $row = $qry->Fetch(); if ( !isset($row->new_sync_token) ) { /** If we got a null back then they gave us a sync token we know not of, so provide a full sync */ $sync_token =0; $params[':sync_token'] = $sync_token; if ( !$qry->QDo($sql, $params) || $qry->rows() <= 0 ) { $request->DoResponse( 500, translate("Database error") ); } $row = $qry->Fetch(); } $new_token = $row->new_sync_token; if ( $sync_token == 0 ) { $sql = << (SELECT modification_time FROM sync_tokens WHERE sync_token = :sync_token) ORDER BY collection.collection_id, sync_changes.dav_name, sync_changes.sync_time EOSQL; } $qry = new AwlQuery($sql, $params ); $last_dav_name = ''; $first_status = 0; if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) { while( $object = $qry->Fetch() ) { if ( $object->dav_name == $last_dav_name ) { /** The complex case: this is the second or subsequent for this dav_id */ if ( $object->sync_status == 404 ) { 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 if ( $object->sync_status == 201 && $first_status == 404 ) { // ... Delete ... Create ... is indicated as a create, but don't forget we started with a delete 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 ); } /** 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,$reply) ); } $response_tag = 'response'; if ( isset($c->use_old_sync_response_tag) && $c->use_old_sync_response_tag ) $response_tag = 'sync-response'; $responses[] = new XMLElement( $response_tag, $resultset ); $first_status = $object->sync_status; $last_dav_name = $object->dav_name; } } $responses[] = new XMLElement( 'sync-token', $new_token ); } else { $request->DoResponse( 500, translate("Database error") ); } $multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() ); $request->XMLResponse( 207, $multistatus );