Completed
Push — developer ( 02a7a3...2908cf )
by Błażej
84:08 queued 41:50
created
libraries/nusoap/nusoapmime.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -447,7 +447,7 @@
 block discarded – undo
447 447
 	*
448 448
 	* @param	array	$headers	The HTTP headers
449 449
 	* @param	string	$data		unprocessed request data from client
450
-	* @return	mixed	value of the message, decoded into a PHP type
450
+	* @return	false|null	value of the message, decoded into a PHP type
451 451
 	* @access   private
452 452
 	*/
453 453
     function parseRequest($headers, $data) {
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
 	* @access public
87 87
 	*/
88 88
 	public function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
89
-		if (! $cid) {
89
+		if (!$cid) {
90 90
 			$cid = md5(uniqid(time()));
91 91
 		}
92 92
 
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 	* @access public
317 317
 	*/
318 318
 	public function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
319
-		if (! $cid) {
319
+		if (!$cid) {
320 320
 			$cid = md5(uniqid(time()));
321 321
 		}
322 322
 
Please login to merge, or discard this patch.
Indentation   +112 added lines, -112 removed lines patch added patch discarded remove patch
@@ -71,20 +71,20 @@  discard block
 block discarded – undo
71 71
 	var $mimeContentType;
72 72
 	
73 73
 	/**
74
-	* adds a MIME attachment to the current request.
75
-	*
76
-	* If the $data parameter contains an empty string, this method will read
77
-	* the contents of the file named by the $filename parameter.
78
-	*
79
-	* If the $cid parameter is false, this method will generate the cid.
80
-	*
81
-	* @param string $data The data of the attachment
82
-	* @param string $filename The filename of the attachment (default is empty string)
83
-	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
84
-	* @param string $cid The content-id (cid) of the attachment (default is false)
85
-	* @return string The content-id (cid) of the attachment
86
-	* @access public
87
-	*/
74
+	 * adds a MIME attachment to the current request.
75
+	 *
76
+	 * If the $data parameter contains an empty string, this method will read
77
+	 * the contents of the file named by the $filename parameter.
78
+	 *
79
+	 * If the $cid parameter is false, this method will generate the cid.
80
+	 *
81
+	 * @param string $data The data of the attachment
82
+	 * @param string $filename The filename of the attachment (default is empty string)
83
+	 * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
84
+	 * @param string $cid The content-id (cid) of the attachment (default is false)
85
+	 * @return string The content-id (cid) of the attachment
86
+	 * @access public
87
+	 */
88 88
 	public function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
89 89
 		if (! $cid) {
90 90
 			$cid = md5(uniqid(time()));
@@ -101,35 +101,35 @@  discard block
 block discarded – undo
101 101
 	}
102 102
 
103 103
 	/**
104
-	* clears the MIME attachments for the current request.
105
-	*
106
-	* @access public
107
-	*/
104
+	 * clears the MIME attachments for the current request.
105
+	 *
106
+	 * @access public
107
+	 */
108 108
 	public function clearAttachments() {
109 109
 		$this->requestAttachments = array();
110 110
 	}
111 111
 
112 112
 	/**
113
-	* gets the MIME attachments from the current response.
114
-	*
115
-	* Each array element in the return is an associative array with keys
116
-	* data, filename, contenttype, cid.  These keys correspond to the parameters
117
-	* for addAttachment.
118
-	*
119
-	* @return array The attachments.
120
-	* @access public
121
-	*/
113
+	 * gets the MIME attachments from the current response.
114
+	 *
115
+	 * Each array element in the return is an associative array with keys
116
+	 * data, filename, contenttype, cid.  These keys correspond to the parameters
117
+	 * for addAttachment.
118
+	 *
119
+	 * @return array The attachments.
120
+	 * @access public
121
+	 */
122 122
 	public function getAttachments() {
123 123
 		return $this->responseAttachments;
124 124
 	}
125 125
 
126 126
 	/**
127
-	* gets the HTTP body for the current request.
128
-	*
129
-	* @param string $soapmsg The SOAP payload
130
-	* @return string The HTTP body, which includes the SOAP payload
131
-	* @access private
132
-	*/
127
+	 * gets the HTTP body for the current request.
128
+	 *
129
+	 * @param string $soapmsg The SOAP payload
130
+	 * @return string The HTTP body, which includes the SOAP payload
131
+	 * @access private
132
+	 */
133 133
 	public function getHTTPBody($soapmsg) {
134 134
 		if (count($this->requestAttachments) > 0) {
135 135
 			$params['content_type'] = 'multipart/related; type="text/xml"';
@@ -182,13 +182,13 @@  discard block
 block discarded – undo
182 182
 	}
183 183
 	
184 184
 	/**
185
-	* gets the HTTP content type for the current request.
186
-	*
187
-	* Note: getHTTPBody must be called before this.
188
-	*
189
-	* @return string the HTTP content type for the current request.
190
-	* @access private
191
-	*/
185
+	 * gets the HTTP content type for the current request.
186
+	 *
187
+	 * Note: getHTTPBody must be called before this.
188
+	 *
189
+	 * @return string the HTTP content type for the current request.
190
+	 * @access private
191
+	 */
192 192
 	public function getHTTPContentType() {
193 193
 		if (count($this->requestAttachments) > 0) {
194 194
 			return $this->mimeContentType;
@@ -197,14 +197,14 @@  discard block
 block discarded – undo
197 197
 	}
198 198
 	
199 199
 	/**
200
-	* gets the HTTP content type charset for the current request.
201
-	* returns false for non-text content types.
202
-	*
203
-	* Note: getHTTPBody must be called before this.
204
-	*
205
-	* @return string the HTTP content type charset for the current request.
206
-	* @access private
207
-	*/
200
+	 * gets the HTTP content type charset for the current request.
201
+	 * returns false for non-text content types.
202
+	 *
203
+	 * Note: getHTTPBody must be called before this.
204
+	 *
205
+	 * @return string the HTTP content type charset for the current request.
206
+	 * @access private
207
+	 */
208 208
 	public function getHTTPContentTypeCharset() {
209 209
 		if (count($this->requestAttachments) > 0) {
210 210
 			return false;
@@ -213,14 +213,14 @@  discard block
 block discarded – undo
213 213
 	}
214 214
 
215 215
 	/**
216
-	* processes SOAP message returned from server
217
-	*
218
-	* @param	array	$headers	The HTTP headers
219
-	* @param	string	$data		unprocessed response data from server
220
-	* @return	mixed	value of the message, decoded into a PHP type
221
-	* @access   private
222
-	*/
223
-    public function parseResponse($headers, $data) {
216
+	 * processes SOAP message returned from server
217
+	 *
218
+	 * @param	array	$headers	The HTTP headers
219
+	 * @param	string	$data		unprocessed response data from server
220
+	 * @return	mixed	value of the message, decoded into a PHP type
221
+	 * @access   private
222
+	 */
223
+	public function parseResponse($headers, $data) {
224 224
 		$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
225 225
 		$this->responseAttachments = array();
226 226
 		if (strstr($headers['content-type'], 'multipart/related')) {
@@ -301,20 +301,20 @@  discard block
 block discarded – undo
301 301
 	var $mimeContentType;
302 302
 	
303 303
 	/**
304
-	* adds a MIME attachment to the current response.
305
-	*
306
-	* If the $data parameter contains an empty string, this method will read
307
-	* the contents of the file named by the $filename parameter.
308
-	*
309
-	* If the $cid parameter is false, this method will generate the cid.
310
-	*
311
-	* @param string $data The data of the attachment
312
-	* @param string $filename The filename of the attachment (default is empty string)
313
-	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
314
-	* @param string $cid The content-id (cid) of the attachment (default is false)
315
-	* @return string The content-id (cid) of the attachment
316
-	* @access public
317
-	*/
304
+	 * adds a MIME attachment to the current response.
305
+	 *
306
+	 * If the $data parameter contains an empty string, this method will read
307
+	 * the contents of the file named by the $filename parameter.
308
+	 *
309
+	 * If the $cid parameter is false, this method will generate the cid.
310
+	 *
311
+	 * @param string $data The data of the attachment
312
+	 * @param string $filename The filename of the attachment (default is empty string)
313
+	 * @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
314
+	 * @param string $cid The content-id (cid) of the attachment (default is false)
315
+	 * @return string The content-id (cid) of the attachment
316
+	 * @access public
317
+	 */
318 318
 	public function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
319 319
 		if (! $cid) {
320 320
 			$cid = md5(uniqid(time()));
@@ -331,35 +331,35 @@  discard block
 block discarded – undo
331 331
 	}
332 332
 
333 333
 	/**
334
-	* clears the MIME attachments for the current response.
335
-	*
336
-	* @access public
337
-	*/
334
+	 * clears the MIME attachments for the current response.
335
+	 *
336
+	 * @access public
337
+	 */
338 338
 	public function clearAttachments() {
339 339
 		$this->responseAttachments = array();
340 340
 	}
341 341
 
342 342
 	/**
343
-	* gets the MIME attachments from the current request.
344
-	*
345
-	* Each array element in the return is an associative array with keys
346
-	* data, filename, contenttype, cid.  These keys correspond to the parameters
347
-	* for addAttachment.
348
-	*
349
-	* @return array The attachments.
350
-	* @access public
351
-	*/
343
+	 * gets the MIME attachments from the current request.
344
+	 *
345
+	 * Each array element in the return is an associative array with keys
346
+	 * data, filename, contenttype, cid.  These keys correspond to the parameters
347
+	 * for addAttachment.
348
+	 *
349
+	 * @return array The attachments.
350
+	 * @access public
351
+	 */
352 352
 	public function getAttachments() {
353 353
 		return $this->requestAttachments;
354 354
 	}
355 355
 
356 356
 	/**
357
-	* gets the HTTP body for the current response.
358
-	*
359
-	* @param string $soapmsg The SOAP payload
360
-	* @return string The HTTP body, which includes the SOAP payload
361
-	* @access private
362
-	*/
357
+	 * gets the HTTP body for the current response.
358
+	 *
359
+	 * @param string $soapmsg The SOAP payload
360
+	 * @return string The HTTP body, which includes the SOAP payload
361
+	 * @access private
362
+	 */
363 363
 	public function getHTTPBody($soapmsg) {
364 364
 		if (count($this->responseAttachments) > 0) {
365 365
 			$params['content_type'] = 'multipart/related; type="text/xml"';
@@ -412,13 +412,13 @@  discard block
 block discarded – undo
412 412
 	}
413 413
 	
414 414
 	/**
415
-	* gets the HTTP content type for the current response.
416
-	*
417
-	* Note: getHTTPBody must be called before this.
418
-	*
419
-	* @return string the HTTP content type for the current response.
420
-	* @access private
421
-	*/
415
+	 * gets the HTTP content type for the current response.
416
+	 *
417
+	 * Note: getHTTPBody must be called before this.
418
+	 *
419
+	 * @return string the HTTP content type for the current response.
420
+	 * @access private
421
+	 */
422 422
 	public function getHTTPContentType() {
423 423
 		if (count($this->responseAttachments) > 0) {
424 424
 			return $this->mimeContentType;
@@ -427,14 +427,14 @@  discard block
 block discarded – undo
427 427
 	}
428 428
 	
429 429
 	/**
430
-	* gets the HTTP content type charset for the current response.
431
-	* returns false for non-text content types.
432
-	*
433
-	* Note: getHTTPBody must be called before this.
434
-	*
435
-	* @return string the HTTP content type charset for the current response.
436
-	* @access private
437
-	*/
430
+	 * gets the HTTP content type charset for the current response.
431
+	 * returns false for non-text content types.
432
+	 *
433
+	 * Note: getHTTPBody must be called before this.
434
+	 *
435
+	 * @return string the HTTP content type charset for the current response.
436
+	 * @access private
437
+	 */
438 438
 	public function getHTTPContentTypeCharset() {
439 439
 		if (count($this->responseAttachments) > 0) {
440 440
 			return false;
@@ -443,14 +443,14 @@  discard block
 block discarded – undo
443 443
 	}
444 444
 
445 445
 	/**
446
-	* processes SOAP message received from client
447
-	*
448
-	* @param	array	$headers	The HTTP headers
449
-	* @param	string	$data		unprocessed request data from client
450
-	* @return	mixed	value of the message, decoded into a PHP type
451
-	* @access   private
452
-	*/
453
-    public function parseRequest($headers, $data) {
446
+	 * processes SOAP message received from client
447
+	 *
448
+	 * @param	array	$headers	The HTTP headers
449
+	 * @param	string	$data		unprocessed request data from client
450
+	 * @return	mixed	value of the message, decoded into a PHP type
451
+	 * @access   private
452
+	 */
453
+	public function parseRequest($headers, $data) {
454 454
 		$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
455 455
 		$this->requestAttachments = array();
456 456
 		if (strstr($headers['content-type'], 'multipart/related')) {
Please login to merge, or discard this patch.
libraries/restler/restler.php 4 patches
Doc Comments   +21 added lines, -4 removed lines patch added patch discarded remove patch
@@ -268,9 +268,9 @@  discard block
 block discarded – undo
268 268
      *
269 269
      * All the protected methods that do not start with _ (underscore)
270 270
      * will exposed as protected api which will require authentication
271
-     * @param string $class name of the service class
272
-     * @param string $basePath optional url prefix for mapping, uses
271
+     * @param string $base_path optional url prefix for mapping, uses
273 272
      * lowercase version of the class name when not specified
273
+     * @param string $class_name
274 274
      * @throws Exception when supplied with invalid class name
275 275
      */
276 276
     public function addAPIClass($class_name, $base_path = null)
@@ -322,8 +322,8 @@  discard block
 block discarded – undo
322 322
 
323 323
     /**
324 324
      * Convenience method to respond with an error message
325
-     * @param int $statusCode http error code
326
-     * @param string $errorMessage optional custom error message
325
+     * @param int $status_code http error code
326
+     * @param string $error_message optional custom error message
327 327
      */
328 328
     public function handleError($status_code, $error_message = null)
329 329
     {
@@ -916,6 +916,10 @@  discard block
 block discarded – undo
916 916
 {
917 917
 
918 918
 
919
+    /**
920
+     * @param integer $http_status_code
921
+     * @param string $error_message
922
+     */
919 923
     public function __construct($http_status_code, $error_message = null)
920 924
     {
921 925
         parent::__construct($error_message, $http_status_code);
@@ -1033,12 +1037,14 @@  discard block
 block discarded – undo
1033 1037
     /**
1034 1038
      * Set the selected MIME type
1035 1039
      * @param string $mime MIME type
1040
+     * @return void
1036 1041
      */
1037 1042
     public function setMIME($mime);
1038 1043
 
1039 1044
 
1040 1045
     /**
1041 1046
      * Get selected MIME type
1047
+     * @return string
1042 1048
      */
1043 1049
     public function getMIME();
1044 1050
 
@@ -1046,6 +1052,7 @@  discard block
 block discarded – undo
1046 1052
     /**
1047 1053
      * Set the selected file extension
1048 1054
      * @param string $extension file extension
1055
+     * @return void
1049 1056
      */
1050 1057
     public function setExtension($extension);
1051 1058
 
@@ -1349,6 +1356,9 @@  discard block
 block discarded – undo
1349 1356
     }
1350 1357
 
1351 1358
 
1359
+    /**
1360
+     * @param string[] $lines
1361
+     */
1352 1362
     private function parseLines($lines)
1353 1363
     {
1354 1364
         foreach ($lines as $line) {
@@ -1398,6 +1408,10 @@  discard block
 block discarded – undo
1398 1408
     }
1399 1409
 
1400 1410
 
1411
+    /**
1412
+     * @param string $param
1413
+     * @param string $value
1414
+     */
1401 1415
     private function setParam($param, $value)
1402 1416
     {
1403 1417
         if ($param == 'param' || $param == 'return') {
@@ -1454,6 +1468,9 @@  discard block
 block discarded – undo
1454 1468
 //
1455 1469
 // ------------------------------------------------------------------
1456 1470
 
1471
+/**
1472
+ * @param string $php_doc_comment
1473
+ */
1457 1474
 function parse_doc($php_doc_comment)
1458 1475
 {
1459 1476
     $p = new DocParser();
Please login to merge, or discard this patch.
Spacing   +7 added lines, -11 removed lines patch added patch discarded remove patch
@@ -472,9 +472,9 @@  discard block
 block discarded – undo
472 472
         header('Content-Type: ' . $this->response_format->getMIME());
473 473
         //.'; charset=utf-8');
474 474
         header("X-Powered-By: Luracast Restler v" . Restler::VERSION);
475
-		if($this->production_mode){
475
+		if ($this->production_mode) {
476 476
 			die($data);
477
-		}else{
477
+		} else {
478 478
 			echo $data;
479 479
 		}
480 480
     }
@@ -649,8 +649,7 @@  discard block
 block discarded – undo
649 649
                 $parts = explode(';q=', trim($accept));
650 650
                 $type = array_shift($parts);
651 651
                 $quality = count($parts) ? 
652
-                    floatval(array_shift($parts)) : 
653
-                    (1000 - $pos) / 1000;
652
+                    floatval(array_shift($parts)) : (1000 - $pos) / 1000;
654 653
                 $acceptList[$type] = $quality;
655 654
             }
656 655
             arsort($acceptList);
@@ -839,8 +838,7 @@  discard block
 block discarded – undo
839 838
                 $position++;
840 839
             }
841 840
             $method_flag = $method->isProtected() ? 
842
-                (isRestlerCompatibilityModeEnabled() ? 2 : 3) : 
843
-                (isset($metadata['protected']) ? 1 : 0);
841
+                (isRestlerCompatibilityModeEnabled() ? 2 : 3) : (isset($metadata['protected']) ? 1 : 0);
844 842
 
845 843
             //take note of the order
846 844
             $call = array(
@@ -873,8 +871,7 @@  discard block
 block discarded – undo
873 871
                     $http_method = 'GET';
874 872
                 }
875 873
                 $url = $base_path
876
-                    . ($method_url == 'index' || $method_url == 'default' ? '' :
877
-                        $method_url);
874
+                    . ($method_url == 'index' || $method_url == 'default' ? '' : $method_url);
878 875
                 $url = rtrim($url, '/');
879 876
                 $this->routes[$http_method][$url] = $call;
880 877
                 foreach ($params as $param) {
@@ -1198,8 +1195,7 @@  discard block
 block discarded – undo
1198 1195
     public function encode($data, $human_readable = false)
1199 1196
     {
1200 1197
         return $human_readable ? 
1201
-            $this->json_format(json_encode(object_to_array($data))) : 
1202
-            json_encode(object_to_array($data));
1198
+            $this->json_format(json_encode(object_to_array($data))) : json_encode(object_to_array($data));
1203 1199
     }
1204 1200
 
1205 1201
 
@@ -1225,7 +1221,7 @@  discard block
 block discarded – undo
1225 1221
                     $message = 'malformed JSON';
1226 1222
                     break;
1227 1223
                 case JSON_ERROR_UTF8:
1228
-                    $message = 'malformed UTF-8 characters, '.
1224
+                    $message = 'malformed UTF-8 characters, ' .
1229 1225
                         'possibly incorrectly encoded';
1230 1226
                     break;
1231 1227
                 default:
Please login to merge, or discard this patch.
Braces   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -474,7 +474,7 @@
 block discarded – undo
474 474
         header("X-Powered-By: Luracast Restler v" . Restler::VERSION);
475 475
 		if($this->production_mode){
476 476
 			die($data);
477
-		}else{
477
+		} else{
478 478
 			echo $data;
479 479
 		}
480 480
     }
Please login to merge, or discard this patch.
Indentation   +1299 added lines, -1299 removed lines patch added patch discarded remove patch
@@ -16,883 +16,883 @@  discard block
 block discarded – undo
16 16
  */
17 17
 class Restler
18 18
 {
19
-    // ==================================================================
20
-    //
21
-    // Public variables
22
-    //
23
-    // ------------------------------------------------------------------
24
-
25
-    const VERSION = '2.2.1';
26
-
27
-    /**
28
-     * URL of the currently mapped service
29
-     * @var string
30
-     */
31
-    public $url;
32
-
33
-    /**
34
-     * Http request method of the current request.
35
-     * Any value between [GET, PUT, POST, DELETE]
36
-     * @var string
37
-     */
38
-    public $request_method;
39
-
40
-    /**
41
-     * Requested data format. Instance of the current format class
42
-     * which implements the iFormat interface
43
-     * @var iFormat
44
-     * @example jsonFormat, xmlFormat, yamlFormat etc
45
-     */
46
-    public $request_format;
47
-
48
-    /**
49
-     * Data sent to the service
50
-     * @var array
51
-     */
52
-    public $request_data = array();
53
-
54
-    /**
55
-     * Used in production mode to store the URL Map to disk
56
-     * @var string
57
-     */
58
-    public $cache_dir;
59
-
60
-    /**
61
-     * base directory to locate format and auth files
62
-     * @var string
63
-     */
64
-    public $base_dir;
65
-
66
-    /**
67
-     * Name of an iRespond implementation class
68
-     * @var string
69
-     */
70
-    public $response = 'DefaultResponse';
71
-
72
-    /**
73
-     * Response data format. Instance of the current format class
74
-     * which implements the iFormat interface
75
-     * @var iFormat
76
-     * @example jsonFormat, xmlFormat, yamlFormat etc
77
-     */
78
-    public $response_format;
79
-
80
-    // ==================================================================
81
-    //
82
-    // Private & Protected variables
83
-    //
84
-    // ------------------------------------------------------------------
85
-
86
-    /**
87
-     * When set to false, it will run in debug mode and parse the
88
-     * class files every time to map it to the URL
89
-     * @var boolean
90
-     */
91
-    protected $production_mode;
92
-
93
-    /**
94
-     * Associated array that maps urls to their respective class and method
95
-     * @var array
96
-     */
97
-    protected $routes = array();
98
-
99
-    /**
100
-     * Associated array that maps formats to their respective format class name
101
-     * @var array
102
-     */
103
-    protected $format_map = array();
104
-
105
-    /**
106
-     * Instance of the current api service class
107
-     * @var object
108
-     */
109
-    protected $service_class_instance;
110
-
111
-    /**
112
-     * Name of the api method being called
113
-     * @var string
114
-     */
115
-    protected $service_method;
116
-
117
-    /**
118
-     * list of authentication classes
119
-     * @var array
120
-     */
121
-    protected $auth_classes = array();
122
-
123
-    /**
124
-     * list of error handling classes
125
-     * @var array
126
-     */
127
-    protected $error_classes = array();
128
-
129
-    /**
130
-     * HTTP status codes
131
-     * @var array
132
-     */
133
-    private $codes = array(
134
-        100 => 'Continue',
135
-        101 => 'Switching Protocols',
136
-        200 => 'OK',
137
-        201 => 'Created',
138
-        202 => 'Accepted',
139
-        203 => 'Non-Authoritative Information',
140
-        204 => 'No Content',
141
-        205 => 'Reset Content',
142
-        206 => 'Partial Content',
143
-        300 => 'Multiple Choices',
144
-        301 => 'Moved Permanently',
145
-        302 => 'Found',
146
-        303 => 'See Other',
147
-        304 => 'Not Modified',
148
-        305 => 'Use Proxy',
149
-        306 => '(Unused)',
150
-        307 => 'Temporary Redirect',
151
-        400 => 'Bad Request',
152
-        401 => 'Unauthorized',
153
-        402 => 'Payment Required',
154
-        403 => 'Forbidden',
155
-        404 => 'Not Found',
156
-        405 => 'Method Not Allowed',
157
-        406 => 'Not Acceptable',
158
-        407 => 'Proxy Authentication Required',
159
-        408 => 'Request Timeout',
160
-        409 => 'Conflict',
161
-        410 => 'Gone',
162
-        411 => 'Length Required',
163
-        412 => 'Precondition Failed',
164
-        413 => 'Request Entity Too Large',
165
-        414 => 'Request-URI Too Long',
166
-        415 => 'Unsupported Media Type',
167
-        416 => 'Requested Range Not Satisfiable',
168
-        417 => 'Expectation Failed',
169
-        500 => 'Internal Server Error',
170
-        501 => 'Not Implemented',
171
-        502 => 'Bad Gateway',
172
-        503 => 'Service Unavailable',
173
-        504 => 'Gateway Timeout',
174
-        505 => 'HTTP Version Not Supported'
175
-    );
176
-
177
-    /**
178
-     * Caching of url map is enabled or not
179
-     * @var boolean
180
-     */
181
-    protected $cached;
182
-
183
-    // ==================================================================
184
-    //
185
-    // Public functions
186
-    //
187
-    // ------------------------------------------------------------------
188
-
189
-
190
-    /**
191
-     * Constructor
192
-     * @param boolean $production_mode When set to false, it will run in
193
-     * debug mode and parse the class files every time to map it to the URL
194
-     */
195
-    public function __construct($production_mode = false)
196
-    {
197
-        $this->production_mode = $production_mode;
198
-        $this->cache_dir = getcwd();
199
-        $this->base_dir = RESTLER_PATH;
200
-    }
201
-
202
-
203
-    /**
204
-     * Store the url map cache if needed
205
-     */
206
-    public function __destruct()
207
-    {
208
-        if ($this->production_mode && !($this->cached)) {
209
-            $this->saveCache();
210
-        }
211
-    }
212
-
213
-
214
-    /**
215
-     * Use it in production mode to refresh the url map cache
216
-     */
217
-    public function refreshCache()
218
-    {
219
-        $this->routes = array();
220
-        $this->cached = false;
221
-    }
222
-
223
-
224
-    /**
225
-     * Call this method and pass all the formats that should be
226
-     * supported by the API. Accepts multiple parameters
227
-     * @param string class name of the format class that implements iFormat
228
-     * @example $restler->setSupportedFormats('JsonFormat', 'XmlFormat'...);
229
-     */
230
-    public function setSupportedFormats()
231
-    {
232
-        $args = func_get_args();
233
-        $extensions = array();
234
-        foreach ($args as $class_name) {
235
-            if (!is_string($class_name) || !class_exists($class_name)) {
236
-                throw new Exception("$class_name is not a vaild Format Class.");
237
-            }
238
-            $obj = new $class_name;
239
-            if (!($obj instanceof iFormat)) {
240
-                throw new Exception('Invalid format class; must implement '
241
-                    . 'iFormat interface');
242
-            }
243
-            foreach ($obj->getMIMEMap() as $extension => $mime) {
244
-                if (!isset($this->format_map[$extension])) {
245
-                    $this->format_map[$extension] = $class_name;
246
-                }
247
-                $mime = explode(',', $mime);
248
-                if (!is_array($mime)) {
249
-                    $mime = array($mime);
250
-                }
251
-                foreach ($mime as $value) {
252
-                    if (!isset($this->format_map[$value])) {
253
-                        $this->format_map[$value] = $class_name;
254
-                    }
255
-                }
256
-                $extensions[".$extension"] = true;
257
-            }
258
-        }
259
-        $this->format_map['default'] = $args[0];
260
-        $this->format_map['extensions'] = array_keys($extensions);
261
-    }
262
-
263
-
264
-    /**
265
-     * Add api classes throgh this method. All the public methods
266
-     * that do not start with _ (underscore) will be  will be exposed
267
-     * as the public api by default.
268
-     *
269
-     * All the protected methods that do not start with _ (underscore)
270
-     * will exposed as protected api which will require authentication
271
-     * @param string $class name of the service class
272
-     * @param string $basePath optional url prefix for mapping, uses
273
-     * lowercase version of the class name when not specified
274
-     * @throws Exception when supplied with invalid class name
275
-     */
276
-    public function addAPIClass($class_name, $base_path = null)
277
-    {
278
-        if (!class_exists($class_name)) {
279
-            throw new Exception("API class $class_name is missing.");
280
-        }
281
-        $this->loadCache();
282
-        if (!$this->cached) {
283
-            if (is_null($base_path)) {
284
-                $base_path = strtolower($class_name);
285
-                $index = strrpos($class_name, '\\');
286
-                if ($index !== false) {
287
-                    $base_path = substr($base_path, $index + 1);
288
-                }
289
-            } else {
290
-                $base_path = trim($base_path, '/');
291
-            }
292
-            if (strlen($base_path) > 0) {
293
-                $base_path .= '/';
294
-            }
295
-            $this->generateMap($class_name, $base_path);
296
-        }
297
-    }
298
-
299
-
300
-    /**
301
-     * protected methods will need atleast one authentication class to be set
302
-     * in order to allow that method to be executed
303
-     * @param string $class_name of the authentication class
304
-     * @param string $base_path optional url prefix for mapping
305
-     */
306
-    public function addAuthenticationClass($class_name, $base_path = null)
307
-    {
308
-        $this->auth_classes[] = $class_name;
309
-        $this->addAPIClass($class_name, $base_path);
310
-    }
311
-
312
-
313
-    /**
314
-     * Add class for custom error handling
315
-     * @param string $class_name of the error handling class
316
-     */
317
-    public function addErrorClass($class_name)
318
-    {
319
-        $this->error_classes[] = $class_name;
320
-    }
321
-
322
-
323
-    /**
324
-     * Convenience method to respond with an error message
325
-     * @param int $statusCode http error code
326
-     * @param string $errorMessage optional custom error message
327
-     */
328
-    public function handleError($status_code, $error_message = null)
329
-    {
330
-        $method = "handle$status_code";
331
-        $handled = false;
332
-        foreach ($this->error_classes as $class_name) {
333
-            if (method_exists($class_name, $method)) {
334
-                $obj = new $class_name();
335
-                $obj->restler = $this;
336
-                $obj->$method();
337
-                $handled = true;
338
-            }
339
-        }
340
-        if ($handled) {
341
-            return;
342
-        }
343
-        $message = $this->codes[$status_code]
344
-            . (!$error_message ? '' : ': ' . $error_message);
345
-        $this->setStatus($status_code);
346
-        $responder = new $this->response();
347
-        $responder->restler = $this;
348
-        $this->sendData($responder->__formatError($status_code, $message));
349
-    }
350
-
351
-
352
-    /**
353
-     * An initialize function to allow use of the restler error generation 
354
-     * functions for pre-processing and pre-routing of requests.
355
-     */
356
-    public function init()
357
-    {
358
-        if (empty($this->format_map)) {
359
-            $this->setSupportedFormats('JsonFormat');
360
-        }
361
-        $this->url = $this->getPath();
362
-        $this->request_method = $this->getRequestMethod();
363
-        $this->response_format = $this->getResponseFormat();
364
-        $this->request_format = $this->getRequestFormat();
365
-        if (is_null($this->request_format)) {
366
-            $this->request_format = $this->response_format;
367
-        }
368
-        if ($this->request_method == 'PUT' || $this->request_method == 'POST') {
369
-            $this->request_data = $this->getRequestData();
370
-        }
371
-    }
372
-
373
-
374
-    /**
375
-     * Main function for processing the api request
376
-     * and return the response
377
-     * @throws Exception when the api service class is missing
378
-     * @throws RestException to send error response
379
-     */
380
-    public function handle()
381
-    {
382
-        $this->init();
383
-        $o = $this->mapUrlToMethod();
384
-
385
-        if (!isset($o->class_name)) {
386
-            $this->handleError(404);
387
-        } else {
388
-            try {
389
-                if ($o->method_flag) {
390
-                    $auth_method = '__isAuthenticated';
391
-                    if (!count($this->auth_classes)) {
392
-                        throw new RestException(401);
393
-                    }
394
-                    foreach ($this->auth_classes as $auth_class) {
395
-                        $auth_obj = new $auth_class();
396
-                        $auth_obj->restler = $this;
397
-                        $this->applyClassMetadata($auth_class, $auth_obj, $o);
398
-                        if (!method_exists($auth_obj, $auth_method)) {
399
-                            throw new RestException(401, 'Authentication Class '
400
-                                . 'should implement iAuthenticate');
401
-                        } else if (!$auth_obj->$auth_method()) {
402
-                            throw new RestException(401);
403
-                        }
404
-                    }
405
-                }
406
-                $this->applyClassMetadata(get_class($this->request_format),
407
-                    $this->request_format, $o);
408
-                $pre_process = '_' . $this->request_format->getExtension() . '_'
409
-                    . $o->method_name;
410
-                $this->service_method = $o->method_name;
411
-                if ($o->method_flag == 2) {
412
-                    $o = unprotect($o);
413
-                }
414
-                $object = $this->service_class_instance = new $o->class_name();
415
-                $object->restler = $this;
416
-                if (method_exists($o->class_name, $pre_process)) {
417
-                    call_user_func_array(
418
-                        array($object, $pre_process), $o->arguments
419
-                    );
420
-                }
421
-                switch ($o->method_flag) {
422
-                    case 3:
423
-                        $reflection_method = new ReflectionMethod($object,
424
-                                $o->method_name);
425
-                        $reflection_method->setAccessible(true);
426
-                        $result = $reflection_method->invokeArgs($object,
427
-                            $o->arguments);
428
-                        break;
429
-                    case 2:
430
-                    case 1:
431
-                    default:
432
-                        $result = call_user_func_array(array(
433
-                            $object,
434
-                            $o->method_name), $o->arguments
435
-                        );
436
-                        break;
437
-                }
438
-            } catch (RestException $e) {
439
-                $this->handleError($e->getCode(), $e->getMessage());
440
-            }
441
-        }
442
-        $responder = new $this->response();
443
-        $responder->restler = $this;
444
-        $this->applyClassMetadata($this->response, $responder, $o);
445
-        if (isset($result) && $result !== null) {
446
-            $result = $responder->__formatResponse($result);
447
-            $this->sendData($result);
448
-        }
449
-    }
450
-
451
-
452
-    /**
453
-     * Encodes the response in the prefered format
454
-     * and sends back
455
-     * @param $data array php data
456
-     */
457
-    public function sendData($data)
458
-    {
459
-        $data = $this->response_format->encode($data, 
460
-            !($this->production_mode)
461
-        );
462
-        $post_process = '_' . $this->service_method . '_'
463
-            . $this->response_format->getExtension();
464
-        if (isset($this->service_class_instance)
465
-            && method_exists($this->service_class_instance, $post_process)
466
-        ) {
467
-            $data = call_user_func(array($this->service_class_instance,
468
-                $post_process), $data);
469
-        }
470
-        header("Cache-Control: no-cache, must-revalidate");
471
-        header("Expires: 0");
472
-        header('Content-Type: ' . $this->response_format->getMIME());
473
-        //.'; charset=utf-8');
474
-        header("X-Powered-By: Luracast Restler v" . Restler::VERSION);
19
+	// ==================================================================
20
+	//
21
+	// Public variables
22
+	//
23
+	// ------------------------------------------------------------------
24
+
25
+	const VERSION = '2.2.1';
26
+
27
+	/**
28
+	 * URL of the currently mapped service
29
+	 * @var string
30
+	 */
31
+	public $url;
32
+
33
+	/**
34
+	 * Http request method of the current request.
35
+	 * Any value between [GET, PUT, POST, DELETE]
36
+	 * @var string
37
+	 */
38
+	public $request_method;
39
+
40
+	/**
41
+	 * Requested data format. Instance of the current format class
42
+	 * which implements the iFormat interface
43
+	 * @var iFormat
44
+	 * @example jsonFormat, xmlFormat, yamlFormat etc
45
+	 */
46
+	public $request_format;
47
+
48
+	/**
49
+	 * Data sent to the service
50
+	 * @var array
51
+	 */
52
+	public $request_data = array();
53
+
54
+	/**
55
+	 * Used in production mode to store the URL Map to disk
56
+	 * @var string
57
+	 */
58
+	public $cache_dir;
59
+
60
+	/**
61
+	 * base directory to locate format and auth files
62
+	 * @var string
63
+	 */
64
+	public $base_dir;
65
+
66
+	/**
67
+	 * Name of an iRespond implementation class
68
+	 * @var string
69
+	 */
70
+	public $response = 'DefaultResponse';
71
+
72
+	/**
73
+	 * Response data format. Instance of the current format class
74
+	 * which implements the iFormat interface
75
+	 * @var iFormat
76
+	 * @example jsonFormat, xmlFormat, yamlFormat etc
77
+	 */
78
+	public $response_format;
79
+
80
+	// ==================================================================
81
+	//
82
+	// Private & Protected variables
83
+	//
84
+	// ------------------------------------------------------------------
85
+
86
+	/**
87
+	 * When set to false, it will run in debug mode and parse the
88
+	 * class files every time to map it to the URL
89
+	 * @var boolean
90
+	 */
91
+	protected $production_mode;
92
+
93
+	/**
94
+	 * Associated array that maps urls to their respective class and method
95
+	 * @var array
96
+	 */
97
+	protected $routes = array();
98
+
99
+	/**
100
+	 * Associated array that maps formats to their respective format class name
101
+	 * @var array
102
+	 */
103
+	protected $format_map = array();
104
+
105
+	/**
106
+	 * Instance of the current api service class
107
+	 * @var object
108
+	 */
109
+	protected $service_class_instance;
110
+
111
+	/**
112
+	 * Name of the api method being called
113
+	 * @var string
114
+	 */
115
+	protected $service_method;
116
+
117
+	/**
118
+	 * list of authentication classes
119
+	 * @var array
120
+	 */
121
+	protected $auth_classes = array();
122
+
123
+	/**
124
+	 * list of error handling classes
125
+	 * @var array
126
+	 */
127
+	protected $error_classes = array();
128
+
129
+	/**
130
+	 * HTTP status codes
131
+	 * @var array
132
+	 */
133
+	private $codes = array(
134
+		100 => 'Continue',
135
+		101 => 'Switching Protocols',
136
+		200 => 'OK',
137
+		201 => 'Created',
138
+		202 => 'Accepted',
139
+		203 => 'Non-Authoritative Information',
140
+		204 => 'No Content',
141
+		205 => 'Reset Content',
142
+		206 => 'Partial Content',
143
+		300 => 'Multiple Choices',
144
+		301 => 'Moved Permanently',
145
+		302 => 'Found',
146
+		303 => 'See Other',
147
+		304 => 'Not Modified',
148
+		305 => 'Use Proxy',
149
+		306 => '(Unused)',
150
+		307 => 'Temporary Redirect',
151
+		400 => 'Bad Request',
152
+		401 => 'Unauthorized',
153
+		402 => 'Payment Required',
154
+		403 => 'Forbidden',
155
+		404 => 'Not Found',
156
+		405 => 'Method Not Allowed',
157
+		406 => 'Not Acceptable',
158
+		407 => 'Proxy Authentication Required',
159
+		408 => 'Request Timeout',
160
+		409 => 'Conflict',
161
+		410 => 'Gone',
162
+		411 => 'Length Required',
163
+		412 => 'Precondition Failed',
164
+		413 => 'Request Entity Too Large',
165
+		414 => 'Request-URI Too Long',
166
+		415 => 'Unsupported Media Type',
167
+		416 => 'Requested Range Not Satisfiable',
168
+		417 => 'Expectation Failed',
169
+		500 => 'Internal Server Error',
170
+		501 => 'Not Implemented',
171
+		502 => 'Bad Gateway',
172
+		503 => 'Service Unavailable',
173
+		504 => 'Gateway Timeout',
174
+		505 => 'HTTP Version Not Supported'
175
+	);
176
+
177
+	/**
178
+	 * Caching of url map is enabled or not
179
+	 * @var boolean
180
+	 */
181
+	protected $cached;
182
+
183
+	// ==================================================================
184
+	//
185
+	// Public functions
186
+	//
187
+	// ------------------------------------------------------------------
188
+
189
+
190
+	/**
191
+	 * Constructor
192
+	 * @param boolean $production_mode When set to false, it will run in
193
+	 * debug mode and parse the class files every time to map it to the URL
194
+	 */
195
+	public function __construct($production_mode = false)
196
+	{
197
+		$this->production_mode = $production_mode;
198
+		$this->cache_dir = getcwd();
199
+		$this->base_dir = RESTLER_PATH;
200
+	}
201
+
202
+
203
+	/**
204
+	 * Store the url map cache if needed
205
+	 */
206
+	public function __destruct()
207
+	{
208
+		if ($this->production_mode && !($this->cached)) {
209
+			$this->saveCache();
210
+		}
211
+	}
212
+
213
+
214
+	/**
215
+	 * Use it in production mode to refresh the url map cache
216
+	 */
217
+	public function refreshCache()
218
+	{
219
+		$this->routes = array();
220
+		$this->cached = false;
221
+	}
222
+
223
+
224
+	/**
225
+	 * Call this method and pass all the formats that should be
226
+	 * supported by the API. Accepts multiple parameters
227
+	 * @param string class name of the format class that implements iFormat
228
+	 * @example $restler->setSupportedFormats('JsonFormat', 'XmlFormat'...);
229
+	 */
230
+	public function setSupportedFormats()
231
+	{
232
+		$args = func_get_args();
233
+		$extensions = array();
234
+		foreach ($args as $class_name) {
235
+			if (!is_string($class_name) || !class_exists($class_name)) {
236
+				throw new Exception("$class_name is not a vaild Format Class.");
237
+			}
238
+			$obj = new $class_name;
239
+			if (!($obj instanceof iFormat)) {
240
+				throw new Exception('Invalid format class; must implement '
241
+					. 'iFormat interface');
242
+			}
243
+			foreach ($obj->getMIMEMap() as $extension => $mime) {
244
+				if (!isset($this->format_map[$extension])) {
245
+					$this->format_map[$extension] = $class_name;
246
+				}
247
+				$mime = explode(',', $mime);
248
+				if (!is_array($mime)) {
249
+					$mime = array($mime);
250
+				}
251
+				foreach ($mime as $value) {
252
+					if (!isset($this->format_map[$value])) {
253
+						$this->format_map[$value] = $class_name;
254
+					}
255
+				}
256
+				$extensions[".$extension"] = true;
257
+			}
258
+		}
259
+		$this->format_map['default'] = $args[0];
260
+		$this->format_map['extensions'] = array_keys($extensions);
261
+	}
262
+
263
+
264
+	/**
265
+	 * Add api classes throgh this method. All the public methods
266
+	 * that do not start with _ (underscore) will be  will be exposed
267
+	 * as the public api by default.
268
+	 *
269
+	 * All the protected methods that do not start with _ (underscore)
270
+	 * will exposed as protected api which will require authentication
271
+	 * @param string $class name of the service class
272
+	 * @param string $basePath optional url prefix for mapping, uses
273
+	 * lowercase version of the class name when not specified
274
+	 * @throws Exception when supplied with invalid class name
275
+	 */
276
+	public function addAPIClass($class_name, $base_path = null)
277
+	{
278
+		if (!class_exists($class_name)) {
279
+			throw new Exception("API class $class_name is missing.");
280
+		}
281
+		$this->loadCache();
282
+		if (!$this->cached) {
283
+			if (is_null($base_path)) {
284
+				$base_path = strtolower($class_name);
285
+				$index = strrpos($class_name, '\\');
286
+				if ($index !== false) {
287
+					$base_path = substr($base_path, $index + 1);
288
+				}
289
+			} else {
290
+				$base_path = trim($base_path, '/');
291
+			}
292
+			if (strlen($base_path) > 0) {
293
+				$base_path .= '/';
294
+			}
295
+			$this->generateMap($class_name, $base_path);
296
+		}
297
+	}
298
+
299
+
300
+	/**
301
+	 * protected methods will need atleast one authentication class to be set
302
+	 * in order to allow that method to be executed
303
+	 * @param string $class_name of the authentication class
304
+	 * @param string $base_path optional url prefix for mapping
305
+	 */
306
+	public function addAuthenticationClass($class_name, $base_path = null)
307
+	{
308
+		$this->auth_classes[] = $class_name;
309
+		$this->addAPIClass($class_name, $base_path);
310
+	}
311
+
312
+
313
+	/**
314
+	 * Add class for custom error handling
315
+	 * @param string $class_name of the error handling class
316
+	 */
317
+	public function addErrorClass($class_name)
318
+	{
319
+		$this->error_classes[] = $class_name;
320
+	}
321
+
322
+
323
+	/**
324
+	 * Convenience method to respond with an error message
325
+	 * @param int $statusCode http error code
326
+	 * @param string $errorMessage optional custom error message
327
+	 */
328
+	public function handleError($status_code, $error_message = null)
329
+	{
330
+		$method = "handle$status_code";
331
+		$handled = false;
332
+		foreach ($this->error_classes as $class_name) {
333
+			if (method_exists($class_name, $method)) {
334
+				$obj = new $class_name();
335
+				$obj->restler = $this;
336
+				$obj->$method();
337
+				$handled = true;
338
+			}
339
+		}
340
+		if ($handled) {
341
+			return;
342
+		}
343
+		$message = $this->codes[$status_code]
344
+			. (!$error_message ? '' : ': ' . $error_message);
345
+		$this->setStatus($status_code);
346
+		$responder = new $this->response();
347
+		$responder->restler = $this;
348
+		$this->sendData($responder->__formatError($status_code, $message));
349
+	}
350
+
351
+
352
+	/**
353
+	 * An initialize function to allow use of the restler error generation 
354
+	 * functions for pre-processing and pre-routing of requests.
355
+	 */
356
+	public function init()
357
+	{
358
+		if (empty($this->format_map)) {
359
+			$this->setSupportedFormats('JsonFormat');
360
+		}
361
+		$this->url = $this->getPath();
362
+		$this->request_method = $this->getRequestMethod();
363
+		$this->response_format = $this->getResponseFormat();
364
+		$this->request_format = $this->getRequestFormat();
365
+		if (is_null($this->request_format)) {
366
+			$this->request_format = $this->response_format;
367
+		}
368
+		if ($this->request_method == 'PUT' || $this->request_method == 'POST') {
369
+			$this->request_data = $this->getRequestData();
370
+		}
371
+	}
372
+
373
+
374
+	/**
375
+	 * Main function for processing the api request
376
+	 * and return the response
377
+	 * @throws Exception when the api service class is missing
378
+	 * @throws RestException to send error response
379
+	 */
380
+	public function handle()
381
+	{
382
+		$this->init();
383
+		$o = $this->mapUrlToMethod();
384
+
385
+		if (!isset($o->class_name)) {
386
+			$this->handleError(404);
387
+		} else {
388
+			try {
389
+				if ($o->method_flag) {
390
+					$auth_method = '__isAuthenticated';
391
+					if (!count($this->auth_classes)) {
392
+						throw new RestException(401);
393
+					}
394
+					foreach ($this->auth_classes as $auth_class) {
395
+						$auth_obj = new $auth_class();
396
+						$auth_obj->restler = $this;
397
+						$this->applyClassMetadata($auth_class, $auth_obj, $o);
398
+						if (!method_exists($auth_obj, $auth_method)) {
399
+							throw new RestException(401, 'Authentication Class '
400
+								. 'should implement iAuthenticate');
401
+						} else if (!$auth_obj->$auth_method()) {
402
+							throw new RestException(401);
403
+						}
404
+					}
405
+				}
406
+				$this->applyClassMetadata(get_class($this->request_format),
407
+					$this->request_format, $o);
408
+				$pre_process = '_' . $this->request_format->getExtension() . '_'
409
+					. $o->method_name;
410
+				$this->service_method = $o->method_name;
411
+				if ($o->method_flag == 2) {
412
+					$o = unprotect($o);
413
+				}
414
+				$object = $this->service_class_instance = new $o->class_name();
415
+				$object->restler = $this;
416
+				if (method_exists($o->class_name, $pre_process)) {
417
+					call_user_func_array(
418
+						array($object, $pre_process), $o->arguments
419
+					);
420
+				}
421
+				switch ($o->method_flag) {
422
+					case 3:
423
+						$reflection_method = new ReflectionMethod($object,
424
+								$o->method_name);
425
+						$reflection_method->setAccessible(true);
426
+						$result = $reflection_method->invokeArgs($object,
427
+							$o->arguments);
428
+						break;
429
+					case 2:
430
+					case 1:
431
+					default:
432
+						$result = call_user_func_array(array(
433
+							$object,
434
+							$o->method_name), $o->arguments
435
+						);
436
+						break;
437
+				}
438
+			} catch (RestException $e) {
439
+				$this->handleError($e->getCode(), $e->getMessage());
440
+			}
441
+		}
442
+		$responder = new $this->response();
443
+		$responder->restler = $this;
444
+		$this->applyClassMetadata($this->response, $responder, $o);
445
+		if (isset($result) && $result !== null) {
446
+			$result = $responder->__formatResponse($result);
447
+			$this->sendData($result);
448
+		}
449
+	}
450
+
451
+
452
+	/**
453
+	 * Encodes the response in the prefered format
454
+	 * and sends back
455
+	 * @param $data array php data
456
+	 */
457
+	public function sendData($data)
458
+	{
459
+		$data = $this->response_format->encode($data, 
460
+			!($this->production_mode)
461
+		);
462
+		$post_process = '_' . $this->service_method . '_'
463
+			. $this->response_format->getExtension();
464
+		if (isset($this->service_class_instance)
465
+			&& method_exists($this->service_class_instance, $post_process)
466
+		) {
467
+			$data = call_user_func(array($this->service_class_instance,
468
+				$post_process), $data);
469
+		}
470
+		header("Cache-Control: no-cache, must-revalidate");
471
+		header("Expires: 0");
472
+		header('Content-Type: ' . $this->response_format->getMIME());
473
+		//.'; charset=utf-8');
474
+		header("X-Powered-By: Luracast Restler v" . Restler::VERSION);
475 475
 		if($this->production_mode){
476 476
 			die($data);
477 477
 		}else{
478 478
 			echo $data;
479 479
 		}
480
-    }
481
-
482
-
483
-    /**
484
-     * Sets the HTTP response status
485
-     * @param int $code response code
486
-     */
487
-    public function setStatus($code)
488
-    {
489
-        header("{$_SERVER['SERVER_PROTOCOL']} $code " . 
490
-            $this->codes[strval($code)]);
491
-    }
492
-
493
-
494
-    /**
495
-     * Compare two strings and remove the common
496
-     * sub string from the first string and return it
497
-     * @param string $first
498
-     * @param string $second
499
-     * @param string $char optional, set it as
500
-     * blank string for char by char comparison
501
-     * @return string
502
-     */
503
-    public function removeCommonPath($first, $second, $char = '/')
504
-    {
505
-        $first = explode($char, $first);
506
-        $second = explode($char, $second);
507
-        while (count($second)) {
508
-            if ($first[0] == $second[0]) {
509
-                array_shift($first);
510
-            } else {
511
-                break;
512
-            }
513
-            array_shift($second);
514
-        }
515
-        return implode($char, $first);
516
-    }
517
-
518
-
519
-    /**
520
-     * Save cache to file
521
-     */
522
-    public function saveCache()
523
-    {
524
-        $file = $this->cache_dir . '/routes.php';
525
-        $s = '$o=array();' . PHP_EOL;
526
-        foreach ($this->routes as $key => $value) {
527
-            $s .= PHP_EOL . PHP_EOL . PHP_EOL . 
528
-                "############### $key ###############" . PHP_EOL . PHP_EOL;
529
-            $s .= '$o[\'' . $key . '\']=array();';
530
-            foreach ($value as $ke => $va) {
531
-                $s .= PHP_EOL . PHP_EOL . "#==== $key $ke" . PHP_EOL . PHP_EOL;
532
-                $s .= '$o[\'' . $key . '\'][\'' . $ke . '\']=' . str_replace(
533
-                        PHP_EOL, PHP_EOL . "\t", var_export($va, true)
534
-                    ) . ';';
535
-            }
536
-        }
537
-        $s .= PHP_EOL . 'return $o;';
538
-        $r = @file_put_contents($file, "<?php $s");
539
-        @chmod($file, 0777);
540
-        if ($r === false) {
541
-            throw new Exception(
542
-                "The cache directory located at '$this->cache_dir' needs to "
543
-                . "have the permissions set to read/write/execute for everyone"
544
-                . " in order to save cache and improve performance.");
545
-        }
546
-    }
547
-
548
-    // ==================================================================
549
-    //
550
-    // Protected functions
551
-    //
552
-    // ------------------------------------------------------------------
553
-
554
-
555
-    /**
556
-     * Parses the requst url and get the api path
557
-     * @return string api path
558
-     */
559
-    protected function getPath()
560
-    {
561
-        $path = urldecode($this->removeCommonPath($_SERVER['REQUEST_URI'],
562
-                $_SERVER['SCRIPT_NAME']));
563
-        $path = preg_replace('/(\/*\?.*$)|(\/$)/', '', $path);
564
-        $path = str_replace($this->format_map['extensions'], '', $path);
565
-        return $path;
566
-    }
567
-
568
-
569
-    /**
570
-     * Parses the request to figure out the http request type
571
-     * @return string which will be one of the following
572
-     * [GET, POST, PUT, DELETE]
573
-     * @example GET
574
-     */
575
-    protected function getRequestMethod()
576
-    {
577
-        $method = $_SERVER['REQUEST_METHOD'];
578
-        if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
579
-            $method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
580
-        }
581
-        //support for HEAD request
582
-        if ($method == 'HEAD') {
583
-            $method = 'GET';
584
-        }
585
-        return $method;
586
-    }
587
-
588
-
589
-    /**
590
-     * Parses the request to figure out format of the request data
591
-     * @return iFormat any class that implements iFormat
592
-     * @example JsonFormat
593
-     */
594
-    protected function getRequestFormat()
595
-    {
596
-        $format = null;
597
-        //check if client has sent any information on request format
598
-        if (isset($_SERVER['CONTENT_TYPE'])) {
599
-            $mime = explode(';', $_SERVER['CONTENT_TYPE']);
600
-            $mime = $mime[0];
601
-            if ($mime == UrlEncodedFormat::MIME) {
602
-                $format = new UrlEncodedFormat();
603
-            } else {
604
-                if (isset($this->format_map[$mime])) {
605
-                    $format = $this->format_map[$mime];
606
-                    $format = is_string($format) ? new $format : $format;
607
-                    $format->setMIME($mime);
608
-                }
609
-            }
610
-        }
611
-        return $format;
612
-    }
613
-
614
-
615
-    /**
616
-     * Parses the request to figure out the best format for response
617
-     * @return iFormat any class that implements iFormat
618
-     * @example JsonFormat
619
-     */
620
-    protected function getResponseFormat()
621
-    {
622
-        //check if client has specified an extension
623
-        /**
624
-         * @var iFormat
625
-         */
626
-        $format = null;
627
-        $extensions = explode('.',
628
-            parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
629
-        while ($extensions) {
630
-            $extension = array_pop($extensions);
631
-            $extension = explode('/', $extension);
632
-            $extension = array_shift($extension);
633
-            if ($extension && isset($this->format_map[$extension])) {
634
-                $format = $this->format_map[$extension];
635
-                $format = is_string($format) ? new $format : $format;
636
-                $format->setExtension($extension);
637
-                //echo "Extension $extension";
638
-                return $format;
639
-            }
640
-        }
641
-        //check if client has sent list of accepted data formats
642
-        if (isset($_SERVER['HTTP_ACCEPT'])) {
643
-            $acceptList = array();
644
-            $accepts = explode(',', strtolower($_SERVER['HTTP_ACCEPT']));
645
-            if (!is_array($accepts)) {
646
-                $accepts = array($accepts);
647
-            }
648
-            foreach ($accepts as $pos => $accept) {
649
-                $parts = explode(';q=', trim($accept));
650
-                $type = array_shift($parts);
651
-                $quality = count($parts) ? 
652
-                    floatval(array_shift($parts)) : 
653
-                    (1000 - $pos) / 1000;
654
-                $acceptList[$type] = $quality;
655
-            }
656
-            arsort($acceptList);
657
-            foreach ($acceptList as $accept => $quality) {
658
-                if (isset($this->format_map[$accept])) {
659
-                    $format = $this->format_map[$accept];
660
-                    $format = is_string($format) ? new $format : $format;
661
-                    $format->setMIME($accept);
662
-                    //echo "MIME $accept";
663
-                    // Tell cache content is based on Accept header
664
-                    header("Vary: Accept"); 
665
-                    return $format;
666
-                }
667
-            }
668
-        } else {
669
-            // RFC 2616: If no Accept header field is
670
-            // present, then it is assumed that the
671
-            // client accepts all media types.
672
-            $_SERVER['HTTP_ACCEPT'] = '*/*';
673
-        }
674
-        if (strpos($_SERVER['HTTP_ACCEPT'], '*') !== false) {
675
-            if (strpos($_SERVER['HTTP_ACCEPT'], 'application/*') !== false) {
676
-                $format = new JsonFormat;
677
-            } else if (strpos($_SERVER['HTTP_ACCEPT'], 'text/*') !== false) {
678
-                $format = new XmlFormat;
679
-            } else if (strpos($_SERVER['HTTP_ACCEPT'], '*/*') !== false) {
680
-                $format = new $this->format_map['default'];
681
-            }
682
-        }
683
-        if (empty($format)) {
684
-            // RFC 2616: If an Accept header field is present, and if the 
685
-            // server cannot send a response which is acceptable according to 
686
-            // the combined Accept field value, then the server SHOULD send 
687
-            // a 406 (not acceptable) response.
688
-            header('HTTP/1.1 406 Not Acceptable');
689
-            die('406 Not Acceptable: The server was unable to ' . 
690
-                    'negotiate content for this request.');
691
-        } else {
692
-            // Tell cache content is based ot Accept header
693
-            header("Vary: Accept"); 
694
-            return $format;
695
-        }
696
-    }
697
-
698
-
699
-    /**
700
-     * Parses the request data and returns it
701
-     * @return array php data
702
-     */
703
-    protected function getRequestData()
704
-    {
705
-        try {
706
-            $r = file_get_contents('php://input');
707
-            if (is_null($r)) {
708
-                return $_GET;
709
-            }
710
-            $r = $this->request_format->decode($r);
711
-            return is_null($r) ? array() : $r;
712
-        } catch (RestException $e) {
713
-            $this->handleError($e->getCode(), $e->getMessage());
714
-        }
715
-    }
716
-
717
-
718
-    protected function mapUrlToMethod()
719
-    {
720
-        if (!isset($this->routes[$this->request_method])) {
721
-            return array();
722
-        }
723
-        $urls = $this->routes[$this->request_method];
724
-        if (!$urls) {
725
-            return array();
726
-        }
727
-
728
-        $found = false;
729
-        $this->request_data += $_GET;
730
-        $params = array('request_data' => $this->request_data);
731
-        $params += $this->request_data;
732
-        $lc = strtolower($this->url);
733
-        foreach ($urls as $url => $call) {
734
-            //echo PHP_EOL.$url.' = '.$this->url.PHP_EOL;
735
-            $call = (object) $call;
736
-            if (strstr($url, ':')) {
737
-                $regex = preg_replace('/\\\:([^\/]+)/', '(?P<$1>[^/]+)',
738
-                    preg_quote($url));
739
-                if (preg_match(":^$regex$:i", $this->url, $matches)) {
740
-                    foreach ($matches as $arg => $match) {
741
-                        if (isset($call->arguments[$arg])) {
742
-                            //flog("$arg => $match $args[$arg]");
743
-                            $params[$arg] = $match;
744
-                        }
745
-                    }
746
-                    $found = true;
747
-                    break;
748
-                }
749
-            } else if ($url == $lc) {
750
-                $found = true;
751
-                break;
752
-            }
753
-        }
754
-        if ($found) {
755
-            //echo PHP_EOL."Found $url ";
756
-            //print_r($call);
757
-            $p = $call->defaults;
758
-            foreach ($call->arguments as $key => $value) {
759
-                //echo "$key => $value \n";
760
-                if (isset($params[$key])) {
761
-                    $p[$value] = $params[$key];
762
-                }
763
-            }
764
-            $call->arguments = $p;
765
-            return $call;
766
-        }
767
-    }
768
-
769
-
770
-    /**
771
-     * Apply static and non-static properties defined in
772
-     * the method information anotation
773
-     * @param String $class_name
774
-     * @param Object $instance instance of that class
775
-     * @param Object $method_info method information and metadata
776
-     */
777
-    protected function applyClassMetadata($class_name, $instance, $method_info)
778
-    {
779
-        if (isset($method_info->metadata[$class_name])
780
-            && is_array($method_info->metadata[$class_name])
781
-        ) {
782
-            foreach ($method_info->metadata[$class_name] as
783
-                    $property => $value) {
784
-                if (property_exists($class_name, $property)) {
785
-                    $reflection_property = 
786
-                        new ReflectionProperty($class_name, $property);
787
-                    $reflection_property->setValue($instance, $value);
788
-                }
789
-            }
790
-        }
791
-    }
792
-
793
-
794
-    protected function loadCache()
795
-    {
796
-        if ($this->cached !== null) {
797
-            return;
798
-        }
799
-        $file = $this->cache_dir . '/routes.php';
800
-        $this->cached = false;
801
-
802
-        if ($this->production_mode) {
803
-            if (file_exists($file)) {
804
-                $routes = include($file);
805
-            }
806
-            if (isset($routes) && is_array($routes)) {
807
-                $this->routes = $routes;
808
-                $this->cached = true;
809
-            }
810
-        } else {
811
-            //@unlink($this->cache_dir . "/$name.php");
812
-        }
813
-    }
814
-
815
-
816
-    /**
817
-     * Generates cachable url to method mapping
818
-     * @param string $class_name
819
-     * @param string $base_path
820
-     */
821
-    protected function generateMap($class_name, $base_path = '')
822
-    {
823
-        $reflection = new ReflectionClass($class_name);
824
-        $class_metadata = parse_doc($reflection->getDocComment());
825
-        $methods = $reflection->getMethods(
826
-            ReflectionMethod::IS_PUBLIC + ReflectionMethod::IS_PROTECTED
827
-        );
828
-        foreach ($methods as $method) {
829
-            $doc = $method->getDocComment();
830
-            $arguments = array();
831
-            $defaults = array();
832
-            $metadata = $class_metadata + parse_doc($doc);
833
-            $params = $method->getParameters();
834
-            $position = 0;
835
-            foreach ($params as $param) {
836
-                $arguments[$param->getName()] = $position;
837
-                $defaults[$position] = $param->isDefaultValueAvailable() ? 
838
-                    $param->getDefaultValue() : null;
839
-                $position++;
840
-            }
841
-            $method_flag = $method->isProtected() ? 
842
-                (isRestlerCompatibilityModeEnabled() ? 2 : 3) : 
843
-                (isset($metadata['protected']) ? 1 : 0);
844
-
845
-            //take note of the order
846
-            $call = array(
847
-                'class_name' => $class_name,
848
-                'method_name' => $method->getName(),
849
-                'arguments' => $arguments,
850
-                'defaults' => $defaults,
851
-                'metadata' => $metadata,
852
-                'method_flag' => $method_flag
853
-            );
854
-            $method_url = strtolower($method->getName());
855
-            if (preg_match_all(
856
-                '/@url\s+(GET|POST|PUT|DELETE|HEAD|OPTIONS)[ \t]*\/?(\S*)/s',
857
-                    $doc, $matches, PREG_SET_ORDER)
858
-            ) {
859
-                foreach ($matches as $match) {
860
-                    $http_method = $match[1];
861
-                    $url = rtrim($base_path . $match[2], '/');
862
-                    $this->routes[$http_method][$url] = $call;
863
-                }
864
-            } elseif ($method_url[0] != '_') { 
865
-                //not prefixed with underscore
866
-                // no configuration found so use convention
867
-                if (preg_match_all('/^(GET|POST|PUT|DELETE|HEAD|OPTIONS)/i',
868
-                        $method_url, $matches)
869
-                ) {
870
-                    $http_method = strtoupper($matches[0][0]);
871
-                    $method_url = substr($method_url, strlen($http_method));
872
-                } else {
873
-                    $http_method = 'GET';
874
-                }
875
-                $url = $base_path
876
-                    . ($method_url == 'index' || $method_url == 'default' ? '' :
877
-                        $method_url);
878
-                $url = rtrim($url, '/');
879
-                $this->routes[$http_method][$url] = $call;
880
-                foreach ($params as $param) {
881
-                    if ($param->getName() == 'request_data') {
882
-                        break;
883
-                    }
884
-                    $url .= $url == '' ? ':' : '/:';
885
-                    $url .= $param->getName();
886
-                    $this->routes[$http_method][$url] = $call;
887
-                }
888
-            }
889
-        }
890
-    }
480
+	}
481
+
482
+
483
+	/**
484
+	 * Sets the HTTP response status
485
+	 * @param int $code response code
486
+	 */
487
+	public function setStatus($code)
488
+	{
489
+		header("{$_SERVER['SERVER_PROTOCOL']} $code " . 
490
+			$this->codes[strval($code)]);
491
+	}
492
+
493
+
494
+	/**
495
+	 * Compare two strings and remove the common
496
+	 * sub string from the first string and return it
497
+	 * @param string $first
498
+	 * @param string $second
499
+	 * @param string $char optional, set it as
500
+	 * blank string for char by char comparison
501
+	 * @return string
502
+	 */
503
+	public function removeCommonPath($first, $second, $char = '/')
504
+	{
505
+		$first = explode($char, $first);
506
+		$second = explode($char, $second);
507
+		while (count($second)) {
508
+			if ($first[0] == $second[0]) {
509
+				array_shift($first);
510
+			} else {
511
+				break;
512
+			}
513
+			array_shift($second);
514
+		}
515
+		return implode($char, $first);
516
+	}
517
+
518
+
519
+	/**
520
+	 * Save cache to file
521
+	 */
522
+	public function saveCache()
523
+	{
524
+		$file = $this->cache_dir . '/routes.php';
525
+		$s = '$o=array();' . PHP_EOL;
526
+		foreach ($this->routes as $key => $value) {
527
+			$s .= PHP_EOL . PHP_EOL . PHP_EOL . 
528
+				"############### $key ###############" . PHP_EOL . PHP_EOL;
529
+			$s .= '$o[\'' . $key . '\']=array();';
530
+			foreach ($value as $ke => $va) {
531
+				$s .= PHP_EOL . PHP_EOL . "#==== $key $ke" . PHP_EOL . PHP_EOL;
532
+				$s .= '$o[\'' . $key . '\'][\'' . $ke . '\']=' . str_replace(
533
+						PHP_EOL, PHP_EOL . "\t", var_export($va, true)
534
+					) . ';';
535
+			}
536
+		}
537
+		$s .= PHP_EOL . 'return $o;';
538
+		$r = @file_put_contents($file, "<?php $s");
539
+		@chmod($file, 0777);
540
+		if ($r === false) {
541
+			throw new Exception(
542
+				"The cache directory located at '$this->cache_dir' needs to "
543
+				. "have the permissions set to read/write/execute for everyone"
544
+				. " in order to save cache and improve performance.");
545
+		}
546
+	}
547
+
548
+	// ==================================================================
549
+	//
550
+	// Protected functions
551
+	//
552
+	// ------------------------------------------------------------------
553
+
554
+
555
+	/**
556
+	 * Parses the requst url and get the api path
557
+	 * @return string api path
558
+	 */
559
+	protected function getPath()
560
+	{
561
+		$path = urldecode($this->removeCommonPath($_SERVER['REQUEST_URI'],
562
+				$_SERVER['SCRIPT_NAME']));
563
+		$path = preg_replace('/(\/*\?.*$)|(\/$)/', '', $path);
564
+		$path = str_replace($this->format_map['extensions'], '', $path);
565
+		return $path;
566
+	}
567
+
568
+
569
+	/**
570
+	 * Parses the request to figure out the http request type
571
+	 * @return string which will be one of the following
572
+	 * [GET, POST, PUT, DELETE]
573
+	 * @example GET
574
+	 */
575
+	protected function getRequestMethod()
576
+	{
577
+		$method = $_SERVER['REQUEST_METHOD'];
578
+		if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
579
+			$method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
580
+		}
581
+		//support for HEAD request
582
+		if ($method == 'HEAD') {
583
+			$method = 'GET';
584
+		}
585
+		return $method;
586
+	}
587
+
588
+
589
+	/**
590
+	 * Parses the request to figure out format of the request data
591
+	 * @return iFormat any class that implements iFormat
592
+	 * @example JsonFormat
593
+	 */
594
+	protected function getRequestFormat()
595
+	{
596
+		$format = null;
597
+		//check if client has sent any information on request format
598
+		if (isset($_SERVER['CONTENT_TYPE'])) {
599
+			$mime = explode(';', $_SERVER['CONTENT_TYPE']);
600
+			$mime = $mime[0];
601
+			if ($mime == UrlEncodedFormat::MIME) {
602
+				$format = new UrlEncodedFormat();
603
+			} else {
604
+				if (isset($this->format_map[$mime])) {
605
+					$format = $this->format_map[$mime];
606
+					$format = is_string($format) ? new $format : $format;
607
+					$format->setMIME($mime);
608
+				}
609
+			}
610
+		}
611
+		return $format;
612
+	}
613
+
614
+
615
+	/**
616
+	 * Parses the request to figure out the best format for response
617
+	 * @return iFormat any class that implements iFormat
618
+	 * @example JsonFormat
619
+	 */
620
+	protected function getResponseFormat()
621
+	{
622
+		//check if client has specified an extension
623
+		/**
624
+		 * @var iFormat
625
+		 */
626
+		$format = null;
627
+		$extensions = explode('.',
628
+			parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
629
+		while ($extensions) {
630
+			$extension = array_pop($extensions);
631
+			$extension = explode('/', $extension);
632
+			$extension = array_shift($extension);
633
+			if ($extension && isset($this->format_map[$extension])) {
634
+				$format = $this->format_map[$extension];
635
+				$format = is_string($format) ? new $format : $format;
636
+				$format->setExtension($extension);
637
+				//echo "Extension $extension";
638
+				return $format;
639
+			}
640
+		}
641
+		//check if client has sent list of accepted data formats
642
+		if (isset($_SERVER['HTTP_ACCEPT'])) {
643
+			$acceptList = array();
644
+			$accepts = explode(',', strtolower($_SERVER['HTTP_ACCEPT']));
645
+			if (!is_array($accepts)) {
646
+				$accepts = array($accepts);
647
+			}
648
+			foreach ($accepts as $pos => $accept) {
649
+				$parts = explode(';q=', trim($accept));
650
+				$type = array_shift($parts);
651
+				$quality = count($parts) ? 
652
+					floatval(array_shift($parts)) : 
653
+					(1000 - $pos) / 1000;
654
+				$acceptList[$type] = $quality;
655
+			}
656
+			arsort($acceptList);
657
+			foreach ($acceptList as $accept => $quality) {
658
+				if (isset($this->format_map[$accept])) {
659
+					$format = $this->format_map[$accept];
660
+					$format = is_string($format) ? new $format : $format;
661
+					$format->setMIME($accept);
662
+					//echo "MIME $accept";
663
+					// Tell cache content is based on Accept header
664
+					header("Vary: Accept"); 
665
+					return $format;
666
+				}
667
+			}
668
+		} else {
669
+			// RFC 2616: If no Accept header field is
670
+			// present, then it is assumed that the
671
+			// client accepts all media types.
672
+			$_SERVER['HTTP_ACCEPT'] = '*/*';
673
+		}
674
+		if (strpos($_SERVER['HTTP_ACCEPT'], '*') !== false) {
675
+			if (strpos($_SERVER['HTTP_ACCEPT'], 'application/*') !== false) {
676
+				$format = new JsonFormat;
677
+			} else if (strpos($_SERVER['HTTP_ACCEPT'], 'text/*') !== false) {
678
+				$format = new XmlFormat;
679
+			} else if (strpos($_SERVER['HTTP_ACCEPT'], '*/*') !== false) {
680
+				$format = new $this->format_map['default'];
681
+			}
682
+		}
683
+		if (empty($format)) {
684
+			// RFC 2616: If an Accept header field is present, and if the 
685
+			// server cannot send a response which is acceptable according to 
686
+			// the combined Accept field value, then the server SHOULD send 
687
+			// a 406 (not acceptable) response.
688
+			header('HTTP/1.1 406 Not Acceptable');
689
+			die('406 Not Acceptable: The server was unable to ' . 
690
+					'negotiate content for this request.');
691
+		} else {
692
+			// Tell cache content is based ot Accept header
693
+			header("Vary: Accept"); 
694
+			return $format;
695
+		}
696
+	}
697
+
698
+
699
+	/**
700
+	 * Parses the request data and returns it
701
+	 * @return array php data
702
+	 */
703
+	protected function getRequestData()
704
+	{
705
+		try {
706
+			$r = file_get_contents('php://input');
707
+			if (is_null($r)) {
708
+				return $_GET;
709
+			}
710
+			$r = $this->request_format->decode($r);
711
+			return is_null($r) ? array() : $r;
712
+		} catch (RestException $e) {
713
+			$this->handleError($e->getCode(), $e->getMessage());
714
+		}
715
+	}
716
+
717
+
718
+	protected function mapUrlToMethod()
719
+	{
720
+		if (!isset($this->routes[$this->request_method])) {
721
+			return array();
722
+		}
723
+		$urls = $this->routes[$this->request_method];
724
+		if (!$urls) {
725
+			return array();
726
+		}
727
+
728
+		$found = false;
729
+		$this->request_data += $_GET;
730
+		$params = array('request_data' => $this->request_data);
731
+		$params += $this->request_data;
732
+		$lc = strtolower($this->url);
733
+		foreach ($urls as $url => $call) {
734
+			//echo PHP_EOL.$url.' = '.$this->url.PHP_EOL;
735
+			$call = (object) $call;
736
+			if (strstr($url, ':')) {
737
+				$regex = preg_replace('/\\\:([^\/]+)/', '(?P<$1>[^/]+)',
738
+					preg_quote($url));
739
+				if (preg_match(":^$regex$:i", $this->url, $matches)) {
740
+					foreach ($matches as $arg => $match) {
741
+						if (isset($call->arguments[$arg])) {
742
+							//flog("$arg => $match $args[$arg]");
743
+							$params[$arg] = $match;
744
+						}
745
+					}
746
+					$found = true;
747
+					break;
748
+				}
749
+			} else if ($url == $lc) {
750
+				$found = true;
751
+				break;
752
+			}
753
+		}
754
+		if ($found) {
755
+			//echo PHP_EOL."Found $url ";
756
+			//print_r($call);
757
+			$p = $call->defaults;
758
+			foreach ($call->arguments as $key => $value) {
759
+				//echo "$key => $value \n";
760
+				if (isset($params[$key])) {
761
+					$p[$value] = $params[$key];
762
+				}
763
+			}
764
+			$call->arguments = $p;
765
+			return $call;
766
+		}
767
+	}
768
+
769
+
770
+	/**
771
+	 * Apply static and non-static properties defined in
772
+	 * the method information anotation
773
+	 * @param String $class_name
774
+	 * @param Object $instance instance of that class
775
+	 * @param Object $method_info method information and metadata
776
+	 */
777
+	protected function applyClassMetadata($class_name, $instance, $method_info)
778
+	{
779
+		if (isset($method_info->metadata[$class_name])
780
+			&& is_array($method_info->metadata[$class_name])
781
+		) {
782
+			foreach ($method_info->metadata[$class_name] as
783
+					$property => $value) {
784
+				if (property_exists($class_name, $property)) {
785
+					$reflection_property = 
786
+						new ReflectionProperty($class_name, $property);
787
+					$reflection_property->setValue($instance, $value);
788
+				}
789
+			}
790
+		}
791
+	}
792
+
793
+
794
+	protected function loadCache()
795
+	{
796
+		if ($this->cached !== null) {
797
+			return;
798
+		}
799
+		$file = $this->cache_dir . '/routes.php';
800
+		$this->cached = false;
801
+
802
+		if ($this->production_mode) {
803
+			if (file_exists($file)) {
804
+				$routes = include($file);
805
+			}
806
+			if (isset($routes) && is_array($routes)) {
807
+				$this->routes = $routes;
808
+				$this->cached = true;
809
+			}
810
+		} else {
811
+			//@unlink($this->cache_dir . "/$name.php");
812
+		}
813
+	}
814
+
815
+
816
+	/**
817
+	 * Generates cachable url to method mapping
818
+	 * @param string $class_name
819
+	 * @param string $base_path
820
+	 */
821
+	protected function generateMap($class_name, $base_path = '')
822
+	{
823
+		$reflection = new ReflectionClass($class_name);
824
+		$class_metadata = parse_doc($reflection->getDocComment());
825
+		$methods = $reflection->getMethods(
826
+			ReflectionMethod::IS_PUBLIC + ReflectionMethod::IS_PROTECTED
827
+		);
828
+		foreach ($methods as $method) {
829
+			$doc = $method->getDocComment();
830
+			$arguments = array();
831
+			$defaults = array();
832
+			$metadata = $class_metadata + parse_doc($doc);
833
+			$params = $method->getParameters();
834
+			$position = 0;
835
+			foreach ($params as $param) {
836
+				$arguments[$param->getName()] = $position;
837
+				$defaults[$position] = $param->isDefaultValueAvailable() ? 
838
+					$param->getDefaultValue() : null;
839
+				$position++;
840
+			}
841
+			$method_flag = $method->isProtected() ? 
842
+				(isRestlerCompatibilityModeEnabled() ? 2 : 3) : 
843
+				(isset($metadata['protected']) ? 1 : 0);
844
+
845
+			//take note of the order
846
+			$call = array(
847
+				'class_name' => $class_name,
848
+				'method_name' => $method->getName(),
849
+				'arguments' => $arguments,
850
+				'defaults' => $defaults,
851
+				'metadata' => $metadata,
852
+				'method_flag' => $method_flag
853
+			);
854
+			$method_url = strtolower($method->getName());
855
+			if (preg_match_all(
856
+				'/@url\s+(GET|POST|PUT|DELETE|HEAD|OPTIONS)[ \t]*\/?(\S*)/s',
857
+					$doc, $matches, PREG_SET_ORDER)
858
+			) {
859
+				foreach ($matches as $match) {
860
+					$http_method = $match[1];
861
+					$url = rtrim($base_path . $match[2], '/');
862
+					$this->routes[$http_method][$url] = $call;
863
+				}
864
+			} elseif ($method_url[0] != '_') { 
865
+				//not prefixed with underscore
866
+				// no configuration found so use convention
867
+				if (preg_match_all('/^(GET|POST|PUT|DELETE|HEAD|OPTIONS)/i',
868
+						$method_url, $matches)
869
+				) {
870
+					$http_method = strtoupper($matches[0][0]);
871
+					$method_url = substr($method_url, strlen($http_method));
872
+				} else {
873
+					$http_method = 'GET';
874
+				}
875
+				$url = $base_path
876
+					. ($method_url == 'index' || $method_url == 'default' ? '' :
877
+						$method_url);
878
+				$url = rtrim($url, '/');
879
+				$this->routes[$http_method][$url] = $call;
880
+				foreach ($params as $param) {
881
+					if ($param->getName() == 'request_data') {
882
+						break;
883
+					}
884
+					$url .= $url == '' ? ':' : '/:';
885
+					$url .= $param->getName();
886
+					$this->routes[$http_method][$url] = $call;
887
+				}
888
+			}
889
+		}
890
+	}
891 891
 
892 892
 }
893 893
 
894 894
 if (version_compare(PHP_VERSION, '5.3.0') < 0) {
895
-    require_once 'compat.php';
895
+	require_once 'compat.php';
896 896
 }
897 897
 
898 898
 // ==================================================================
@@ -916,10 +916,10 @@  discard block
 block discarded – undo
916 916
 {
917 917
 
918 918
 
919
-    public function __construct($http_status_code, $error_message = null)
920
-    {
921
-        parent::__construct($error_message, $http_status_code);
922
-    }
919
+	public function __construct($http_status_code, $error_message = null)
920
+	{
921
+		parent::__construct($error_message, $http_status_code);
922
+	}
923 923
 
924 924
 }
925 925
 
@@ -937,21 +937,21 @@  discard block
 block discarded – undo
937 937
 {
938 938
 
939 939
 
940
-    /**
941
-     * Result of an api call is passed to this method
942
-     * to create a standard structure for the data
943
-     * @param unknown_type $result can be a primitive or array or object
944
-     */
945
-    public function __formatResponse($result);
940
+	/**
941
+	 * Result of an api call is passed to this method
942
+	 * to create a standard structure for the data
943
+	 * @param unknown_type $result can be a primitive or array or object
944
+	 */
945
+	public function __formatResponse($result);
946 946
 
947 947
 
948
-    /**
949
-     * When the api call results in RestException this method
950
-     * will be called to return the error message
951
-     * @param int $status_code
952
-     * @param String $message
953
-     */
954
-    public function __formatError($status_code, $message);
948
+	/**
949
+	 * When the api call results in RestException this method
950
+	 * will be called to return the error message
951
+	 * @param int $status_code
952
+	 * @param String $message
953
+	 */
954
+	public function __formatError($status_code, $message);
955 955
 }
956 956
 
957 957
 /**
@@ -968,21 +968,21 @@  discard block
 block discarded – undo
968 968
 {
969 969
 
970 970
 
971
-    public function __formatResponse($result)
972
-    {
973
-        return $result;
974
-    }
971
+	public function __formatResponse($result)
972
+	{
973
+		return $result;
974
+	}
975 975
 
976 976
 
977
-    public function __formatError($statusCode, $message)
978
-    {
979
-        return array(
980
-            'error' => array(
981
-                'code' => $statusCode,
982
-                'message' => $message
983
-            )
984
-        );
985
-    }
977
+	public function __formatError($statusCode, $message)
978
+	{
979
+		return array(
980
+			'error' => array(
981
+				'code' => $statusCode,
982
+				'message' => $message
983
+			)
984
+		);
985
+	}
986 986
 
987 987
 }
988 988
 
@@ -1000,11 +1000,11 @@  discard block
 block discarded – undo
1000 1000
 {
1001 1001
 
1002 1002
 
1003
-    /**
1004
-     * Auth function that is called when a protected method is requested
1005
-     * @return boolean true or false
1006
-     */
1007
-    public function __isAuthenticated();
1003
+	/**
1004
+	 * Auth function that is called when a protected method is requested
1005
+	 * @return boolean true or false
1006
+	 */
1007
+	public function __isAuthenticated();
1008 1008
 }
1009 1009
 
1010 1010
 /**
@@ -1022,60 +1022,60 @@  discard block
 block discarded – undo
1022 1022
 {
1023 1023
 
1024 1024
 
1025
-    /**
1026
-     * Get Extension => MIME type mappings as an associative array
1027
-     * @return array list of mime strings for the format
1028
-     * @example array('json'=>'application/json');
1029
-     */
1030
-    public function getMIMEMap();
1025
+	/**
1026
+	 * Get Extension => MIME type mappings as an associative array
1027
+	 * @return array list of mime strings for the format
1028
+	 * @example array('json'=>'application/json');
1029
+	 */
1030
+	public function getMIMEMap();
1031 1031
 
1032 1032
 
1033
-    /**
1034
-     * Set the selected MIME type
1035
-     * @param string $mime MIME type
1036
-     */
1037
-    public function setMIME($mime);
1033
+	/**
1034
+	 * Set the selected MIME type
1035
+	 * @param string $mime MIME type
1036
+	 */
1037
+	public function setMIME($mime);
1038 1038
 
1039 1039
 
1040
-    /**
1041
-     * Get selected MIME type
1042
-     */
1043
-    public function getMIME();
1040
+	/**
1041
+	 * Get selected MIME type
1042
+	 */
1043
+	public function getMIME();
1044 1044
 
1045 1045
 
1046
-    /**
1047
-     * Set the selected file extension
1048
-     * @param string $extension file extension
1049
-     */
1050
-    public function setExtension($extension);
1046
+	/**
1047
+	 * Set the selected file extension
1048
+	 * @param string $extension file extension
1049
+	 */
1050
+	public function setExtension($extension);
1051 1051
 
1052 1052
 
1053
-    /**
1054
-     * Get the selected file extension
1055
-     * @return string file extension
1056
-     */
1057
-    public function getExtension();
1053
+	/**
1054
+	 * Get the selected file extension
1055
+	 * @return string file extension
1056
+	 */
1057
+	public function getExtension();
1058 1058
 
1059 1059
 
1060
-    /**
1061
-     * Encode the given data in the format
1062
-     * @param array $data resulting data that needs to
1063
-     * be encoded in the given format
1064
-     * @param boolean $human_readable set to true when restler
1065
-     * is not running in production mode. Formatter has to
1066
-     * make the encoded output more human readable
1067
-     * @return string encoded string
1068
-     */
1069
-    public function encode($data, $human_readable = false);
1060
+	/**
1061
+	 * Encode the given data in the format
1062
+	 * @param array $data resulting data that needs to
1063
+	 * be encoded in the given format
1064
+	 * @param boolean $human_readable set to true when restler
1065
+	 * is not running in production mode. Formatter has to
1066
+	 * make the encoded output more human readable
1067
+	 * @return string encoded string
1068
+	 */
1069
+	public function encode($data, $human_readable = false);
1070 1070
 
1071 1071
 
1072
-    /**
1073
-     * Decode the given data from the format
1074
-     * @param string $data data sent from client to
1075
-     * the api in the given format.
1076
-     * @return array associative array of the parsed data
1077
-     */
1078
-    public function decode($data);
1072
+	/**
1073
+	 * Decode the given data from the format
1074
+	 * @param string $data data sent from client to
1075
+	 * the api in the given format.
1076
+	 * @return array associative array of the parsed data
1077
+	 */
1078
+	public function decode($data);
1079 1079
 }
1080 1080
 
1081 1081
 /**
@@ -1091,57 +1091,57 @@  discard block
 block discarded – undo
1091 1091
 class UrlEncodedFormat implements iFormat
1092 1092
 {
1093 1093
 
1094
-    const MIME = 'application/x-www-form-urlencoded';
1095
-    const EXTENSION = 'post';
1094
+	const MIME = 'application/x-www-form-urlencoded';
1095
+	const EXTENSION = 'post';
1096 1096
 
1097 1097
 
1098
-    public function getMIMEMap()
1099
-    {
1100
-        return array(self::EXTENSION => self::MIME);
1101
-    }
1098
+	public function getMIMEMap()
1099
+	{
1100
+		return array(self::EXTENSION => self::MIME);
1101
+	}
1102 1102
 
1103 1103
 
1104
-    public function getMIME()
1105
-    {
1106
-        return self::MIME;
1107
-    }
1104
+	public function getMIME()
1105
+	{
1106
+		return self::MIME;
1107
+	}
1108 1108
 
1109 1109
 
1110
-    public function getExtension()
1111
-    {
1112
-        return self::EXTENSION;
1113
-    }
1110
+	public function getExtension()
1111
+	{
1112
+		return self::EXTENSION;
1113
+	}
1114 1114
 
1115 1115
 
1116
-    public function setMIME($mime)
1117
-    {
1118
-        //do nothing
1119
-    }
1116
+	public function setMIME($mime)
1117
+	{
1118
+		//do nothing
1119
+	}
1120 1120
 
1121 1121
 
1122
-    public function setExtension($extension)
1123
-    {
1124
-        //do nothing
1125
-    }
1122
+	public function setExtension($extension)
1123
+	{
1124
+		//do nothing
1125
+	}
1126 1126
 
1127 1127
 
1128
-    public function encode($data, $human_readable = false)
1129
-    {
1130
-        return http_build_query($data);
1131
-    }
1128
+	public function encode($data, $human_readable = false)
1129
+	{
1130
+		return http_build_query($data);
1131
+	}
1132 1132
 
1133 1133
 
1134
-    public function decode($data)
1135
-    {
1136
-        parse_str($data, $r);
1137
-        return $r;
1138
-    }
1134
+	public function decode($data)
1135
+	{
1136
+		parse_str($data, $r);
1137
+		return $r;
1138
+	}
1139 1139
 
1140 1140
 
1141
-    public function __toString()
1142
-    {
1143
-        return $this->getExtension();
1144
-    }
1141
+	public function __toString()
1142
+	{
1143
+		return $this->getExtension();
1144
+	}
1145 1145
 
1146 1146
 }
1147 1147
 
@@ -1158,158 +1158,158 @@  discard block
 block discarded – undo
1158 1158
 class JsonFormat implements iFormat
1159 1159
 {
1160 1160
 
1161
-    const MIME = 'application/json,application/javascript';
1162
-
1163
-    static $mime = 'application/json';
1164
-
1165
-    const EXTENSION = 'json';
1166
-
1167
-
1168
-    public function getMIMEMap()
1169
-    {
1170
-        return array(self::EXTENSION => self::MIME);
1171
-    }
1172
-
1173
-
1174
-    public function getMIME()
1175
-    {
1176
-        return self::$mime;
1177
-    }
1178
-
1179
-
1180
-    public function getExtension()
1181
-    {
1182
-        return self::EXTENSION;
1183
-    }
1184
-
1185
-
1186
-    public function setMIME($mime)
1187
-    {
1188
-        self::$mime = $mime;
1189
-    }
1190
-
1191
-
1192
-    public function setExtension($extension)
1193
-    {
1194
-        //do nothing
1195
-    }
1196
-
1197
-
1198
-    public function encode($data, $human_readable = false)
1199
-    {
1200
-        return $human_readable ? 
1201
-            $this->json_format(json_encode(object_to_array($data))) : 
1202
-            json_encode(object_to_array($data));
1203
-    }
1204
-
1205
-
1206
-    public function decode($data)
1207
-    {
1208
-        $decoded = json_decode($data);
1209
-        if (function_exists('json_last_error')) {
1210
-            $message = '';
1211
-            switch (json_last_error()) {
1212
-                case JSON_ERROR_NONE:
1213
-                    return object_to_array($decoded);
1214
-                    break;
1215
-                case JSON_ERROR_DEPTH:
1216
-                    $message = 'maximum stack depth exceeded';
1217
-                    break;
1218
-                case JSON_ERROR_STATE_MISMATCH:
1219
-                    $message = 'underflow or the modes mismatch';
1220
-                    break;
1221
-                case JSON_ERROR_CTRL_CHAR:
1222
-                    $message = 'unexpected control character found';
1223
-                    break;
1224
-                case JSON_ERROR_SYNTAX:
1225
-                    $message = 'malformed JSON';
1226
-                    break;
1227
-                case JSON_ERROR_UTF8:
1228
-                    $message = 'malformed UTF-8 characters, '.
1229
-                        'possibly incorrectly encoded';
1230
-                    break;
1231
-                default:
1232
-                    $message = 'unknown error';
1233
-                    break;
1234
-            }
1235
-            throw new RestException(400, 'Error parsing JSON, ' . $message);
1236
-        } else if (strlen($data) && $decoded === null || $decoded === $data) {
1237
-            throw new RestException(400, 'Error parsing JSON');
1238
-        }
1239
-        return object_to_array($decoded);
1240
-    }
1241
-
1242
-
1243
-    /**
1244
-     * Pretty print JSON string
1245
-     * @param string $json
1246
-     * @return string formated json
1247
-     */
1248
-    private function json_format($json)
1249
-    {
1250
-        $tab = "  ";
1251
-        $new_json = "";
1252
-        $indent_level = 0;
1253
-        $in_string = false;
1254
-        $len = strlen($json);
1255
-
1256
-        for ($c = 0; $c < $len; $c++) {
1257
-            $char = $json[$c];
1258
-            switch ($char) {
1259
-                case '{':
1260
-                case '[':
1261
-                    if (!$in_string) {
1262
-                        $new_json .= $char . "\n" .
1263
-                            str_repeat($tab, $indent_level + 1);
1264
-                        $indent_level++;
1265
-                    } else {
1266
-                        $new_json .= $char;
1267
-                    }
1268
-                    break;
1269
-                case '}':
1270
-                case ']':
1271
-                    if (!$in_string) {
1272
-                        $indent_level--;
1273
-                        $new_json .= "\n" . str_repeat($tab, $indent_level) 
1274
-                            . $char;
1275
-                    } else {
1276
-                        $new_json .= $char;
1277
-                    }
1278
-                    break;
1279
-                case ',':
1280
-                    if (!$in_string) {
1281
-                        $new_json .= ",\n" . str_repeat($tab, $indent_level);
1282
-                    } else {
1283
-                        $new_json .= $char;
1284
-                    }
1285
-                    break;
1286
-                case ':':
1287
-                    if (!$in_string) {
1288
-                        $new_json .= ": ";
1289
-                    } else {
1290
-                        $new_json .= $char;
1291
-                    }
1292
-                    break;
1293
-                case '"':
1294
-                    if ($c == 0) {
1295
-                        $in_string = true;
1296
-                    } else if ($c > 0 && $json[$c - 1] != '\\') {
1297
-                        $in_string = !$in_string;
1298
-                    }
1299
-                default:
1300
-                    $new_json .= $char;
1301
-                    break;
1302
-            }
1303
-        }
1304
-
1305
-        return $new_json;
1306
-    }
1307
-
1308
-
1309
-    public function __toString()
1310
-    {
1311
-        return $this->getExtension();
1312
-    }
1161
+	const MIME = 'application/json,application/javascript';
1162
+
1163
+	static $mime = 'application/json';
1164
+
1165
+	const EXTENSION = 'json';
1166
+
1167
+
1168
+	public function getMIMEMap()
1169
+	{
1170
+		return array(self::EXTENSION => self::MIME);
1171
+	}
1172
+
1173
+
1174
+	public function getMIME()
1175
+	{
1176
+		return self::$mime;
1177
+	}
1178
+
1179
+
1180
+	public function getExtension()
1181
+	{
1182
+		return self::EXTENSION;
1183
+	}
1184
+
1185
+
1186
+	public function setMIME($mime)
1187
+	{
1188
+		self::$mime = $mime;
1189
+	}
1190
+
1191
+
1192
+	public function setExtension($extension)
1193
+	{
1194
+		//do nothing
1195
+	}
1196
+
1197
+
1198
+	public function encode($data, $human_readable = false)
1199
+	{
1200
+		return $human_readable ? 
1201
+			$this->json_format(json_encode(object_to_array($data))) : 
1202
+			json_encode(object_to_array($data));
1203
+	}
1204
+
1205
+
1206
+	public function decode($data)
1207
+	{
1208
+		$decoded = json_decode($data);
1209
+		if (function_exists('json_last_error')) {
1210
+			$message = '';
1211
+			switch (json_last_error()) {
1212
+				case JSON_ERROR_NONE:
1213
+					return object_to_array($decoded);
1214
+					break;
1215
+				case JSON_ERROR_DEPTH:
1216
+					$message = 'maximum stack depth exceeded';
1217
+					break;
1218
+				case JSON_ERROR_STATE_MISMATCH:
1219
+					$message = 'underflow or the modes mismatch';
1220
+					break;
1221
+				case JSON_ERROR_CTRL_CHAR:
1222
+					$message = 'unexpected control character found';
1223
+					break;
1224
+				case JSON_ERROR_SYNTAX:
1225
+					$message = 'malformed JSON';
1226
+					break;
1227
+				case JSON_ERROR_UTF8:
1228
+					$message = 'malformed UTF-8 characters, '.
1229
+						'possibly incorrectly encoded';
1230
+					break;
1231
+				default:
1232
+					$message = 'unknown error';
1233
+					break;
1234
+			}
1235
+			throw new RestException(400, 'Error parsing JSON, ' . $message);
1236
+		} else if (strlen($data) && $decoded === null || $decoded === $data) {
1237
+			throw new RestException(400, 'Error parsing JSON');
1238
+		}
1239
+		return object_to_array($decoded);
1240
+	}
1241
+
1242
+
1243
+	/**
1244
+	 * Pretty print JSON string
1245
+	 * @param string $json
1246
+	 * @return string formated json
1247
+	 */
1248
+	private function json_format($json)
1249
+	{
1250
+		$tab = "  ";
1251
+		$new_json = "";
1252
+		$indent_level = 0;
1253
+		$in_string = false;
1254
+		$len = strlen($json);
1255
+
1256
+		for ($c = 0; $c < $len; $c++) {
1257
+			$char = $json[$c];
1258
+			switch ($char) {
1259
+				case '{':
1260
+				case '[':
1261
+					if (!$in_string) {
1262
+						$new_json .= $char . "\n" .
1263
+							str_repeat($tab, $indent_level + 1);
1264
+						$indent_level++;
1265
+					} else {
1266
+						$new_json .= $char;
1267
+					}
1268
+					break;
1269
+				case '}':
1270
+				case ']':
1271
+					if (!$in_string) {
1272
+						$indent_level--;
1273
+						$new_json .= "\n" . str_repeat($tab, $indent_level) 
1274
+							. $char;
1275
+					} else {
1276
+						$new_json .= $char;
1277
+					}
1278
+					break;
1279
+				case ',':
1280
+					if (!$in_string) {
1281
+						$new_json .= ",\n" . str_repeat($tab, $indent_level);
1282
+					} else {
1283
+						$new_json .= $char;
1284
+					}
1285
+					break;
1286
+				case ':':
1287
+					if (!$in_string) {
1288
+						$new_json .= ": ";
1289
+					} else {
1290
+						$new_json .= $char;
1291
+					}
1292
+					break;
1293
+				case '"':
1294
+					if ($c == 0) {
1295
+						$in_string = true;
1296
+					} else if ($c > 0 && $json[$c - 1] != '\\') {
1297
+						$in_string = !$in_string;
1298
+					}
1299
+				default:
1300
+					$new_json .= $char;
1301
+					break;
1302
+			}
1303
+		}
1304
+
1305
+		return $new_json;
1306
+	}
1307
+
1308
+
1309
+	public function __toString()
1310
+	{
1311
+		return $this->getExtension();
1312
+	}
1313 1313
 
1314 1314
 }
1315 1315
 
@@ -1327,123 +1327,123 @@  discard block
 block discarded – undo
1327 1327
 class DocParser
1328 1328
 {
1329 1329
 
1330
-    private $params = array();
1331
-
1332
-
1333
-    public function parse($doc = '')
1334
-    {
1335
-        if ($doc == '') {
1336
-            return $this->params;
1337
-        }
1338
-        //Get the comment
1339
-        if (preg_match('#^/\*\*(.*)\*/#s', $doc, $comment) === false) {
1340
-            return $this->params;
1341
-        }
1342
-        $comment = trim($comment[1]);
1343
-        //Get all the lines and strip the * from the first character
1344
-        if (preg_match_all('#^\s*\*(.*)#m', $comment, $lines) === false) {
1345
-            return $this->params;
1346
-        }
1347
-        $this->parseLines($lines[1]);
1348
-        return $this->params;
1349
-    }
1350
-
1351
-
1352
-    private function parseLines($lines)
1353
-    {
1354
-        foreach ($lines as $line) {
1355
-            $parsedLine = $this->parseLine($line); //Parse the line
1356
-
1357
-            if ($parsedLine === false && !isset($this->params['description'])) {
1358
-                if (isset($desc)) {
1359
-                    //Store the first line in the short description
1360
-                    $this->params['description'] = implode(PHP_EOL, $desc);
1361
-                }
1362
-                $desc = array();
1363
-            } else if ($parsedLine !== false) {
1364
-                $desc[] = $parsedLine; //Store the line in the long description
1365
-            }
1366
-        }
1367
-        $desc = implode(' ', $desc);
1368
-        if (!empty($desc)) {
1369
-            $this->params['long_description'] = $desc;
1370
-        }
1371
-    }
1372
-
1373
-
1374
-    private function parseLine($line)
1375
-    {
1376
-        //trim the whitespace from the line
1377
-        $line = trim($line);
1378
-
1379
-        if (empty($line)) {
1380
-            return false; //Empty line
1381
-        }
1382
-
1383
-        if (strpos($line, '@') === 0) {
1384
-            if (strpos($line, ' ') > 0) {
1385
-                //Get the parameter name
1386
-                $param = substr($line, 1, strpos($line, ' ') - 1);
1387
-                $value = substr($line, strlen($param) + 2); //Get the value
1388
-            } else {
1389
-                $param = substr($line, 1);
1390
-                $value = '';
1391
-            }
1392
-            //Parse the line and return false if the parameter is valid
1393
-            if ($this->setParam($param, $value)) {
1394
-                return false;
1395
-            }
1396
-        }
1397
-        return $line;
1398
-    }
1399
-
1400
-
1401
-    private function setParam($param, $value)
1402
-    {
1403
-        if ($param == 'param' || $param == 'return') {
1404
-            $value = $this->formatParamOrReturn($value);
1405
-        }
1406
-        if ($param == 'class') {
1407
-            list($param, $value) = $this->formatClass($value);
1408
-        }
1409
-
1410
-        if (empty($this->params[$param])) {
1411
-            $this->params[$param] = $value;
1412
-        } else if ($param == 'param') {
1413
-            $arr = array($this->params[$param], $value);
1414
-            $this->params[$param] = $arr;
1415
-        } else {
1416
-            $this->params[$param] = $value + $this->params[$param];
1417
-        }
1418
-        return true;
1419
-    }
1420
-
1421
-
1422
-    private function formatClass($value)
1423
-    {
1424
-        $r = preg_split("[\(|\)]", $value);
1425
-        if (count($r) > 1) {
1426
-            $param = $r[0];
1427
-            parse_str($r[1], $value);
1428
-            foreach ($value as $key => $val) {
1429
-                $val = explode(',', $val);
1430
-                if (count($val) > 1) {
1431
-                    $value[$key] = $val;
1432
-                }
1433
-            }
1434
-        } else {
1435
-            $param = 'Unknown';
1436
-        }
1437
-        return array($param, $value);
1438
-    }
1439
-
1440
-
1441
-    private function formatParamOrReturn($string)
1442
-    {
1443
-        $pos = strpos($string, ' ');
1444
-        $type = substr($string, 0, $pos);
1445
-        return '(' . $type . ')' . substr($string, $pos + 1);
1446
-    }
1330
+	private $params = array();
1331
+
1332
+
1333
+	public function parse($doc = '')
1334
+	{
1335
+		if ($doc == '') {
1336
+			return $this->params;
1337
+		}
1338
+		//Get the comment
1339
+		if (preg_match('#^/\*\*(.*)\*/#s', $doc, $comment) === false) {
1340
+			return $this->params;
1341
+		}
1342
+		$comment = trim($comment[1]);
1343
+		//Get all the lines and strip the * from the first character
1344
+		if (preg_match_all('#^\s*\*(.*)#m', $comment, $lines) === false) {
1345
+			return $this->params;
1346
+		}
1347
+		$this->parseLines($lines[1]);
1348
+		return $this->params;
1349
+	}
1350
+
1351
+
1352
+	private function parseLines($lines)
1353
+	{
1354
+		foreach ($lines as $line) {
1355
+			$parsedLine = $this->parseLine($line); //Parse the line
1356
+
1357
+			if ($parsedLine === false && !isset($this->params['description'])) {
1358
+				if (isset($desc)) {
1359
+					//Store the first line in the short description
1360
+					$this->params['description'] = implode(PHP_EOL, $desc);
1361
+				}
1362
+				$desc = array();
1363
+			} else if ($parsedLine !== false) {
1364
+				$desc[] = $parsedLine; //Store the line in the long description
1365
+			}
1366
+		}
1367
+		$desc = implode(' ', $desc);
1368
+		if (!empty($desc)) {
1369
+			$this->params['long_description'] = $desc;
1370
+		}
1371
+	}
1372
+
1373
+
1374
+	private function parseLine($line)
1375
+	{
1376
+		//trim the whitespace from the line
1377
+		$line = trim($line);
1378
+
1379
+		if (empty($line)) {
1380
+			return false; //Empty line
1381
+		}
1382
+
1383
+		if (strpos($line, '@') === 0) {
1384
+			if (strpos($line, ' ') > 0) {
1385
+				//Get the parameter name
1386
+				$param = substr($line, 1, strpos($line, ' ') - 1);
1387
+				$value = substr($line, strlen($param) + 2); //Get the value
1388
+			} else {
1389
+				$param = substr($line, 1);
1390
+				$value = '';
1391
+			}
1392
+			//Parse the line and return false if the parameter is valid
1393
+			if ($this->setParam($param, $value)) {
1394
+				return false;
1395
+			}
1396
+		}
1397
+		return $line;
1398
+	}
1399
+
1400
+
1401
+	private function setParam($param, $value)
1402
+	{
1403
+		if ($param == 'param' || $param == 'return') {
1404
+			$value = $this->formatParamOrReturn($value);
1405
+		}
1406
+		if ($param == 'class') {
1407
+			list($param, $value) = $this->formatClass($value);
1408
+		}
1409
+
1410
+		if (empty($this->params[$param])) {
1411
+			$this->params[$param] = $value;
1412
+		} else if ($param == 'param') {
1413
+			$arr = array($this->params[$param], $value);
1414
+			$this->params[$param] = $arr;
1415
+		} else {
1416
+			$this->params[$param] = $value + $this->params[$param];
1417
+		}
1418
+		return true;
1419
+	}
1420
+
1421
+
1422
+	private function formatClass($value)
1423
+	{
1424
+		$r = preg_split("[\(|\)]", $value);
1425
+		if (count($r) > 1) {
1426
+			$param = $r[0];
1427
+			parse_str($r[1], $value);
1428
+			foreach ($value as $key => $val) {
1429
+				$val = explode(',', $val);
1430
+				if (count($val) > 1) {
1431
+					$value[$key] = $val;
1432
+				}
1433
+			}
1434
+		} else {
1435
+			$param = 'Unknown';
1436
+		}
1437
+		return array($param, $value);
1438
+	}
1439
+
1440
+
1441
+	private function formatParamOrReturn($string)
1442
+	{
1443
+		$pos = strpos($string, ' ');
1444
+		$type = substr($string, 0, $pos);
1445
+		return '(' . $type . ')' . substr($string, $pos + 1);
1446
+	}
1447 1447
 
1448 1448
 }
1449 1449
 
@@ -1456,30 +1456,30 @@  discard block
 block discarded – undo
1456 1456
 
1457 1457
 function parse_doc($php_doc_comment)
1458 1458
 {
1459
-    $p = new DocParser();
1460
-    return $p->parse($php_doc_comment);
1459
+	$p = new DocParser();
1460
+	return $p->parse($php_doc_comment);
1461 1461
 
1462
-    $p = new Parser($php_doc_comment);
1463
-    return $p;
1462
+	$p = new Parser($php_doc_comment);
1463
+	return $p;
1464 1464
 
1465
-    $php_doc_comment = preg_replace(
1466
-        "/(^[\\s]*\\/\\*\\*)
1465
+	$php_doc_comment = preg_replace(
1466
+		"/(^[\\s]*\\/\\*\\*)
1467 1467
         |(^[\\s]\\*\\/)
1468 1468
         |(^[\\s]*\\*?\\s)
1469 1469
         |(^[\\s]*)
1470 1470
         |(^[\\t]*)/ixm",
1471
-        "", $php_doc_comment);
1472
-    $php_doc_comment = str_replace("\r", "", $php_doc_comment);
1473
-    $php_doc_comment = preg_replace("/([\\t])+/", "\t", $php_doc_comment);
1474
-    return explode("\n", $php_doc_comment);
1475
-
1476
-    $php_doc_comment = trim(preg_replace('/\r?\n *\* */', ' ', 
1477
-            $php_doc_comment));
1478
-    return $php_doc_comment;
1479
-
1480
-    preg_match_all('/@([a-z]+)\s+(.*?)\s*(?=$|@[a-z]+\s)/s', $php_doc_comment,
1481
-        $matches);
1482
-    return array_combine($matches[1], $matches[2]);
1471
+		"", $php_doc_comment);
1472
+	$php_doc_comment = str_replace("\r", "", $php_doc_comment);
1473
+	$php_doc_comment = preg_replace("/([\\t])+/", "\t", $php_doc_comment);
1474
+	return explode("\n", $php_doc_comment);
1475
+
1476
+	$php_doc_comment = trim(preg_replace('/\r?\n *\* */', ' ', 
1477
+			$php_doc_comment));
1478
+	return $php_doc_comment;
1479
+
1480
+	preg_match_all('/@([a-z]+)\s+(.*?)\s*(?=$|@[a-z]+\s)/s', $php_doc_comment,
1481
+		$matches);
1482
+	return array_combine($matches[1], $matches[2]);
1483 1483
 }
1484 1484
 
1485 1485
 
@@ -1498,21 +1498,21 @@  discard block
 block discarded – undo
1498 1498
  */
1499 1499
 function object_to_array($object, $utf_encode = false)
1500 1500
 {
1501
-    if (is_array($object)
1502
-        || (is_object($object)
1503
-        && !($object instanceof JsonSerializable))
1504
-    ) {
1505
-        $array = array();
1506
-        foreach ($object as $key => $value) {
1507
-            $value = object_to_array($value, $utf_encode);
1508
-            if ($utf_encode && is_string($value)) {
1509
-                $value = utf8_encode($value);
1510
-            }
1511
-            $array[$key] = $value;
1512
-        }
1513
-        return $array;
1514
-    }
1515
-    return $object;
1501
+	if (is_array($object)
1502
+		|| (is_object($object)
1503
+		&& !($object instanceof JsonSerializable))
1504
+	) {
1505
+		$array = array();
1506
+		foreach ($object as $key => $value) {
1507
+			$value = object_to_array($value, $utf_encode);
1508
+			if ($utf_encode && is_string($value)) {
1509
+				$value = utf8_encode($value);
1510
+			}
1511
+			$array[$key] = $value;
1512
+		}
1513
+		return $array;
1514
+	}
1515
+	return $object;
1516 1516
 }
1517 1517
 
1518 1518
 
@@ -1522,21 +1522,21 @@  discard block
 block discarded – undo
1522 1522
  */
1523 1523
 function autoload_formats($class_name)
1524 1524
 {
1525
-    $class_name = strtolower($class_name);
1525
+	$class_name = strtolower($class_name);
1526 1526
 	
1527
-    $file = RESTLER_PATH . "../../../api/mobile_services/$class_name.php";
1528
-    if (file_exists($file)) {
1529
-        require_once ($file);
1530
-    } else {
1527
+	$file = RESTLER_PATH . "../../../api/mobile_services/$class_name.php";
1528
+	if (file_exists($file)) {
1529
+		require_once ($file);
1530
+	} else {
1531 1531
 		$file = RESTLER_PATH . "/../../api/mobile_services/$class_name.php";
1532
-        if (file_exists($file)) {
1533
-            require_once ($file);
1534
-        } elseif (file_exists(RESTLER_PATH . "/../api/mobile_services/$class_name.php")) {
1535
-            require_once ("/../api/mobile_services/$class_name.php");
1536
-        } elseif (file_exists("$class_name.php")) {
1537
-            require_once ("$class_name.php");
1538
-        }
1539
-    }
1532
+		if (file_exists($file)) {
1533
+			require_once ($file);
1534
+		} elseif (file_exists(RESTLER_PATH . "/../api/mobile_services/$class_name.php")) {
1535
+			require_once ("/../api/mobile_services/$class_name.php");
1536
+		} elseif (file_exists("$class_name.php")) {
1537
+			require_once ("$class_name.php");
1538
+		}
1539
+	}
1540 1540
 }
1541 1541
 
1542 1542
 // ==================================================================
@@ -1553,10 +1553,10 @@  discard block
 block discarded – undo
1553 1553
 if (!function_exists('isRestlerCompatibilityModeEnabled')) {
1554 1554
 
1555 1555
 
1556
-    function isRestlerCompatibilityModeEnabled()
1557
-    {
1558
-        return false;
1559
-    }
1556
+	function isRestlerCompatibilityModeEnabled()
1557
+	{
1558
+		return false;
1559
+	}
1560 1560
 
1561 1561
 }
1562 1562
 define('RESTLER_PATH', dirname(__FILE__));
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/FS/HomeCollection.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@
 block discarded – undo
70 70
      * supplied by the authentication backend.
71 71
      *
72 72
      * @param array $principalInfo
73
-     * @return void
73
+     * @return Collection
74 74
      */
75 75
     function getChildForPrincipal(array $principalInfo) {
76 76
 
Please login to merge, or discard this patch.
Unused Use Statements   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -2,10 +2,10 @@
 block discarded – undo
2 2
 
3 3
 namespace Sabre\DAVACL\FS;
4 4
 
5
-use Sabre\DAV\Exception\Forbidden;
6 5
 use Sabre\DAVACL\AbstractPrincipalCollection;
7 6
 use Sabre\DAVACL\IACL;
8 7
 use Sabre\DAVACL\PrincipalBackend\BackendInterface;
8
+use Sabre\DAV\Exception\Forbidden;
9 9
 use Sabre\Uri;
10 10
 
11 11
 /**
Please login to merge, or discard this patch.
Indentation   +163 added lines, -163 removed lines patch added patch discarded remove patch
@@ -21,168 +21,168 @@
 block discarded – undo
21 21
  */
22 22
 class HomeCollection extends AbstractPrincipalCollection implements IACL {
23 23
 
24
-    /**
25
-     * Name of this collection.
26
-     *
27
-     * @var string
28
-     */
29
-    public $collectionName = 'home';
30
-
31
-    /**
32
-     * Path to where the users' files are actually stored.
33
-     *
34
-     * @var string
35
-     */
36
-    protected $storagePath;
37
-
38
-    /**
39
-     * Creates the home collection.
40
-     *
41
-     * @param BackendInterface $principalBackend
42
-     * @param string $storagePath Where the actual files are stored.
43
-     * @param string $principalPrefix list of principals to iterate.
44
-     */
45
-    public function __construct(BackendInterface $principalBackend, $storagePath, $principalPrefix = 'principals') {
46
-
47
-        parent::__construct($principalBackend, $principalPrefix);
48
-        $this->storagePath = $storagePath;
49
-
50
-    }
51
-
52
-    /**
53
-     * Returns the name of the node.
54
-     *
55
-     * This is used to generate the url.
56
-     *
57
-     * @return string
58
-     */
59
-    public function getName() {
60
-
61
-        return $this->collectionName;
62
-
63
-    }
64
-
65
-    /**
66
-     * Returns a principals' collection of files.
67
-     *
68
-     * The passed array contains principal information, and is guaranteed to
69
-     * at least contain a uri item. Other properties may or may not be
70
-     * supplied by the authentication backend.
71
-     *
72
-     * @param array $principalInfo
73
-     * @return void
74
-     */
75
-    public function getChildForPrincipal(array $principalInfo) {
76
-
77
-        $owner = $principalInfo['uri'];
78
-        $acl = [
79
-            [
80
-                'privilege' => '{DAV:}read',
81
-                'principal' => $owner,
82
-                'protected' => true,
83
-            ],
84
-            [
85
-                'privilege' => '{DAV:}write',
86
-                'principal' => $owner,
87
-                'protected' => true,
88
-            ],
89
-        ];
90
-
91
-        list(, $principalBaseName) = Uri\split($owner);
92
-
93
-        $path = $this->storagePath . '/' . $principalBaseName;
94
-
95
-        if (!is_dir($path)) {
96
-            mkdir($path, 0777, true);
97
-        }
98
-        return new Collection(
99
-            $path,
100
-            $acl,
101
-            $owner
102
-        );
103
-
104
-    }
105
-
106
-    /**
107
-     * Returns the owner principal
108
-     *
109
-     * This must be a url to a principal, or null if there's no owner
110
-     *
111
-     * @return string|null
112
-     */
113
-    public function getOwner() {
114
-
115
-        return null;
116
-
117
-    }
118
-
119
-    /**
120
-     * Returns a group principal
121
-     *
122
-     * This must be a url to a principal, or null if there's no owner
123
-     *
124
-     * @return string|null
125
-     */
126
-    public function getGroup() {
127
-
128
-        return null;
129
-
130
-    }
131
-
132
-    /**
133
-     * Returns a list of ACE's for this node.
134
-     *
135
-     * Each ACE has the following properties:
136
-     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
137
-     *     currently the only supported privileges
138
-     *   * 'principal', a url to the principal who owns the node
139
-     *   * 'protected' (optional), indicating that this ACE is not allowed to
140
-     *      be updated.
141
-     *
142
-     * @return array
143
-     */
144
-    public function getACL() {
145
-
146
-        return [
147
-            [
148
-                'principal' => '{DAV:}authenticated',
149
-                'privilege' => '{DAV:}read',
150
-                'protected' => true,
151
-            ]
152
-        ];
153
-
154
-    }
155
-
156
-    /**
157
-     * Updates the ACL
158
-     *
159
-     * This method will receive a list of new ACE's as an array argument.
160
-     *
161
-     * @param array $acl
162
-     * @return void
163
-     */
164
-    public function setACL(array $acl) {
165
-
166
-        throw new Forbidden('Setting ACL is not allowed here');
167
-
168
-    }
169
-
170
-    /**
171
-     * Returns the list of supported privileges for this node.
172
-     *
173
-     * The returned data structure is a list of nested privileges.
174
-     * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
175
-     * standard structure.
176
-     *
177
-     * If null is returned from this method, the default privilege set is used,
178
-     * which is fine for most common usecases.
179
-     *
180
-     * @return array|null
181
-     */
182
-    public function getSupportedPrivilegeSet() {
183
-
184
-        return null;
185
-
186
-    }
24
+	/**
25
+	 * Name of this collection.
26
+	 *
27
+	 * @var string
28
+	 */
29
+	public $collectionName = 'home';
30
+
31
+	/**
32
+	 * Path to where the users' files are actually stored.
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $storagePath;
37
+
38
+	/**
39
+	 * Creates the home collection.
40
+	 *
41
+	 * @param BackendInterface $principalBackend
42
+	 * @param string $storagePath Where the actual files are stored.
43
+	 * @param string $principalPrefix list of principals to iterate.
44
+	 */
45
+	public function __construct(BackendInterface $principalBackend, $storagePath, $principalPrefix = 'principals') {
46
+
47
+		parent::__construct($principalBackend, $principalPrefix);
48
+		$this->storagePath = $storagePath;
49
+
50
+	}
51
+
52
+	/**
53
+	 * Returns the name of the node.
54
+	 *
55
+	 * This is used to generate the url.
56
+	 *
57
+	 * @return string
58
+	 */
59
+	public function getName() {
60
+
61
+		return $this->collectionName;
62
+
63
+	}
64
+
65
+	/**
66
+	 * Returns a principals' collection of files.
67
+	 *
68
+	 * The passed array contains principal information, and is guaranteed to
69
+	 * at least contain a uri item. Other properties may or may not be
70
+	 * supplied by the authentication backend.
71
+	 *
72
+	 * @param array $principalInfo
73
+	 * @return void
74
+	 */
75
+	public function getChildForPrincipal(array $principalInfo) {
76
+
77
+		$owner = $principalInfo['uri'];
78
+		$acl = [
79
+			[
80
+				'privilege' => '{DAV:}read',
81
+				'principal' => $owner,
82
+				'protected' => true,
83
+			],
84
+			[
85
+				'privilege' => '{DAV:}write',
86
+				'principal' => $owner,
87
+				'protected' => true,
88
+			],
89
+		];
90
+
91
+		list(, $principalBaseName) = Uri\split($owner);
92
+
93
+		$path = $this->storagePath . '/' . $principalBaseName;
94
+
95
+		if (!is_dir($path)) {
96
+			mkdir($path, 0777, true);
97
+		}
98
+		return new Collection(
99
+			$path,
100
+			$acl,
101
+			$owner
102
+		);
103
+
104
+	}
105
+
106
+	/**
107
+	 * Returns the owner principal
108
+	 *
109
+	 * This must be a url to a principal, or null if there's no owner
110
+	 *
111
+	 * @return string|null
112
+	 */
113
+	public function getOwner() {
114
+
115
+		return null;
116
+
117
+	}
118
+
119
+	/**
120
+	 * Returns a group principal
121
+	 *
122
+	 * This must be a url to a principal, or null if there's no owner
123
+	 *
124
+	 * @return string|null
125
+	 */
126
+	public function getGroup() {
127
+
128
+		return null;
129
+
130
+	}
131
+
132
+	/**
133
+	 * Returns a list of ACE's for this node.
134
+	 *
135
+	 * Each ACE has the following properties:
136
+	 *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
137
+	 *     currently the only supported privileges
138
+	 *   * 'principal', a url to the principal who owns the node
139
+	 *   * 'protected' (optional), indicating that this ACE is not allowed to
140
+	 *      be updated.
141
+	 *
142
+	 * @return array
143
+	 */
144
+	public function getACL() {
145
+
146
+		return [
147
+			[
148
+				'principal' => '{DAV:}authenticated',
149
+				'privilege' => '{DAV:}read',
150
+				'protected' => true,
151
+			]
152
+		];
153
+
154
+	}
155
+
156
+	/**
157
+	 * Updates the ACL
158
+	 *
159
+	 * This method will receive a list of new ACE's as an array argument.
160
+	 *
161
+	 * @param array $acl
162
+	 * @return void
163
+	 */
164
+	public function setACL(array $acl) {
165
+
166
+		throw new Forbidden('Setting ACL is not allowed here');
167
+
168
+	}
169
+
170
+	/**
171
+	 * Returns the list of supported privileges for this node.
172
+	 *
173
+	 * The returned data structure is a list of nested privileges.
174
+	 * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
175
+	 * standard structure.
176
+	 *
177
+	 * If null is returned from this method, the default privilege set is used,
178
+	 * which is fine for most common usecases.
179
+	 *
180
+	 * @return array|null
181
+	 */
182
+	public function getSupportedPrivilegeSet() {
183
+
184
+		return null;
185
+
186
+	}
187 187
 
188 188
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/Plugin.php 5 patches
Doc Comments   +9 added lines, -11 removed lines patch added patch discarded remove patch
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
      *
114 114
      * This list is used in the response of a HTTP OPTIONS request.
115 115
      *
116
-     * @return array
116
+     * @return string[]
117 117
      */
118 118
     function getFeatures() {
119 119
 
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
      * Returns a list of available methods for a given url
126 126
      *
127 127
      * @param string $uri
128
-     * @return array
128
+     * @return string[]
129 129
      */
130 130
     function getMethods($uri) {
131 131
 
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
      * implement them
156 156
      *
157 157
      * @param string $uri
158
-     * @return array
158
+     * @return string[]
159 159
      */
160 160
     function getSupportedReportSet($uri) {
161 161
 
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
      * and return true otherwise.
177 177
      *
178 178
      * @param string $uri
179
-     * @param array|string $privileges
179
+     * @param string $privileges
180 180
      * @param int $recursion
181 181
      * @param bool $throwExceptions if set to false, this method won't throw exceptions.
182 182
      * @throws Sabre\DAVACL\Exception\NeedPrivileges
@@ -269,7 +269,7 @@  discard block
 block discarded – undo
269 269
     /**
270 270
      * Returns all the principal groups the specified principal is a member of.
271 271
      *
272
-     * @param string $principal
272
+     * @param string $mainPrincipal
273 273
      * @return array
274 274
      */
275 275
     function getPrincipalMembership($mainPrincipal) {
@@ -831,10 +831,8 @@  discard block
 block discarded – undo
831 831
      *
832 832
      * @param DAV\PropFind $propFind
833 833
      * @param DAV\INode $node
834
-     * @param array $requestedProperties
835
-     * @param array $returnedProperties
836 834
      * @TODO really should be broken into multiple methods, or even a class.
837
-     * @return bool
835
+     * @return false|null
838 836
      */
839 837
     function propFind(DAV\PropFind $propFind, DAV\INode $node) {
840 838
 
@@ -982,7 +980,7 @@  discard block
 block discarded – undo
982 980
      * @param string $reportName
983 981
      * @param mixed $report
984 982
      * @param mixed $path
985
-     * @return bool
983
+     * @return false|null
986 984
      */
987 985
     function report($reportName, $report, $path) {
988 986
 
@@ -1133,7 +1131,7 @@  discard block
 block discarded – undo
1133 1131
      * @param array $path
1134 1132
      * @param array $requestedProperties the list of required properties
1135 1133
      * @param int $depth
1136
-     * @return array
1134
+     * @return DAV\Xml\Element\Response[]
1137 1135
      */
1138 1136
     protected function expandProperties($path, array $requestedProperties, $depth) {
1139 1137
 
@@ -1278,7 +1276,7 @@  discard block
 block discarded – undo
1278 1276
      *
1279 1277
      * @param DAV\INode $node
1280 1278
      * @param string $output
1281
-     * @return bool
1279
+     * @return null|false
1282 1280
      */
1283 1281
     function htmlActionsPanel(DAV\INode $node, &$output) {
1284 1282
 
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -674,15 +674,15 @@
 block discarded – undo
674 674
     function initialize(DAV\Server $server) {
675 675
 
676 676
         $this->server = $server;
677
-        $server->on('propFind',            [$this, 'propFind'], 20);
678
-        $server->on('beforeMethod',        [$this, 'beforeMethod'], 20);
679
-        $server->on('beforeBind',          [$this, 'beforeBind'], 20);
680
-        $server->on('beforeUnbind',        [$this, 'beforeUnbind'], 20);
681
-        $server->on('propPatch',           [$this, 'propPatch']);
682
-        $server->on('beforeUnlock',        [$this, 'beforeUnlock'], 20);
683
-        $server->on('report',              [$this, 'report']);
684
-        $server->on('method:ACL',          [$this, 'httpAcl']);
685
-        $server->on('onHTMLActionsPanel',  [$this, 'htmlActionsPanel']);
677
+        $server->on('propFind', [$this, 'propFind'], 20);
678
+        $server->on('beforeMethod', [$this, 'beforeMethod'], 20);
679
+        $server->on('beforeBind', [$this, 'beforeBind'], 20);
680
+        $server->on('beforeUnbind', [$this, 'beforeUnbind'], 20);
681
+        $server->on('propPatch', [$this, 'propPatch']);
682
+        $server->on('beforeUnlock', [$this, 'beforeUnlock'], 20);
683
+        $server->on('report', [$this, 'report']);
684
+        $server->on('method:ACL', [$this, 'httpAcl']);
685
+        $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']);
686 686
 
687 687
         array_push($server->protectedProperties,
688 688
             '{DAV:}alternate-URI-set',
Please login to merge, or discard this patch.
Braces   +49 added lines, -25 removed lines patch added patch discarded remove patch
@@ -184,7 +184,9 @@  discard block
 block discarded – undo
184 184
      */
185 185
     function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
186 186
 
187
-        if (!is_array($privileges)) $privileges = [$privileges];
187
+        if (!is_array($privileges)) {
188
+        	$privileges = [$privileges];
189
+        }
188 190
 
189 191
         $acl = $this->getCurrentUserPrivilegeSet($uri);
190 192
 
@@ -192,10 +194,11 @@  discard block
 block discarded – undo
192 194
             if ($this->allowAccessToNodesWithoutACL) {
193 195
                 return true;
194 196
             } else {
195
-                if ($throwExceptions)
196
-                    throw new Exception\NeedPrivileges($uri, $privileges);
197
-                else
198
-                    return false;
197
+                if ($throwExceptions) {
198
+                                    throw new Exception\NeedPrivileges($uri, $privileges);
199
+                } else {
200
+                                    return false;
201
+                }
199 202
 
200 203
             }
201 204
         }
@@ -210,10 +213,11 @@  discard block
 block discarded – undo
210 213
         }
211 214
 
212 215
         if ($failed) {
213
-            if ($throwExceptions)
214
-                throw new Exception\NeedPrivileges($uri, $failed);
215
-            else
216
-                return false;
216
+            if ($throwExceptions) {
217
+                            throw new Exception\NeedPrivileges($uri, $failed);
218
+            } else {
219
+                            return false;
220
+            }
217 221
         }
218 222
         return true;
219 223
 
@@ -230,7 +234,9 @@  discard block
 block discarded – undo
230 234
     function getCurrentUserPrincipal() {
231 235
 
232 236
         $authPlugin = $this->server->getPlugin('auth');
233
-        if (is_null($authPlugin)) return null;
237
+        if (is_null($authPlugin)) {
238
+        	return null;
239
+        }
234 240
         /** @var $authPlugin Sabre\DAV\Auth\Plugin */
235 241
 
236 242
         return $authPlugin->getCurrentPrincipal();
@@ -248,7 +254,9 @@  discard block
 block discarded – undo
248 254
 
249 255
         $currentUser = $this->getCurrentUserPrincipal();
250 256
 
251
-        if (is_null($currentUser)) return [];
257
+        if (is_null($currentUser)) {
258
+        	return [];
259
+        }
252 260
 
253 261
         return array_merge(
254 262
             [$currentUser],
@@ -331,8 +339,9 @@  discard block
 block discarded – undo
331 339
         if ($node instanceof IACL) {
332 340
             $result = $node->getSupportedPrivilegeSet();
333 341
 
334
-            if ($result)
335
-                return $result;
342
+            if ($result) {
343
+                            return $result;
344
+            }
336 345
         }
337 346
 
338 347
         return self::getDefaultSupportedPrivilegeSet();
@@ -506,7 +515,9 @@  discard block
 block discarded – undo
506 515
 
507 516
         $acl = $this->getACL($node);
508 517
 
509
-        if (is_null($acl)) return null;
518
+        if (is_null($acl)) {
519
+        	return null;
520
+        }
510 521
 
511 522
         $principals = $this->getCurrentUserPrincipals();
512 523
 
@@ -730,7 +741,9 @@  discard block
 block discarded – undo
730 741
         $exists = $this->server->tree->nodeExists($path);
731 742
 
732 743
         // If the node doesn't exists, none of these checks apply
733
-        if (!$exists) return;
744
+        if (!$exists) {
745
+        	return;
746
+        }
734 747
 
735 748
         switch ($method) {
736 749
 
@@ -891,7 +904,9 @@  discard block
 block discarded – undo
891 904
 
892 905
             $val = $this->principalCollectionSet;
893 906
             // Ensuring all collections end with a slash
894
-            foreach ($val as $k => $v) $val[$k] = $v . '/';
907
+            foreach ($val as $k => $v) {
908
+            	$val[$k] = $v . '/';
909
+            }
895 910
             return new DAV\Xml\Property\Href($val);
896 911
 
897 912
         });
@@ -1042,7 +1057,9 @@  discard block
 block discarded – undo
1042 1057
            not overwritten. */
1043 1058
         foreach ($oldAcl as $oldAce) {
1044 1059
 
1045
-            if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
1060
+            if (!isset($oldAce['protected']) || !$oldAce['protected']) {
1061
+            	continue;
1062
+            }
1046 1063
 
1047 1064
             $found = false;
1048 1065
             foreach ($newAcl as $newAce) {
@@ -1050,12 +1067,14 @@  discard block
 block discarded – undo
1050 1067
                     $newAce['privilege'] === $oldAce['privilege'] &&
1051 1068
                     $newAce['principal'] === $oldAce['principal'] &&
1052 1069
                     $newAce['protected']
1053
-                )
1054
-                $found = true;
1070
+                ) {
1071
+                                $found = true;
1072
+                }
1055 1073
             }
1056 1074
 
1057
-            if (!$found)
1058
-                throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
1075
+            if (!$found) {
1076
+                            throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
1077
+            }
1059 1078
 
1060 1079
         }
1061 1080
 
@@ -1146,11 +1165,15 @@  discard block
 block discarded – undo
1146 1165
             foreach ($requestedProperties as $propertyName => $childRequestedProperties) {
1147 1166
 
1148 1167
                 // We're only traversing if sub-properties were requested
1149
-                if (count($childRequestedProperties) === 0) continue;
1168
+                if (count($childRequestedProperties) === 0) {
1169
+                	continue;
1170
+                }
1150 1171
 
1151 1172
                 // We only have to do the expansion if the property was found
1152 1173
                 // and it contains an href element.
1153
-                if (!array_key_exists($propertyName, $node[200])) continue;
1174
+                if (!array_key_exists($propertyName, $node[200])) {
1175
+                	continue;
1176
+                }
1154 1177
 
1155 1178
                 if (!$node[200][$propertyName] instanceof DAV\Xml\Property\Href) {
1156 1179
                     continue;
@@ -1282,8 +1305,9 @@  discard block
 block discarded – undo
1282 1305
      */
1283 1306
     function htmlActionsPanel(DAV\INode $node, &$output) {
1284 1307
 
1285
-        if (!$node instanceof PrincipalCollection)
1286
-            return;
1308
+        if (!$node instanceof PrincipalCollection) {
1309
+                    return;
1310
+        }
1287 1311
 
1288 1312
         $output .= '<tr><td colspan="2"><form method="post" action="">
1289 1313
             <h3>Create new principal</h3>
Please login to merge, or discard this patch.
Unused Use Statements   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -3,8 +3,8 @@
 block discarded – undo
3 3
 namespace Sabre\DAVACL;
4 4
 
5 5
 use Sabre\DAV;
6
-use Sabre\DAV\INode;
7 6
 use Sabre\DAV\Exception\BadRequest;
7
+use Sabre\DAV\INode;
8 8
 use Sabre\HTTP\RequestInterface;
9 9
 use Sabre\HTTP\ResponseInterface;
10 10
 use Sabre\Uri;
Please login to merge, or discard this patch.
Indentation   +1255 added lines, -1255 removed lines patch added patch discarded remove patch
@@ -25,1265 +25,1265 @@  discard block
 block discarded – undo
25 25
  */
26 26
 class Plugin extends DAV\ServerPlugin {
27 27
 
28
-    /**
29
-     * Recursion constants
30
-     *
31
-     * This only checks the base node
32
-     */
33
-    const R_PARENT = 1;
34
-
35
-    /**
36
-     * Recursion constants
37
-     *
38
-     * This checks every node in the tree
39
-     */
40
-    const R_RECURSIVE = 2;
41
-
42
-    /**
43
-     * Recursion constants
44
-     *
45
-     * This checks every parentnode in the tree, but not leaf-nodes.
46
-     */
47
-    const R_RECURSIVEPARENTS = 3;
48
-
49
-    /**
50
-     * Reference to server object.
51
-     *
52
-     * @var Sabre\DAV\Server
53
-     */
54
-    protected $server;
55
-
56
-    /**
57
-     * List of urls containing principal collections.
58
-     * Modify this if your principals are located elsewhere.
59
-     *
60
-     * @var array
61
-     */
62
-    public $principalCollectionSet = [
63
-        'principals',
64
-    ];
65
-
66
-    /**
67
-     * By default ACL is only enforced for nodes that have ACL support (the
68
-     * ones that implement IACL). For any other node, access is
69
-     * always granted.
70
-     *
71
-     * To override this behaviour you can turn this setting off. This is useful
72
-     * if you plan to fully support ACL in the entire tree.
73
-     *
74
-     * @var bool
75
-     */
76
-    public $allowAccessToNodesWithoutACL = true;
77
-
78
-    /**
79
-     * By default nodes that are inaccessible by the user, can still be seen
80
-     * in directory listings (PROPFIND on parent with Depth: 1)
81
-     *
82
-     * In certain cases it's desirable to hide inaccessible nodes. Setting this
83
-     * to true will cause these nodes to be hidden from directory listings.
84
-     *
85
-     * @var bool
86
-     */
87
-    public $hideNodesFromListings = false;
88
-
89
-    /**
90
-     * This list of properties are the properties a client can search on using
91
-     * the {DAV:}principal-property-search report.
92
-     *
93
-     * The keys are the property names, values are descriptions.
94
-     *
95
-     * @var array
96
-     */
97
-    public $principalSearchPropertySet = [
98
-        '{DAV:}displayname'                     => 'Display name',
99
-        '{http://sabredav.org/ns}email-address' => 'Email address',
100
-    ];
101
-
102
-    /**
103
-     * Any principal uri's added here, will automatically be added to the list
104
-     * of ACL's. They will effectively receive {DAV:}all privileges, as a
105
-     * protected privilege.
106
-     *
107
-     * @var array
108
-     */
109
-    public $adminPrincipals = [];
110
-
111
-    /**
112
-     * Returns a list of features added by this plugin.
113
-     *
114
-     * This list is used in the response of a HTTP OPTIONS request.
115
-     *
116
-     * @return array
117
-     */
118
-    public function getFeatures() {
119
-
120
-        return ['access-control', 'calendarserver-principal-property-search'];
121
-
122
-    }
123
-
124
-    /**
125
-     * Returns a list of available methods for a given url
126
-     *
127
-     * @param string $uri
128
-     * @return array
129
-     */
130
-    public function getMethods($uri) {
131
-
132
-        return ['ACL'];
133
-
134
-    }
135
-
136
-    /**
137
-     * Returns a plugin name.
138
-     *
139
-     * Using this name other plugins will be able to access other plugins
140
-     * using Sabre\DAV\Server::getPlugin
141
-     *
142
-     * @return string
143
-     */
144
-    public function getPluginName() {
145
-
146
-        return 'acl';
147
-
148
-    }
149
-
150
-    /**
151
-     * Returns a list of reports this plugin supports.
152
-     *
153
-     * This will be used in the {DAV:}supported-report-set property.
154
-     * Note that you still need to subscribe to the 'report' event to actually
155
-     * implement them
156
-     *
157
-     * @param string $uri
158
-     * @return array
159
-     */
160
-    public function getSupportedReportSet($uri) {
161
-
162
-        return [
163
-            '{DAV:}expand-property',
164
-            '{DAV:}principal-property-search',
165
-            '{DAV:}principal-search-property-set',
166
-        ];
167
-
168
-    }
169
-
170
-
171
-    /**
172
-     * Checks if the current user has the specified privilege(s).
173
-     *
174
-     * You can specify a single privilege, or a list of privileges.
175
-     * This method will throw an exception if the privilege is not available
176
-     * and return true otherwise.
177
-     *
178
-     * @param string $uri
179
-     * @param array|string $privileges
180
-     * @param int $recursion
181
-     * @param bool $throwExceptions if set to false, this method won't throw exceptions.
182
-     * @throws Sabre\DAVACL\Exception\NeedPrivileges
183
-     * @return bool
184
-     */
185
-    public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
186
-
187
-        if (!is_array($privileges)) $privileges = [$privileges];
188
-
189
-        $acl = $this->getCurrentUserPrivilegeSet($uri);
190
-
191
-        if (is_null($acl)) {
192
-            if ($this->allowAccessToNodesWithoutACL) {
193
-                return true;
194
-            } else {
195
-                if ($throwExceptions)
196
-                    throw new Exception\NeedPrivileges($uri, $privileges);
197
-                else
198
-                    return false;
199
-
200
-            }
201
-        }
202
-
203
-        $failed = [];
204
-        foreach ($privileges as $priv) {
205
-
206
-            if (!in_array($priv, $acl)) {
207
-                $failed[] = $priv;
208
-            }
209
-
210
-        }
211
-
212
-        if ($failed) {
213
-            if ($throwExceptions)
214
-                throw new Exception\NeedPrivileges($uri, $failed);
215
-            else
216
-                return false;
217
-        }
218
-        return true;
28
+	/**
29
+	 * Recursion constants
30
+	 *
31
+	 * This only checks the base node
32
+	 */
33
+	const R_PARENT = 1;
34
+
35
+	/**
36
+	 * Recursion constants
37
+	 *
38
+	 * This checks every node in the tree
39
+	 */
40
+	const R_RECURSIVE = 2;
41
+
42
+	/**
43
+	 * Recursion constants
44
+	 *
45
+	 * This checks every parentnode in the tree, but not leaf-nodes.
46
+	 */
47
+	const R_RECURSIVEPARENTS = 3;
48
+
49
+	/**
50
+	 * Reference to server object.
51
+	 *
52
+	 * @var Sabre\DAV\Server
53
+	 */
54
+	protected $server;
55
+
56
+	/**
57
+	 * List of urls containing principal collections.
58
+	 * Modify this if your principals are located elsewhere.
59
+	 *
60
+	 * @var array
61
+	 */
62
+	public $principalCollectionSet = [
63
+		'principals',
64
+	];
65
+
66
+	/**
67
+	 * By default ACL is only enforced for nodes that have ACL support (the
68
+	 * ones that implement IACL). For any other node, access is
69
+	 * always granted.
70
+	 *
71
+	 * To override this behaviour you can turn this setting off. This is useful
72
+	 * if you plan to fully support ACL in the entire tree.
73
+	 *
74
+	 * @var bool
75
+	 */
76
+	public $allowAccessToNodesWithoutACL = true;
77
+
78
+	/**
79
+	 * By default nodes that are inaccessible by the user, can still be seen
80
+	 * in directory listings (PROPFIND on parent with Depth: 1)
81
+	 *
82
+	 * In certain cases it's desirable to hide inaccessible nodes. Setting this
83
+	 * to true will cause these nodes to be hidden from directory listings.
84
+	 *
85
+	 * @var bool
86
+	 */
87
+	public $hideNodesFromListings = false;
88
+
89
+	/**
90
+	 * This list of properties are the properties a client can search on using
91
+	 * the {DAV:}principal-property-search report.
92
+	 *
93
+	 * The keys are the property names, values are descriptions.
94
+	 *
95
+	 * @var array
96
+	 */
97
+	public $principalSearchPropertySet = [
98
+		'{DAV:}displayname'                     => 'Display name',
99
+		'{http://sabredav.org/ns}email-address' => 'Email address',
100
+	];
101
+
102
+	/**
103
+	 * Any principal uri's added here, will automatically be added to the list
104
+	 * of ACL's. They will effectively receive {DAV:}all privileges, as a
105
+	 * protected privilege.
106
+	 *
107
+	 * @var array
108
+	 */
109
+	public $adminPrincipals = [];
110
+
111
+	/**
112
+	 * Returns a list of features added by this plugin.
113
+	 *
114
+	 * This list is used in the response of a HTTP OPTIONS request.
115
+	 *
116
+	 * @return array
117
+	 */
118
+	public function getFeatures() {
119
+
120
+		return ['access-control', 'calendarserver-principal-property-search'];
121
+
122
+	}
123
+
124
+	/**
125
+	 * Returns a list of available methods for a given url
126
+	 *
127
+	 * @param string $uri
128
+	 * @return array
129
+	 */
130
+	public function getMethods($uri) {
131
+
132
+		return ['ACL'];
133
+
134
+	}
135
+
136
+	/**
137
+	 * Returns a plugin name.
138
+	 *
139
+	 * Using this name other plugins will be able to access other plugins
140
+	 * using Sabre\DAV\Server::getPlugin
141
+	 *
142
+	 * @return string
143
+	 */
144
+	public function getPluginName() {
145
+
146
+		return 'acl';
147
+
148
+	}
149
+
150
+	/**
151
+	 * Returns a list of reports this plugin supports.
152
+	 *
153
+	 * This will be used in the {DAV:}supported-report-set property.
154
+	 * Note that you still need to subscribe to the 'report' event to actually
155
+	 * implement them
156
+	 *
157
+	 * @param string $uri
158
+	 * @return array
159
+	 */
160
+	public function getSupportedReportSet($uri) {
161
+
162
+		return [
163
+			'{DAV:}expand-property',
164
+			'{DAV:}principal-property-search',
165
+			'{DAV:}principal-search-property-set',
166
+		];
167
+
168
+	}
169
+
170
+
171
+	/**
172
+	 * Checks if the current user has the specified privilege(s).
173
+	 *
174
+	 * You can specify a single privilege, or a list of privileges.
175
+	 * This method will throw an exception if the privilege is not available
176
+	 * and return true otherwise.
177
+	 *
178
+	 * @param string $uri
179
+	 * @param array|string $privileges
180
+	 * @param int $recursion
181
+	 * @param bool $throwExceptions if set to false, this method won't throw exceptions.
182
+	 * @throws Sabre\DAVACL\Exception\NeedPrivileges
183
+	 * @return bool
184
+	 */
185
+	public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
186
+
187
+		if (!is_array($privileges)) $privileges = [$privileges];
188
+
189
+		$acl = $this->getCurrentUserPrivilegeSet($uri);
190
+
191
+		if (is_null($acl)) {
192
+			if ($this->allowAccessToNodesWithoutACL) {
193
+				return true;
194
+			} else {
195
+				if ($throwExceptions)
196
+					throw new Exception\NeedPrivileges($uri, $privileges);
197
+				else
198
+					return false;
199
+
200
+			}
201
+		}
202
+
203
+		$failed = [];
204
+		foreach ($privileges as $priv) {
205
+
206
+			if (!in_array($priv, $acl)) {
207
+				$failed[] = $priv;
208
+			}
209
+
210
+		}
211
+
212
+		if ($failed) {
213
+			if ($throwExceptions)
214
+				throw new Exception\NeedPrivileges($uri, $failed);
215
+			else
216
+				return false;
217
+		}
218
+		return true;
219 219
 
220
-    }
221
-
222
-    /**
223
-     * Returns the standard users' principal.
224
-     *
225
-     * This is one authorative principal url for the current user.
226
-     * This method will return null if the user wasn't logged in.
227
-     *
228
-     * @return string|null
229
-     */
230
-    public function getCurrentUserPrincipal() {
231
-
232
-        $authPlugin = $this->server->getPlugin('auth');
233
-        if (is_null($authPlugin)) return null;
234
-        /** @var $authPlugin Sabre\DAV\Auth\Plugin */
235
-
236
-        return $authPlugin->getCurrentPrincipal();
237
-
238
-    }
239
-
240
-
241
-    /**
242
-     * Returns a list of principals that's associated to the current
243
-     * user, either directly or through group membership.
244
-     *
245
-     * @return array
246
-     */
247
-    public function getCurrentUserPrincipals() {
248
-
249
-        $currentUser = $this->getCurrentUserPrincipal();
250
-
251
-        if (is_null($currentUser)) return [];
252
-
253
-        return array_merge(
254
-            [$currentUser],
255
-            $this->getPrincipalMembership($currentUser)
256
-        );
257
-
258
-    }
259
-
260
-    /**
261
-     * This array holds a cache for all the principals that are associated with
262
-     * a single principal.
263
-     *
264
-     * @var array
265
-     */
266
-    protected $principalMembershipCache = [];
267
-
268
-
269
-    /**
270
-     * Returns all the principal groups the specified principal is a member of.
271
-     *
272
-     * @param string $principal
273
-     * @return array
274
-     */
275
-    public function getPrincipalMembership($mainPrincipal) {
276
-
277
-        // First check our cache
278
-        if (isset($this->principalMembershipCache[$mainPrincipal])) {
279
-            return $this->principalMembershipCache[$mainPrincipal];
280
-        }
281
-
282
-        $check = [$mainPrincipal];
283
-        $principals = [];
284
-
285
-        while (count($check)) {
286
-
287
-            $principal = array_shift($check);
288
-
289
-            $node = $this->server->tree->getNodeForPath($principal);
290
-            if ($node instanceof IPrincipal) {
291
-                foreach ($node->getGroupMembership() as $groupMember) {
292
-
293
-                    if (!in_array($groupMember, $principals)) {
294
-
295
-                        $check[] = $groupMember;
296
-                        $principals[] = $groupMember;
297
-
298
-                    }
299
-
300
-                }
301
-
302
-            }
303
-
304
-        }
305
-
306
-        // Store the result in the cache
307
-        $this->principalMembershipCache[$mainPrincipal] = $principals;
308
-
309
-        return $principals;
310
-
311
-    }
312
-
313
-    /**
314
-     * Returns the supported privilege structure for this ACL plugin.
315
-     *
316
-     * See RFC3744 for more details. Currently we default on a simple,
317
-     * standard structure.
318
-     *
319
-     * You can either get the list of privileges by a uri (path) or by
320
-     * specifying a Node.
321
-     *
322
-     * @param string|INode $node
323
-     * @return array
324
-     */
325
-    public function getSupportedPrivilegeSet($node) {
326
-
327
-        if (is_string($node)) {
328
-            $node = $this->server->tree->getNodeForPath($node);
329
-        }
330
-
331
-        if ($node instanceof IACL) {
332
-            $result = $node->getSupportedPrivilegeSet();
333
-
334
-            if ($result)
335
-                return $result;
336
-        }
337
-
338
-        return self::getDefaultSupportedPrivilegeSet();
339
-
340
-    }
341
-
342
-    /**
343
-     * Returns a fairly standard set of privileges, which may be useful for
344
-     * other systems to use as a basis.
345
-     *
346
-     * @return array
347
-     */
348
-    static function getDefaultSupportedPrivilegeSet() {
349
-
350
-        return [
351
-            'privilege'  => '{DAV:}all',
352
-            'abstract'   => true,
353
-            'aggregates' => [
354
-                [
355
-                    'privilege'  => '{DAV:}read',
356
-                    'aggregates' => [
357
-                        [
358
-                            'privilege' => '{DAV:}read-acl',
359
-                            'abstract'  => false,
360
-                        ],
361
-                        [
362
-                            'privilege' => '{DAV:}read-current-user-privilege-set',
363
-                            'abstract'  => false,
364
-                        ],
365
-                    ],
366
-                ], // {DAV:}read
367
-                [
368
-                    'privilege'  => '{DAV:}write',
369
-                    'aggregates' => [
370
-                        [
371
-                            'privilege' => '{DAV:}write-acl',
372
-                            'abstract'  => false,
373
-                        ],
374
-                        [
375
-                            'privilege' => '{DAV:}write-properties',
376
-                            'abstract'  => false,
377
-                        ],
378
-                        [
379
-                            'privilege' => '{DAV:}write-content',
380
-                            'abstract'  => false,
381
-                        ],
382
-                        [
383
-                            'privilege' => '{DAV:}bind',
384
-                            'abstract'  => false,
385
-                        ],
386
-                        [
387
-                            'privilege' => '{DAV:}unbind',
388
-                            'abstract'  => false,
389
-                        ],
390
-                        [
391
-                            'privilege' => '{DAV:}unlock',
392
-                            'abstract'  => false,
393
-                        ],
394
-                    ],
395
-                ], // {DAV:}write
396
-            ],
397
-        ]; // {DAV:}all
398
-
399
-    }
400
-
401
-    /**
402
-     * Returns the supported privilege set as a flat list
403
-     *
404
-     * This is much easier to parse.
405
-     *
406
-     * The returned list will be index by privilege name.
407
-     * The value is a struct containing the following properties:
408
-     *   - aggregates
409
-     *   - abstract
410
-     *   - concrete
411
-     *
412
-     * @param string|INode $node
413
-     * @return array
414
-     */
415
-    final function getFlatPrivilegeSet($node) {
416
-
417
-        $privs = $this->getSupportedPrivilegeSet($node);
418
-
419
-        $fpsTraverse = null;
420
-        $fpsTraverse = function($priv, $concrete, &$flat) use (&$fpsTraverse) {
421
-
422
-            $myPriv = [
423
-                'privilege'  => $priv['privilege'],
424
-                'abstract'   => isset($priv['abstract']) && $priv['abstract'],
425
-                'aggregates' => [],
426
-                'concrete'   => isset($priv['abstract']) && $priv['abstract'] ? $concrete : $priv['privilege'],
427
-            ];
428
-
429
-            if (isset($priv['aggregates'])) {
430
-
431
-                foreach ($priv['aggregates'] as $subPriv) {
432
-
433
-                    $myPriv['aggregates'][] = $subPriv['privilege'];
434
-
435
-                }
436
-
437
-            }
438
-
439
-            $flat[$priv['privilege']] = $myPriv;
440
-
441
-            if (isset($priv['aggregates'])) {
442
-
443
-                foreach ($priv['aggregates'] as $subPriv) {
444
-
445
-                    $fpsTraverse($subPriv, $myPriv['concrete'], $flat);
446
-
447
-                }
448
-
449
-            }
450
-
451
-        };
452
-
453
-        $flat = [];
454
-        $fpsTraverse($privs, null, $flat);
455
-
456
-        return $flat;
457
-
458
-    }
459
-
460
-    /**
461
-     * Returns the full ACL list.
462
-     *
463
-     * Either a uri or a INode may be passed.
464
-     *
465
-     * null will be returned if the node doesn't support ACLs.
466
-     *
467
-     * @param string|DAV\INode $node
468
-     * @return array
469
-     */
470
-    public function getACL($node) {
471
-
472
-        if (is_string($node)) {
473
-            $node = $this->server->tree->getNodeForPath($node);
474
-        }
475
-        if (!$node instanceof IACL) {
476
-            return null;
477
-        }
478
-        $acl = $node->getACL();
479
-        foreach ($this->adminPrincipals as $adminPrincipal) {
480
-            $acl[] = [
481
-                'principal' => $adminPrincipal,
482
-                'privilege' => '{DAV:}all',
483
-                'protected' => true,
484
-            ];
485
-        }
486
-        return $acl;
220
+	}
221
+
222
+	/**
223
+	 * Returns the standard users' principal.
224
+	 *
225
+	 * This is one authorative principal url for the current user.
226
+	 * This method will return null if the user wasn't logged in.
227
+	 *
228
+	 * @return string|null
229
+	 */
230
+	public function getCurrentUserPrincipal() {
231
+
232
+		$authPlugin = $this->server->getPlugin('auth');
233
+		if (is_null($authPlugin)) return null;
234
+		/** @var $authPlugin Sabre\DAV\Auth\Plugin */
235
+
236
+		return $authPlugin->getCurrentPrincipal();
237
+
238
+	}
239
+
240
+
241
+	/**
242
+	 * Returns a list of principals that's associated to the current
243
+	 * user, either directly or through group membership.
244
+	 *
245
+	 * @return array
246
+	 */
247
+	public function getCurrentUserPrincipals() {
248
+
249
+		$currentUser = $this->getCurrentUserPrincipal();
250
+
251
+		if (is_null($currentUser)) return [];
252
+
253
+		return array_merge(
254
+			[$currentUser],
255
+			$this->getPrincipalMembership($currentUser)
256
+		);
257
+
258
+	}
259
+
260
+	/**
261
+	 * This array holds a cache for all the principals that are associated with
262
+	 * a single principal.
263
+	 *
264
+	 * @var array
265
+	 */
266
+	protected $principalMembershipCache = [];
267
+
268
+
269
+	/**
270
+	 * Returns all the principal groups the specified principal is a member of.
271
+	 *
272
+	 * @param string $principal
273
+	 * @return array
274
+	 */
275
+	public function getPrincipalMembership($mainPrincipal) {
276
+
277
+		// First check our cache
278
+		if (isset($this->principalMembershipCache[$mainPrincipal])) {
279
+			return $this->principalMembershipCache[$mainPrincipal];
280
+		}
281
+
282
+		$check = [$mainPrincipal];
283
+		$principals = [];
284
+
285
+		while (count($check)) {
286
+
287
+			$principal = array_shift($check);
288
+
289
+			$node = $this->server->tree->getNodeForPath($principal);
290
+			if ($node instanceof IPrincipal) {
291
+				foreach ($node->getGroupMembership() as $groupMember) {
292
+
293
+					if (!in_array($groupMember, $principals)) {
294
+
295
+						$check[] = $groupMember;
296
+						$principals[] = $groupMember;
297
+
298
+					}
299
+
300
+				}
301
+
302
+			}
303
+
304
+		}
305
+
306
+		// Store the result in the cache
307
+		$this->principalMembershipCache[$mainPrincipal] = $principals;
308
+
309
+		return $principals;
310
+
311
+	}
312
+
313
+	/**
314
+	 * Returns the supported privilege structure for this ACL plugin.
315
+	 *
316
+	 * See RFC3744 for more details. Currently we default on a simple,
317
+	 * standard structure.
318
+	 *
319
+	 * You can either get the list of privileges by a uri (path) or by
320
+	 * specifying a Node.
321
+	 *
322
+	 * @param string|INode $node
323
+	 * @return array
324
+	 */
325
+	public function getSupportedPrivilegeSet($node) {
326
+
327
+		if (is_string($node)) {
328
+			$node = $this->server->tree->getNodeForPath($node);
329
+		}
330
+
331
+		if ($node instanceof IACL) {
332
+			$result = $node->getSupportedPrivilegeSet();
333
+
334
+			if ($result)
335
+				return $result;
336
+		}
337
+
338
+		return self::getDefaultSupportedPrivilegeSet();
339
+
340
+	}
341
+
342
+	/**
343
+	 * Returns a fairly standard set of privileges, which may be useful for
344
+	 * other systems to use as a basis.
345
+	 *
346
+	 * @return array
347
+	 */
348
+	static function getDefaultSupportedPrivilegeSet() {
349
+
350
+		return [
351
+			'privilege'  => '{DAV:}all',
352
+			'abstract'   => true,
353
+			'aggregates' => [
354
+				[
355
+					'privilege'  => '{DAV:}read',
356
+					'aggregates' => [
357
+						[
358
+							'privilege' => '{DAV:}read-acl',
359
+							'abstract'  => false,
360
+						],
361
+						[
362
+							'privilege' => '{DAV:}read-current-user-privilege-set',
363
+							'abstract'  => false,
364
+						],
365
+					],
366
+				], // {DAV:}read
367
+				[
368
+					'privilege'  => '{DAV:}write',
369
+					'aggregates' => [
370
+						[
371
+							'privilege' => '{DAV:}write-acl',
372
+							'abstract'  => false,
373
+						],
374
+						[
375
+							'privilege' => '{DAV:}write-properties',
376
+							'abstract'  => false,
377
+						],
378
+						[
379
+							'privilege' => '{DAV:}write-content',
380
+							'abstract'  => false,
381
+						],
382
+						[
383
+							'privilege' => '{DAV:}bind',
384
+							'abstract'  => false,
385
+						],
386
+						[
387
+							'privilege' => '{DAV:}unbind',
388
+							'abstract'  => false,
389
+						],
390
+						[
391
+							'privilege' => '{DAV:}unlock',
392
+							'abstract'  => false,
393
+						],
394
+					],
395
+				], // {DAV:}write
396
+			],
397
+		]; // {DAV:}all
398
+
399
+	}
400
+
401
+	/**
402
+	 * Returns the supported privilege set as a flat list
403
+	 *
404
+	 * This is much easier to parse.
405
+	 *
406
+	 * The returned list will be index by privilege name.
407
+	 * The value is a struct containing the following properties:
408
+	 *   - aggregates
409
+	 *   - abstract
410
+	 *   - concrete
411
+	 *
412
+	 * @param string|INode $node
413
+	 * @return array
414
+	 */
415
+	final function getFlatPrivilegeSet($node) {
416
+
417
+		$privs = $this->getSupportedPrivilegeSet($node);
418
+
419
+		$fpsTraverse = null;
420
+		$fpsTraverse = function($priv, $concrete, &$flat) use (&$fpsTraverse) {
421
+
422
+			$myPriv = [
423
+				'privilege'  => $priv['privilege'],
424
+				'abstract'   => isset($priv['abstract']) && $priv['abstract'],
425
+				'aggregates' => [],
426
+				'concrete'   => isset($priv['abstract']) && $priv['abstract'] ? $concrete : $priv['privilege'],
427
+			];
428
+
429
+			if (isset($priv['aggregates'])) {
430
+
431
+				foreach ($priv['aggregates'] as $subPriv) {
432
+
433
+					$myPriv['aggregates'][] = $subPriv['privilege'];
434
+
435
+				}
436
+
437
+			}
438
+
439
+			$flat[$priv['privilege']] = $myPriv;
440
+
441
+			if (isset($priv['aggregates'])) {
442
+
443
+				foreach ($priv['aggregates'] as $subPriv) {
444
+
445
+					$fpsTraverse($subPriv, $myPriv['concrete'], $flat);
446
+
447
+				}
448
+
449
+			}
450
+
451
+		};
452
+
453
+		$flat = [];
454
+		$fpsTraverse($privs, null, $flat);
455
+
456
+		return $flat;
457
+
458
+	}
459
+
460
+	/**
461
+	 * Returns the full ACL list.
462
+	 *
463
+	 * Either a uri or a INode may be passed.
464
+	 *
465
+	 * null will be returned if the node doesn't support ACLs.
466
+	 *
467
+	 * @param string|DAV\INode $node
468
+	 * @return array
469
+	 */
470
+	public function getACL($node) {
471
+
472
+		if (is_string($node)) {
473
+			$node = $this->server->tree->getNodeForPath($node);
474
+		}
475
+		if (!$node instanceof IACL) {
476
+			return null;
477
+		}
478
+		$acl = $node->getACL();
479
+		foreach ($this->adminPrincipals as $adminPrincipal) {
480
+			$acl[] = [
481
+				'principal' => $adminPrincipal,
482
+				'privilege' => '{DAV:}all',
483
+				'protected' => true,
484
+			];
485
+		}
486
+		return $acl;
487 487
 
488
-    }
488
+	}
489 489
 
490
-    /**
491
-     * Returns a list of privileges the current user has
492
-     * on a particular node.
493
-     *
494
-     * Either a uri or a DAV\INode may be passed.
495
-     *
496
-     * null will be returned if the node doesn't support ACLs.
497
-     *
498
-     * @param string|DAV\INode $node
499
-     * @return array
500
-     */
501
-    public function getCurrentUserPrivilegeSet($node) {
490
+	/**
491
+	 * Returns a list of privileges the current user has
492
+	 * on a particular node.
493
+	 *
494
+	 * Either a uri or a DAV\INode may be passed.
495
+	 *
496
+	 * null will be returned if the node doesn't support ACLs.
497
+	 *
498
+	 * @param string|DAV\INode $node
499
+	 * @return array
500
+	 */
501
+	public function getCurrentUserPrivilegeSet($node) {
502 502
 
503
-        if (is_string($node)) {
504
-            $node = $this->server->tree->getNodeForPath($node);
505
-        }
503
+		if (is_string($node)) {
504
+			$node = $this->server->tree->getNodeForPath($node);
505
+		}
506 506
 
507
-        $acl = $this->getACL($node);
507
+		$acl = $this->getACL($node);
508 508
 
509
-        if (is_null($acl)) return null;
509
+		if (is_null($acl)) return null;
510 510
 
511
-        $principals = $this->getCurrentUserPrincipals();
511
+		$principals = $this->getCurrentUserPrincipals();
512 512
 
513
-        $collected = [];
513
+		$collected = [];
514 514
 
515
-        foreach ($acl as $ace) {
515
+		foreach ($acl as $ace) {
516 516
 
517
-            $principal = $ace['principal'];
517
+			$principal = $ace['principal'];
518 518
 
519
-            switch ($principal) {
519
+			switch ($principal) {
520 520
 
521
-                case '{DAV:}owner' :
522
-                    $owner = $node->getOwner();
523
-                    if ($owner && in_array($owner, $principals)) {
524
-                        $collected[] = $ace;
525
-                    }
526
-                    break;
521
+				case '{DAV:}owner' :
522
+					$owner = $node->getOwner();
523
+					if ($owner && in_array($owner, $principals)) {
524
+						$collected[] = $ace;
525
+					}
526
+					break;
527 527
 
528 528
 
529
-                // 'all' matches for every user
530
-                case '{DAV:}all' :
529
+				// 'all' matches for every user
530
+				case '{DAV:}all' :
531 531
 
532
-                // 'authenticated' matched for every user that's logged in.
533
-                // Since it's not possible to use ACL while not being logged
534
-                // in, this is also always true.
535
-                case '{DAV:}authenticated' :
536
-                    $collected[] = $ace;
537
-                    break;
538
-
539
-                // 'unauthenticated' can never occur either, so we simply
540
-                // ignore these.
541
-                case '{DAV:}unauthenticated' :
542
-                    break;
543
-
544
-                default :
545
-                    if (in_array($ace['principal'], $principals)) {
546
-                        $collected[] = $ace;
547
-                    }
548
-                    break;
549
-
550
-            }
551
-
552
-
553
-        }
554
-
555
-        // Now we deduct all aggregated privileges.
556
-        $flat = $this->getFlatPrivilegeSet($node);
557
-
558
-        $collected2 = [];
559
-        while (count($collected)) {
560
-
561
-            $current = array_pop($collected);
562
-            $collected2[] = $current['privilege'];
563
-
564
-            foreach ($flat[$current['privilege']]['aggregates'] as $subPriv) {
565
-                $collected2[] = $subPriv;
566
-                $collected[] = $flat[$subPriv];
567
-            }
568
-
569
-        }
570
-
571
-        return array_values(array_unique($collected2));
572
-
573
-    }
574
-
575
-
576
-    /**
577
-     * Returns a principal based on its uri.
578
-     *
579
-     * Returns null if the principal could not be found.
580
-     *
581
-     * @param string $uri
582
-     * @return null|string
583
-     */
584
-    public function getPrincipalByUri($uri) {
585
-
586
-        $result = null;
587
-        $collections = $this->principalCollectionSet;
588
-        foreach ($collections as $collection) {
589
-
590
-            $principalCollection = $this->server->tree->getNodeForPath($collection);
591
-            if (!$principalCollection instanceof IPrincipalCollection) {
592
-                // Not a principal collection, we're simply going to ignore
593
-                // this.
594
-                continue;
595
-            }
596
-
597
-            $result = $principalCollection->findByUri($uri);
598
-            if ($result) {
599
-                return $result;
600
-            }
601
-
602
-        }
603
-
604
-    }
605
-
606
-    /**
607
-     * Principal property search
608
-     *
609
-     * This method can search for principals matching certain values in
610
-     * properties.
611
-     *
612
-     * This method will return a list of properties for the matched properties.
613
-     *
614
-     * @param array $searchProperties    The properties to search on. This is a
615
-     *                                   key-value list. The keys are property
616
-     *                                   names, and the values the strings to
617
-     *                                   match them on.
618
-     * @param array $requestedProperties This is the list of properties to
619
-     *                                   return for every match.
620
-     * @param string $collectionUri      The principal collection to search on.
621
-     *                                   If this is ommitted, the standard
622
-     *                                   principal collection-set will be used.
623
-     * @param string $test               "allof" to use AND to search the
624
-     *                                   properties. 'anyof' for OR.
625
-     * @return array     This method returns an array structure similar to
626
-     *                  Sabre\DAV\Server::getPropertiesForPath. Returned
627
-     *                  properties are index by a HTTP status code.
628
-     */
629
-    public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null, $test = 'allof') {
630
-
631
-        if (!is_null($collectionUri)) {
632
-            $uris = [$collectionUri];
633
-        } else {
634
-            $uris = $this->principalCollectionSet;
635
-        }
636
-
637
-        $lookupResults = [];
638
-        foreach ($uris as $uri) {
639
-
640
-            $principalCollection = $this->server->tree->getNodeForPath($uri);
641
-            if (!$principalCollection instanceof IPrincipalCollection) {
642
-                // Not a principal collection, we're simply going to ignore
643
-                // this.
644
-                continue;
645
-            }
646
-
647
-            $results = $principalCollection->searchPrincipals($searchProperties, $test);
648
-            foreach ($results as $result) {
649
-                $lookupResults[] = rtrim($uri, '/') . '/' . $result;
650
-            }
651
-
652
-        }
653
-
654
-        $matches = [];
655
-
656
-        foreach ($lookupResults as $lookupResult) {
657
-
658
-            list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0);
659
-
660
-        }
661
-
662
-        return $matches;
663
-
664
-    }
665
-
666
-    /**
667
-     * Sets up the plugin
668
-     *
669
-     * This method is automatically called by the server class.
670
-     *
671
-     * @param DAV\Server $server
672
-     * @return void
673
-     */
674
-    public function initialize(DAV\Server $server) {
675
-
676
-        $this->server = $server;
677
-        $server->on('propFind',            [$this, 'propFind'], 20);
678
-        $server->on('beforeMethod',        [$this, 'beforeMethod'], 20);
679
-        $server->on('beforeBind',          [$this, 'beforeBind'], 20);
680
-        $server->on('beforeUnbind',        [$this, 'beforeUnbind'], 20);
681
-        $server->on('propPatch',           [$this, 'propPatch']);
682
-        $server->on('beforeUnlock',        [$this, 'beforeUnlock'], 20);
683
-        $server->on('report',              [$this, 'report']);
684
-        $server->on('method:ACL',          [$this, 'httpAcl']);
685
-        $server->on('onHTMLActionsPanel',  [$this, 'htmlActionsPanel']);
686
-
687
-        array_push($server->protectedProperties,
688
-            '{DAV:}alternate-URI-set',
689
-            '{DAV:}principal-URL',
690
-            '{DAV:}group-membership',
691
-            '{DAV:}principal-collection-set',
692
-            '{DAV:}current-user-principal',
693
-            '{DAV:}supported-privilege-set',
694
-            '{DAV:}current-user-privilege-set',
695
-            '{DAV:}acl',
696
-            '{DAV:}acl-restrictions',
697
-            '{DAV:}inherited-acl-set',
698
-            '{DAV:}owner',
699
-            '{DAV:}group'
700
-        );
701
-
702
-        // Automatically mapping nodes implementing IPrincipal to the
703
-        // {DAV:}principal resourcetype.
704
-        $server->resourceTypeMapping['Sabre\\DAVACL\\IPrincipal'] = '{DAV:}principal';
705
-
706
-        // Mapping the group-member-set property to the HrefList property
707
-        // class.
708
-        $server->xml->elementMap['{DAV:}group-member-set'] = 'Sabre\\DAV\\Xml\\Property\\Href';
709
-        $server->xml->elementMap['{DAV:}acl'] = 'Sabre\\DAVACL\\Xml\\Property\\Acl';
710
-        $server->xml->elementMap['{DAV:}expand-property'] = 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport';
711
-        $server->xml->elementMap['{DAV:}principal-property-search'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport';
712
-        $server->xml->elementMap['{DAV:}principal-search-property-set'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport';
713
-
714
-    }
715
-
716
-    /* {{{ Event handlers */
717
-
718
-    /**
719
-     * Triggered before any method is handled
720
-     *
721
-     * @param RequestInterface $request
722
-     * @param ResponseInterface $response
723
-     * @return void
724
-     */
725
-    public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
726
-
727
-        $method = $request->getMethod();
728
-        $path = $request->getPath();
729
-
730
-        $exists = $this->server->tree->nodeExists($path);
731
-
732
-        // If the node doesn't exists, none of these checks apply
733
-        if (!$exists) return;
734
-
735
-        switch ($method) {
736
-
737
-            case 'GET' :
738
-            case 'HEAD' :
739
-            case 'OPTIONS' :
740
-                // For these 3 we only need to know if the node is readable.
741
-                $this->checkPrivileges($path, '{DAV:}read');
742
-                break;
743
-
744
-            case 'PUT' :
745
-            case 'LOCK' :
746
-            case 'UNLOCK' :
747
-                // This method requires the write-content priv if the node
748
-                // already exists, and bind on the parent if the node is being
749
-                // created.
750
-                // The bind privilege is handled in the beforeBind event.
751
-                $this->checkPrivileges($path, '{DAV:}write-content');
752
-                break;
753
-
754
-
755
-            case 'PROPPATCH' :
756
-                $this->checkPrivileges($path, '{DAV:}write-properties');
757
-                break;
758
-
759
-            case 'ACL' :
760
-                $this->checkPrivileges($path, '{DAV:}write-acl');
761
-                break;
762
-
763
-            case 'COPY' :
764
-            case 'MOVE' :
765
-                // Copy requires read privileges on the entire source tree.
766
-                // If the target exists write-content normally needs to be
767
-                // checked, however, we're deleting the node beforehand and
768
-                // creating a new one after, so this is handled by the
769
-                // beforeUnbind event.
770
-                //
771
-                // The creation of the new node is handled by the beforeBind
772
-                // event.
773
-                //
774
-                // If MOVE is used beforeUnbind will also be used to check if
775
-                // the sourcenode can be deleted.
776
-                $this->checkPrivileges($path, '{DAV:}read', self::R_RECURSIVE);
777
-
778
-                break;
779
-
780
-        }
781
-
782
-    }
783
-
784
-    /**
785
-     * Triggered before a new node is created.
786
-     *
787
-     * This allows us to check permissions for any operation that creates a
788
-     * new node, such as PUT, MKCOL, MKCALENDAR, LOCK, COPY and MOVE.
789
-     *
790
-     * @param string $uri
791
-     * @return void
792
-     */
793
-    public function beforeBind($uri) {
794
-
795
-        list($parentUri) = Uri\split($uri);
796
-        $this->checkPrivileges($parentUri, '{DAV:}bind');
797
-
798
-    }
799
-
800
-    /**
801
-     * Triggered before a node is deleted
802
-     *
803
-     * This allows us to check permissions for any operation that will delete
804
-     * an existing node.
805
-     *
806
-     * @param string $uri
807
-     * @return void
808
-     */
809
-    public function beforeUnbind($uri) {
810
-
811
-        list($parentUri) = Uri\split($uri);
812
-        $this->checkPrivileges($parentUri, '{DAV:}unbind', self::R_RECURSIVEPARENTS);
813
-
814
-    }
815
-
816
-    /**
817
-     * Triggered before a node is unlocked.
818
-     *
819
-     * @param string $uri
820
-     * @param DAV\Locks\LockInfo $lock
821
-     * @return void
822
-     */
823
-    public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) {
824
-
825
-
826
-    }
827
-
828
-    /**
829
-     * Triggered before properties are looked up in specific nodes.
830
-     *
831
-     * @param DAV\PropFind $propFind
832
-     * @param DAV\INode $node
833
-     * @param array $requestedProperties
834
-     * @param array $returnedProperties
835
-     * @return bool
836
-     */
837
-    public function propFind(DAV\PropFind $propFind, DAV\INode $node) {
838
-
839
-        $path = $propFind->getPath();
840
-
841
-        // Checking the read permission
842
-        if (!$this->checkPrivileges($path, '{DAV:}read', self::R_PARENT, false)) {
843
-            // User is not allowed to read properties
844
-
845
-            // Returning false causes the property-fetching system to pretend
846
-            // that the node does not exist, and will cause it to be hidden
847
-            // from listings such as PROPFIND or the browser plugin.
848
-            if ($this->hideNodesFromListings) {
849
-                return false;
850
-            }
851
-
852
-            // Otherwise we simply mark every property as 403.
853
-            foreach ($propFind->getRequestedProperties() as $requestedProperty) {
854
-                $propFind->set($requestedProperty, null, 403);
855
-            }
856
-
857
-            return;
858
-
859
-        }
860
-
861
-        /* Adding principal properties */
862
-        if ($node instanceof IPrincipal) {
863
-
864
-            $propFind->handle('{DAV:}alternate-URI-set', function() use ($node) {
865
-                return new DAV\Xml\Property\Href($node->getAlternateUriSet());
866
-            });
867
-            $propFind->handle('{DAV:}principal-URL', function() use ($node) {
868
-                return new DAV\Xml\Property\Href($node->getPrincipalUrl() . '/');
869
-            });
870
-            $propFind->handle('{DAV:}group-member-set', function() use ($node) {
871
-                $members = $node->getGroupMemberSet();
872
-                foreach ($members as $k => $member) {
873
-                    $members[$k] = rtrim($member, '/') . '/';
874
-                }
875
-                return new DAV\Xml\Property\Href($members);
876
-            });
877
-            $propFind->handle('{DAV:}group-membership', function() use ($node) {
878
-                $members = $node->getGroupMembership();
879
-                foreach ($members as $k => $member) {
880
-                    $members[$k] = rtrim($member, '/') . '/';
881
-                }
882
-                return new DAV\Xml\Property\Href($members);
883
-            });
884
-            $propFind->handle('{DAV:}displayname', [$node, 'getDisplayName']);
885
-
886
-        }
887
-
888
-        $propFind->handle('{DAV:}principal-collection-set', function() {
889
-
890
-            $val = $this->principalCollectionSet;
891
-            // Ensuring all collections end with a slash
892
-            foreach ($val as $k => $v) $val[$k] = $v . '/';
893
-            return new DAV\Xml\Property\Href($val);
894
-
895
-        });
896
-        $propFind->handle('{DAV:}current-user-principal', function() {
897
-            if ($url = $this->getCurrentUserPrincipal()) {
898
-                return new Xml\Property\Principal(Xml\Property\Principal::HREF, $url . '/');
899
-            } else {
900
-                return new Xml\Property\Principal(Xml\Property\Principal::UNAUTHENTICATED);
901
-            }
902
-        });
903
-        $propFind->handle('{DAV:}supported-privilege-set', function() use ($node) {
904
-            return new Xml\Property\SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node));
905
-        });
906
-        $propFind->handle('{DAV:}current-user-privilege-set', function() use ($node, $propFind, $path) {
907
-            if (!$this->checkPrivileges($path, '{DAV:}read-current-user-privilege-set', self::R_PARENT, false)) {
908
-                $propFind->set('{DAV:}current-user-privilege-set', null, 403);
909
-            } else {
910
-                $val = $this->getCurrentUserPrivilegeSet($node);
911
-                if (!is_null($val)) {
912
-                    return new Xml\Property\CurrentUserPrivilegeSet($val);
913
-                }
914
-            }
915
-        });
916
-        $propFind->handle('{DAV:}acl', function() use ($node, $propFind, $path) {
917
-            /* The ACL property contains all the permissions */
918
-            if (!$this->checkPrivileges($path, '{DAV:}read-acl', self::R_PARENT, false)) {
919
-                $propFind->set('{DAV:}acl', null, 403);
920
-            } else {
921
-                $acl = $this->getACL($node);
922
-                if (!is_null($acl)) {
923
-                    return new Xml\Property\Acl($this->getACL($node));
924
-                }
925
-            }
926
-        });
927
-        $propFind->handle('{DAV:}acl-restrictions', function() {
928
-            return new Xml\Property\AclRestrictions();
929
-        });
930
-
931
-        /* Adding ACL properties */
932
-        if ($node instanceof IACL) {
933
-            $propFind->handle('{DAV:}owner', function() use ($node) {
934
-                return new DAV\Xml\Property\Href($node->getOwner() . '/');
935
-            });
936
-        }
937
-
938
-    }
939
-
940
-    /**
941
-     * This method intercepts PROPPATCH methods and make sure the
942
-     * group-member-set is updated correctly.
943
-     *
944
-     * @param string $path
945
-     * @param DAV\PropPatch $propPatch
946
-     * @return void
947
-     */
948
-    public function propPatch($path, DAV\PropPatch $propPatch) {
949
-
950
-        $propPatch->handle('{DAV:}group-member-set', function($value) use ($path) {
951
-            if (is_null($value)) {
952
-                $memberSet = [];
953
-            } elseif ($value instanceof DAV\Xml\Property\Href) {
954
-                $memberSet = array_map(
955
-                    [$this->server, 'calculateUri'],
956
-                    $value->getHrefs()
957
-                );
958
-            } else {
959
-                throw new DAV\Exception('The group-member-set property MUST be an instance of Sabre\DAV\Property\HrefList or null');
960
-            }
961
-            $node = $this->server->tree->getNodeForPath($path);
962
-            if (!($node instanceof IPrincipal)) {
963
-                // Fail
964
-                return false;
965
-            }
966
-
967
-            $node->setGroupMemberSet($memberSet);
968
-            // We must also clear our cache, just in case
969
-
970
-            $this->principalMembershipCache = [];
971
-
972
-            return true;
973
-        });
974
-
975
-    }
976
-
977
-    /**
978
-     * This method handles HTTP REPORT requests
979
-     *
980
-     * @param string $reportName
981
-     * @param mixed $report
982
-     * @param mixed $path
983
-     * @return bool
984
-     */
985
-    public function report($reportName, $report, $path) {
986
-
987
-        switch ($reportName) {
988
-
989
-            case '{DAV:}principal-property-search' :
990
-                $this->server->transactionType = 'report-principal-property-search';
991
-                $this->principalPropertySearchReport($report);
992
-                return false;
993
-            case '{DAV:}principal-search-property-set' :
994
-                $this->server->transactionType = 'report-principal-search-property-set';
995
-                $this->principalSearchPropertySetReport($report);
996
-                return false;
997
-            case '{DAV:}expand-property' :
998
-                $this->server->transactionType = 'report-expand-property';
999
-                $this->expandPropertyReport($report);
1000
-                return false;
1001
-
1002
-        }
1003
-
1004
-    }
1005
-
1006
-    /**
1007
-     * This method is responsible for handling the 'ACL' event.
1008
-     *
1009
-     * @param RequestInterface $request
1010
-     * @param ResponseInterface $response
1011
-     * @return bool
1012
-     */
1013
-    public function httpAcl(RequestInterface $request, ResponseInterface $response) {
1014
-
1015
-        $path = $request->getPath();
1016
-        $body = $request->getBodyAsString();
1017
-
1018
-        if (!$body) {
1019
-            throw new DAV\Exception\BadRequest('XML body expected in ACL request');
1020
-        }
1021
-
1022
-        $acl = $this->server->xml->expect('{DAV:}acl', $body);
1023
-        $newAcl = $acl->getPrivileges();
1024
-
1025
-        // Normalizing urls
1026
-        foreach ($newAcl as $k => $newAce) {
1027
-            $newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']);
1028
-        }
1029
-        $node = $this->server->tree->getNodeForPath($path);
1030
-
1031
-        if (!$node instanceof IACL) {
1032
-            throw new DAV\Exception\MethodNotAllowed('This node does not support the ACL method');
1033
-        }
1034
-
1035
-        $oldAcl = $this->getACL($node);
1036
-
1037
-        $supportedPrivileges = $this->getFlatPrivilegeSet($node);
1038
-
1039
-        /* Checking if protected principals from the existing principal set are
532
+				// 'authenticated' matched for every user that's logged in.
533
+				// Since it's not possible to use ACL while not being logged
534
+				// in, this is also always true.
535
+				case '{DAV:}authenticated' :
536
+					$collected[] = $ace;
537
+					break;
538
+
539
+				// 'unauthenticated' can never occur either, so we simply
540
+				// ignore these.
541
+				case '{DAV:}unauthenticated' :
542
+					break;
543
+
544
+				default :
545
+					if (in_array($ace['principal'], $principals)) {
546
+						$collected[] = $ace;
547
+					}
548
+					break;
549
+
550
+			}
551
+
552
+
553
+		}
554
+
555
+		// Now we deduct all aggregated privileges.
556
+		$flat = $this->getFlatPrivilegeSet($node);
557
+
558
+		$collected2 = [];
559
+		while (count($collected)) {
560
+
561
+			$current = array_pop($collected);
562
+			$collected2[] = $current['privilege'];
563
+
564
+			foreach ($flat[$current['privilege']]['aggregates'] as $subPriv) {
565
+				$collected2[] = $subPriv;
566
+				$collected[] = $flat[$subPriv];
567
+			}
568
+
569
+		}
570
+
571
+		return array_values(array_unique($collected2));
572
+
573
+	}
574
+
575
+
576
+	/**
577
+	 * Returns a principal based on its uri.
578
+	 *
579
+	 * Returns null if the principal could not be found.
580
+	 *
581
+	 * @param string $uri
582
+	 * @return null|string
583
+	 */
584
+	public function getPrincipalByUri($uri) {
585
+
586
+		$result = null;
587
+		$collections = $this->principalCollectionSet;
588
+		foreach ($collections as $collection) {
589
+
590
+			$principalCollection = $this->server->tree->getNodeForPath($collection);
591
+			if (!$principalCollection instanceof IPrincipalCollection) {
592
+				// Not a principal collection, we're simply going to ignore
593
+				// this.
594
+				continue;
595
+			}
596
+
597
+			$result = $principalCollection->findByUri($uri);
598
+			if ($result) {
599
+				return $result;
600
+			}
601
+
602
+		}
603
+
604
+	}
605
+
606
+	/**
607
+	 * Principal property search
608
+	 *
609
+	 * This method can search for principals matching certain values in
610
+	 * properties.
611
+	 *
612
+	 * This method will return a list of properties for the matched properties.
613
+	 *
614
+	 * @param array $searchProperties    The properties to search on. This is a
615
+	 *                                   key-value list. The keys are property
616
+	 *                                   names, and the values the strings to
617
+	 *                                   match them on.
618
+	 * @param array $requestedProperties This is the list of properties to
619
+	 *                                   return for every match.
620
+	 * @param string $collectionUri      The principal collection to search on.
621
+	 *                                   If this is ommitted, the standard
622
+	 *                                   principal collection-set will be used.
623
+	 * @param string $test               "allof" to use AND to search the
624
+	 *                                   properties. 'anyof' for OR.
625
+	 * @return array     This method returns an array structure similar to
626
+	 *                  Sabre\DAV\Server::getPropertiesForPath. Returned
627
+	 *                  properties are index by a HTTP status code.
628
+	 */
629
+	public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null, $test = 'allof') {
630
+
631
+		if (!is_null($collectionUri)) {
632
+			$uris = [$collectionUri];
633
+		} else {
634
+			$uris = $this->principalCollectionSet;
635
+		}
636
+
637
+		$lookupResults = [];
638
+		foreach ($uris as $uri) {
639
+
640
+			$principalCollection = $this->server->tree->getNodeForPath($uri);
641
+			if (!$principalCollection instanceof IPrincipalCollection) {
642
+				// Not a principal collection, we're simply going to ignore
643
+				// this.
644
+				continue;
645
+			}
646
+
647
+			$results = $principalCollection->searchPrincipals($searchProperties, $test);
648
+			foreach ($results as $result) {
649
+				$lookupResults[] = rtrim($uri, '/') . '/' . $result;
650
+			}
651
+
652
+		}
653
+
654
+		$matches = [];
655
+
656
+		foreach ($lookupResults as $lookupResult) {
657
+
658
+			list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0);
659
+
660
+		}
661
+
662
+		return $matches;
663
+
664
+	}
665
+
666
+	/**
667
+	 * Sets up the plugin
668
+	 *
669
+	 * This method is automatically called by the server class.
670
+	 *
671
+	 * @param DAV\Server $server
672
+	 * @return void
673
+	 */
674
+	public function initialize(DAV\Server $server) {
675
+
676
+		$this->server = $server;
677
+		$server->on('propFind',            [$this, 'propFind'], 20);
678
+		$server->on('beforeMethod',        [$this, 'beforeMethod'], 20);
679
+		$server->on('beforeBind',          [$this, 'beforeBind'], 20);
680
+		$server->on('beforeUnbind',        [$this, 'beforeUnbind'], 20);
681
+		$server->on('propPatch',           [$this, 'propPatch']);
682
+		$server->on('beforeUnlock',        [$this, 'beforeUnlock'], 20);
683
+		$server->on('report',              [$this, 'report']);
684
+		$server->on('method:ACL',          [$this, 'httpAcl']);
685
+		$server->on('onHTMLActionsPanel',  [$this, 'htmlActionsPanel']);
686
+
687
+		array_push($server->protectedProperties,
688
+			'{DAV:}alternate-URI-set',
689
+			'{DAV:}principal-URL',
690
+			'{DAV:}group-membership',
691
+			'{DAV:}principal-collection-set',
692
+			'{DAV:}current-user-principal',
693
+			'{DAV:}supported-privilege-set',
694
+			'{DAV:}current-user-privilege-set',
695
+			'{DAV:}acl',
696
+			'{DAV:}acl-restrictions',
697
+			'{DAV:}inherited-acl-set',
698
+			'{DAV:}owner',
699
+			'{DAV:}group'
700
+		);
701
+
702
+		// Automatically mapping nodes implementing IPrincipal to the
703
+		// {DAV:}principal resourcetype.
704
+		$server->resourceTypeMapping['Sabre\\DAVACL\\IPrincipal'] = '{DAV:}principal';
705
+
706
+		// Mapping the group-member-set property to the HrefList property
707
+		// class.
708
+		$server->xml->elementMap['{DAV:}group-member-set'] = 'Sabre\\DAV\\Xml\\Property\\Href';
709
+		$server->xml->elementMap['{DAV:}acl'] = 'Sabre\\DAVACL\\Xml\\Property\\Acl';
710
+		$server->xml->elementMap['{DAV:}expand-property'] = 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport';
711
+		$server->xml->elementMap['{DAV:}principal-property-search'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport';
712
+		$server->xml->elementMap['{DAV:}principal-search-property-set'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport';
713
+
714
+	}
715
+
716
+	/* {{{ Event handlers */
717
+
718
+	/**
719
+	 * Triggered before any method is handled
720
+	 *
721
+	 * @param RequestInterface $request
722
+	 * @param ResponseInterface $response
723
+	 * @return void
724
+	 */
725
+	public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
726
+
727
+		$method = $request->getMethod();
728
+		$path = $request->getPath();
729
+
730
+		$exists = $this->server->tree->nodeExists($path);
731
+
732
+		// If the node doesn't exists, none of these checks apply
733
+		if (!$exists) return;
734
+
735
+		switch ($method) {
736
+
737
+			case 'GET' :
738
+			case 'HEAD' :
739
+			case 'OPTIONS' :
740
+				// For these 3 we only need to know if the node is readable.
741
+				$this->checkPrivileges($path, '{DAV:}read');
742
+				break;
743
+
744
+			case 'PUT' :
745
+			case 'LOCK' :
746
+			case 'UNLOCK' :
747
+				// This method requires the write-content priv if the node
748
+				// already exists, and bind on the parent if the node is being
749
+				// created.
750
+				// The bind privilege is handled in the beforeBind event.
751
+				$this->checkPrivileges($path, '{DAV:}write-content');
752
+				break;
753
+
754
+
755
+			case 'PROPPATCH' :
756
+				$this->checkPrivileges($path, '{DAV:}write-properties');
757
+				break;
758
+
759
+			case 'ACL' :
760
+				$this->checkPrivileges($path, '{DAV:}write-acl');
761
+				break;
762
+
763
+			case 'COPY' :
764
+			case 'MOVE' :
765
+				// Copy requires read privileges on the entire source tree.
766
+				// If the target exists write-content normally needs to be
767
+				// checked, however, we're deleting the node beforehand and
768
+				// creating a new one after, so this is handled by the
769
+				// beforeUnbind event.
770
+				//
771
+				// The creation of the new node is handled by the beforeBind
772
+				// event.
773
+				//
774
+				// If MOVE is used beforeUnbind will also be used to check if
775
+				// the sourcenode can be deleted.
776
+				$this->checkPrivileges($path, '{DAV:}read', self::R_RECURSIVE);
777
+
778
+				break;
779
+
780
+		}
781
+
782
+	}
783
+
784
+	/**
785
+	 * Triggered before a new node is created.
786
+	 *
787
+	 * This allows us to check permissions for any operation that creates a
788
+	 * new node, such as PUT, MKCOL, MKCALENDAR, LOCK, COPY and MOVE.
789
+	 *
790
+	 * @param string $uri
791
+	 * @return void
792
+	 */
793
+	public function beforeBind($uri) {
794
+
795
+		list($parentUri) = Uri\split($uri);
796
+		$this->checkPrivileges($parentUri, '{DAV:}bind');
797
+
798
+	}
799
+
800
+	/**
801
+	 * Triggered before a node is deleted
802
+	 *
803
+	 * This allows us to check permissions for any operation that will delete
804
+	 * an existing node.
805
+	 *
806
+	 * @param string $uri
807
+	 * @return void
808
+	 */
809
+	public function beforeUnbind($uri) {
810
+
811
+		list($parentUri) = Uri\split($uri);
812
+		$this->checkPrivileges($parentUri, '{DAV:}unbind', self::R_RECURSIVEPARENTS);
813
+
814
+	}
815
+
816
+	/**
817
+	 * Triggered before a node is unlocked.
818
+	 *
819
+	 * @param string $uri
820
+	 * @param DAV\Locks\LockInfo $lock
821
+	 * @return void
822
+	 */
823
+	public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) {
824
+
825
+
826
+	}
827
+
828
+	/**
829
+	 * Triggered before properties are looked up in specific nodes.
830
+	 *
831
+	 * @param DAV\PropFind $propFind
832
+	 * @param DAV\INode $node
833
+	 * @param array $requestedProperties
834
+	 * @param array $returnedProperties
835
+	 * @return bool
836
+	 */
837
+	public function propFind(DAV\PropFind $propFind, DAV\INode $node) {
838
+
839
+		$path = $propFind->getPath();
840
+
841
+		// Checking the read permission
842
+		if (!$this->checkPrivileges($path, '{DAV:}read', self::R_PARENT, false)) {
843
+			// User is not allowed to read properties
844
+
845
+			// Returning false causes the property-fetching system to pretend
846
+			// that the node does not exist, and will cause it to be hidden
847
+			// from listings such as PROPFIND or the browser plugin.
848
+			if ($this->hideNodesFromListings) {
849
+				return false;
850
+			}
851
+
852
+			// Otherwise we simply mark every property as 403.
853
+			foreach ($propFind->getRequestedProperties() as $requestedProperty) {
854
+				$propFind->set($requestedProperty, null, 403);
855
+			}
856
+
857
+			return;
858
+
859
+		}
860
+
861
+		/* Adding principal properties */
862
+		if ($node instanceof IPrincipal) {
863
+
864
+			$propFind->handle('{DAV:}alternate-URI-set', function() use ($node) {
865
+				return new DAV\Xml\Property\Href($node->getAlternateUriSet());
866
+			});
867
+			$propFind->handle('{DAV:}principal-URL', function() use ($node) {
868
+				return new DAV\Xml\Property\Href($node->getPrincipalUrl() . '/');
869
+			});
870
+			$propFind->handle('{DAV:}group-member-set', function() use ($node) {
871
+				$members = $node->getGroupMemberSet();
872
+				foreach ($members as $k => $member) {
873
+					$members[$k] = rtrim($member, '/') . '/';
874
+				}
875
+				return new DAV\Xml\Property\Href($members);
876
+			});
877
+			$propFind->handle('{DAV:}group-membership', function() use ($node) {
878
+				$members = $node->getGroupMembership();
879
+				foreach ($members as $k => $member) {
880
+					$members[$k] = rtrim($member, '/') . '/';
881
+				}
882
+				return new DAV\Xml\Property\Href($members);
883
+			});
884
+			$propFind->handle('{DAV:}displayname', [$node, 'getDisplayName']);
885
+
886
+		}
887
+
888
+		$propFind->handle('{DAV:}principal-collection-set', function() {
889
+
890
+			$val = $this->principalCollectionSet;
891
+			// Ensuring all collections end with a slash
892
+			foreach ($val as $k => $v) $val[$k] = $v . '/';
893
+			return new DAV\Xml\Property\Href($val);
894
+
895
+		});
896
+		$propFind->handle('{DAV:}current-user-principal', function() {
897
+			if ($url = $this->getCurrentUserPrincipal()) {
898
+				return new Xml\Property\Principal(Xml\Property\Principal::HREF, $url . '/');
899
+			} else {
900
+				return new Xml\Property\Principal(Xml\Property\Principal::UNAUTHENTICATED);
901
+			}
902
+		});
903
+		$propFind->handle('{DAV:}supported-privilege-set', function() use ($node) {
904
+			return new Xml\Property\SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node));
905
+		});
906
+		$propFind->handle('{DAV:}current-user-privilege-set', function() use ($node, $propFind, $path) {
907
+			if (!$this->checkPrivileges($path, '{DAV:}read-current-user-privilege-set', self::R_PARENT, false)) {
908
+				$propFind->set('{DAV:}current-user-privilege-set', null, 403);
909
+			} else {
910
+				$val = $this->getCurrentUserPrivilegeSet($node);
911
+				if (!is_null($val)) {
912
+					return new Xml\Property\CurrentUserPrivilegeSet($val);
913
+				}
914
+			}
915
+		});
916
+		$propFind->handle('{DAV:}acl', function() use ($node, $propFind, $path) {
917
+			/* The ACL property contains all the permissions */
918
+			if (!$this->checkPrivileges($path, '{DAV:}read-acl', self::R_PARENT, false)) {
919
+				$propFind->set('{DAV:}acl', null, 403);
920
+			} else {
921
+				$acl = $this->getACL($node);
922
+				if (!is_null($acl)) {
923
+					return new Xml\Property\Acl($this->getACL($node));
924
+				}
925
+			}
926
+		});
927
+		$propFind->handle('{DAV:}acl-restrictions', function() {
928
+			return new Xml\Property\AclRestrictions();
929
+		});
930
+
931
+		/* Adding ACL properties */
932
+		if ($node instanceof IACL) {
933
+			$propFind->handle('{DAV:}owner', function() use ($node) {
934
+				return new DAV\Xml\Property\Href($node->getOwner() . '/');
935
+			});
936
+		}
937
+
938
+	}
939
+
940
+	/**
941
+	 * This method intercepts PROPPATCH methods and make sure the
942
+	 * group-member-set is updated correctly.
943
+	 *
944
+	 * @param string $path
945
+	 * @param DAV\PropPatch $propPatch
946
+	 * @return void
947
+	 */
948
+	public function propPatch($path, DAV\PropPatch $propPatch) {
949
+
950
+		$propPatch->handle('{DAV:}group-member-set', function($value) use ($path) {
951
+			if (is_null($value)) {
952
+				$memberSet = [];
953
+			} elseif ($value instanceof DAV\Xml\Property\Href) {
954
+				$memberSet = array_map(
955
+					[$this->server, 'calculateUri'],
956
+					$value->getHrefs()
957
+				);
958
+			} else {
959
+				throw new DAV\Exception('The group-member-set property MUST be an instance of Sabre\DAV\Property\HrefList or null');
960
+			}
961
+			$node = $this->server->tree->getNodeForPath($path);
962
+			if (!($node instanceof IPrincipal)) {
963
+				// Fail
964
+				return false;
965
+			}
966
+
967
+			$node->setGroupMemberSet($memberSet);
968
+			// We must also clear our cache, just in case
969
+
970
+			$this->principalMembershipCache = [];
971
+
972
+			return true;
973
+		});
974
+
975
+	}
976
+
977
+	/**
978
+	 * This method handles HTTP REPORT requests
979
+	 *
980
+	 * @param string $reportName
981
+	 * @param mixed $report
982
+	 * @param mixed $path
983
+	 * @return bool
984
+	 */
985
+	public function report($reportName, $report, $path) {
986
+
987
+		switch ($reportName) {
988
+
989
+			case '{DAV:}principal-property-search' :
990
+				$this->server->transactionType = 'report-principal-property-search';
991
+				$this->principalPropertySearchReport($report);
992
+				return false;
993
+			case '{DAV:}principal-search-property-set' :
994
+				$this->server->transactionType = 'report-principal-search-property-set';
995
+				$this->principalSearchPropertySetReport($report);
996
+				return false;
997
+			case '{DAV:}expand-property' :
998
+				$this->server->transactionType = 'report-expand-property';
999
+				$this->expandPropertyReport($report);
1000
+				return false;
1001
+
1002
+		}
1003
+
1004
+	}
1005
+
1006
+	/**
1007
+	 * This method is responsible for handling the 'ACL' event.
1008
+	 *
1009
+	 * @param RequestInterface $request
1010
+	 * @param ResponseInterface $response
1011
+	 * @return bool
1012
+	 */
1013
+	public function httpAcl(RequestInterface $request, ResponseInterface $response) {
1014
+
1015
+		$path = $request->getPath();
1016
+		$body = $request->getBodyAsString();
1017
+
1018
+		if (!$body) {
1019
+			throw new DAV\Exception\BadRequest('XML body expected in ACL request');
1020
+		}
1021
+
1022
+		$acl = $this->server->xml->expect('{DAV:}acl', $body);
1023
+		$newAcl = $acl->getPrivileges();
1024
+
1025
+		// Normalizing urls
1026
+		foreach ($newAcl as $k => $newAce) {
1027
+			$newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']);
1028
+		}
1029
+		$node = $this->server->tree->getNodeForPath($path);
1030
+
1031
+		if (!$node instanceof IACL) {
1032
+			throw new DAV\Exception\MethodNotAllowed('This node does not support the ACL method');
1033
+		}
1034
+
1035
+		$oldAcl = $this->getACL($node);
1036
+
1037
+		$supportedPrivileges = $this->getFlatPrivilegeSet($node);
1038
+
1039
+		/* Checking if protected principals from the existing principal set are
1040 1040
            not overwritten. */
1041
-        foreach ($oldAcl as $oldAce) {
1042
-
1043
-            if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
1044
-
1045
-            $found = false;
1046
-            foreach ($newAcl as $newAce) {
1047
-                if (
1048
-                    $newAce['privilege'] === $oldAce['privilege'] &&
1049
-                    $newAce['principal'] === $oldAce['principal'] &&
1050
-                    $newAce['protected']
1051
-                )
1052
-                $found = true;
1053
-            }
1054
-
1055
-            if (!$found)
1056
-                throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
1057
-
1058
-        }
1041
+		foreach ($oldAcl as $oldAce) {
1042
+
1043
+			if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
1044
+
1045
+			$found = false;
1046
+			foreach ($newAcl as $newAce) {
1047
+				if (
1048
+					$newAce['privilege'] === $oldAce['privilege'] &&
1049
+					$newAce['principal'] === $oldAce['principal'] &&
1050
+					$newAce['protected']
1051
+				)
1052
+				$found = true;
1053
+			}
1054
+
1055
+			if (!$found)
1056
+				throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
1057
+
1058
+		}
1059 1059
 
1060
-        foreach ($newAcl as $newAce) {
1061
-
1062
-            // Do we recognize the privilege
1063
-            if (!isset($supportedPrivileges[$newAce['privilege']])) {
1064
-                throw new Exception\NotSupportedPrivilege('The privilege you specified (' . $newAce['privilege'] . ') is not recognized by this server');
1065
-            }
1066
-
1067
-            if ($supportedPrivileges[$newAce['privilege']]['abstract']) {
1068
-                throw new Exception\NoAbstract('The privilege you specified (' . $newAce['privilege'] . ') is an abstract privilege');
1069
-            }
1070
-
1071
-            // Looking up the principal
1072
-            try {
1073
-                $principal = $this->server->tree->getNodeForPath($newAce['principal']);
1074
-            } catch (DAV\Exception\NotFound $e) {
1075
-                throw new Exception\NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
1076
-            }
1077
-            if (!($principal instanceof IPrincipal)) {
1078
-                throw new Exception\NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
1079
-            }
1060
+		foreach ($newAcl as $newAce) {
1061
+
1062
+			// Do we recognize the privilege
1063
+			if (!isset($supportedPrivileges[$newAce['privilege']])) {
1064
+				throw new Exception\NotSupportedPrivilege('The privilege you specified (' . $newAce['privilege'] . ') is not recognized by this server');
1065
+			}
1066
+
1067
+			if ($supportedPrivileges[$newAce['privilege']]['abstract']) {
1068
+				throw new Exception\NoAbstract('The privilege you specified (' . $newAce['privilege'] . ') is an abstract privilege');
1069
+			}
1070
+
1071
+			// Looking up the principal
1072
+			try {
1073
+				$principal = $this->server->tree->getNodeForPath($newAce['principal']);
1074
+			} catch (DAV\Exception\NotFound $e) {
1075
+				throw new Exception\NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
1076
+			}
1077
+			if (!($principal instanceof IPrincipal)) {
1078
+				throw new Exception\NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
1079
+			}
1080 1080
 
1081
-        }
1082
-        $node->setACL($newAcl);
1081
+		}
1082
+		$node->setACL($newAcl);
1083 1083
 
1084
-        $response->setStatus(200);
1085
-
1086
-        // Breaking the event chain, because we handled this method.
1087
-        return false;
1088
-
1089
-    }
1090
-
1091
-    /* }}} */
1092
-
1093
-    /* Reports {{{ */
1094
-
1095
-    /**
1096
-     * The expand-property report is defined in RFC3253 section 3-8.
1097
-     *
1098
-     * This report is very similar to a standard PROPFIND. The difference is
1099
-     * that it has the additional ability to look at properties containing a
1100
-     * {DAV:}href element, follow that property and grab additional elements
1101
-     * there.
1102
-     *
1103
-     * Other rfc's, such as ACL rely on this report, so it made sense to put
1104
-     * it in this plugin.
1105
-     *
1106
-     * @param Xml\Request\ExpandPropertyReport $report
1107
-     * @return void
1108
-     */
1109
-    protected function expandPropertyReport($report) {
1084
+		$response->setStatus(200);
1085
+
1086
+		// Breaking the event chain, because we handled this method.
1087
+		return false;
1088
+
1089
+	}
1090
+
1091
+	/* }}} */
1092
+
1093
+	/* Reports {{{ */
1094
+
1095
+	/**
1096
+	 * The expand-property report is defined in RFC3253 section 3-8.
1097
+	 *
1098
+	 * This report is very similar to a standard PROPFIND. The difference is
1099
+	 * that it has the additional ability to look at properties containing a
1100
+	 * {DAV:}href element, follow that property and grab additional elements
1101
+	 * there.
1102
+	 *
1103
+	 * Other rfc's, such as ACL rely on this report, so it made sense to put
1104
+	 * it in this plugin.
1105
+	 *
1106
+	 * @param Xml\Request\ExpandPropertyReport $report
1107
+	 * @return void
1108
+	 */
1109
+	protected function expandPropertyReport($report) {
1110 1110
 
1111
-        $depth = $this->server->getHTTPDepth(0);
1112
-        $requestUri = $this->server->getRequestUri();
1111
+		$depth = $this->server->getHTTPDepth(0);
1112
+		$requestUri = $this->server->getRequestUri();
1113 1113
 
1114
-        $result = $this->expandProperties($requestUri, $report->properties, $depth);
1114
+		$result = $this->expandProperties($requestUri, $report->properties, $depth);
1115 1115
 
1116
-        $xml = $this->server->xml->write(
1117
-            '{DAV:}multistatus',
1118
-            new DAV\Xml\Response\MultiStatus($result),
1119
-            $this->server->getBaseUri()
1120
-        );
1121
-        $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1122
-        $this->server->httpResponse->setStatus(207);
1123
-        $this->server->httpResponse->setBody($xml);
1116
+		$xml = $this->server->xml->write(
1117
+			'{DAV:}multistatus',
1118
+			new DAV\Xml\Response\MultiStatus($result),
1119
+			$this->server->getBaseUri()
1120
+		);
1121
+		$this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1122
+		$this->server->httpResponse->setStatus(207);
1123
+		$this->server->httpResponse->setBody($xml);
1124 1124
 
1125
-    }
1125
+	}
1126 1126
 
1127
-    /**
1128
-     * This method expands all the properties and returns
1129
-     * a list with property values
1130
-     *
1131
-     * @param array $path
1132
-     * @param array $requestedProperties the list of required properties
1133
-     * @param int $depth
1134
-     * @return array
1135
-     */
1136
-    protected function expandProperties($path, array $requestedProperties, $depth) {
1127
+	/**
1128
+	 * This method expands all the properties and returns
1129
+	 * a list with property values
1130
+	 *
1131
+	 * @param array $path
1132
+	 * @param array $requestedProperties the list of required properties
1133
+	 * @param int $depth
1134
+	 * @return array
1135
+	 */
1136
+	protected function expandProperties($path, array $requestedProperties, $depth) {
1137 1137
 
1138
-        $foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth);
1138
+		$foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth);
1139 1139
 
1140
-        $result = [];
1140
+		$result = [];
1141 1141
 
1142
-        foreach ($foundProperties as $node) {
1143
-
1144
-            foreach ($requestedProperties as $propertyName => $childRequestedProperties) {
1145
-
1146
-                // We're only traversing if sub-properties were requested
1147
-                if (count($childRequestedProperties) === 0) continue;
1148
-
1149
-                // We only have to do the expansion if the property was found
1150
-                // and it contains an href element.
1151
-                if (!array_key_exists($propertyName, $node[200])) continue;
1152
-
1153
-                if (!$node[200][$propertyName] instanceof DAV\Xml\Property\Href) {
1154
-                    continue;
1155
-                }
1156
-
1157
-                $childHrefs = $node[200][$propertyName]->getHrefs();
1158
-                $childProps = [];
1159
-
1160
-                foreach ($childHrefs as $href) {
1161
-                    // Gathering the result of the children
1162
-                    $childProps[] = [
1163
-                        'name'  => '{DAV:}response',
1164
-                        'value' => $this->expandProperties($href, $childRequestedProperties, 0)[0]
1165
-                    ];
1166
-                }
1167
-
1168
-                // Replacing the property with its expannded form.
1169
-                $node[200][$propertyName] = $childProps;
1170
-
1171
-            }
1172
-            $result[] = new DAV\Xml\Element\Response($node['href'], $node);
1173
-
1174
-        }
1175
-
1176
-        return $result;
1177
-
1178
-    }
1179
-
1180
-    /**
1181
-     * principalSearchPropertySetReport
1182
-     *
1183
-     * This method responsible for handing the
1184
-     * {DAV:}principal-search-property-set report. This report returns a list
1185
-     * of properties the client may search on, using the
1186
-     * {DAV:}principal-property-search report.
1187
-     *
1188
-     * @param Xml\Request\PrincipalSearchPropertySetReport $report
1189
-     * @return void
1190
-     */
1191
-    protected function principalSearchPropertySetReport($report) {
1192
-
1193
-        $httpDepth = $this->server->getHTTPDepth(0);
1194
-        if ($httpDepth !== 0) {
1195
-            throw new DAV\Exception\BadRequest('This report is only defined when Depth: 0');
1196
-        }
1197
-
1198
-        $writer = $this->server->xml->getWriter();
1199
-        $writer->openMemory();
1200
-        $writer->startDocument();
1201
-
1202
-        $writer->startElement('{DAV:}principal-search-property-set');
1203
-
1204
-        foreach ($this->principalSearchPropertySet as $propertyName => $description) {
1205
-
1206
-            $writer->startElement('{DAV:}principal-search-property');
1207
-            $writer->startElement('{DAV:}prop');
1208
-
1209
-            $writer->writeElement($propertyName);
1210
-
1211
-            $writer->endElement(); // prop
1212
-
1213
-            if ($description) {
1214
-                $writer->write([[
1215
-                    'name'       => '{DAV:}description',
1216
-                    'value'      => $description,
1217
-                    'attributes' => ['xml:lang' => 'en']
1218
-                ]]);
1219
-            }
1220
-
1221
-            $writer->endElement(); // principal-search-property
1222
-
1223
-
1224
-        }
1225
-
1226
-        $writer->endElement(); // principal-search-property-set
1227
-
1228
-        $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1229
-        $this->server->httpResponse->setStatus(200);
1230
-        $this->server->httpResponse->setBody($writer->outputMemory());
1231
-
1232
-    }
1142
+		foreach ($foundProperties as $node) {
1143
+
1144
+			foreach ($requestedProperties as $propertyName => $childRequestedProperties) {
1145
+
1146
+				// We're only traversing if sub-properties were requested
1147
+				if (count($childRequestedProperties) === 0) continue;
1148
+
1149
+				// We only have to do the expansion if the property was found
1150
+				// and it contains an href element.
1151
+				if (!array_key_exists($propertyName, $node[200])) continue;
1152
+
1153
+				if (!$node[200][$propertyName] instanceof DAV\Xml\Property\Href) {
1154
+					continue;
1155
+				}
1156
+
1157
+				$childHrefs = $node[200][$propertyName]->getHrefs();
1158
+				$childProps = [];
1159
+
1160
+				foreach ($childHrefs as $href) {
1161
+					// Gathering the result of the children
1162
+					$childProps[] = [
1163
+						'name'  => '{DAV:}response',
1164
+						'value' => $this->expandProperties($href, $childRequestedProperties, 0)[0]
1165
+					];
1166
+				}
1167
+
1168
+				// Replacing the property with its expannded form.
1169
+				$node[200][$propertyName] = $childProps;
1170
+
1171
+			}
1172
+			$result[] = new DAV\Xml\Element\Response($node['href'], $node);
1173
+
1174
+		}
1175
+
1176
+		return $result;
1177
+
1178
+	}
1179
+
1180
+	/**
1181
+	 * principalSearchPropertySetReport
1182
+	 *
1183
+	 * This method responsible for handing the
1184
+	 * {DAV:}principal-search-property-set report. This report returns a list
1185
+	 * of properties the client may search on, using the
1186
+	 * {DAV:}principal-property-search report.
1187
+	 *
1188
+	 * @param Xml\Request\PrincipalSearchPropertySetReport $report
1189
+	 * @return void
1190
+	 */
1191
+	protected function principalSearchPropertySetReport($report) {
1192
+
1193
+		$httpDepth = $this->server->getHTTPDepth(0);
1194
+		if ($httpDepth !== 0) {
1195
+			throw new DAV\Exception\BadRequest('This report is only defined when Depth: 0');
1196
+		}
1197
+
1198
+		$writer = $this->server->xml->getWriter();
1199
+		$writer->openMemory();
1200
+		$writer->startDocument();
1201
+
1202
+		$writer->startElement('{DAV:}principal-search-property-set');
1203
+
1204
+		foreach ($this->principalSearchPropertySet as $propertyName => $description) {
1205
+
1206
+			$writer->startElement('{DAV:}principal-search-property');
1207
+			$writer->startElement('{DAV:}prop');
1208
+
1209
+			$writer->writeElement($propertyName);
1210
+
1211
+			$writer->endElement(); // prop
1212
+
1213
+			if ($description) {
1214
+				$writer->write([[
1215
+					'name'       => '{DAV:}description',
1216
+					'value'      => $description,
1217
+					'attributes' => ['xml:lang' => 'en']
1218
+				]]);
1219
+			}
1220
+
1221
+			$writer->endElement(); // principal-search-property
1222
+
1223
+
1224
+		}
1225
+
1226
+		$writer->endElement(); // principal-search-property-set
1227
+
1228
+		$this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1229
+		$this->server->httpResponse->setStatus(200);
1230
+		$this->server->httpResponse->setBody($writer->outputMemory());
1231
+
1232
+	}
1233 1233
 
1234
-    /**
1235
-     * principalPropertySearchReport
1236
-     *
1237
-     * This method is responsible for handing the
1238
-     * {DAV:}principal-property-search report. This report can be used for
1239
-     * clients to search for groups of principals, based on the value of one
1240
-     * or more properties.
1241
-     *
1242
-     * @param Xml\Request\PrincipalPropertySearchReport $report
1243
-     * @return void
1244
-     */
1245
-    protected function principalPropertySearchReport($report) {
1246
-
1247
-        $uri = null;
1248
-        if (!$report->applyToPrincipalCollectionSet) {
1249
-            $uri = $this->server->httpRequest->getPath();
1250
-        }
1251
-        if ($this->server->getHttpDepth('0') !== 0) {
1252
-            throw new BadRequest('Depth must be 0');
1253
-        }
1254
-        $result = $this->principalSearch(
1255
-            $report->searchProperties,
1256
-            $report->properties,
1257
-            $uri,
1258
-            $report->test
1259
-        );
1260
-
1261
-        $prefer = $this->server->getHTTPPrefer();
1262
-
1263
-        $this->server->httpResponse->setStatus(207);
1264
-        $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1265
-        $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
1266
-        $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return'] === 'minimal'));
1267
-
1268
-    }
1269
-
1270
-    /* }}} */
1271
-
1272
-    /**
1273
-     * This method is used to generate HTML output for the
1274
-     * DAV\Browser\Plugin. This allows us to generate an interface users
1275
-     * can use to create new calendars.
1276
-     *
1277
-     * @param DAV\INode $node
1278
-     * @param string $output
1279
-     * @return bool
1280
-     */
1281
-    public function htmlActionsPanel(DAV\INode $node, &$output) {
1282
-
1283
-        if (!$node instanceof PrincipalCollection)
1284
-            return;
1285
-
1286
-        $output .= '<tr><td colspan="2"><form method="post" action="">
1234
+	/**
1235
+	 * principalPropertySearchReport
1236
+	 *
1237
+	 * This method is responsible for handing the
1238
+	 * {DAV:}principal-property-search report. This report can be used for
1239
+	 * clients to search for groups of principals, based on the value of one
1240
+	 * or more properties.
1241
+	 *
1242
+	 * @param Xml\Request\PrincipalPropertySearchReport $report
1243
+	 * @return void
1244
+	 */
1245
+	protected function principalPropertySearchReport($report) {
1246
+
1247
+		$uri = null;
1248
+		if (!$report->applyToPrincipalCollectionSet) {
1249
+			$uri = $this->server->httpRequest->getPath();
1250
+		}
1251
+		if ($this->server->getHttpDepth('0') !== 0) {
1252
+			throw new BadRequest('Depth must be 0');
1253
+		}
1254
+		$result = $this->principalSearch(
1255
+			$report->searchProperties,
1256
+			$report->properties,
1257
+			$uri,
1258
+			$report->test
1259
+		);
1260
+
1261
+		$prefer = $this->server->getHTTPPrefer();
1262
+
1263
+		$this->server->httpResponse->setStatus(207);
1264
+		$this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
1265
+		$this->server->httpResponse->setHeader('Vary', 'Brief,Prefer');
1266
+		$this->server->httpResponse->setBody($this->server->generateMultiStatus($result, $prefer['return'] === 'minimal'));
1267
+
1268
+	}
1269
+
1270
+	/* }}} */
1271
+
1272
+	/**
1273
+	 * This method is used to generate HTML output for the
1274
+	 * DAV\Browser\Plugin. This allows us to generate an interface users
1275
+	 * can use to create new calendars.
1276
+	 *
1277
+	 * @param DAV\INode $node
1278
+	 * @param string $output
1279
+	 * @return bool
1280
+	 */
1281
+	public function htmlActionsPanel(DAV\INode $node, &$output) {
1282
+
1283
+		if (!$node instanceof PrincipalCollection)
1284
+			return;
1285
+
1286
+		$output .= '<tr><td colspan="2"><form method="post" action="">
1287 1287
             <h3>Create new principal</h3>
1288 1288
             <input type="hidden" name="sabreAction" value="mkcol" />
1289 1289
             <input type="hidden" name="resourceType" value="{DAV:}principal" />
@@ -1294,28 +1294,28 @@  discard block
 block discarded – undo
1294 1294
             </form>
1295 1295
             </td></tr>';
1296 1296
 
1297
-        return false;
1298
-
1299
-    }
1300
-
1301
-    /**
1302
-     * Returns a bunch of meta-data about the plugin.
1303
-     *
1304
-     * Providing this information is optional, and is mainly displayed by the
1305
-     * Browser plugin.
1306
-     *
1307
-     * The description key in the returned array may contain html and will not
1308
-     * be sanitized.
1309
-     *
1310
-     * @return array
1311
-     */
1312
-    public function getPluginInfo() {
1313
-
1314
-        return [
1315
-            'name'        => $this->getPluginName(),
1316
-            'description' => 'Adds support for WebDAV ACL (rfc3744)',
1317
-            'link'        => 'http://sabre.io/dav/acl/',
1318
-        ];
1319
-
1320
-    }
1297
+		return false;
1298
+
1299
+	}
1300
+
1301
+	/**
1302
+	 * Returns a bunch of meta-data about the plugin.
1303
+	 *
1304
+	 * Providing this information is optional, and is mainly displayed by the
1305
+	 * Browser plugin.
1306
+	 *
1307
+	 * The description key in the returned array may contain html and will not
1308
+	 * be sanitized.
1309
+	 *
1310
+	 * @return array
1311
+	 */
1312
+	public function getPluginInfo() {
1313
+
1314
+		return [
1315
+			'name'        => $this->getPluginName(),
1316
+			'description' => 'Adds support for WebDAV ACL (rfc3744)',
1317
+			'link'        => 'http://sabre.io/dav/acl/',
1318
+		];
1319
+
1320
+	}
1321 1321
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/Principal.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@
 block discarded – undo
39 39
     /**
40 40
      * Creates the principal object
41 41
      *
42
-     * @param IPrincipalBackend $principalBackend
42
+     * @param PrincipalBackend\BackendInterface $principalBackend
43 43
      * @param array $principalProperties
44 44
      */
45 45
     function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = []) {
Please login to merge, or discard this patch.
Indentation   +262 added lines, -262 removed lines patch added patch discarded remove patch
@@ -22,267 +22,267 @@
 block discarded – undo
22 22
  */
23 23
 class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL {
24 24
 
25
-    /**
26
-     * Struct with principal information.
27
-     *
28
-     * @var array
29
-     */
30
-    protected $principalProperties;
31
-
32
-    /**
33
-     * Principal backend
34
-     *
35
-     * @var PrincipalBackend\BackendInterface
36
-     */
37
-    protected $principalBackend;
38
-
39
-    /**
40
-     * Creates the principal object
41
-     *
42
-     * @param IPrincipalBackend $principalBackend
43
-     * @param array $principalProperties
44
-     */
45
-    public function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = []) {
46
-
47
-        if (!isset($principalProperties['uri'])) {
48
-            throw new DAV\Exception('The principal properties must at least contain the \'uri\' key');
49
-        }
50
-        $this->principalBackend = $principalBackend;
51
-        $this->principalProperties = $principalProperties;
52
-
53
-    }
54
-
55
-    /**
56
-     * Returns the full principal url
57
-     *
58
-     * @return string
59
-     */
60
-    public function getPrincipalUrl() {
61
-
62
-        return $this->principalProperties['uri'];
63
-
64
-    }
65
-
66
-    /**
67
-     * Returns a list of alternative urls for a principal
68
-     *
69
-     * This can for example be an email address, or ldap url.
70
-     *
71
-     * @return array
72
-     */
73
-    public function getAlternateUriSet() {
74
-
75
-        $uris = [];
76
-        if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) {
77
-
78
-            $uris = $this->principalProperties['{DAV:}alternate-URI-set'];
79
-
80
-        }
81
-
82
-        if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) {
83
-            $uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
84
-        }
85
-
86
-        return array_unique($uris);
87
-
88
-    }
89
-
90
-    /**
91
-     * Returns the list of group members
92
-     *
93
-     * If this principal is a group, this function should return
94
-     * all member principal uri's for the group.
95
-     *
96
-     * @return array
97
-     */
98
-    public function getGroupMemberSet() {
99
-
100
-        return $this->principalBackend->getGroupMemberSet($this->principalProperties['uri']);
101
-
102
-    }
103
-
104
-    /**
105
-     * Returns the list of groups this principal is member of
106
-     *
107
-     * If this principal is a member of a (list of) groups, this function
108
-     * should return a list of principal uri's for it's members.
109
-     *
110
-     * @return array
111
-     */
112
-    public function getGroupMembership() {
113
-
114
-        return $this->principalBackend->getGroupMemberShip($this->principalProperties['uri']);
115
-
116
-    }
117
-
118
-    /**
119
-     * Sets a list of group members
120
-     *
121
-     * If this principal is a group, this method sets all the group members.
122
-     * The list of members is always overwritten, never appended to.
123
-     *
124
-     * This method should throw an exception if the members could not be set.
125
-     *
126
-     * @param array $groupMembers
127
-     * @return void
128
-     */
129
-    public function setGroupMemberSet(array $groupMembers) {
130
-
131
-        $this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers);
132
-
133
-    }
134
-
135
-    /**
136
-     * Returns this principals name.
137
-     *
138
-     * @return string
139
-     */
140
-    public function getName() {
141
-
142
-        $uri = $this->principalProperties['uri'];
143
-        list(, $name) = URLUtil::splitPath($uri);
144
-        return $name;
145
-
146
-    }
147
-
148
-    /**
149
-     * Returns the name of the user
150
-     *
151
-     * @return string
152
-     */
153
-    public function getDisplayName() {
154
-
155
-        if (isset($this->principalProperties['{DAV:}displayname'])) {
156
-            return $this->principalProperties['{DAV:}displayname'];
157
-        } else {
158
-            return $this->getName();
159
-        }
160
-
161
-    }
162
-
163
-    /**
164
-     * Returns a list of properties
165
-     *
166
-     * @param array $requestedProperties
167
-     * @return array
168
-     */
169
-    public function getProperties($requestedProperties) {
170
-
171
-        $newProperties = [];
172
-        foreach ($requestedProperties as $propName) {
173
-
174
-            if (isset($this->principalProperties[$propName])) {
175
-                $newProperties[$propName] = $this->principalProperties[$propName];
176
-            }
177
-
178
-        }
179
-
180
-        return $newProperties;
181
-
182
-    }
183
-
184
-    /**
185
-     * Updates properties on this node.
186
-     *
187
-     * This method received a PropPatch object, which contains all the
188
-     * information about the update.
189
-     *
190
-     * To update specific properties, call the 'handle' method on this object.
191
-     * Read the PropPatch documentation for more information.
192
-     *
193
-     * @param DAV\PropPatch $propPatch
194
-     * @return void
195
-     */
196
-    public function propPatch(DAV\PropPatch $propPatch) {
197
-
198
-        return $this->principalBackend->updatePrincipal(
199
-            $this->principalProperties['uri'],
200
-            $propPatch
201
-        );
202
-
203
-    }
204
-
205
-    /**
206
-     * Returns the owner principal
207
-     *
208
-     * This must be a url to a principal, or null if there's no owner
209
-     *
210
-     * @return string|null
211
-     */
212
-    public function getOwner() {
213
-
214
-        return $this->principalProperties['uri'];
215
-
216
-
217
-    }
218
-
219
-    /**
220
-     * Returns a group principal
221
-     *
222
-     * This must be a url to a principal, or null if there's no owner
223
-     *
224
-     * @return string|null
225
-     */
226
-    public function getGroup() {
227
-
228
-        return null;
229
-
230
-    }
231
-
232
-    /**
233
-     * Returns a list of ACE's for this node.
234
-     *
235
-     * Each ACE has the following properties:
236
-     *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
237
-     *     currently the only supported privileges
238
-     *   * 'principal', a url to the principal who owns the node
239
-     *   * 'protected' (optional), indicating that this ACE is not allowed to
240
-     *      be updated.
241
-     *
242
-     * @return array
243
-     */
244
-    public function getACL() {
245
-
246
-        return [
247
-            [
248
-                'privilege' => '{DAV:}read',
249
-                'principal' => '{DAV:}authenticated',
250
-                'protected' => true,
251
-            ],
252
-        ];
253
-
254
-    }
255
-
256
-    /**
257
-     * Updates the ACL
258
-     *
259
-     * This method will receive a list of new ACE's.
260
-     *
261
-     * @param array $acl
262
-     * @return void
263
-     */
264
-    public function setACL(array $acl) {
265
-
266
-        throw new DAV\Exception\MethodNotAllowed('Updating ACLs is not allowed here');
267
-
268
-    }
269
-
270
-    /**
271
-     * Returns the list of supported privileges for this node.
272
-     *
273
-     * The returned data structure is a list of nested privileges.
274
-     * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
275
-     * standard structure.
276
-     *
277
-     * If null is returned from this method, the default privilege set is used,
278
-     * which is fine for most common usecases.
279
-     *
280
-     * @return array|null
281
-     */
282
-    public function getSupportedPrivilegeSet() {
283
-
284
-        return null;
285
-
286
-    }
25
+	/**
26
+	 * Struct with principal information.
27
+	 *
28
+	 * @var array
29
+	 */
30
+	protected $principalProperties;
31
+
32
+	/**
33
+	 * Principal backend
34
+	 *
35
+	 * @var PrincipalBackend\BackendInterface
36
+	 */
37
+	protected $principalBackend;
38
+
39
+	/**
40
+	 * Creates the principal object
41
+	 *
42
+	 * @param IPrincipalBackend $principalBackend
43
+	 * @param array $principalProperties
44
+	 */
45
+	public function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = []) {
46
+
47
+		if (!isset($principalProperties['uri'])) {
48
+			throw new DAV\Exception('The principal properties must at least contain the \'uri\' key');
49
+		}
50
+		$this->principalBackend = $principalBackend;
51
+		$this->principalProperties = $principalProperties;
52
+
53
+	}
54
+
55
+	/**
56
+	 * Returns the full principal url
57
+	 *
58
+	 * @return string
59
+	 */
60
+	public function getPrincipalUrl() {
61
+
62
+		return $this->principalProperties['uri'];
63
+
64
+	}
65
+
66
+	/**
67
+	 * Returns a list of alternative urls for a principal
68
+	 *
69
+	 * This can for example be an email address, or ldap url.
70
+	 *
71
+	 * @return array
72
+	 */
73
+	public function getAlternateUriSet() {
74
+
75
+		$uris = [];
76
+		if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) {
77
+
78
+			$uris = $this->principalProperties['{DAV:}alternate-URI-set'];
79
+
80
+		}
81
+
82
+		if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) {
83
+			$uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
84
+		}
85
+
86
+		return array_unique($uris);
87
+
88
+	}
89
+
90
+	/**
91
+	 * Returns the list of group members
92
+	 *
93
+	 * If this principal is a group, this function should return
94
+	 * all member principal uri's for the group.
95
+	 *
96
+	 * @return array
97
+	 */
98
+	public function getGroupMemberSet() {
99
+
100
+		return $this->principalBackend->getGroupMemberSet($this->principalProperties['uri']);
101
+
102
+	}
103
+
104
+	/**
105
+	 * Returns the list of groups this principal is member of
106
+	 *
107
+	 * If this principal is a member of a (list of) groups, this function
108
+	 * should return a list of principal uri's for it's members.
109
+	 *
110
+	 * @return array
111
+	 */
112
+	public function getGroupMembership() {
113
+
114
+		return $this->principalBackend->getGroupMemberShip($this->principalProperties['uri']);
115
+
116
+	}
117
+
118
+	/**
119
+	 * Sets a list of group members
120
+	 *
121
+	 * If this principal is a group, this method sets all the group members.
122
+	 * The list of members is always overwritten, never appended to.
123
+	 *
124
+	 * This method should throw an exception if the members could not be set.
125
+	 *
126
+	 * @param array $groupMembers
127
+	 * @return void
128
+	 */
129
+	public function setGroupMemberSet(array $groupMembers) {
130
+
131
+		$this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers);
132
+
133
+	}
134
+
135
+	/**
136
+	 * Returns this principals name.
137
+	 *
138
+	 * @return string
139
+	 */
140
+	public function getName() {
141
+
142
+		$uri = $this->principalProperties['uri'];
143
+		list(, $name) = URLUtil::splitPath($uri);
144
+		return $name;
145
+
146
+	}
147
+
148
+	/**
149
+	 * Returns the name of the user
150
+	 *
151
+	 * @return string
152
+	 */
153
+	public function getDisplayName() {
154
+
155
+		if (isset($this->principalProperties['{DAV:}displayname'])) {
156
+			return $this->principalProperties['{DAV:}displayname'];
157
+		} else {
158
+			return $this->getName();
159
+		}
160
+
161
+	}
162
+
163
+	/**
164
+	 * Returns a list of properties
165
+	 *
166
+	 * @param array $requestedProperties
167
+	 * @return array
168
+	 */
169
+	public function getProperties($requestedProperties) {
170
+
171
+		$newProperties = [];
172
+		foreach ($requestedProperties as $propName) {
173
+
174
+			if (isset($this->principalProperties[$propName])) {
175
+				$newProperties[$propName] = $this->principalProperties[$propName];
176
+			}
177
+
178
+		}
179
+
180
+		return $newProperties;
181
+
182
+	}
183
+
184
+	/**
185
+	 * Updates properties on this node.
186
+	 *
187
+	 * This method received a PropPatch object, which contains all the
188
+	 * information about the update.
189
+	 *
190
+	 * To update specific properties, call the 'handle' method on this object.
191
+	 * Read the PropPatch documentation for more information.
192
+	 *
193
+	 * @param DAV\PropPatch $propPatch
194
+	 * @return void
195
+	 */
196
+	public function propPatch(DAV\PropPatch $propPatch) {
197
+
198
+		return $this->principalBackend->updatePrincipal(
199
+			$this->principalProperties['uri'],
200
+			$propPatch
201
+		);
202
+
203
+	}
204
+
205
+	/**
206
+	 * Returns the owner principal
207
+	 *
208
+	 * This must be a url to a principal, or null if there's no owner
209
+	 *
210
+	 * @return string|null
211
+	 */
212
+	public function getOwner() {
213
+
214
+		return $this->principalProperties['uri'];
215
+
216
+
217
+	}
218
+
219
+	/**
220
+	 * Returns a group principal
221
+	 *
222
+	 * This must be a url to a principal, or null if there's no owner
223
+	 *
224
+	 * @return string|null
225
+	 */
226
+	public function getGroup() {
227
+
228
+		return null;
229
+
230
+	}
231
+
232
+	/**
233
+	 * Returns a list of ACE's for this node.
234
+	 *
235
+	 * Each ACE has the following properties:
236
+	 *   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
237
+	 *     currently the only supported privileges
238
+	 *   * 'principal', a url to the principal who owns the node
239
+	 *   * 'protected' (optional), indicating that this ACE is not allowed to
240
+	 *      be updated.
241
+	 *
242
+	 * @return array
243
+	 */
244
+	public function getACL() {
245
+
246
+		return [
247
+			[
248
+				'privilege' => '{DAV:}read',
249
+				'principal' => '{DAV:}authenticated',
250
+				'protected' => true,
251
+			],
252
+		];
253
+
254
+	}
255
+
256
+	/**
257
+	 * Updates the ACL
258
+	 *
259
+	 * This method will receive a list of new ACE's.
260
+	 *
261
+	 * @param array $acl
262
+	 * @return void
263
+	 */
264
+	public function setACL(array $acl) {
265
+
266
+		throw new DAV\Exception\MethodNotAllowed('Updating ACLs is not allowed here');
267
+
268
+	}
269
+
270
+	/**
271
+	 * Returns the list of supported privileges for this node.
272
+	 *
273
+	 * The returned data structure is a list of nested privileges.
274
+	 * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
275
+	 * standard structure.
276
+	 *
277
+	 * If null is returned from this method, the default privilege set is used,
278
+	 * which is fine for most common usecases.
279
+	 *
280
+	 * @return array|null
281
+	 */
282
+	public function getSupportedPrivilegeSet() {
283
+
284
+		return null;
285
+
286
+	}
287 287
 
288 288
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/PrincipalBackend/PDO.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -65,7 +65,7 @@
 block discarded – undo
65 65
     /**
66 66
      * Sets up the backend.
67 67
      *
68
-     * @param PDO $pdo
68
+     * @param \PDO $pdo
69 69
      */
70 70
     function __construct(\PDO $pdo) {
71 71
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
      * @return array
241 241
      */
242 242
     function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
243
-        if (count($searchProperties) == 0) return [];    //No criteria
243
+        if (count($searchProperties) == 0) return []; //No criteria
244 244
 
245 245
         $query = sprintf('SELECT uri FROM %s WHERE ', $this->tableName);
246 246
         $values = [];
@@ -303,11 +303,11 @@  discard block
 block discarded – undo
303 303
         if ($value == null) return null;
304 304
 
305 305
         $uri = null;
306
-        switch ($scheme){
306
+        switch ($scheme) {
307 307
             case "mailto":
308 308
                 $query = sprintf('SELECT uri FROM %s WHERE lower(email)=lower(?)', $this->tableName);
309 309
                 $stmt = $this->pdo->prepare($query);
310
-                $stmt->execute([ $value ]);
310
+                $stmt->execute([$value]);
311 311
             
312 312
                 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
313 313
                     // Checking if the principal is in the prefix
@@ -383,7 +383,7 @@  discard block
 block discarded – undo
383 383
     function setGroupMemberSet($principal, array $members) {
384 384
 
385 385
         // Grabbing the list of principal id's.
386
-        $stmt = $this->pdo->prepare(sprintf('SELECT id, uri FROM %s WHERE uri IN (? %s);',$this->tableName, str_repeat(', ? ', count($members))));
386
+        $stmt = $this->pdo->prepare(sprintf('SELECT id, uri FROM %s WHERE uri IN (? %s);', $this->tableName, str_repeat(', ? ', count($members))));
387 387
         $stmt->execute(array_merge([$principal], $members));
388 388
 
389 389
         $memberIds = [];
Please login to merge, or discard this patch.
Indentation   +405 added lines, -405 removed lines patch added patch discarded remove patch
@@ -19,415 +19,415 @@
 block discarded – undo
19 19
  */
20 20
 class PDO extends AbstractBackend implements CreatePrincipalSupport {
21 21
 
22
-    /**
23
-     * PDO table name for 'principals'
24
-     *
25
-     * @var string
26
-     */
27
-    public $tableName = 'principals';
28
-
29
-    /**
30
-     * PDO table name for 'group members'
31
-     *
32
-     * @var string
33
-     */
34
-    public $groupMembersTableName = 'groupmembers';
35
-
36
-    /**
37
-     * pdo
38
-     *
39
-     * @var PDO
40
-     */
41
-    protected $pdo;
42
-
43
-    /**
44
-     * A list of additional fields to support
45
-     *
46
-     * @var array
47
-     */
48
-    protected $fieldMap = [
49
-
50
-        /**
51
-         * This property can be used to display the users' real name.
52
-         */
53
-        '{DAV:}displayname' => [
54
-            'dbField' => 'displayname',
55
-        ],
56
-
57
-        /**
58
-         * This is the users' primary email-address.
59
-         */
60
-        '{http://sabredav.org/ns}email-address' => [
61
-            'dbField' => 'email',
62
-        ],
63
-    ];
64
-
65
-    /**
66
-     * Sets up the backend.
67
-     *
68
-     * @param PDO $pdo
69
-     */
70
-    public function __construct(\PDO $pdo) {
71
-
72
-        $this->pdo = $pdo;
73
-
74
-    }
75
-
76
-    /**
77
-     * Returns a list of principals based on a prefix.
78
-     *
79
-     * This prefix will often contain something like 'principals'. You are only
80
-     * expected to return principals that are in this base path.
81
-     *
82
-     * You are expected to return at least a 'uri' for every user, you can
83
-     * return any additional properties if you wish so. Common properties are:
84
-     *   {DAV:}displayname
85
-     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV
86
-     *     field that's actualy injected in a number of other properties. If
87
-     *     you have an email address, use this property.
88
-     *
89
-     * @param string $prefixPath
90
-     * @return array
91
-     */
92
-    public function getPrincipalsByPrefix($prefixPath) {
93
-
94
-        $fields = [
95
-            'uri',
96
-        ];
97
-
98
-        foreach ($this->fieldMap as $key => $value) {
99
-            $fields[] = $value['dbField'];
100
-        }
101
-        $result = $this->pdo->query(sprintf('SELECT %s FROM %s', implode(',', $fields), $this->tableName));
102
-
103
-        $principals = [];
104
-
105
-        while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
106
-
107
-            // Checking if the principal is in the prefix
108
-            list($rowPrefix) = URLUtil::splitPath($row['uri']);
109
-            if ($rowPrefix !== $prefixPath) continue;
110
-
111
-            $principal = [
112
-                'uri' => $row['uri'],
113
-            ];
114
-            foreach ($this->fieldMap as $key => $value) {
115
-                if ($row[$value['dbField']]) {
116
-                    $principal[$key] = $row[$value['dbField']];
117
-                }
118
-            }
119
-            $principals[] = $principal;
120
-
121
-        }
122
-
123
-        return $principals;
124
-
125
-    }
126
-
127
-    /**
128
-     * Returns a specific principal, specified by it's path.
129
-     * The returned structure should be the exact same as from
130
-     * getPrincipalsByPrefix.
131
-     *
132
-     * @param string $path
133
-     * @return array
134
-     */
135
-    public function getPrincipalByPath($path) {
136
-
137
-        $fields = [
138
-            'id',
139
-            'uri',
140
-        ];
141
-
142
-        foreach ($this->fieldMap as $key => $value) {
143
-            $fields[] = $value['dbField'];
144
-        }
145
-        $stmt = $this->pdo->prepare(sprintf('SELECT %s FROM %s WHERE uri = ?', implode(',', $fields), $this->tableName));
146
-        $stmt->execute([$path]);
147
-
148
-        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
149
-        if (!$row) return;
150
-
151
-        $principal = [
152
-            'id'  => $row['id'],
153
-            'uri' => $row['uri'],
154
-        ];
155
-        foreach ($this->fieldMap as $key => $value) {
156
-            if ($row[$value['dbField']]) {
157
-                $principal[$key] = $row[$value['dbField']];
158
-            }
159
-        }
160
-        return $principal;
161
-
162
-    }
163
-
164
-    /**
165
-     * Updates one ore more webdav properties on a principal.
166
-     *
167
-     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
168
-     * To do the actual updates, you must tell this object which properties
169
-     * you're going to process with the handle() method.
170
-     *
171
-     * Calling the handle method is like telling the PropPatch object "I
172
-     * promise I can handle updating this property".
173
-     *
174
-     * Read the PropPatch documenation for more info and examples.
175
-     *
176
-     * @param string $path
177
-     * @param DAV\PropPatch $propPatch
178
-     */
179
-    public function updatePrincipal($path, DAV\PropPatch $propPatch) {
180
-
181
-        $propPatch->handle(array_keys($this->fieldMap), function($properties) use ($path) {
182
-
183
-            $query = sprintf('UPDATE %s SET ', $this->tableName);
184
-            $first = true;
185
-
186
-            $values = [];
187
-
188
-            foreach ($properties as $key => $value) {
189
-
190
-                $dbField = $this->fieldMap[$key]['dbField'];
191
-
192
-                if (!$first) {
193
-                    $query .= ', ';
194
-                }
195
-                $first = false;
196
-                $query .= $dbField . ' = :' . $dbField;
197
-                $values[$dbField] = $value;
198
-
199
-            }
200
-
201
-            $query .= " WHERE uri = :uri";
202
-            $values['uri'] = $path;
203
-
204
-            $stmt = $this->pdo->prepare($query);
205
-            $stmt->execute($values);
206
-
207
-            return true;
208
-
209
-        });
210
-
211
-    }
212
-
213
-    /**
214
-     * This method is used to search for principals matching a set of
215
-     * properties.
216
-     *
217
-     * This search is specifically used by RFC3744's principal-property-search
218
-     * REPORT.
219
-     *
220
-     * The actual search should be a unicode-non-case-sensitive search. The
221
-     * keys in searchProperties are the WebDAV property names, while the values
222
-     * are the property values to search on.
223
-     *
224
-     * By default, if multiple properties are submitted to this method, the
225
-     * various properties should be combined with 'AND'. If $test is set to
226
-     * 'anyof', it should be combined using 'OR'.
227
-     *
228
-     * This method should simply return an array with full principal uri's.
229
-     *
230
-     * If somebody attempted to search on a property the backend does not
231
-     * support, you should simply return 0 results.
232
-     *
233
-     * You can also just return 0 results if you choose to not support
234
-     * searching at all, but keep in mind that this may stop certain features
235
-     * from working.
236
-     *
237
-     * @param string $prefixPath
238
-     * @param array $searchProperties
239
-     * @param string $test
240
-     * @return array
241
-     */
242
-    public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
243
-        if (count($searchProperties) == 0) return [];    //No criteria
244
-
245
-        $query = sprintf('SELECT uri FROM %s WHERE ', $this->tableName);
246
-        $values = [];
247
-        foreach ($searchProperties as $property => $value) {
248
-            switch ($property) {
249
-                case '{DAV:}displayname' :
250
-                    $column = "displayname";
251
-                    break;
252
-                case '{http://sabredav.org/ns}email-address' :
253
-                    $column = "email";
254
-                    break;
255
-                default :
256
-                    // Unsupported property
257
-                    return [];
258
-            }
259
-            if (count($values) > 0) $query .= (strcmp($test, "anyof") == 0 ? " || " : " && ");
260
-            $query .= 'lower(' . $column . ') LIKE lower(?)';
261
-            $values[] = '%' . $value . '%';
262
-
263
-        }
264
-        $stmt = $this->pdo->prepare($query);
265
-        $stmt->execute($values);
266
-
267
-        $principals = [];
268
-        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
269
-
270
-            // Checking if the principal is in the prefix
271
-            list($rowPrefix) = URLUtil::splitPath($row['uri']);
272
-            if ($rowPrefix !== $prefixPath) continue;
273
-
274
-            $principals[] = $row['uri'];
275
-
276
-        }
277
-
278
-        return $principals;
279
-
280
-    }
281
-
282
-    /**
283
-     * Finds a principal by its URI.
284
-     *
285
-     * This method may receive any type of uri, but mailto: addresses will be
286
-     * the most common.
287
-     *
288
-     * Implementation of this API is optional. It is currently used by the
289
-     * CalDAV system to find principals based on their email addresses. If this
290
-     * API is not implemented, some features may not work correctly.
291
-     *
292
-     * This method must return a relative principal path, or null, if the
293
-     * principal was not found or you refuse to find it.
294
-     *
295
-     * @param string $uri
296
-     * @param string $principalPrefix
297
-     * @return string
298
-     */
299
-    public function findByUri($uri, $principalPrefix) {
300
-        $value = null;
301
-        $scheme = null;
302
-        list($scheme, $value) = explode(":", $uri, 2);
303
-        if ($value === null) return null;
304
-
305
-        $uri = null;
306
-        switch ($scheme){
307
-            case "mailto":
308
-                $query = sprintf('SELECT uri FROM %s WHERE lower(email)=lower(?)', $this->tableName);
309
-                $stmt = $this->pdo->prepare($query);
310
-                $stmt->execute([ $value ]);
22
+	/**
23
+	 * PDO table name for 'principals'
24
+	 *
25
+	 * @var string
26
+	 */
27
+	public $tableName = 'principals';
28
+
29
+	/**
30
+	 * PDO table name for 'group members'
31
+	 *
32
+	 * @var string
33
+	 */
34
+	public $groupMembersTableName = 'groupmembers';
35
+
36
+	/**
37
+	 * pdo
38
+	 *
39
+	 * @var PDO
40
+	 */
41
+	protected $pdo;
42
+
43
+	/**
44
+	 * A list of additional fields to support
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $fieldMap = [
49
+
50
+		/**
51
+		 * This property can be used to display the users' real name.
52
+		 */
53
+		'{DAV:}displayname' => [
54
+			'dbField' => 'displayname',
55
+		],
56
+
57
+		/**
58
+		 * This is the users' primary email-address.
59
+		 */
60
+		'{http://sabredav.org/ns}email-address' => [
61
+			'dbField' => 'email',
62
+		],
63
+	];
64
+
65
+	/**
66
+	 * Sets up the backend.
67
+	 *
68
+	 * @param PDO $pdo
69
+	 */
70
+	public function __construct(\PDO $pdo) {
71
+
72
+		$this->pdo = $pdo;
73
+
74
+	}
75
+
76
+	/**
77
+	 * Returns a list of principals based on a prefix.
78
+	 *
79
+	 * This prefix will often contain something like 'principals'. You are only
80
+	 * expected to return principals that are in this base path.
81
+	 *
82
+	 * You are expected to return at least a 'uri' for every user, you can
83
+	 * return any additional properties if you wish so. Common properties are:
84
+	 *   {DAV:}displayname
85
+	 *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV
86
+	 *     field that's actualy injected in a number of other properties. If
87
+	 *     you have an email address, use this property.
88
+	 *
89
+	 * @param string $prefixPath
90
+	 * @return array
91
+	 */
92
+	public function getPrincipalsByPrefix($prefixPath) {
93
+
94
+		$fields = [
95
+			'uri',
96
+		];
97
+
98
+		foreach ($this->fieldMap as $key => $value) {
99
+			$fields[] = $value['dbField'];
100
+		}
101
+		$result = $this->pdo->query(sprintf('SELECT %s FROM %s', implode(',', $fields), $this->tableName));
102
+
103
+		$principals = [];
104
+
105
+		while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
106
+
107
+			// Checking if the principal is in the prefix
108
+			list($rowPrefix) = URLUtil::splitPath($row['uri']);
109
+			if ($rowPrefix !== $prefixPath) continue;
110
+
111
+			$principal = [
112
+				'uri' => $row['uri'],
113
+			];
114
+			foreach ($this->fieldMap as $key => $value) {
115
+				if ($row[$value['dbField']]) {
116
+					$principal[$key] = $row[$value['dbField']];
117
+				}
118
+			}
119
+			$principals[] = $principal;
120
+
121
+		}
122
+
123
+		return $principals;
124
+
125
+	}
126
+
127
+	/**
128
+	 * Returns a specific principal, specified by it's path.
129
+	 * The returned structure should be the exact same as from
130
+	 * getPrincipalsByPrefix.
131
+	 *
132
+	 * @param string $path
133
+	 * @return array
134
+	 */
135
+	public function getPrincipalByPath($path) {
136
+
137
+		$fields = [
138
+			'id',
139
+			'uri',
140
+		];
141
+
142
+		foreach ($this->fieldMap as $key => $value) {
143
+			$fields[] = $value['dbField'];
144
+		}
145
+		$stmt = $this->pdo->prepare(sprintf('SELECT %s FROM %s WHERE uri = ?', implode(',', $fields), $this->tableName));
146
+		$stmt->execute([$path]);
147
+
148
+		$row = $stmt->fetch(\PDO::FETCH_ASSOC);
149
+		if (!$row) return;
150
+
151
+		$principal = [
152
+			'id'  => $row['id'],
153
+			'uri' => $row['uri'],
154
+		];
155
+		foreach ($this->fieldMap as $key => $value) {
156
+			if ($row[$value['dbField']]) {
157
+				$principal[$key] = $row[$value['dbField']];
158
+			}
159
+		}
160
+		return $principal;
161
+
162
+	}
163
+
164
+	/**
165
+	 * Updates one ore more webdav properties on a principal.
166
+	 *
167
+	 * The list of mutations is stored in a Sabre\DAV\PropPatch object.
168
+	 * To do the actual updates, you must tell this object which properties
169
+	 * you're going to process with the handle() method.
170
+	 *
171
+	 * Calling the handle method is like telling the PropPatch object "I
172
+	 * promise I can handle updating this property".
173
+	 *
174
+	 * Read the PropPatch documenation for more info and examples.
175
+	 *
176
+	 * @param string $path
177
+	 * @param DAV\PropPatch $propPatch
178
+	 */
179
+	public function updatePrincipal($path, DAV\PropPatch $propPatch) {
180
+
181
+		$propPatch->handle(array_keys($this->fieldMap), function($properties) use ($path) {
182
+
183
+			$query = sprintf('UPDATE %s SET ', $this->tableName);
184
+			$first = true;
185
+
186
+			$values = [];
187
+
188
+			foreach ($properties as $key => $value) {
189
+
190
+				$dbField = $this->fieldMap[$key]['dbField'];
191
+
192
+				if (!$first) {
193
+					$query .= ', ';
194
+				}
195
+				$first = false;
196
+				$query .= $dbField . ' = :' . $dbField;
197
+				$values[$dbField] = $value;
198
+
199
+			}
200
+
201
+			$query .= " WHERE uri = :uri";
202
+			$values['uri'] = $path;
203
+
204
+			$stmt = $this->pdo->prepare($query);
205
+			$stmt->execute($values);
206
+
207
+			return true;
208
+
209
+		});
210
+
211
+	}
212
+
213
+	/**
214
+	 * This method is used to search for principals matching a set of
215
+	 * properties.
216
+	 *
217
+	 * This search is specifically used by RFC3744's principal-property-search
218
+	 * REPORT.
219
+	 *
220
+	 * The actual search should be a unicode-non-case-sensitive search. The
221
+	 * keys in searchProperties are the WebDAV property names, while the values
222
+	 * are the property values to search on.
223
+	 *
224
+	 * By default, if multiple properties are submitted to this method, the
225
+	 * various properties should be combined with 'AND'. If $test is set to
226
+	 * 'anyof', it should be combined using 'OR'.
227
+	 *
228
+	 * This method should simply return an array with full principal uri's.
229
+	 *
230
+	 * If somebody attempted to search on a property the backend does not
231
+	 * support, you should simply return 0 results.
232
+	 *
233
+	 * You can also just return 0 results if you choose to not support
234
+	 * searching at all, but keep in mind that this may stop certain features
235
+	 * from working.
236
+	 *
237
+	 * @param string $prefixPath
238
+	 * @param array $searchProperties
239
+	 * @param string $test
240
+	 * @return array
241
+	 */
242
+	public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
243
+		if (count($searchProperties) == 0) return [];    //No criteria
244
+
245
+		$query = sprintf('SELECT uri FROM %s WHERE ', $this->tableName);
246
+		$values = [];
247
+		foreach ($searchProperties as $property => $value) {
248
+			switch ($property) {
249
+				case '{DAV:}displayname' :
250
+					$column = "displayname";
251
+					break;
252
+				case '{http://sabredav.org/ns}email-address' :
253
+					$column = "email";
254
+					break;
255
+				default :
256
+					// Unsupported property
257
+					return [];
258
+			}
259
+			if (count($values) > 0) $query .= (strcmp($test, "anyof") == 0 ? " || " : " && ");
260
+			$query .= 'lower(' . $column . ') LIKE lower(?)';
261
+			$values[] = '%' . $value . '%';
262
+
263
+		}
264
+		$stmt = $this->pdo->prepare($query);
265
+		$stmt->execute($values);
266
+
267
+		$principals = [];
268
+		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
269
+
270
+			// Checking if the principal is in the prefix
271
+			list($rowPrefix) = URLUtil::splitPath($row['uri']);
272
+			if ($rowPrefix !== $prefixPath) continue;
273
+
274
+			$principals[] = $row['uri'];
275
+
276
+		}
277
+
278
+		return $principals;
279
+
280
+	}
281
+
282
+	/**
283
+	 * Finds a principal by its URI.
284
+	 *
285
+	 * This method may receive any type of uri, but mailto: addresses will be
286
+	 * the most common.
287
+	 *
288
+	 * Implementation of this API is optional. It is currently used by the
289
+	 * CalDAV system to find principals based on their email addresses. If this
290
+	 * API is not implemented, some features may not work correctly.
291
+	 *
292
+	 * This method must return a relative principal path, or null, if the
293
+	 * principal was not found or you refuse to find it.
294
+	 *
295
+	 * @param string $uri
296
+	 * @param string $principalPrefix
297
+	 * @return string
298
+	 */
299
+	public function findByUri($uri, $principalPrefix) {
300
+		$value = null;
301
+		$scheme = null;
302
+		list($scheme, $value) = explode(":", $uri, 2);
303
+		if ($value === null) return null;
304
+
305
+		$uri = null;
306
+		switch ($scheme){
307
+			case "mailto":
308
+				$query = sprintf('SELECT uri FROM %s WHERE lower(email)=lower(?)', $this->tableName);
309
+				$stmt = $this->pdo->prepare($query);
310
+				$stmt->execute([ $value ]);
311 311
             
312
-                while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
313
-                    // Checking if the principal is in the prefix
314
-                    list($rowPrefix) = URLUtil::splitPath($row['uri']);
315
-                    if ($rowPrefix !== $principalPrefix) continue;
312
+				while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
313
+					// Checking if the principal is in the prefix
314
+					list($rowPrefix) = URLUtil::splitPath($row['uri']);
315
+					if ($rowPrefix !== $principalPrefix) continue;
316 316
                     
317
-                    $uri = $row['uri'];
318
-                    break; //Stop on first match
319
-                }
320
-                break;
321
-            default:
322
-                //unsupported uri scheme
323
-                return null;
324
-        }
325
-        return $uri;
326
-    }
327
-
328
-    /**
329
-     * Returns the list of members for a group-principal
330
-     *
331
-     * @param string $principal
332
-     * @return array
333
-     */
334
-    public function getGroupMemberSet($principal) {
335
-
336
-        $principal = $this->getPrincipalByPath($principal);
337
-        if (!$principal) throw new DAV\Exception('Principal not found');
317
+					$uri = $row['uri'];
318
+					break; //Stop on first match
319
+				}
320
+				break;
321
+			default:
322
+				//unsupported uri scheme
323
+				return null;
324
+		}
325
+		return $uri;
326
+	}
327
+
328
+	/**
329
+	 * Returns the list of members for a group-principal
330
+	 *
331
+	 * @param string $principal
332
+	 * @return array
333
+	 */
334
+	public function getGroupMemberSet($principal) {
335
+
336
+		$principal = $this->getPrincipalByPath($principal);
337
+		if (!$principal) throw new DAV\Exception('Principal not found');
338 338
 
339 339
 		$query = 'SELECT principals.uri as uri FROM %s AS groupmembers LEFT JOIN %s AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?';
340
-        $query = sprintf($query, $this->groupMembersTableName, $this->tableName);
340
+		$query = sprintf($query, $this->groupMembersTableName, $this->tableName);
341 341
 		$stmt = $this->pdo->prepare($query);
342
-        $stmt->execute([$principal['id']]);
343
-
344
-        $result = [];
345
-        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
346
-            $result[] = $row['uri'];
347
-        }
348
-        return $result;
349
-
350
-    }
351
-
352
-    /**
353
-     * Returns the list of groups a principal is a member of
354
-     *
355
-     * @param string $principal
356
-     * @return array
357
-     */
358
-    public function getGroupMembership($principal) {
359
-
360
-        $principal = $this->getPrincipalByPath($principal);
361
-        if (!$principal) throw new DAV\Exception('Principal not found');
362
-
363
-        $stmt = $this->pdo->prepare(sprintf('SELECT principals.uri as uri FROM %s AS groupmembers LEFT JOIN %s AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?', $this->groupMembersTableName, $this->tableName));
364
-        $stmt->execute([$principal['id']]);
365
-
366
-        $result = [];
367
-        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
368
-            $result[] = $row['uri'];
369
-        }
370
-        return $result;
371
-
372
-    }
373
-
374
-    /**
375
-     * Updates the list of group members for a group principal.
376
-     *
377
-     * The principals should be passed as a list of uri's.
378
-     *
379
-     * @param string $principal
380
-     * @param array $members
381
-     * @return void
382
-     */
383
-    public function setGroupMemberSet($principal, array $members) {
384
-
385
-        // Grabbing the list of principal id's.
386
-        $stmt = $this->pdo->prepare(sprintf('SELECT id, uri FROM %s WHERE uri IN (? %s);',$this->tableName, str_repeat(', ? ', count($members))));
387
-        $stmt->execute(array_merge([$principal], $members));
388
-
389
-        $memberIds = [];
390
-        $principalId = null;
391
-
392
-        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
393
-            if ($row['uri'] == $principal) {
394
-                $principalId = $row['id'];
395
-            } else {
396
-                $memberIds[] = $row['id'];
397
-            }
398
-        }
399
-        if (!$principalId) throw new DAV\Exception('Principal not found');
400
-
401
-        // Wiping out old members
402
-        $stmt = $this->pdo->prepare(sprintf('DELETE FROM %s WHERE principal_id = ?;', $this->groupMembersTableName));
403
-        $stmt->execute([$principalId]);
404
-
405
-        foreach ($memberIds as $memberId) {
406
-
407
-            $stmt = $this->pdo->prepare('INSERT INTO ' . $this->groupMembersTableName . ' (principal_id, member_id) VALUES (?, ?);');
408
-            $stmt->execute([$principalId, $memberId]);
409
-
410
-        }
411
-
412
-    }
413
-
414
-    /**
415
-     * Creates a new principal.
416
-     *
417
-     * This method receives a full path for the new principal. The mkCol object
418
-     * contains any additional webdav properties specified during the creation
419
-     * of the principal.
420
-     *
421
-     * @param string $path
422
-     * @param MkCol $mkCol
423
-     * @return void
424
-     */
425
-    public function createPrincipal($path, MkCol $mkCol) {
426
-
427
-        $stmt = $this->pdo->prepare('INSERT INTO ' . $this->tableName . ' (uri) VALUES (?)');
428
-        $stmt->execute([$path]);
429
-        $this->updatePrincipal($path, $mkCol);
430
-
431
-    }
342
+		$stmt->execute([$principal['id']]);
343
+
344
+		$result = [];
345
+		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
346
+			$result[] = $row['uri'];
347
+		}
348
+		return $result;
349
+
350
+	}
351
+
352
+	/**
353
+	 * Returns the list of groups a principal is a member of
354
+	 *
355
+	 * @param string $principal
356
+	 * @return array
357
+	 */
358
+	public function getGroupMembership($principal) {
359
+
360
+		$principal = $this->getPrincipalByPath($principal);
361
+		if (!$principal) throw new DAV\Exception('Principal not found');
362
+
363
+		$stmt = $this->pdo->prepare(sprintf('SELECT principals.uri as uri FROM %s AS groupmembers LEFT JOIN %s AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?', $this->groupMembersTableName, $this->tableName));
364
+		$stmt->execute([$principal['id']]);
365
+
366
+		$result = [];
367
+		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
368
+			$result[] = $row['uri'];
369
+		}
370
+		return $result;
371
+
372
+	}
373
+
374
+	/**
375
+	 * Updates the list of group members for a group principal.
376
+	 *
377
+	 * The principals should be passed as a list of uri's.
378
+	 *
379
+	 * @param string $principal
380
+	 * @param array $members
381
+	 * @return void
382
+	 */
383
+	public function setGroupMemberSet($principal, array $members) {
384
+
385
+		// Grabbing the list of principal id's.
386
+		$stmt = $this->pdo->prepare(sprintf('SELECT id, uri FROM %s WHERE uri IN (? %s);',$this->tableName, str_repeat(', ? ', count($members))));
387
+		$stmt->execute(array_merge([$principal], $members));
388
+
389
+		$memberIds = [];
390
+		$principalId = null;
391
+
392
+		while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
393
+			if ($row['uri'] == $principal) {
394
+				$principalId = $row['id'];
395
+			} else {
396
+				$memberIds[] = $row['id'];
397
+			}
398
+		}
399
+		if (!$principalId) throw new DAV\Exception('Principal not found');
400
+
401
+		// Wiping out old members
402
+		$stmt = $this->pdo->prepare(sprintf('DELETE FROM %s WHERE principal_id = ?;', $this->groupMembersTableName));
403
+		$stmt->execute([$principalId]);
404
+
405
+		foreach ($memberIds as $memberId) {
406
+
407
+			$stmt = $this->pdo->prepare('INSERT INTO ' . $this->groupMembersTableName . ' (principal_id, member_id) VALUES (?, ?);');
408
+			$stmt->execute([$principalId, $memberId]);
409
+
410
+		}
411
+
412
+	}
413
+
414
+	/**
415
+	 * Creates a new principal.
416
+	 *
417
+	 * This method receives a full path for the new principal. The mkCol object
418
+	 * contains any additional webdav properties specified during the creation
419
+	 * of the principal.
420
+	 *
421
+	 * @param string $path
422
+	 * @param MkCol $mkCol
423
+	 * @return void
424
+	 */
425
+	public function createPrincipal($path, MkCol $mkCol) {
426
+
427
+		$stmt = $this->pdo->prepare('INSERT INTO ' . $this->tableName . ' (uri) VALUES (?)');
428
+		$stmt->execute([$path]);
429
+		$this->updatePrincipal($path, $mkCol);
430
+
431
+	}
432 432
 
433 433
 }
Please login to merge, or discard this patch.
Braces   +31 added lines, -10 removed lines patch added patch discarded remove patch
@@ -106,7 +106,9 @@  discard block
 block discarded – undo
106 106
 
107 107
             // Checking if the principal is in the prefix
108 108
             list($rowPrefix) = URLUtil::splitPath($row['uri']);
109
-            if ($rowPrefix !== $prefixPath) continue;
109
+            if ($rowPrefix !== $prefixPath) {
110
+            	continue;
111
+            }
110 112
 
111 113
             $principal = [
112 114
                 'uri' => $row['uri'],
@@ -146,7 +148,9 @@  discard block
 block discarded – undo
146 148
         $stmt->execute([$path]);
147 149
 
148 150
         $row = $stmt->fetch(\PDO::FETCH_ASSOC);
149
-        if (!$row) return;
151
+        if (!$row) {
152
+        	return;
153
+        }
150 154
 
151 155
         $principal = [
152 156
             'id'  => $row['id'],
@@ -240,7 +244,10 @@  discard block
 block discarded – undo
240 244
      * @return array
241 245
      */
242 246
     public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
243
-        if (count($searchProperties) == 0) return [];    //No criteria
247
+        if (count($searchProperties) == 0) {
248
+        	return [];
249
+        }
250
+        //No criteria
244 251
 
245 252
         $query = sprintf('SELECT uri FROM %s WHERE ', $this->tableName);
246 253
         $values = [];
@@ -256,7 +263,9 @@  discard block
 block discarded – undo
256 263
                     // Unsupported property
257 264
                     return [];
258 265
             }
259
-            if (count($values) > 0) $query .= (strcmp($test, "anyof") == 0 ? " || " : " && ");
266
+            if (count($values) > 0) {
267
+            	$query .= (strcmp($test, "anyof") == 0 ? " || " : " && ");
268
+            }
260 269
             $query .= 'lower(' . $column . ') LIKE lower(?)';
261 270
             $values[] = '%' . $value . '%';
262 271
 
@@ -269,7 +278,9 @@  discard block
 block discarded – undo
269 278
 
270 279
             // Checking if the principal is in the prefix
271 280
             list($rowPrefix) = URLUtil::splitPath($row['uri']);
272
-            if ($rowPrefix !== $prefixPath) continue;
281
+            if ($rowPrefix !== $prefixPath) {
282
+            	continue;
283
+            }
273 284
 
274 285
             $principals[] = $row['uri'];
275 286
 
@@ -300,7 +311,9 @@  discard block
 block discarded – undo
300 311
         $value = null;
301 312
         $scheme = null;
302 313
         list($scheme, $value) = explode(":", $uri, 2);
303
-        if ($value === null) return null;
314
+        if ($value === null) {
315
+        	return null;
316
+        }
304 317
 
305 318
         $uri = null;
306 319
         switch ($scheme){
@@ -312,7 +325,9 @@  discard block
 block discarded – undo
312 325
                 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
313 326
                     // Checking if the principal is in the prefix
314 327
                     list($rowPrefix) = URLUtil::splitPath($row['uri']);
315
-                    if ($rowPrefix !== $principalPrefix) continue;
328
+                    if ($rowPrefix !== $principalPrefix) {
329
+                    	continue;
330
+                    }
316 331
                     
317 332
                     $uri = $row['uri'];
318 333
                     break; //Stop on first match
@@ -334,7 +349,9 @@  discard block
 block discarded – undo
334 349
     public function getGroupMemberSet($principal) {
335 350
 
336 351
         $principal = $this->getPrincipalByPath($principal);
337
-        if (!$principal) throw new DAV\Exception('Principal not found');
352
+        if (!$principal) {
353
+        	throw new DAV\Exception('Principal not found');
354
+        }
338 355
 
339 356
 		$query = 'SELECT principals.uri as uri FROM %s AS groupmembers LEFT JOIN %s AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?';
340 357
         $query = sprintf($query, $this->groupMembersTableName, $this->tableName);
@@ -358,7 +375,9 @@  discard block
 block discarded – undo
358 375
     public function getGroupMembership($principal) {
359 376
 
360 377
         $principal = $this->getPrincipalByPath($principal);
361
-        if (!$principal) throw new DAV\Exception('Principal not found');
378
+        if (!$principal) {
379
+        	throw new DAV\Exception('Principal not found');
380
+        }
362 381
 
363 382
         $stmt = $this->pdo->prepare(sprintf('SELECT principals.uri as uri FROM %s AS groupmembers LEFT JOIN %s AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?', $this->groupMembersTableName, $this->tableName));
364 383
         $stmt->execute([$principal['id']]);
@@ -396,7 +415,9 @@  discard block
 block discarded – undo
396 415
                 $memberIds[] = $row['id'];
397 416
             }
398 417
         }
399
-        if (!$principalId) throw new DAV\Exception('Principal not found');
418
+        if (!$principalId) {
419
+        	throw new DAV\Exception('Principal not found');
420
+        }
400 421
 
401 422
         // Wiping out old members
402 423
         $stmt = $this->pdo->prepare(sprintf('DELETE FROM %s WHERE principal_id = ?;', $this->groupMembersTableName));
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/Xml/Property/Acl.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -165,7 +165,7 @@
 block discarded – undo
165 165
      * the next element.
166 166
      *
167 167
      * @param Reader $reader
168
-     * @return mixed
168
+     * @return Acl
169 169
      */
170 170
     static function xmlDeserialize(Reader $reader) {
171 171
 
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -177,7 +177,7 @@
 block discarded – undo
177 177
 
178 178
         $privileges = [];
179 179
 
180
-        foreach ((array)$reader->parseInnerTree($elementMap) as $element) {
180
+        foreach ((array) $reader->parseInnerTree($elementMap) as $element) {
181 181
 
182 182
             if ($element['name'] !== '{DAV:}ace') {
183 183
                 continue;
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -136,7 +136,9 @@
 block discarded – undo
136 136
             }
137 137
             echo '<td>', $html->xmlName($privilege['privilege']), '</td>';
138 138
             echo '<td>';
139
-            if (!empty($privilege['protected'])) echo '(protected)';
139
+            if (!empty($privilege['protected'])) {
140
+            	echo '(protected)';
141
+            }
140 142
             echo '</td>';
141 143
             echo '</tr>';
142 144
 
Please login to merge, or discard this patch.
Indentation   +246 added lines, -246 removed lines patch added patch discarded remove patch
@@ -27,251 +27,251 @@
 block discarded – undo
27 27
  */
28 28
 class Acl implements Element, HtmlOutput {
29 29
 
30
-    /**
31
-     * List of privileges
32
-     *
33
-     * @var array
34
-     */
35
-    protected $privileges;
36
-
37
-    /**
38
-     * Whether or not the server base url is required to be prefixed when
39
-     * serializing the property.
40
-     *
41
-     * @var bool
42
-     */
43
-    protected $prefixBaseUrl;
44
-
45
-    /**
46
-     * Constructor
47
-     *
48
-     * This object requires a structure similar to the return value from
49
-     * Sabre\DAVACL\Plugin::getACL().
50
-     *
51
-     * Each privilege is a an array with at least a 'privilege' property, and a
52
-     * 'principal' property. A privilege may have a 'protected' property as
53
-     * well.
54
-     *
55
-     * The prefixBaseUrl should be set to false, if the supplied principal urls
56
-     * are already full urls. If this is kept to true, the servers base url
57
-     * will automatically be prefixed.
58
-     *
59
-     * @param array $privileges
60
-     * @param bool $prefixBaseUrl
61
-     */
62
-    public function __construct(array $privileges, $prefixBaseUrl = true) {
63
-
64
-        $this->privileges = $privileges;
65
-        $this->prefixBaseUrl = $prefixBaseUrl;
66
-
67
-    }
68
-
69
-    /**
70
-     * Returns the list of privileges for this property
71
-     *
72
-     * @return array
73
-     */
74
-    public function getPrivileges() {
75
-
76
-        return $this->privileges;
77
-
78
-    }
79
-
80
-    /**
81
-     * The xmlSerialize metod is called during xml writing.
82
-     *
83
-     * Use the $writer argument to write its own xml serialization.
84
-     *
85
-     * An important note: do _not_ create a parent element. Any element
86
-     * implementing XmlSerializble should only ever write what's considered
87
-     * its 'inner xml'.
88
-     *
89
-     * The parent of the current element is responsible for writing a
90
-     * containing element.
91
-     *
92
-     * This allows serializers to be re-used for different element names.
93
-     *
94
-     * If you are opening new elements, you must also close them again.
95
-     *
96
-     * @param Writer $writer
97
-     * @return void
98
-     */
99
-    public function xmlSerialize(Writer $writer) {
100
-
101
-        foreach ($this->privileges as $ace) {
102
-
103
-            $this->serializeAce($writer, $ace);
104
-
105
-        }
106
-
107
-    }
108
-
109
-    /**
110
-     * Generate html representation for this value.
111
-     *
112
-     * The html output is 100% trusted, and no effort is being made to sanitize
113
-     * it. It's up to the implementor to sanitize user provided values.
114
-     *
115
-     * The output must be in UTF-8.
116
-     *
117
-     * The baseUri parameter is a url to the root of the application, and can
118
-     * be used to construct local links.
119
-     *
120
-     * @param HtmlOutputHelper $html
121
-     * @return string
122
-     */
123
-    public function toHtml(HtmlOutputHelper $html) {
124
-
125
-        ob_start();
126
-        echo "<table>";
127
-        echo "<tr><th>Principal</th><th>Privilege</th><th></th></tr>";
128
-        foreach ($this->privileges as $privilege) {
129
-
130
-            echo '<tr>';
131
-            // if it starts with a {, it's a special principal
132
-            if ($privilege['principal'][0] === '{') {
133
-                echo '<td>', $html->xmlName($privilege['principal']), '</td>';
134
-            } else {
135
-                echo '<td>', $html->link($privilege['principal']), '</td>';
136
-            }
137
-            echo '<td>', $html->xmlName($privilege['privilege']), '</td>';
138
-            echo '<td>';
139
-            if (!empty($privilege['protected'])) echo '(protected)';
140
-            echo '</td>';
141
-            echo '</tr>';
142
-
143
-        }
144
-        echo "</table>";
145
-        return ob_get_clean();
146
-
147
-    }
148
-
149
-    /**
150
-     * The deserialize method is called during xml parsing.
151
-     *
152
-     * This method is called statictly, this is because in theory this method
153
-     * may be used as a type of constructor, or factory method.
154
-     *
155
-     * Often you want to return an instance of the current class, but you are
156
-     * free to return other data as well.
157
-     *
158
-     * Important note 2: You are responsible for advancing the reader to the
159
-     * next element. Not doing anything will result in a never-ending loop.
160
-     *
161
-     * If you just want to skip parsing for this element altogether, you can
162
-     * just call $reader->next();
163
-     *
164
-     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
165
-     * the next element.
166
-     *
167
-     * @param Reader $reader
168
-     * @return mixed
169
-     */
170
-    static function xmlDeserialize(Reader $reader) {
171
-
172
-        $elementMap = [
173
-            '{DAV:}ace'       => 'Sabre\Xml\Element\KeyValue',
174
-            '{DAV:}privilege' => 'Sabre\Xml\Element\Elements',
175
-            '{DAV:}principal' => 'Sabre\DAVACL\Xml\Property\Principal',
176
-        ];
177
-
178
-        $privileges = [];
179
-
180
-        foreach ((array)$reader->parseInnerTree($elementMap) as $element) {
181
-
182
-            if ($element['name'] !== '{DAV:}ace') {
183
-                continue;
184
-            }
185
-            $ace = $element['value'];
186
-
187
-            if (empty($ace['{DAV:}principal'])) {
188
-                throw new DAV\Exception\BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
189
-            }
190
-            $principal = $ace['{DAV:}principal'];
191
-
192
-            switch ($principal->getType()) {
193
-                case Principal::HREF :
194
-                    $principal = $principal->getHref();
195
-                    break;
196
-                case Principal::AUTHENTICATED :
197
-                    $principal = '{DAV:}authenticated';
198
-                    break;
199
-                case Principal::UNAUTHENTICATED :
200
-                    $principal = '{DAV:}unauthenticated';
201
-                    break;
202
-                case Principal::ALL :
203
-                    $principal = '{DAV:}all';
204
-                    break;
205
-
206
-            }
207
-
208
-            $protected = array_key_exists('{DAV:}protected', $ace);
209
-
210
-            if (!isset($ace['{DAV:}grant'])) {
211
-                throw new DAV\Exception\NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
212
-            }
213
-            foreach ($ace['{DAV:}grant'] as $elem) {
214
-                if ($elem['name'] !== '{DAV:}privilege') {
215
-                    continue;
216
-                }
217
-
218
-                foreach ($elem['value'] as $priv) {
219
-                    $privileges[] = [
220
-                        'principal' => $principal,
221
-                        'protected' => $protected,
222
-                        'privilege' => $priv,
223
-                    ];
224
-                }
225
-
226
-            }
227
-
228
-        }
229
-
230
-        return new self($privileges);
231
-
232
-    }
233
-
234
-    /**
235
-     * Serializes a single access control entry.
236
-     *
237
-     * @param Writer $writer
238
-     * @param array $ace
239
-     * @return void
240
-     */
241
-    private function serializeAce(Writer $writer, array $ace) {
242
-
243
-        $writer->startElement('{DAV:}ace');
244
-
245
-        switch ($ace['principal']) {
246
-            case '{DAV:}authenticated' :
247
-                $principal = new Principal(Principal::AUTHENTICATED);
248
-                break;
249
-            case '{DAV:}unauthenticated' :
250
-                $principal = new Principal(Principal::UNAUTHENTICATED);
251
-                break;
252
-            case '{DAV:}all' :
253
-                $principal = new Principal(Principal::ALL);
254
-                break;
255
-            default:
256
-                $principal = new Principal(Principal::HREF, $ace['principal']);
257
-                break;
258
-        }
259
-
260
-        $writer->writeElement('{DAV:}principal', $principal);
261
-        $writer->startElement('{DAV:}grant');
262
-        $writer->startElement('{DAV:}privilege');
263
-
264
-        $writer->writeElement($ace['privilege']);
265
-
266
-        $writer->endElement(); // privilege
267
-        $writer->endElement(); // grant
268
-
269
-        if (!empty($ace['protected'])) {
270
-            $writer->writeElement('{DAV:}protected');
271
-        }
272
-
273
-        $writer->endElement(); // ace
274
-
275
-    }
30
+	/**
31
+	 * List of privileges
32
+	 *
33
+	 * @var array
34
+	 */
35
+	protected $privileges;
36
+
37
+	/**
38
+	 * Whether or not the server base url is required to be prefixed when
39
+	 * serializing the property.
40
+	 *
41
+	 * @var bool
42
+	 */
43
+	protected $prefixBaseUrl;
44
+
45
+	/**
46
+	 * Constructor
47
+	 *
48
+	 * This object requires a structure similar to the return value from
49
+	 * Sabre\DAVACL\Plugin::getACL().
50
+	 *
51
+	 * Each privilege is a an array with at least a 'privilege' property, and a
52
+	 * 'principal' property. A privilege may have a 'protected' property as
53
+	 * well.
54
+	 *
55
+	 * The prefixBaseUrl should be set to false, if the supplied principal urls
56
+	 * are already full urls. If this is kept to true, the servers base url
57
+	 * will automatically be prefixed.
58
+	 *
59
+	 * @param array $privileges
60
+	 * @param bool $prefixBaseUrl
61
+	 */
62
+	public function __construct(array $privileges, $prefixBaseUrl = true) {
63
+
64
+		$this->privileges = $privileges;
65
+		$this->prefixBaseUrl = $prefixBaseUrl;
66
+
67
+	}
68
+
69
+	/**
70
+	 * Returns the list of privileges for this property
71
+	 *
72
+	 * @return array
73
+	 */
74
+	public function getPrivileges() {
75
+
76
+		return $this->privileges;
77
+
78
+	}
79
+
80
+	/**
81
+	 * The xmlSerialize metod is called during xml writing.
82
+	 *
83
+	 * Use the $writer argument to write its own xml serialization.
84
+	 *
85
+	 * An important note: do _not_ create a parent element. Any element
86
+	 * implementing XmlSerializble should only ever write what's considered
87
+	 * its 'inner xml'.
88
+	 *
89
+	 * The parent of the current element is responsible for writing a
90
+	 * containing element.
91
+	 *
92
+	 * This allows serializers to be re-used for different element names.
93
+	 *
94
+	 * If you are opening new elements, you must also close them again.
95
+	 *
96
+	 * @param Writer $writer
97
+	 * @return void
98
+	 */
99
+	public function xmlSerialize(Writer $writer) {
100
+
101
+		foreach ($this->privileges as $ace) {
102
+
103
+			$this->serializeAce($writer, $ace);
104
+
105
+		}
106
+
107
+	}
108
+
109
+	/**
110
+	 * Generate html representation for this value.
111
+	 *
112
+	 * The html output is 100% trusted, and no effort is being made to sanitize
113
+	 * it. It's up to the implementor to sanitize user provided values.
114
+	 *
115
+	 * The output must be in UTF-8.
116
+	 *
117
+	 * The baseUri parameter is a url to the root of the application, and can
118
+	 * be used to construct local links.
119
+	 *
120
+	 * @param HtmlOutputHelper $html
121
+	 * @return string
122
+	 */
123
+	public function toHtml(HtmlOutputHelper $html) {
124
+
125
+		ob_start();
126
+		echo "<table>";
127
+		echo "<tr><th>Principal</th><th>Privilege</th><th></th></tr>";
128
+		foreach ($this->privileges as $privilege) {
129
+
130
+			echo '<tr>';
131
+			// if it starts with a {, it's a special principal
132
+			if ($privilege['principal'][0] === '{') {
133
+				echo '<td>', $html->xmlName($privilege['principal']), '</td>';
134
+			} else {
135
+				echo '<td>', $html->link($privilege['principal']), '</td>';
136
+			}
137
+			echo '<td>', $html->xmlName($privilege['privilege']), '</td>';
138
+			echo '<td>';
139
+			if (!empty($privilege['protected'])) echo '(protected)';
140
+			echo '</td>';
141
+			echo '</tr>';
142
+
143
+		}
144
+		echo "</table>";
145
+		return ob_get_clean();
146
+
147
+	}
148
+
149
+	/**
150
+	 * The deserialize method is called during xml parsing.
151
+	 *
152
+	 * This method is called statictly, this is because in theory this method
153
+	 * may be used as a type of constructor, or factory method.
154
+	 *
155
+	 * Often you want to return an instance of the current class, but you are
156
+	 * free to return other data as well.
157
+	 *
158
+	 * Important note 2: You are responsible for advancing the reader to the
159
+	 * next element. Not doing anything will result in a never-ending loop.
160
+	 *
161
+	 * If you just want to skip parsing for this element altogether, you can
162
+	 * just call $reader->next();
163
+	 *
164
+	 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
165
+	 * the next element.
166
+	 *
167
+	 * @param Reader $reader
168
+	 * @return mixed
169
+	 */
170
+	static function xmlDeserialize(Reader $reader) {
171
+
172
+		$elementMap = [
173
+			'{DAV:}ace'       => 'Sabre\Xml\Element\KeyValue',
174
+			'{DAV:}privilege' => 'Sabre\Xml\Element\Elements',
175
+			'{DAV:}principal' => 'Sabre\DAVACL\Xml\Property\Principal',
176
+		];
177
+
178
+		$privileges = [];
179
+
180
+		foreach ((array)$reader->parseInnerTree($elementMap) as $element) {
181
+
182
+			if ($element['name'] !== '{DAV:}ace') {
183
+				continue;
184
+			}
185
+			$ace = $element['value'];
186
+
187
+			if (empty($ace['{DAV:}principal'])) {
188
+				throw new DAV\Exception\BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
189
+			}
190
+			$principal = $ace['{DAV:}principal'];
191
+
192
+			switch ($principal->getType()) {
193
+				case Principal::HREF :
194
+					$principal = $principal->getHref();
195
+					break;
196
+				case Principal::AUTHENTICATED :
197
+					$principal = '{DAV:}authenticated';
198
+					break;
199
+				case Principal::UNAUTHENTICATED :
200
+					$principal = '{DAV:}unauthenticated';
201
+					break;
202
+				case Principal::ALL :
203
+					$principal = '{DAV:}all';
204
+					break;
205
+
206
+			}
207
+
208
+			$protected = array_key_exists('{DAV:}protected', $ace);
209
+
210
+			if (!isset($ace['{DAV:}grant'])) {
211
+				throw new DAV\Exception\NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
212
+			}
213
+			foreach ($ace['{DAV:}grant'] as $elem) {
214
+				if ($elem['name'] !== '{DAV:}privilege') {
215
+					continue;
216
+				}
217
+
218
+				foreach ($elem['value'] as $priv) {
219
+					$privileges[] = [
220
+						'principal' => $principal,
221
+						'protected' => $protected,
222
+						'privilege' => $priv,
223
+					];
224
+				}
225
+
226
+			}
227
+
228
+		}
229
+
230
+		return new self($privileges);
231
+
232
+	}
233
+
234
+	/**
235
+	 * Serializes a single access control entry.
236
+	 *
237
+	 * @param Writer $writer
238
+	 * @param array $ace
239
+	 * @return void
240
+	 */
241
+	private function serializeAce(Writer $writer, array $ace) {
242
+
243
+		$writer->startElement('{DAV:}ace');
244
+
245
+		switch ($ace['principal']) {
246
+			case '{DAV:}authenticated' :
247
+				$principal = new Principal(Principal::AUTHENTICATED);
248
+				break;
249
+			case '{DAV:}unauthenticated' :
250
+				$principal = new Principal(Principal::UNAUTHENTICATED);
251
+				break;
252
+			case '{DAV:}all' :
253
+				$principal = new Principal(Principal::ALL);
254
+				break;
255
+			default:
256
+				$principal = new Principal(Principal::HREF, $ace['principal']);
257
+				break;
258
+		}
259
+
260
+		$writer->writeElement('{DAV:}principal', $principal);
261
+		$writer->startElement('{DAV:}grant');
262
+		$writer->startElement('{DAV:}privilege');
263
+
264
+		$writer->writeElement($ace['privilege']);
265
+
266
+		$writer->endElement(); // privilege
267
+		$writer->endElement(); // grant
268
+
269
+		if (!empty($ace['protected'])) {
270
+			$writer->writeElement('{DAV:}protected');
271
+		}
272
+
273
+		$writer->endElement(); // ace
274
+
275
+	}
276 276
 
277 277
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -115,7 +115,7 @@
 block discarded – undo
115 115
      * the next element.
116 116
      *
117 117
      * @param Reader $reader
118
-     * @return mixed
118
+     * @return CurrentUserPrivilegeSet
119 119
      */
120 120
     static function xmlDeserialize(Reader $reader) {
121 121
 
Please login to merge, or discard this patch.
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -20,140 +20,140 @@
 block discarded – undo
20 20
  */
21 21
 class CurrentUserPrivilegeSet implements Element, HtmlOutput {
22 22
 
23
-    /**
24
-     * List of privileges
25
-     *
26
-     * @var array
27
-     */
28
-    private $privileges;
29
-
30
-    /**
31
-     * Creates the object
32
-     *
33
-     * Pass the privileges in clark-notation
34
-     *
35
-     * @param array $privileges
36
-     */
37
-    public function __construct(array $privileges) {
38
-
39
-        $this->privileges = $privileges;
40
-
41
-    }
42
-
43
-    /**
44
-     * The xmlSerialize metod is called during xml writing.
45
-     *
46
-     * Use the $writer argument to write its own xml serialization.
47
-     *
48
-     * An important note: do _not_ create a parent element. Any element
49
-     * implementing XmlSerializble should only ever write what's considered
50
-     * its 'inner xml'.
51
-     *
52
-     * The parent of the current element is responsible for writing a
53
-     * containing element.
54
-     *
55
-     * This allows serializers to be re-used for different element names.
56
-     *
57
-     * If you are opening new elements, you must also close them again.
58
-     *
59
-     * @param Writer $writer
60
-     * @return void
61
-     */
62
-    public function xmlSerialize(Writer $writer) {
63
-
64
-        foreach ($this->privileges as $privName) {
65
-
66
-            $writer->startElement('{DAV:}privilege');
67
-            $writer->writeElement($privName);
68
-            $writer->endElement();
69
-
70
-        }
71
-
72
-
73
-    }
74
-
75
-    /**
76
-     * Returns true or false, whether the specified principal appears in the
77
-     * list.
78
-     *
79
-     * @param string $privilegeName
80
-     * @return bool
81
-     */
82
-    public function has($privilegeName) {
83
-
84
-        return in_array($privilegeName, $this->privileges);
85
-
86
-    }
87
-
88
-    /**
89
-     * Returns the list of privileges.
90
-     *
91
-     * @return array
92
-     */
93
-    public function getValue() {
94
-
95
-        return $this->privileges;
96
-
97
-    }
98
-
99
-    /**
100
-     * The deserialize method is called during xml parsing.
101
-     *
102
-     * This method is called statictly, this is because in theory this method
103
-     * may be used as a type of constructor, or factory method.
104
-     *
105
-     * Often you want to return an instance of the current class, but you are
106
-     * free to return other data as well.
107
-     *
108
-     * You are responsible for advancing the reader to the next element. Not
109
-     * doing anything will result in a never-ending loop.
110
-     *
111
-     * If you just want to skip parsing for this element altogether, you can
112
-     * just call $reader->next();
113
-     *
114
-     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
115
-     * the next element.
116
-     *
117
-     * @param Reader $reader
118
-     * @return mixed
119
-     */
120
-    static function xmlDeserialize(Reader $reader) {
121
-
122
-        $result = [];
123
-
124
-        $tree = $reader->parseInnerTree(['{DAV:}privilege' => 'Sabre\\Xml\\Element\\Elements']);
125
-        foreach ($tree as $element) {
126
-            if ($element['name'] !== '{DAV:}privilege') {
127
-                continue;
128
-            }
129
-            $result[] = $element['value'][0];
130
-        }
131
-        return new self($result);
132
-
133
-    }
134
-
135
-    /**
136
-     * Generate html representation for this value.
137
-     *
138
-     * The html output is 100% trusted, and no effort is being made to sanitize
139
-     * it. It's up to the implementor to sanitize user provided values.
140
-     *
141
-     * The output must be in UTF-8.
142
-     *
143
-     * The baseUri parameter is a url to the root of the application, and can
144
-     * be used to construct local links.
145
-     *
146
-     * @param HtmlOutputHelper $html
147
-     * @return string
148
-     */
149
-    public function toHtml(HtmlOutputHelper $html) {
150
-
151
-        return implode(
152
-            ', ',
153
-            array_map([$html, 'xmlName'], $this->getValue())
154
-        );
155
-
156
-    }
23
+	/**
24
+	 * List of privileges
25
+	 *
26
+	 * @var array
27
+	 */
28
+	private $privileges;
29
+
30
+	/**
31
+	 * Creates the object
32
+	 *
33
+	 * Pass the privileges in clark-notation
34
+	 *
35
+	 * @param array $privileges
36
+	 */
37
+	public function __construct(array $privileges) {
38
+
39
+		$this->privileges = $privileges;
40
+
41
+	}
42
+
43
+	/**
44
+	 * The xmlSerialize metod is called during xml writing.
45
+	 *
46
+	 * Use the $writer argument to write its own xml serialization.
47
+	 *
48
+	 * An important note: do _not_ create a parent element. Any element
49
+	 * implementing XmlSerializble should only ever write what's considered
50
+	 * its 'inner xml'.
51
+	 *
52
+	 * The parent of the current element is responsible for writing a
53
+	 * containing element.
54
+	 *
55
+	 * This allows serializers to be re-used for different element names.
56
+	 *
57
+	 * If you are opening new elements, you must also close them again.
58
+	 *
59
+	 * @param Writer $writer
60
+	 * @return void
61
+	 */
62
+	public function xmlSerialize(Writer $writer) {
63
+
64
+		foreach ($this->privileges as $privName) {
65
+
66
+			$writer->startElement('{DAV:}privilege');
67
+			$writer->writeElement($privName);
68
+			$writer->endElement();
69
+
70
+		}
71
+
72
+
73
+	}
74
+
75
+	/**
76
+	 * Returns true or false, whether the specified principal appears in the
77
+	 * list.
78
+	 *
79
+	 * @param string $privilegeName
80
+	 * @return bool
81
+	 */
82
+	public function has($privilegeName) {
83
+
84
+		return in_array($privilegeName, $this->privileges);
85
+
86
+	}
87
+
88
+	/**
89
+	 * Returns the list of privileges.
90
+	 *
91
+	 * @return array
92
+	 */
93
+	public function getValue() {
94
+
95
+		return $this->privileges;
96
+
97
+	}
98
+
99
+	/**
100
+	 * The deserialize method is called during xml parsing.
101
+	 *
102
+	 * This method is called statictly, this is because in theory this method
103
+	 * may be used as a type of constructor, or factory method.
104
+	 *
105
+	 * Often you want to return an instance of the current class, but you are
106
+	 * free to return other data as well.
107
+	 *
108
+	 * You are responsible for advancing the reader to the next element. Not
109
+	 * doing anything will result in a never-ending loop.
110
+	 *
111
+	 * If you just want to skip parsing for this element altogether, you can
112
+	 * just call $reader->next();
113
+	 *
114
+	 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
115
+	 * the next element.
116
+	 *
117
+	 * @param Reader $reader
118
+	 * @return mixed
119
+	 */
120
+	static function xmlDeserialize(Reader $reader) {
121
+
122
+		$result = [];
123
+
124
+		$tree = $reader->parseInnerTree(['{DAV:}privilege' => 'Sabre\\Xml\\Element\\Elements']);
125
+		foreach ($tree as $element) {
126
+			if ($element['name'] !== '{DAV:}privilege') {
127
+				continue;
128
+			}
129
+			$result[] = $element['value'][0];
130
+		}
131
+		return new self($result);
132
+
133
+	}
134
+
135
+	/**
136
+	 * Generate html representation for this value.
137
+	 *
138
+	 * The html output is 100% trusted, and no effort is being made to sanitize
139
+	 * it. It's up to the implementor to sanitize user provided values.
140
+	 *
141
+	 * The output must be in UTF-8.
142
+	 *
143
+	 * The baseUri parameter is a url to the root of the application, and can
144
+	 * be used to construct local links.
145
+	 *
146
+	 * @param HtmlOutputHelper $html
147
+	 * @return string
148
+	 */
149
+	public function toHtml(HtmlOutputHelper $html) {
150
+
151
+		return implode(
152
+			', ',
153
+			array_map([$html, 'xmlName'], $this->getValue())
154
+		);
155
+
156
+	}
157 157
 
158 158
 
159 159
 }
Please login to merge, or discard this patch.
libraries/SabreDAV/DAVACL/Xml/Property/Principal.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -172,7 +172,7 @@
 block discarded – undo
172 172
      * the next element.
173 173
      *
174 174
      * @param Reader $reader
175
-     * @return mixed
175
+     * @return Principal
176 176
      */
177 177
     static function xmlDeserialize(Reader $reader) {
178 178
 
Please login to merge, or discard this patch.
Indentation   +172 added lines, -172 removed lines patch added patch discarded remove patch
@@ -20,177 +20,177 @@
 block discarded – undo
20 20
  */
21 21
 class Principal extends DAV\Xml\Property\Href {
22 22
 
23
-    /**
24
-     * To specify a not-logged-in user, use the UNAUTHENTICATED principal
25
-     */
26
-    const UNAUTHENTICATED = 1;
27
-
28
-    /**
29
-     * To specify any principal that is logged in, use AUTHENTICATED
30
-     */
31
-    const AUTHENTICATED = 2;
32
-
33
-    /**
34
-     * Specific principals can be specified with the HREF
35
-     */
36
-    const HREF = 3;
37
-
38
-    /**
39
-     * Everybody, basically
40
-     */
41
-    const ALL = 4;
42
-
43
-    /**
44
-     * Principal-type
45
-     *
46
-     * Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
47
-     *
48
-     * @var int
49
-     */
50
-    protected $type;
51
-
52
-    /**
53
-     * Creates the property.
54
-     *
55
-     * The 'type' argument must be one of the type constants defined in this class.
56
-     *
57
-     * 'href' is only required for the HREF type.
58
-     *
59
-     * @param int $type
60
-     * @param string|null $href
61
-     */
62
-    public function __construct($type, $href = null) {
63
-
64
-        $this->type = $type;
65
-        if ($type === self::HREF && is_null($href)) {
66
-            throw new DAV\Exception('The href argument must be specified for the HREF principal type.');
67
-        }
68
-        if ($href) {
69
-            $href = rtrim($href, '/') . '/';
70
-            parent::__construct($href);
71
-        }
72
-
73
-    }
74
-
75
-    /**
76
-     * Returns the principal type
77
-     *
78
-     * @return int
79
-     */
80
-    public function getType() {
81
-
82
-        return $this->type;
83
-
84
-    }
85
-
86
-
87
-    /**
88
-     * The xmlSerialize metod is called during xml writing.
89
-     *
90
-     * Use the $writer argument to write its own xml serialization.
91
-     *
92
-     * An important note: do _not_ create a parent element. Any element
93
-     * implementing XmlSerializble should only ever write what's considered
94
-     * its 'inner xml'.
95
-     *
96
-     * The parent of the current element is responsible for writing a
97
-     * containing element.
98
-     *
99
-     * This allows serializers to be re-used for different element names.
100
-     *
101
-     * If you are opening new elements, you must also close them again.
102
-     *
103
-     * @param Writer $writer
104
-     * @return void
105
-     */
106
-    public function xmlSerialize(Writer $writer) {
107
-
108
-        switch ($this->type) {
109
-
110
-            case self::UNAUTHENTICATED :
111
-                $writer->writeElement('{DAV:}unauthenticated');
112
-                break;
113
-            case self::AUTHENTICATED :
114
-                $writer->writeElement('{DAV:}authenticated');
115
-                break;
116
-            case self::HREF :
117
-                parent::xmlSerialize($writer);
118
-                break;
119
-            case self::ALL :
120
-                $writer->writeElement('{DAV:}all');
121
-                break;
122
-        }
123
-
124
-    }
125
-
126
-    /**
127
-     * Generate html representation for this value.
128
-     *
129
-     * The html output is 100% trusted, and no effort is being made to sanitize
130
-     * it. It's up to the implementor to sanitize user provided values.
131
-     *
132
-     * The output must be in UTF-8.
133
-     *
134
-     * The baseUri parameter is a url to the root of the application, and can
135
-     * be used to construct local links.
136
-     *
137
-     * @param HtmlOutputHelper $html
138
-     * @return string
139
-     */
140
-    public function toHtml(HtmlOutputHelper $html) {
141
-
142
-        switch ($this->type) {
143
-
144
-            case self::UNAUTHENTICATED :
145
-                return '<em>unauthenticated</em>';
146
-            case self::AUTHENTICATED :
147
-                return '<em>authenticated</em>';
148
-            case self::HREF :
149
-                return parent::toHtml($html);
150
-            case self::ALL :
151
-                return '<em>all</em>';
152
-        }
153
-
154
-    }
155
-
156
-    /**
157
-     * The deserialize method is called during xml parsing.
158
-     *
159
-     * This method is called staticly, this is because in theory this method
160
-     * may be used as a type of constructor, or factory method.
161
-     *
162
-     * Often you want to return an instance of the current class, but you are
163
-     * free to return other data as well.
164
-     *
165
-     * Important note 2: You are responsible for advancing the reader to the
166
-     * next element. Not doing anything will result in a never-ending loop.
167
-     *
168
-     * If you just want to skip parsing for this element altogether, you can
169
-     * just call $reader->next();
170
-     *
171
-     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
172
-     * the next element.
173
-     *
174
-     * @param Reader $reader
175
-     * @return mixed
176
-     */
177
-    static function xmlDeserialize(Reader $reader) {
178
-
179
-        $tree = $reader->parseInnerTree()[0];
180
-
181
-        switch ($tree['name']) {
182
-            case '{DAV:}unauthenticated' :
183
-                return new self(self::UNAUTHENTICATED);
184
-            case '{DAV:}authenticated' :
185
-                return new self(self::AUTHENTICATED);
186
-            case '{DAV:}href':
187
-                return new self(self::HREF, $tree['value']);
188
-            case '{DAV:}all':
189
-                return new self(self::ALL);
190
-            default :
191
-                throw new BadRequest('Unknown or unsupported principal type: ' . $tree['name']);
192
-        }
193
-
194
-    }
23
+	/**
24
+	 * To specify a not-logged-in user, use the UNAUTHENTICATED principal
25
+	 */
26
+	const UNAUTHENTICATED = 1;
27
+
28
+	/**
29
+	 * To specify any principal that is logged in, use AUTHENTICATED
30
+	 */
31
+	const AUTHENTICATED = 2;
32
+
33
+	/**
34
+	 * Specific principals can be specified with the HREF
35
+	 */
36
+	const HREF = 3;
37
+
38
+	/**
39
+	 * Everybody, basically
40
+	 */
41
+	const ALL = 4;
42
+
43
+	/**
44
+	 * Principal-type
45
+	 *
46
+	 * Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
47
+	 *
48
+	 * @var int
49
+	 */
50
+	protected $type;
51
+
52
+	/**
53
+	 * Creates the property.
54
+	 *
55
+	 * The 'type' argument must be one of the type constants defined in this class.
56
+	 *
57
+	 * 'href' is only required for the HREF type.
58
+	 *
59
+	 * @param int $type
60
+	 * @param string|null $href
61
+	 */
62
+	public function __construct($type, $href = null) {
63
+
64
+		$this->type = $type;
65
+		if ($type === self::HREF && is_null($href)) {
66
+			throw new DAV\Exception('The href argument must be specified for the HREF principal type.');
67
+		}
68
+		if ($href) {
69
+			$href = rtrim($href, '/') . '/';
70
+			parent::__construct($href);
71
+		}
72
+
73
+	}
74
+
75
+	/**
76
+	 * Returns the principal type
77
+	 *
78
+	 * @return int
79
+	 */
80
+	public function getType() {
81
+
82
+		return $this->type;
83
+
84
+	}
85
+
86
+
87
+	/**
88
+	 * The xmlSerialize metod is called during xml writing.
89
+	 *
90
+	 * Use the $writer argument to write its own xml serialization.
91
+	 *
92
+	 * An important note: do _not_ create a parent element. Any element
93
+	 * implementing XmlSerializble should only ever write what's considered
94
+	 * its 'inner xml'.
95
+	 *
96
+	 * The parent of the current element is responsible for writing a
97
+	 * containing element.
98
+	 *
99
+	 * This allows serializers to be re-used for different element names.
100
+	 *
101
+	 * If you are opening new elements, you must also close them again.
102
+	 *
103
+	 * @param Writer $writer
104
+	 * @return void
105
+	 */
106
+	public function xmlSerialize(Writer $writer) {
107
+
108
+		switch ($this->type) {
109
+
110
+			case self::UNAUTHENTICATED :
111
+				$writer->writeElement('{DAV:}unauthenticated');
112
+				break;
113
+			case self::AUTHENTICATED :
114
+				$writer->writeElement('{DAV:}authenticated');
115
+				break;
116
+			case self::HREF :
117
+				parent::xmlSerialize($writer);
118
+				break;
119
+			case self::ALL :
120
+				$writer->writeElement('{DAV:}all');
121
+				break;
122
+		}
123
+
124
+	}
125
+
126
+	/**
127
+	 * Generate html representation for this value.
128
+	 *
129
+	 * The html output is 100% trusted, and no effort is being made to sanitize
130
+	 * it. It's up to the implementor to sanitize user provided values.
131
+	 *
132
+	 * The output must be in UTF-8.
133
+	 *
134
+	 * The baseUri parameter is a url to the root of the application, and can
135
+	 * be used to construct local links.
136
+	 *
137
+	 * @param HtmlOutputHelper $html
138
+	 * @return string
139
+	 */
140
+	public function toHtml(HtmlOutputHelper $html) {
141
+
142
+		switch ($this->type) {
143
+
144
+			case self::UNAUTHENTICATED :
145
+				return '<em>unauthenticated</em>';
146
+			case self::AUTHENTICATED :
147
+				return '<em>authenticated</em>';
148
+			case self::HREF :
149
+				return parent::toHtml($html);
150
+			case self::ALL :
151
+				return '<em>all</em>';
152
+		}
153
+
154
+	}
155
+
156
+	/**
157
+	 * The deserialize method is called during xml parsing.
158
+	 *
159
+	 * This method is called staticly, this is because in theory this method
160
+	 * may be used as a type of constructor, or factory method.
161
+	 *
162
+	 * Often you want to return an instance of the current class, but you are
163
+	 * free to return other data as well.
164
+	 *
165
+	 * Important note 2: You are responsible for advancing the reader to the
166
+	 * next element. Not doing anything will result in a never-ending loop.
167
+	 *
168
+	 * If you just want to skip parsing for this element altogether, you can
169
+	 * just call $reader->next();
170
+	 *
171
+	 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
172
+	 * the next element.
173
+	 *
174
+	 * @param Reader $reader
175
+	 * @return mixed
176
+	 */
177
+	static function xmlDeserialize(Reader $reader) {
178
+
179
+		$tree = $reader->parseInnerTree()[0];
180
+
181
+		switch ($tree['name']) {
182
+			case '{DAV:}unauthenticated' :
183
+				return new self(self::UNAUTHENTICATED);
184
+			case '{DAV:}authenticated' :
185
+				return new self(self::AUTHENTICATED);
186
+			case '{DAV:}href':
187
+				return new self(self::HREF, $tree['value']);
188
+			case '{DAV:}all':
189
+				return new self(self::ALL);
190
+			default :
191
+				throw new BadRequest('Unknown or unsupported principal type: ' . $tree['name']);
192
+		}
193
+
194
+	}
195 195
 
196 196
 }
Please login to merge, or discard this patch.