source: contrib/davical/inc/caldav-MOVE.php @ 3733

Revision 3733, 5.9 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 MOVE method
4*
5* @package   davical
6* @subpackage   caldav
7* @author    Andrew McMillan <andrew@morphoss.com>
8* @copyright Morphoss Ltd
9* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2
10*/
11dbg_error_log("MOVE", "method handler");
12
13require_once('DAVResource.php');
14
15$request->NeedPrivilege('DAV::unbind');
16
17if ( ! ini_get('open_basedir') && (isset($c->dbg['ALL']) || (isset($c->dbg['move']) && $c->dbg['move'])) ) {
18  $fh = fopen('/tmp/MOVE.txt','w');
19  if ( $fh ) {
20    fwrite($fh,$request->raw_post);
21    fclose($fh);
22  }
23}
24
25$lock_opener = $request->FailIfLocked();
26
27$dest = new DAVResource($request->destination);
28
29if ( $dest->dav_name() == '/' || $dest->IsPrincipal() ) {
30  $dest->NeedPrivilege('DAV::bind');
31}
32
33if ( ! $dest->ContainerExists() ) {
34  $request->DoResponse( 409, translate('Destination collection does not exist') );
35}
36
37if ( ! $request->overwrite && $dest->Exists() ) {
38  $request->DoResponse( 412, translate('Not overwriting existing destination resource') );
39}
40
41if ( isset($request->etag_none_match) && $request->etag_none_match != '*' ) {
42  $request->DoResponse( 412 );  /** request to move, but only if there is no source? WTF! */
43}
44
45$src  = new DAVResource($request->path);
46if ( ! $src->Exists() ) {
47  $request->DoResponse( 412, translate('Source resource does not exist.') );
48}
49
50if ( $src->IsCollection() ) {
51  switch( $dest->ContainerType() ) {
52    case 'calendar':
53    case 'addressbook':
54    case 'schedule-inbox':
55    case 'schedule-outbox':
56      $request->DoResponse( 412, translate('Special collections may not contain a calendar or other special collection.') );
57  };
58}
59else {
60  if ( (isset($request->etag_if_match) && $request->etag_if_match != '' )
61        || ( isset($request->etag_none_match) && $request->etag_none_match != '') ) {
62
63    /**
64    * RFC2068, 14.25:
65    * If none of the entity tags match, or if "*" is given and no current
66    * entity exists, the server MUST NOT perform the requested method, and
67    * MUST return a 412 (Precondition Failed) response.
68    *
69    * RFC2068, 14.26:
70    * If any of the entity tags match the entity tag of the entity that
71    * would have been returned in the response to a similar GET request
72    * (without the If-None-Match header) on that resource, or if "*" is
73    * given and any current entity exists for that resource, then the
74    * server MUST NOT perform the requested method.
75    */
76    $error = '';
77    if ( isset($request->etag_if_match) && $request->etag_if_match != $src->unique_tag() ) {
78      $error = translate( 'Existing resource does not match "If-Match" header - not accepted.');
79    }
80    else if ( isset($request->etag_none_match) && $request->etag_none_match != '' && $request->etag_none_match == $src->unique_tag() ) {
81      $error = translate( 'Existing resource matches "If-None-Match" header - not accepted.');
82    }
83    if ( $error != '' ) $request->DoResponse( 412, $error );
84  }
85}
86
87$src->NeedPrivilege('DAV::unbind');
88$dest->NeedPrivilege('DAV::write-content');
89if ( ! $dest->Exists() ) $dest->NeedPrivilege('DAV::bind');
90
91
92function rollback( $response_code = 412 ) {
93  global $request;
94  $qry = new AwlQuery('ROLLBACK');
95  $qry->Exec('move'); // Just in case
96  $request->DoResponse( $response_code );
97  // And we don't return from that.
98}
99
100
101$qry = new AwlQuery('BEGIN');
102if ( !$qry->Exec('move') ) rollback(500);
103
104$src_name = $src->dav_name();
105$dst_name = $dest->dav_name();
106$src_collection = $src->GetProperty('collection_id');
107$dst_collection = $dest->GetProperty('collection_id');
108$src_user_no = $src->GetProperty('user_no');
109$dst_user_no = $dest->GetProperty('user_no');
110
111
112if ( $src->IsCollection()  ) {
113  if ( $dest->Exists() ) {
114    $qry = new AwlQuery( 'DELETE FROM collection WHERE dav_name = :dst_name', array( ':dst_name' => $dst_name ) );
115    if ( !$qry->Exec('move') ) rollback(500);
116  }
117  /** @TODO: Need to confirm this will work correctly if we move this into another user's hierarchy. */
118  $sql = 'UPDATE collection SET dav_name = :dst_name ';
119  $params = array(':dst_name' => $dst_name);
120  if ( $src_user_no != $dst_user_no ) {
121    $sql .= ', user_no = :dst_user_no ';
122    $params[':dst_user_no'] = $dst_user_no;
123  }
124  $sql .= 'WHERE collection_id = :src_collection';
125  $params[':src_collection'] = $src_collection;
126  $qry = new AwlQuery( $sql, $params );
127  if ( !$qry->Exec('move') ) rollback(500);
128}
129else {
130  if ( $dest->Exists() ) {
131    $qry = new AwlQuery( 'DELETE FROM caldav_data WHERE dav_name = :dst_name', array( ':dst_name' => $dst_name) );
132    if ( !$qry->Exec('move') ) rollback(500);
133  }
134  $sql = 'UPDATE caldav_data SET dav_name = :dst_name';
135  $params = array( ':dst_name' => $dst_name );
136  if ( $src_user_no != $dst_user_no ) {
137    $sql .= ', user_no = :dst_user_no';
138    $params[':dst_user_no'] = $dst_user_no;
139  }
140  if ( $src_collection != $dst_collection ) {
141    $sql .= ', collection_id = :dst_collection';
142    $params[':dst_collection'] = $dst_collection;
143  }
144  $sql .=' WHERE dav_name = :src_name';
145  $params[':src_name'] = $src_name;
146  $qry = new AwlQuery( $sql, $params );
147  if ( !$qry->Exec('move') ) rollback(500);
148
149  $qry = new AwlQuery( 'SELECT write_sync_change( :src_collection, 404, :src_name );', array(
150    ':src_name' => $src_name,
151    ':src_collection' => $src_collection
152  ) );
153  if ( !$qry->Exec('move') ) rollback(500);
154  if ( function_exists('log_caldav_action') ) {
155    log_caldav_action( 'DELETE', $src->GetProperty('uid'), $src_user_no, $src_collection, $src_name );
156  }
157
158  $qry = new AwlQuery( 'SELECT write_sync_change( :dst_collection, :sync_type, :dst_name );', array(
159    ':dst_name' => $dst_name,
160    ':dst_collection' => $dst_collection,
161    ':sync_type' => ( $dest->Exists() ? 200 : 201 )
162  ) );
163  if ( !$qry->Exec('move') ) rollback(500);
164  if ( function_exists('log_caldav_action') ) {
165    log_caldav_action( ( $dest->Exists() ? 'UPDATE' : 'INSERT' ), $src->GetProperty('uid'), $dst_user_no, $dst_collection, $dst_name );
166  }
167
168}
169
170$qry = new AwlQuery('COMMIT');
171if ( !$qry->Exec('move') ) rollback(500);
172
173$request->DoResponse( 200 );
Note: See TracBrowser for help on using the repository browser.