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

Revision 3733, 5.5 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* We support both LOCK and UNLOCK methods in this function
4*/
5
6require_once('XMLDocument.php');
7$reply = new XMLDocument(array( 'DAV:' => '' ));
8
9if ( ! $request->AllowedTo('write') ) {
10  $request->NeedPrivilege( 'write', $request->path );
11}
12
13if ( ! isset($request->xml_tags) ) {
14  if ( isset($request->lock_token) ) {
15    // It's OK for LOCK refresh requests to be empty.
16    $request->xml_tags = array();
17  }
18  else {
19    $request->XMLResponse( 400, new XMLElement( 'error', new XMLElement('missing-xml-for-request'), $reply->GetXmlNsArray() ) );
20  }
21}
22
23
24$unsupported = array();
25$lockinfo = array();
26$inside = array();
27
28foreach( $request->xml_tags AS $k => $v ) {
29
30  $tag = $v['tag'];
31  dbg_error_log( "LOCK", " Handling Tag '%s' => '%s' ", $k, $v );
32  switch ( $tag ) {
33    case 'DAV::lockinfo':
34      dbg_error_log( "LOCK", ":Request: %s -> %s", $v['type'], $tag );
35      if ( $v['type'] == "open" ) {
36        $lockscope = "";
37        $locktype = "";
38        $lockowner = "";
39        $inside[$tag] = true;
40      }
41      else if ( $inside[$tag] && $v['type'] == "close" ) {
42        $lockinfo['scope']  = $lockscope;   unset($lockscope);
43        $lockinfo['type']   = $locktype;    unset($locktype);
44        $lockinfo['owner']  = $lockowner;   unset($lockowner);
45        $inside[$tag] = false;
46      }
47      break;
48
49    case 'DAV::owner':
50    case 'DAV::locktype':
51    case 'DAV::lockscope':
52      dbg_error_log( "LOCK", ":Request: %s -> %s", $v['type'], $tag );
53      if ( $inside['DAV::lockinfo'] ) {
54        if ( $v['type'] == "open" ) {
55          $inside[$tag] = true;
56        }
57        else if ( $inside[$tag] && $v['type'] == "close" ) {
58          $inside[$tag] = false;
59        }
60      }
61      break;
62
63    /*case 'DAV::SHARED': */ /** Shared lock is not supported yet */
64    case 'DAV::exclusive':
65      dbg_error_log( "LOCK", ":Request: %s -> %s", $v['type'], $tag );
66      if ( $inside['DAV::lockscope'] && $v['type'] == "complete" ) {
67        $lockscope = strtolower(substr($tag,5));
68      }
69      break;
70
71    /* case 'DAV::READ': */ /** RFC2518 is pretty vague about read locks */
72    case 'DAV::write':
73      dbg_error_log( "LOCK", ":Request: %s -> %s", $v['type'], $tag );
74      if ( $inside['DAV::locktype'] && $v['type'] == "complete" ) {
75        $locktype = strtolower(substr($tag,5));
76      }
77      break;
78
79    case 'DAV::href':
80      dbg_error_log( "LOCK", ":Request: %s -> %s", $v['type'], $tag );
81      dbg_log_array( "LOCK", "DAV:href", $v, true );
82      if ( $inside['DAV::owner'] && $v['type'] == "complete" ) {
83        $lockowner = $v['value'];
84      }
85      break;
86
87    default:
88      if ( preg_match('/^(.*):([^:]+)$/', $tag, $matches) ) {
89        $unsupported[$matches[2]] = $matches[1];
90      }
91      else {
92        $unsupported[$tag] = "";
93      }
94      dbg_error_log( "LOCK", "Unhandled tag >>%s<<", $tag);
95  }
96}
97
98
99
100
101$request->UnsupportedRequest($unsupported); // Won't return if there was unsupported stuff.
102
103$lock_opener = $request->FailIfLocked();
104
105
106if ( $request->method == "LOCK" ) {
107  dbg_error_log( "LOCK", "Attempting to lock resource '%s'", $request->path);
108  if ( ($lock_token = $request->IsLocked()) ) { // NOTE Assignment in if() is expected here.
109    $sql = 'UPDATE locks SET start = current_timestamp WHERE opaquelocktoken = :lock_token';
110    $params = array( ':lock_token' => $lock_token);
111  }
112  else {
113    /**
114    * A fresh lock
115    */
116    $lock_token = uuid();
117    $sql = 'INSERT INTO locks ( dav_name, opaquelocktoken, type, scope, depth, owner, timeout, start )
118             VALUES( :dav_name, :lock_token, :type, :scope, :request_depth, :owner, :timeout::interval, current_timestamp )';
119    $params = array(
120        ':dav_name'      => $request->path,
121        ':lock_token'    => $lock_token,
122        ':type'          => $lockinfo['type'],
123        ':scope'         => $lockinfo['scope'],
124        ':request_depth' => $request->depth,
125        ':owner'         => $lockinfo['owner'],
126        ':timeout'       => $request->timeout.' seconds'
127    );
128    header( "Lock-Token: <opaquelocktoken:$lock_token>" );
129  }
130  $qry = new AwlQuery($sql, $params  );
131  $qry->Exec("LOCK",__LINE__,__FILE__);
132
133  $lock_row = $request->GetLockRow($lock_token);
134  $activelock = array(
135      new XMLElement( 'locktype',  new XMLElement( $lock_row->type )),
136      new XMLElement( 'lockscope', new XMLElement( $lock_row->scope )),
137      new XMLElement( 'depth',     $request->GetDepthName() ),
138      new XMLElement( 'owner',     new XMLElement( 'href', $lock_row->owner )),
139      new XMLElement( 'timeout',   'Second-'.$request->timeout),
140      new XMLElement( 'locktoken', new XMLElement( 'href', 'opaquelocktoken:'.$lock_token ))
141  );
142  $response = new XMLElement("lockdiscovery", new XMLElement( "activelock", $activelock), array("xmlns" => "DAV:") );
143}
144elseif (  $request->method == "UNLOCK" ) {
145  /**
146  * @TODO: respond with preconditionfailed(409,'lock-token-matches-request-uri') if
147  * there is no lock to be deleted.
148  */
149  dbg_error_log( "LOCK", "Attempting to unlock resource '%s'", $request->path);
150  if ( ($lock_token = $request->IsLocked()) ) { // NOTE Assignment in if() is expected here.
151    $sql = 'DELETE FROM locks WHERE opaquelocktoken = :lock_token';
152    $qry = new AwlQuery($sql, array( ':lock_token' => $lock_token) );
153    $qry->Exec("LOCK",__LINE__,__FILE__);
154  }
155  $request->DoResponse( 204 );
156}
157
158
159$prop = new XMLElement( "prop", $response, array('xmlns'=>'DAV:') );
160// dbg_log_array( "LOCK", "XML", $response, true );
161$xmldoc = $prop->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
162$request->DoResponse( 200, $xmldoc, 'text/xml; charset="utf-8"' );
163
Note: See TracBrowser for help on using the repository browser.