11 dbg_error_log(
"PUT",
"method handler");
13 require_once(
'DAVResource.php');
15 include_once(
'caldav-PUT-functions.php');
17 if ( ! ini_get(
'open_basedir') && (isset($c->dbg[
'ALL']) || (isset($c->dbg[
'put']) && $c->dbg[
'put'])) ) {
18 $fh = fopen(
'/var/log/davical/PUT.debug',
'w');
20 fwrite($fh,$request->raw_post);
25 $lock_opener = $request->FailIfLocked();
27 require_once(
'vcard.php');
28 $vcard =
new vCard( $request->raw_post );
29 $uid = $vcard->GetPValue(
'UID');
32 $vcard->AddProperty(
'UID',$uid);
36 $request->path = $request->dav_name() . $uid .
'.vcf';
38 if ( $dest->Exists() ) {
40 $vcard->AddProperty(
'UID',$uid);
41 $request->path = $request->dav_name() . $uid .
'.vcf';
43 if ( $dest->Exists() )
throw new Exception(
"Failed to generate unique segment name for add-member!");
50 $container = $dest->GetParentContainer();
51 if ( ! $dest->Exists() ) {
52 if ( $container->IsPrincipal() ) {
53 $request->PreconditionFailed(405,
'method-not-allowed',translate(
'A DAViCal principal collection may only contain collections'));
55 if ( ! $container->Exists() ) {
56 $request->PreconditionFailed( 409,
'collection-must-exist',translate(
'The destination collection does not exist') );
58 $container->NeedPrivilege(
'DAV::bind');
61 if ( $dest->IsCollection() ) {
62 if ( ! isset($c->readonly_webdav_collections) || $c->readonly_webdav_collections ) {
63 $request->PreconditionFailed(405,
'method-not-allowed',translate(
'You may not PUT to a collection URL'));
66 $dest->NeedPrivilege(
'DAV::write-content');
69 $request->CheckEtagMatch( $dest->Exists(), $dest->unique_tag() );
71 $user_no = $dest->GetProperty(
'user_no');
72 $collection_id = $container->GetProperty(
'collection_id');
74 $original_etag = md5($request->raw_post);
76 $uid = $vcard->GetPValue(
'UID');
79 $vcard->AddProperty(
'UID',$uid);
82 $last_modified = $vcard->GetPValue(
'REV');
83 if ( empty($last_modified) ) {
84 $last_modified = gmdate(
'Ymd\THis\Z' );
85 $vcard->AddProperty(
'REV',$last_modified);
87 elseif ( stripos($last_modified,
'TZ') ) {
89 $last_modified = str_replace(
'TZ',
'T000000Z',$last_modified);
90 $vcard->ClearProperties(
'REV');
91 $vcard->AddProperty(
'REV',$last_modified);
93 elseif( preg_match(
'{^(\d{8})(\d{6})Z?}', $last_modified, $matches) ) {
95 $last_modified = $matches[1] .
'T' . $matches[2] .
'Z';
96 $vcard->ClearProperties(
'REV');
97 $vcard->AddProperty(
'REV',$last_modified);
99 elseif( preg_match(
'{([0-9]{4})-([0-9]{2})-([0-9]{2}T)([0-9]{2}):([0-9]{2}):([0-9]{2})Z?}', $last_modified, $matches) ){
101 $last_modified = $matches[1] . $matches[2] .$matches[3] .$matches[4] .$matches[5]. $matches[6] .
'Z';
102 $vcard->ClearProperties(
'REV');
103 $vcard->AddProperty(
'REV', $last_modified);
105 elseif( !preg_match(
'{^\d{8}T\d{6}Z$}', $last_modified) ) {
107 $last_modified = gmdate(
'Ymd\THis\Z' );
108 $vcard->ClearProperties(
'REV');
109 $vcard->AddProperty(
'REV',$last_modified);
111 $rendered_card = $vcard->Render();
112 $etag = md5($rendered_card);
114 ':user_no' => $user_no,
115 ':dav_name' => $dest->bound_from(),
117 ':dav_data' => $rendered_card,
118 ':session_user' => $session->user_no,
119 ':modified' => $last_modified
122 if ($dest->IsCollection()) {
123 if ( $dest->IsPrincipal() || $dest->IsBinding() || !isset($c->readonly_webdav_collections) || $c->readonly_webdav_collections ==
true ) {
124 $request->DoResponse( 405 );
128 $appending = (isset($_GET[
'mode']) && $_GET[
'mode'] ==
'append' );
130 import_collection($request->raw_post, $request->user_no, $request->path,
true, $appending);
132 $request->DoResponse( 200 );
137 $qry =
new AwlQuery();
140 if ( $dest->Exists() ) {
141 $sql =
'UPDATE caldav_data SET caldav_data=:dav_data, dav_etag=:etag, logged_user=:session_user,
142 modified=:modified, user_no=:user_no, caldav_type=\'VCARD\' WHERE dav_name=:dav_name';
143 $response_code = 200;
144 $put_action_type =
'UPDATE';
145 $qry->QDo( $sql, $params );
147 $qry->QDo(
"SELECT dav_id FROM caldav_data WHERE dav_name = :dav_name ", array(
':dav_name' => $params[
':dav_name']) );
150 $sql =
'INSERT INTO caldav_data ( user_no, dav_name, dav_etag, caldav_data, caldav_type, logged_user, created, modified, collection_id )
151 VALUES( :user_no, :dav_name, :etag, :dav_data, \'VCARD\', :session_user, current_timestamp, :modified, :collection_id )';
152 $params[
':collection_id'] = $collection_id;
153 $response_code = 201;
154 $qry->QDo( $sql, $params );
155 $put_action_type =
'INSERT';
157 $qry->QDo(
"SELECT currval('dav_id_seq') AS dav_id" );
159 $row = $qry->Fetch();
161 $vcard->Write( $row->dav_id, $dest->Exists() );
163 $qry->QDo(
"SELECT write_sync_change( $collection_id, $response_code, :dav_name)", array(
':dav_name' => $dest->bound_from() ) );
165 if ( function_exists(
'log_caldav_action') ) {
166 log_caldav_action( $put_action_type, $uid, $user_no, $collection_id, $request->path );
168 else if ( isset($log_action) && $log_action ) {
169 dbg_error_log(
'PUT',
'No log_caldav_action( %s, %s, %s, %s, %s) can be called.',
170 $put_action_type, $uid, $user_no, $collection_id, $request->path );
174 if ( !$qry->Commit() ) {
176 $request->DoResponse( 500,
"A database error occurred" );
180 $cache = getCacheInstance();
181 $cache->delete(
'collection-'.$container->dav_name(),
null );
183 if ( $add_member ) header(
'Location: '.$c->protocol_server_port_script.$request->path);
185 if ( $etag == $original_etag ) header(
'ETag: "'. $etag .
'"' );
186 if ( $response_code == 200 ) $response_code = 204;
187 $request->DoResponse( $response_code );