source: contrib/davical/inc/caldav-REPORT-sync-collection.php @ 3733

Revision 3733, 5.2 KB checked in by gabriel.malheiros, 13 years ago (diff)

Ticket #1541 - <Davical customizado para o Expresso.Utiliza Caldav e CardDav?>

Line 
1<?php
2/**
3* CalDAV Server - handle sync-collection report (draft-daboo-webdav-sync-01)
4*
5* @package   davical
6* @subpackage   caldav
7* @author    Andrew McMillan <andrew@mcmillan.net.nz>
8* @copyright Morphoss Ltd - http://www.morphoss.com/
9* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
10*/
11
12$responses = array();
13
14/**
15 * Build the array of properties to include in the report output
16 */
17$sync_tokens = $xmltree->GetPath('/DAV::sync-collection/DAV::sync-token');
18$sync_token = $sync_tokens[0]->GetContent();
19if ( !isset($sync_token) ) $sync_token = 0;
20$sync_token = intval($sync_token);
21dbg_error_log( 'sync', " sync-token: %s", $sync_token );
22
23
24$props = $xmltree->GetElements('DAV::prop');
25$v = $props[0];
26$props = $v->GetContent();
27$proplist = array();
28foreach( $props AS $k => $v ) {
29  $proplist[] = $v->GetTag();
30}
31
32function display_status( $status_code ) {
33  return sprintf( 'HTTP/1.1 %03d %s', intval($status_code), getStatusMessage($status_code) );
34}
35
36$collection = new DAVResource( $request->path );
37
38$params = array( ':collection_id' => $collection->GetProperty('collection_id'), ':sync_token' => $sync_token );
39$sql = "SELECT new_sync_token( :sync_token, :collection_id)";
40$qry = new AwlQuery($sql, $params);
41if ( !$qry->Exec("REPORT",__LINE__,__FILE__) || $qry->rows() <= 0 ) {
42  $request->DoResponse( 500, translate("Database error") );
43}
44$row = $qry->Fetch();
45
46if ( !isset($row->new_sync_token) ) {
47  /** If we got a null back then they gave us a sync token we know not of, so provide a full sync */
48  $sync_token =0;
49  $params[':sync_token'] = $sync_token;
50  if ( !$qry->QDo($sql, $params) || $qry->rows() <= 0 ) {
51    $request->DoResponse( 500, translate("Database error") );
52  }
53  $row = $qry->Fetch();
54}
55$new_token = $row->new_sync_token;
56
57if ( $sync_token == 0 ) {
58  $sql = <<<EOSQL
59SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, 201 AS sync_status FROM collection
60            LEFT JOIN caldav_data USING (collection_id)
61            LEFT JOIN calendar_item USING (dav_id)
62                         LEFT JOIN addressbook_resource USING (dav_id)
63            WHERE collection.collection_id = :collection_id
64   ORDER BY collection.collection_id, caldav_data.dav_id
65EOSQL;
66  unset($params[':sync_token']);
67}
68else {
69  $sql = <<<EOSQL
70SELECT collection.*, calendar_item.*, caldav_data.*, addressbook_resource.*, sync_changes.*
71  FROM collection LEFT JOIN sync_changes USING(collection_id)
72                         LEFT JOIN caldav_data USING (collection_id,dav_id)
73                         LEFT JOIN calendar_item USING (collection_id,dav_id)
74                         LEFT JOIN addressbook_resource USING (dav_id)
75                         WHERE collection.collection_id = :collection_id
76       AND sync_time > (SELECT modification_time FROM sync_tokens WHERE sync_token = :sync_token)
77   ORDER BY collection.collection_id, sync_changes.dav_name, sync_changes.sync_time
78EOSQL;
79}
80$qry = new AwlQuery($sql, $params );
81
82$last_dav_name = '';
83$first_status = 0;
84
85if ( $qry->Exec("REPORT",__LINE__,__FILE__) ) {
86  while( $object = $qry->Fetch() ) {
87    if ( $object->dav_name == $last_dav_name ) {
88      /** The complex case: this is the second or subsequent for this dav_id */
89      if ( $object->sync_status == 404 ) {
90        array_pop($responses);
91        $resultset = array(
92          new XMLElement( 'href', ConstructURL($object->dav_name) ),
93          new XMLElement( 'status', display_status($object->sync_status) )
94        );
95        $responses[] = new XMLElement( 'sync-response', $resultset );
96        $first_status = 404;
97      }
98      else if ( $object->sync_status == 201 && $first_status == 404 ) {
99        // ... Delete ... Create ... is indicated as a create, but don't forget we started with a delete
100        array_pop($responses);
101        $resultset = array(
102          new XMLElement( 'href', ConstructURL($object->dav_name) ),
103          new XMLElement( 'status', display_status($object->sync_status) )
104        );
105        $responses[] = new XMLElement( 'sync-response', $resultset );
106      }
107      /** Else:
108       *    the object existed at start and we have multiple modifications,
109       *  or,
110       *    the object didn't exist at start and we have subsequent modifications,
111       *  but:
112       *    in either case we simply stick with our first report.
113       */
114    }
115    else {
116      /** The simple case: this is the first one for this dav_id */
117      $resultset = array(
118        new XMLElement( 'href', ConstructURL($object->dav_name) ),
119        new XMLElement( 'status', display_status($object->sync_status) )
120      );
121      if ( $object->sync_status != 404 ) {
122        $dav_resource = new DAVResource($object);
123        $resultset = array_merge( $resultset, $dav_resource->GetPropStat($proplist,$reply) );
124      }
125      $response_tag = 'response';
126      if ( isset($c->use_old_sync_response_tag) && $c->use_old_sync_response_tag ) $response_tag = 'sync-response';
127      $responses[] = new XMLElement( $response_tag, $resultset );
128      $first_status = $object->sync_status;
129      $last_dav_name  = $object->dav_name;
130    }
131  }
132  $responses[] = new XMLElement( 'sync-token', $new_token );
133}
134else {
135  $request->DoResponse( 500, translate("Database error") );
136}
137
138$multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() );
139
140$request->XMLResponse( 207, $multistatus );
Note: See TracBrowser for help on using the repository browser.