Completed
Branch develop (37f7b7)
by
unknown
24:41
created
htdocs/includes/sabre/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -18,13 +18,13 @@
 block discarded – undo
18 18
  */
19 19
 class UnsupportedMediaType extends DAV\Exception
20 20
 {
21
-    /**
22
-     * returns the http statuscode for this exception.
23
-     *
24
-     * @return int
25
-     */
26
-    public function getHTTPCode()
27
-    {
28
-        return 415;
29
-    }
21
+	/**
22
+	 * returns the http statuscode for this exception.
23
+	 *
24
+	 * @return int
25
+	 */
26
+	public function getHTTPCode()
27
+	{
28
+		return 415;
29
+	}
30 30
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/Exception/NotAuthenticated.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -18,13 +18,13 @@
 block discarded – undo
18 18
  */
19 19
 class NotAuthenticated extends DAV\Exception
20 20
 {
21
-    /**
22
-     * Returns the HTTP statuscode for this exception.
23
-     *
24
-     * @return int
25
-     */
26
-    public function getHTTPCode()
27
-    {
28
-        return 401;
29
-    }
21
+	/**
22
+	 * Returns the HTTP statuscode for this exception.
23
+	 *
24
+	 * @return int
25
+	 */
26
+	public function getHTTPCode()
27
+	{
28
+		return 401;
29
+	}
30 30
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/Exception/PreconditionFailed.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -19,47 +19,47 @@
 block discarded – undo
19 19
  */
20 20
 class PreconditionFailed extends DAV\Exception
21 21
 {
22
-    /**
23
-     * When this exception is thrown, the header-name might be set.
24
-     *
25
-     * This allows the exception-catching code to determine which HTTP header
26
-     * caused the exception.
27
-     *
28
-     * @var string
29
-     */
30
-    public $header = null;
22
+	/**
23
+	 * When this exception is thrown, the header-name might be set.
24
+	 *
25
+	 * This allows the exception-catching code to determine which HTTP header
26
+	 * caused the exception.
27
+	 *
28
+	 * @var string
29
+	 */
30
+	public $header = null;
31 31
 
32
-    /**
33
-     * Create the exception.
34
-     *
35
-     * @param string $message
36
-     * @param string $header
37
-     */
38
-    public function __construct($message, $header = null)
39
-    {
40
-        parent::__construct($message);
41
-        $this->header = $header;
42
-    }
32
+	/**
33
+	 * Create the exception.
34
+	 *
35
+	 * @param string $message
36
+	 * @param string $header
37
+	 */
38
+	public function __construct($message, $header = null)
39
+	{
40
+		parent::__construct($message);
41
+		$this->header = $header;
42
+	}
43 43
 
44
-    /**
45
-     * Returns the HTTP statuscode for this exception.
46
-     *
47
-     * @return int
48
-     */
49
-    public function getHTTPCode()
50
-    {
51
-        return 412;
52
-    }
44
+	/**
45
+	 * Returns the HTTP statuscode for this exception.
46
+	 *
47
+	 * @return int
48
+	 */
49
+	public function getHTTPCode()
50
+	{
51
+		return 412;
52
+	}
53 53
 
54
-    /**
55
-     * This method allows the exception to include additional information into the WebDAV error response.
56
-     */
57
-    public function serialize(DAV\Server $server, \DOMElement $errorNode)
58
-    {
59
-        if ($this->header) {
60
-            $prop = $errorNode->ownerDocument->createElement('s:header');
61
-            $prop->nodeValue = $this->header;
62
-            $errorNode->appendChild($prop);
63
-        }
64
-    }
54
+	/**
55
+	 * This method allows the exception to include additional information into the WebDAV error response.
56
+	 */
57
+	public function serialize(DAV\Server $server, \DOMElement $errorNode)
58
+	{
59
+		if ($this->header) {
60
+			$prop = $errorNode->ownerDocument->createElement('s:header');
61
+			$prop->nodeValue = $this->header;
62
+			$errorNode->appendChild($prop);
63
+		}
64
+	}
65 65
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/Node.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -15,37 +15,37 @@
 block discarded – undo
15 15
  */
16 16
 abstract class Node implements INode
17 17
 {
18
-    /**
19
-     * Returns the last modification time as a unix timestamp.
20
-     *
21
-     * If the information is not available, return null.
22
-     *
23
-     * @return int
24
-     */
25
-    public function getLastModified()
26
-    {
27
-        return null;
28
-    }
18
+	/**
19
+	 * Returns the last modification time as a unix timestamp.
20
+	 *
21
+	 * If the information is not available, return null.
22
+	 *
23
+	 * @return int
24
+	 */
25
+	public function getLastModified()
26
+	{
27
+		return null;
28
+	}
29 29
 
30
-    /**
31
-     * Deletes the current node.
32
-     *
33
-     * @throws Exception\Forbidden
34
-     */
35
-    public function delete()
36
-    {
37
-        throw new Exception\Forbidden('Permission denied to delete node');
38
-    }
30
+	/**
31
+	 * Deletes the current node.
32
+	 *
33
+	 * @throws Exception\Forbidden
34
+	 */
35
+	public function delete()
36
+	{
37
+		throw new Exception\Forbidden('Permission denied to delete node');
38
+	}
39 39
 
40
-    /**
41
-     * Renames the node.
42
-     *
43
-     * @param string $name The new name
44
-     *
45
-     * @throws Exception\Forbidden
46
-     */
47
-    public function setName($name)
48
-    {
49
-        throw new Exception\Forbidden('Permission denied to rename file');
50
-    }
40
+	/**
41
+	 * Renames the node.
42
+	 *
43
+	 * @param string $name The new name
44
+	 *
45
+	 * @throws Exception\Forbidden
46
+	 */
47
+	public function setName($name)
48
+	{
49
+		throw new Exception\Forbidden('Permission denied to rename file');
50
+	}
51 51
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/PropFind.php 1 patch
Indentation   +294 added lines, -294 removed lines patch added patch discarded remove patch
@@ -12,324 +12,324 @@
 block discarded – undo
12 12
  */
13 13
 class PropFind
14 14
 {
15
-    /**
16
-     * A normal propfind.
17
-     */
18
-    const NORMAL = 0;
15
+	/**
16
+	 * A normal propfind.
17
+	 */
18
+	const NORMAL = 0;
19 19
 
20
-    /**
21
-     * An allprops request.
22
-     *
23
-     * While this was originally intended for instructing the server to really
24
-     * fetch every property, because it was used so often and it's so heavy
25
-     * this turned into a small list of default properties after a while.
26
-     *
27
-     * So 'all properties' now means a hardcoded list.
28
-     */
29
-    const ALLPROPS = 1;
20
+	/**
21
+	 * An allprops request.
22
+	 *
23
+	 * While this was originally intended for instructing the server to really
24
+	 * fetch every property, because it was used so often and it's so heavy
25
+	 * this turned into a small list of default properties after a while.
26
+	 *
27
+	 * So 'all properties' now means a hardcoded list.
28
+	 */
29
+	const ALLPROPS = 1;
30 30
 
31
-    /**
32
-     * A propname request. This just returns a list of properties that are
33
-     * defined on a node, without their values.
34
-     */
35
-    const PROPNAME = 2;
31
+	/**
32
+	 * A propname request. This just returns a list of properties that are
33
+	 * defined on a node, without their values.
34
+	 */
35
+	const PROPNAME = 2;
36 36
 
37
-    /**
38
-     * Creates the PROPFIND object.
39
-     *
40
-     * @param string $path
41
-     * @param int    $depth
42
-     * @param int    $requestType
43
-     */
44
-    public function __construct($path, array $properties, $depth = 0, $requestType = self::NORMAL)
45
-    {
46
-        $this->path = $path;
47
-        $this->properties = $properties;
48
-        $this->depth = $depth;
49
-        $this->requestType = $requestType;
37
+	/**
38
+	 * Creates the PROPFIND object.
39
+	 *
40
+	 * @param string $path
41
+	 * @param int    $depth
42
+	 * @param int    $requestType
43
+	 */
44
+	public function __construct($path, array $properties, $depth = 0, $requestType = self::NORMAL)
45
+	{
46
+		$this->path = $path;
47
+		$this->properties = $properties;
48
+		$this->depth = $depth;
49
+		$this->requestType = $requestType;
50 50
 
51
-        if (self::ALLPROPS === $requestType) {
52
-            $this->properties = [
53
-                '{DAV:}getlastmodified',
54
-                '{DAV:}getcontentlength',
55
-                '{DAV:}resourcetype',
56
-                '{DAV:}quota-used-bytes',
57
-                '{DAV:}quota-available-bytes',
58
-                '{DAV:}getetag',
59
-                '{DAV:}getcontenttype',
60
-            ];
61
-        }
51
+		if (self::ALLPROPS === $requestType) {
52
+			$this->properties = [
53
+				'{DAV:}getlastmodified',
54
+				'{DAV:}getcontentlength',
55
+				'{DAV:}resourcetype',
56
+				'{DAV:}quota-used-bytes',
57
+				'{DAV:}quota-available-bytes',
58
+				'{DAV:}getetag',
59
+				'{DAV:}getcontenttype',
60
+			];
61
+		}
62 62
 
63
-        foreach ($this->properties as $propertyName) {
64
-            // Seeding properties with 404's.
65
-            $this->result[$propertyName] = [404, null];
66
-        }
67
-        $this->itemsLeft = count($this->result);
68
-    }
63
+		foreach ($this->properties as $propertyName) {
64
+			// Seeding properties with 404's.
65
+			$this->result[$propertyName] = [404, null];
66
+		}
67
+		$this->itemsLeft = count($this->result);
68
+	}
69 69
 
70
-    /**
71
-     * Handles a specific property.
72
-     *
73
-     * This method checks whether the specified property was requested in this
74
-     * PROPFIND request, and if so, it will call the callback and use the
75
-     * return value for it's value.
76
-     *
77
-     * Example:
78
-     *
79
-     * $propFind->handle('{DAV:}displayname', function() {
80
-     *      return 'hello';
81
-     * });
82
-     *
83
-     * Note that handle will only work the first time. If null is returned, the
84
-     * value is ignored.
85
-     *
86
-     * It's also possible to not pass a callback, but immediately pass a value
87
-     *
88
-     * @param string $propertyName
89
-     * @param mixed  $valueOrCallBack
90
-     */
91
-    public function handle($propertyName, $valueOrCallBack)
92
-    {
93
-        if ($this->itemsLeft && isset($this->result[$propertyName]) && 404 === $this->result[$propertyName][0]) {
94
-            if (is_callable($valueOrCallBack)) {
95
-                $value = $valueOrCallBack();
96
-            } else {
97
-                $value = $valueOrCallBack;
98
-            }
99
-            if (!is_null($value)) {
100
-                --$this->itemsLeft;
101
-                $this->result[$propertyName] = [200, $value];
102
-            }
103
-        }
104
-    }
70
+	/**
71
+	 * Handles a specific property.
72
+	 *
73
+	 * This method checks whether the specified property was requested in this
74
+	 * PROPFIND request, and if so, it will call the callback and use the
75
+	 * return value for it's value.
76
+	 *
77
+	 * Example:
78
+	 *
79
+	 * $propFind->handle('{DAV:}displayname', function() {
80
+	 *      return 'hello';
81
+	 * });
82
+	 *
83
+	 * Note that handle will only work the first time. If null is returned, the
84
+	 * value is ignored.
85
+	 *
86
+	 * It's also possible to not pass a callback, but immediately pass a value
87
+	 *
88
+	 * @param string $propertyName
89
+	 * @param mixed  $valueOrCallBack
90
+	 */
91
+	public function handle($propertyName, $valueOrCallBack)
92
+	{
93
+		if ($this->itemsLeft && isset($this->result[$propertyName]) && 404 === $this->result[$propertyName][0]) {
94
+			if (is_callable($valueOrCallBack)) {
95
+				$value = $valueOrCallBack();
96
+			} else {
97
+				$value = $valueOrCallBack;
98
+			}
99
+			if (!is_null($value)) {
100
+				--$this->itemsLeft;
101
+				$this->result[$propertyName] = [200, $value];
102
+			}
103
+		}
104
+	}
105 105
 
106
-    /**
107
-     * Sets the value of the property.
108
-     *
109
-     * If status is not supplied, the status will default to 200 for non-null
110
-     * properties, and 404 for null properties.
111
-     *
112
-     * @param string $propertyName
113
-     * @param mixed  $value
114
-     * @param int    $status
115
-     */
116
-    public function set($propertyName, $value, $status = null)
117
-    {
118
-        if (is_null($status)) {
119
-            $status = is_null($value) ? 404 : 200;
120
-        }
121
-        // If this is an ALLPROPS request and the property is
122
-        // unknown, add it to the result; else ignore it:
123
-        if (!isset($this->result[$propertyName])) {
124
-            if (self::ALLPROPS === $this->requestType) {
125
-                $this->result[$propertyName] = [$status, $value];
126
-            }
106
+	/**
107
+	 * Sets the value of the property.
108
+	 *
109
+	 * If status is not supplied, the status will default to 200 for non-null
110
+	 * properties, and 404 for null properties.
111
+	 *
112
+	 * @param string $propertyName
113
+	 * @param mixed  $value
114
+	 * @param int    $status
115
+	 */
116
+	public function set($propertyName, $value, $status = null)
117
+	{
118
+		if (is_null($status)) {
119
+			$status = is_null($value) ? 404 : 200;
120
+		}
121
+		// If this is an ALLPROPS request and the property is
122
+		// unknown, add it to the result; else ignore it:
123
+		if (!isset($this->result[$propertyName])) {
124
+			if (self::ALLPROPS === $this->requestType) {
125
+				$this->result[$propertyName] = [$status, $value];
126
+			}
127 127
 
128
-            return;
129
-        }
130
-        if (404 !== $status && 404 === $this->result[$propertyName][0]) {
131
-            --$this->itemsLeft;
132
-        } elseif (404 === $status && 404 !== $this->result[$propertyName][0]) {
133
-            ++$this->itemsLeft;
134
-        }
135
-        $this->result[$propertyName] = [$status, $value];
136
-    }
128
+			return;
129
+		}
130
+		if (404 !== $status && 404 === $this->result[$propertyName][0]) {
131
+			--$this->itemsLeft;
132
+		} elseif (404 === $status && 404 !== $this->result[$propertyName][0]) {
133
+			++$this->itemsLeft;
134
+		}
135
+		$this->result[$propertyName] = [$status, $value];
136
+	}
137 137
 
138
-    /**
139
-     * Returns the current value for a property.
140
-     *
141
-     * @param string $propertyName
142
-     *
143
-     * @return mixed
144
-     */
145
-    public function get($propertyName)
146
-    {
147
-        return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null;
148
-    }
138
+	/**
139
+	 * Returns the current value for a property.
140
+	 *
141
+	 * @param string $propertyName
142
+	 *
143
+	 * @return mixed
144
+	 */
145
+	public function get($propertyName)
146
+	{
147
+		return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null;
148
+	}
149 149
 
150
-    /**
151
-     * Returns the current status code for a property name.
152
-     *
153
-     * If the property does not appear in the list of requested properties,
154
-     * null will be returned.
155
-     *
156
-     * @param string $propertyName
157
-     *
158
-     * @return int|null
159
-     */
160
-    public function getStatus($propertyName)
161
-    {
162
-        return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : null;
163
-    }
150
+	/**
151
+	 * Returns the current status code for a property name.
152
+	 *
153
+	 * If the property does not appear in the list of requested properties,
154
+	 * null will be returned.
155
+	 *
156
+	 * @param string $propertyName
157
+	 *
158
+	 * @return int|null
159
+	 */
160
+	public function getStatus($propertyName)
161
+	{
162
+		return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : null;
163
+	}
164 164
 
165
-    /**
166
-     * Updates the path for this PROPFIND.
167
-     *
168
-     * @param string $path
169
-     */
170
-    public function setPath($path)
171
-    {
172
-        $this->path = $path;
173
-    }
165
+	/**
166
+	 * Updates the path for this PROPFIND.
167
+	 *
168
+	 * @param string $path
169
+	 */
170
+	public function setPath($path)
171
+	{
172
+		$this->path = $path;
173
+	}
174 174
 
175
-    /**
176
-     * Returns the path this PROPFIND request is for.
177
-     *
178
-     * @return string
179
-     */
180
-    public function getPath()
181
-    {
182
-        return $this->path;
183
-    }
175
+	/**
176
+	 * Returns the path this PROPFIND request is for.
177
+	 *
178
+	 * @return string
179
+	 */
180
+	public function getPath()
181
+	{
182
+		return $this->path;
183
+	}
184 184
 
185
-    /**
186
-     * Returns the depth of this propfind request.
187
-     *
188
-     * @return int
189
-     */
190
-    public function getDepth()
191
-    {
192
-        return $this->depth;
193
-    }
185
+	/**
186
+	 * Returns the depth of this propfind request.
187
+	 *
188
+	 * @return int
189
+	 */
190
+	public function getDepth()
191
+	{
192
+		return $this->depth;
193
+	}
194 194
 
195
-    /**
196
-     * Updates the depth of this propfind request.
197
-     *
198
-     * @param int $depth
199
-     */
200
-    public function setDepth($depth)
201
-    {
202
-        $this->depth = $depth;
203
-    }
195
+	/**
196
+	 * Updates the depth of this propfind request.
197
+	 *
198
+	 * @param int $depth
199
+	 */
200
+	public function setDepth($depth)
201
+	{
202
+		$this->depth = $depth;
203
+	}
204 204
 
205
-    /**
206
-     * Returns all propertynames that have a 404 status, and thus don't have a
207
-     * value yet.
208
-     *
209
-     * @return array
210
-     */
211
-    public function get404Properties()
212
-    {
213
-        if (0 === $this->itemsLeft) {
214
-            return [];
215
-        }
216
-        $result = [];
217
-        foreach ($this->result as $propertyName => $stuff) {
218
-            if (404 === $stuff[0]) {
219
-                $result[] = $propertyName;
220
-            }
221
-        }
205
+	/**
206
+	 * Returns all propertynames that have a 404 status, and thus don't have a
207
+	 * value yet.
208
+	 *
209
+	 * @return array
210
+	 */
211
+	public function get404Properties()
212
+	{
213
+		if (0 === $this->itemsLeft) {
214
+			return [];
215
+		}
216
+		$result = [];
217
+		foreach ($this->result as $propertyName => $stuff) {
218
+			if (404 === $stuff[0]) {
219
+				$result[] = $propertyName;
220
+			}
221
+		}
222 222
 
223
-        return $result;
224
-    }
223
+		return $result;
224
+	}
225 225
 
226
-    /**
227
-     * Returns the full list of requested properties.
228
-     *
229
-     * This returns just their names, not a status or value.
230
-     *
231
-     * @return array
232
-     */
233
-    public function getRequestedProperties()
234
-    {
235
-        return $this->properties;
236
-    }
226
+	/**
227
+	 * Returns the full list of requested properties.
228
+	 *
229
+	 * This returns just their names, not a status or value.
230
+	 *
231
+	 * @return array
232
+	 */
233
+	public function getRequestedProperties()
234
+	{
235
+		return $this->properties;
236
+	}
237 237
 
238
-    /**
239
-     * Returns true if this was an '{DAV:}allprops' request.
240
-     *
241
-     * @return bool
242
-     */
243
-    public function isAllProps()
244
-    {
245
-        return self::ALLPROPS === $this->requestType;
246
-    }
238
+	/**
239
+	 * Returns true if this was an '{DAV:}allprops' request.
240
+	 *
241
+	 * @return bool
242
+	 */
243
+	public function isAllProps()
244
+	{
245
+		return self::ALLPROPS === $this->requestType;
246
+	}
247 247
 
248
-    /**
249
-     * Returns a result array that's often used in multistatus responses.
250
-     *
251
-     * The array uses status codes as keys, and property names and value pairs
252
-     * as the value of the top array.. such as :
253
-     *
254
-     * [
255
-     *  200 => [ '{DAV:}displayname' => 'foo' ],
256
-     * ]
257
-     *
258
-     * @return array
259
-     */
260
-    public function getResultForMultiStatus()
261
-    {
262
-        $r = [
263
-            200 => [],
264
-            404 => [],
265
-        ];
266
-        foreach ($this->result as $propertyName => $info) {
267
-            if (!isset($r[$info[0]])) {
268
-                $r[$info[0]] = [$propertyName => $info[1]];
269
-            } else {
270
-                $r[$info[0]][$propertyName] = $info[1];
271
-            }
272
-        }
273
-        // Removing the 404's for multi-status requests.
274
-        if (self::ALLPROPS === $this->requestType) {
275
-            unset($r[404]);
276
-        }
248
+	/**
249
+	 * Returns a result array that's often used in multistatus responses.
250
+	 *
251
+	 * The array uses status codes as keys, and property names and value pairs
252
+	 * as the value of the top array.. such as :
253
+	 *
254
+	 * [
255
+	 *  200 => [ '{DAV:}displayname' => 'foo' ],
256
+	 * ]
257
+	 *
258
+	 * @return array
259
+	 */
260
+	public function getResultForMultiStatus()
261
+	{
262
+		$r = [
263
+			200 => [],
264
+			404 => [],
265
+		];
266
+		foreach ($this->result as $propertyName => $info) {
267
+			if (!isset($r[$info[0]])) {
268
+				$r[$info[0]] = [$propertyName => $info[1]];
269
+			} else {
270
+				$r[$info[0]][$propertyName] = $info[1];
271
+			}
272
+		}
273
+		// Removing the 404's for multi-status requests.
274
+		if (self::ALLPROPS === $this->requestType) {
275
+			unset($r[404]);
276
+		}
277 277
 
278
-        return $r;
279
-    }
278
+		return $r;
279
+	}
280 280
 
281
-    /**
282
-     * The path that we're fetching properties for.
283
-     *
284
-     * @var string
285
-     */
286
-    protected $path;
281
+	/**
282
+	 * The path that we're fetching properties for.
283
+	 *
284
+	 * @var string
285
+	 */
286
+	protected $path;
287 287
 
288
-    /**
289
-     * The Depth of the request.
290
-     *
291
-     * 0 means only the current item. 1 means the current item + its children.
292
-     * It can also be DEPTH_INFINITY if this is enabled in the server.
293
-     *
294
-     * @var int
295
-     */
296
-    protected $depth = 0;
288
+	/**
289
+	 * The Depth of the request.
290
+	 *
291
+	 * 0 means only the current item. 1 means the current item + its children.
292
+	 * It can also be DEPTH_INFINITY if this is enabled in the server.
293
+	 *
294
+	 * @var int
295
+	 */
296
+	protected $depth = 0;
297 297
 
298
-    /**
299
-     * The type of request. See the TYPE constants.
300
-     */
301
-    protected $requestType;
298
+	/**
299
+	 * The type of request. See the TYPE constants.
300
+	 */
301
+	protected $requestType;
302 302
 
303
-    /**
304
-     * A list of requested properties.
305
-     *
306
-     * @var array
307
-     */
308
-    protected $properties = [];
303
+	/**
304
+	 * A list of requested properties.
305
+	 *
306
+	 * @var array
307
+	 */
308
+	protected $properties = [];
309 309
 
310
-    /**
311
-     * The result of the operation.
312
-     *
313
-     * The keys in this array are property names.
314
-     * The values are an array with two elements: the http status code and then
315
-     * optionally a value.
316
-     *
317
-     * Example:
318
-     *
319
-     * [
320
-     *    "{DAV:}owner" : [404],
321
-     *    "{DAV:}displayname" : [200, "Admin"]
322
-     * ]
323
-     *
324
-     * @var array
325
-     */
326
-    protected $result = [];
310
+	/**
311
+	 * The result of the operation.
312
+	 *
313
+	 * The keys in this array are property names.
314
+	 * The values are an array with two elements: the http status code and then
315
+	 * optionally a value.
316
+	 *
317
+	 * Example:
318
+	 *
319
+	 * [
320
+	 *    "{DAV:}owner" : [404],
321
+	 *    "{DAV:}displayname" : [200, "Admin"]
322
+	 * ]
323
+	 *
324
+	 * @var array
325
+	 */
326
+	protected $result = [];
327 327
 
328
-    /**
329
-     * This is used as an internal counter for the number of properties that do
330
-     * not yet have a value.
331
-     *
332
-     * @var int
333
-     */
334
-    protected $itemsLeft;
328
+	/**
329
+	 * This is used as an internal counter for the number of properties that do
330
+	 * not yet have a value.
331
+	 *
332
+	 * @var int
333
+	 */
334
+	protected $itemsLeft;
335 335
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/PartialUpdate/Plugin.php 1 patch
Indentation   +185 added lines, -185 removed lines patch added patch discarded remove patch
@@ -24,189 +24,189 @@
 block discarded – undo
24 24
  */
25 25
 class Plugin extends DAV\ServerPlugin
26 26
 {
27
-    const RANGE_APPEND = 1;
28
-    const RANGE_START = 2;
29
-    const RANGE_END = 3;
30
-
31
-    /**
32
-     * Reference to server.
33
-     *
34
-     * @var DAV\Server
35
-     */
36
-    protected $server;
37
-
38
-    /**
39
-     * Initializes the plugin.
40
-     *
41
-     * This method is automatically called by the Server class after addPlugin.
42
-     */
43
-    public function initialize(DAV\Server $server)
44
-    {
45
-        $this->server = $server;
46
-        $server->on('method:PATCH', [$this, 'httpPatch']);
47
-    }
48
-
49
-    /**
50
-     * Returns a plugin name.
51
-     *
52
-     * Using this name other plugins will be able to access other plugins
53
-     * using DAV\Server::getPlugin
54
-     *
55
-     * @return string
56
-     */
57
-    public function getPluginName()
58
-    {
59
-        return 'partialupdate';
60
-    }
61
-
62
-    /**
63
-     * Use this method to tell the server this plugin defines additional
64
-     * HTTP methods.
65
-     *
66
-     * This method is passed a uri. It should only return HTTP methods that are
67
-     * available for the specified uri.
68
-     *
69
-     * We claim to support PATCH method (partirl update) if and only if
70
-     *     - the node exist
71
-     *     - the node implements our partial update interface
72
-     *
73
-     * @param string $uri
74
-     *
75
-     * @return array
76
-     */
77
-    public function getHTTPMethods($uri)
78
-    {
79
-        $tree = $this->server->tree;
80
-
81
-        if ($tree->nodeExists($uri)) {
82
-            $node = $tree->getNodeForPath($uri);
83
-            if ($node instanceof IPatchSupport) {
84
-                return ['PATCH'];
85
-            }
86
-        }
87
-
88
-        return [];
89
-    }
90
-
91
-    /**
92
-     * Returns a list of features for the HTTP OPTIONS Dav: header.
93
-     *
94
-     * @return array
95
-     */
96
-    public function getFeatures()
97
-    {
98
-        return ['sabredav-partialupdate'];
99
-    }
100
-
101
-    /**
102
-     * Patch an uri.
103
-     *
104
-     * The WebDAV patch request can be used to modify only a part of an
105
-     * existing resource. If the resource does not exist yet and the first
106
-     * offset is not 0, the request fails
107
-     */
108
-    public function httpPatch(RequestInterface $request, ResponseInterface $response)
109
-    {
110
-        $path = $request->getPath();
111
-
112
-        // Get the node. Will throw a 404 if not found
113
-        $node = $this->server->tree->getNodeForPath($path);
114
-        if (!$node instanceof IPatchSupport) {
115
-            throw new DAV\Exception\MethodNotAllowed('The target resource does not support the PATCH method.');
116
-        }
117
-
118
-        $range = $this->getHTTPUpdateRange($request);
119
-
120
-        if (!$range) {
121
-            throw new DAV\Exception\BadRequest('No valid "X-Update-Range" found in the headers');
122
-        }
123
-
124
-        $contentType = strtolower(
125
-            (string) $request->getHeader('Content-Type')
126
-        );
127
-
128
-        if ('application/x-sabredav-partialupdate' != $contentType) {
129
-            throw new DAV\Exception\UnsupportedMediaType('Unknown Content-Type header "'.$contentType.'"');
130
-        }
131
-
132
-        $len = $this->server->httpRequest->getHeader('Content-Length');
133
-        if (!$len) {
134
-            throw new DAV\Exception\LengthRequired('A Content-Length header is required');
135
-        }
136
-        switch ($range[0]) {
137
-            case self::RANGE_START:
138
-                // Calculate the end-range if it doesn't exist.
139
-                if (!$range[2]) {
140
-                    $range[2] = $range[1] + $len - 1;
141
-                } else {
142
-                    if ($range[2] < $range[1]) {
143
-                        throw new DAV\Exception\RequestedRangeNotSatisfiable('The end offset ('.$range[2].') is lower than the start offset ('.$range[1].')');
144
-                    }
145
-                    if ($range[2] - $range[1] + 1 != $len) {
146
-                        throw new DAV\Exception\RequestedRangeNotSatisfiable('Actual data length ('.$len.') is not consistent with begin ('.$range[1].') and end ('.$range[2].') offsets');
147
-                    }
148
-                }
149
-                break;
150
-        }
151
-
152
-        if (!$this->server->emit('beforeWriteContent', [$path, $node, null])) {
153
-            return;
154
-        }
155
-
156
-        $body = $this->server->httpRequest->getBody();
157
-
158
-        $etag = $node->patch($body, $range[0], isset($range[1]) ? $range[1] : null);
159
-
160
-        $this->server->emit('afterWriteContent', [$path, $node]);
161
-
162
-        $response->setHeader('Content-Length', '0');
163
-        if ($etag) {
164
-            $response->setHeader('ETag', $etag);
165
-        }
166
-        $response->setStatus(204);
167
-
168
-        // Breaks the event chain
169
-        return false;
170
-    }
171
-
172
-    /**
173
-     * Returns the HTTP custom range update header.
174
-     *
175
-     * This method returns null if there is no well-formed HTTP range request
176
-     * header. It returns array(1) if it was an append request, array(2,
177
-     * $start, $end) if it's a start and end range, lastly it's array(3,
178
-     * $endoffset) if the offset was negative, and should be calculated from
179
-     * the end of the file.
180
-     *
181
-     * Examples:
182
-     *
183
-     * null - invalid
184
-     * [1] - append
185
-     * [2,10,15] - update bytes 10, 11, 12, 13, 14, 15
186
-     * [2,10,null] - update bytes 10 until the end of the patch body
187
-     * [3,-5] - update from 5 bytes from the end of the file.
188
-     *
189
-     * @return array|null
190
-     */
191
-    public function getHTTPUpdateRange(RequestInterface $request)
192
-    {
193
-        $range = $request->getHeader('X-Update-Range');
194
-        if (is_null($range)) {
195
-            return null;
196
-        }
197
-
198
-        // Matching "Range: bytes=1234-5678: both numbers are optional
199
-
200
-        if (!preg_match('/^(append)|(?:bytes=([0-9]+)-([0-9]*))|(?:bytes=(-[0-9]+))$/i', $range, $matches)) {
201
-            return null;
202
-        }
203
-
204
-        if ('append' === $matches[1]) {
205
-            return [self::RANGE_APPEND];
206
-        } elseif (strlen($matches[2]) > 0) {
207
-            return [self::RANGE_START, (int) $matches[2], (int) $matches[3] ?: null];
208
-        } else {
209
-            return [self::RANGE_END, (int) $matches[4]];
210
-        }
211
-    }
27
+	const RANGE_APPEND = 1;
28
+	const RANGE_START = 2;
29
+	const RANGE_END = 3;
30
+
31
+	/**
32
+	 * Reference to server.
33
+	 *
34
+	 * @var DAV\Server
35
+	 */
36
+	protected $server;
37
+
38
+	/**
39
+	 * Initializes the plugin.
40
+	 *
41
+	 * This method is automatically called by the Server class after addPlugin.
42
+	 */
43
+	public function initialize(DAV\Server $server)
44
+	{
45
+		$this->server = $server;
46
+		$server->on('method:PATCH', [$this, 'httpPatch']);
47
+	}
48
+
49
+	/**
50
+	 * Returns a plugin name.
51
+	 *
52
+	 * Using this name other plugins will be able to access other plugins
53
+	 * using DAV\Server::getPlugin
54
+	 *
55
+	 * @return string
56
+	 */
57
+	public function getPluginName()
58
+	{
59
+		return 'partialupdate';
60
+	}
61
+
62
+	/**
63
+	 * Use this method to tell the server this plugin defines additional
64
+	 * HTTP methods.
65
+	 *
66
+	 * This method is passed a uri. It should only return HTTP methods that are
67
+	 * available for the specified uri.
68
+	 *
69
+	 * We claim to support PATCH method (partirl update) if and only if
70
+	 *     - the node exist
71
+	 *     - the node implements our partial update interface
72
+	 *
73
+	 * @param string $uri
74
+	 *
75
+	 * @return array
76
+	 */
77
+	public function getHTTPMethods($uri)
78
+	{
79
+		$tree = $this->server->tree;
80
+
81
+		if ($tree->nodeExists($uri)) {
82
+			$node = $tree->getNodeForPath($uri);
83
+			if ($node instanceof IPatchSupport) {
84
+				return ['PATCH'];
85
+			}
86
+		}
87
+
88
+		return [];
89
+	}
90
+
91
+	/**
92
+	 * Returns a list of features for the HTTP OPTIONS Dav: header.
93
+	 *
94
+	 * @return array
95
+	 */
96
+	public function getFeatures()
97
+	{
98
+		return ['sabredav-partialupdate'];
99
+	}
100
+
101
+	/**
102
+	 * Patch an uri.
103
+	 *
104
+	 * The WebDAV patch request can be used to modify only a part of an
105
+	 * existing resource. If the resource does not exist yet and the first
106
+	 * offset is not 0, the request fails
107
+	 */
108
+	public function httpPatch(RequestInterface $request, ResponseInterface $response)
109
+	{
110
+		$path = $request->getPath();
111
+
112
+		// Get the node. Will throw a 404 if not found
113
+		$node = $this->server->tree->getNodeForPath($path);
114
+		if (!$node instanceof IPatchSupport) {
115
+			throw new DAV\Exception\MethodNotAllowed('The target resource does not support the PATCH method.');
116
+		}
117
+
118
+		$range = $this->getHTTPUpdateRange($request);
119
+
120
+		if (!$range) {
121
+			throw new DAV\Exception\BadRequest('No valid "X-Update-Range" found in the headers');
122
+		}
123
+
124
+		$contentType = strtolower(
125
+			(string) $request->getHeader('Content-Type')
126
+		);
127
+
128
+		if ('application/x-sabredav-partialupdate' != $contentType) {
129
+			throw new DAV\Exception\UnsupportedMediaType('Unknown Content-Type header "'.$contentType.'"');
130
+		}
131
+
132
+		$len = $this->server->httpRequest->getHeader('Content-Length');
133
+		if (!$len) {
134
+			throw new DAV\Exception\LengthRequired('A Content-Length header is required');
135
+		}
136
+		switch ($range[0]) {
137
+			case self::RANGE_START:
138
+				// Calculate the end-range if it doesn't exist.
139
+				if (!$range[2]) {
140
+					$range[2] = $range[1] + $len - 1;
141
+				} else {
142
+					if ($range[2] < $range[1]) {
143
+						throw new DAV\Exception\RequestedRangeNotSatisfiable('The end offset ('.$range[2].') is lower than the start offset ('.$range[1].')');
144
+					}
145
+					if ($range[2] - $range[1] + 1 != $len) {
146
+						throw new DAV\Exception\RequestedRangeNotSatisfiable('Actual data length ('.$len.') is not consistent with begin ('.$range[1].') and end ('.$range[2].') offsets');
147
+					}
148
+				}
149
+				break;
150
+		}
151
+
152
+		if (!$this->server->emit('beforeWriteContent', [$path, $node, null])) {
153
+			return;
154
+		}
155
+
156
+		$body = $this->server->httpRequest->getBody();
157
+
158
+		$etag = $node->patch($body, $range[0], isset($range[1]) ? $range[1] : null);
159
+
160
+		$this->server->emit('afterWriteContent', [$path, $node]);
161
+
162
+		$response->setHeader('Content-Length', '0');
163
+		if ($etag) {
164
+			$response->setHeader('ETag', $etag);
165
+		}
166
+		$response->setStatus(204);
167
+
168
+		// Breaks the event chain
169
+		return false;
170
+	}
171
+
172
+	/**
173
+	 * Returns the HTTP custom range update header.
174
+	 *
175
+	 * This method returns null if there is no well-formed HTTP range request
176
+	 * header. It returns array(1) if it was an append request, array(2,
177
+	 * $start, $end) if it's a start and end range, lastly it's array(3,
178
+	 * $endoffset) if the offset was negative, and should be calculated from
179
+	 * the end of the file.
180
+	 *
181
+	 * Examples:
182
+	 *
183
+	 * null - invalid
184
+	 * [1] - append
185
+	 * [2,10,15] - update bytes 10, 11, 12, 13, 14, 15
186
+	 * [2,10,null] - update bytes 10 until the end of the patch body
187
+	 * [3,-5] - update from 5 bytes from the end of the file.
188
+	 *
189
+	 * @return array|null
190
+	 */
191
+	public function getHTTPUpdateRange(RequestInterface $request)
192
+	{
193
+		$range = $request->getHeader('X-Update-Range');
194
+		if (is_null($range)) {
195
+			return null;
196
+		}
197
+
198
+		// Matching "Range: bytes=1234-5678: both numbers are optional
199
+
200
+		if (!preg_match('/^(append)|(?:bytes=([0-9]+)-([0-9]*))|(?:bytes=(-[0-9]+))$/i', $range, $matches)) {
201
+			return null;
202
+		}
203
+
204
+		if ('append' === $matches[1]) {
205
+			return [self::RANGE_APPEND];
206
+		} elseif (strlen($matches[2]) > 0) {
207
+			return [self::RANGE_START, (int) $matches[2], (int) $matches[3] ?: null];
208
+		} else {
209
+			return [self::RANGE_END, (int) $matches[4]];
210
+		}
211
+	}
212 212
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -17,33 +17,33 @@
 block discarded – undo
17 17
  */
18 18
 interface IPatchSupport extends DAV\IFile
19 19
 {
20
-    /**
21
-     * Updates the file based on a range specification.
22
-     *
23
-     * The first argument is the data, which is either a readable stream
24
-     * resource or a string.
25
-     *
26
-     * The second argument is the type of update we're doing.
27
-     * This is either:
28
-     * * 1. append
29
-     * * 2. update based on a start byte
30
-     * * 3. update based on an end byte
31
-     *;
32
-     * The third argument is the start or end byte.
33
-     *
34
-     * After a successful put operation, you may choose to return an ETag. The
35
-     * etag must always be surrounded by double-quotes. These quotes must
36
-     * appear in the actual string you're returning.
37
-     *
38
-     * Clients may use the ETag from a PUT request to later on make sure that
39
-     * when they update the file, the contents haven't changed in the mean
40
-     * time.
41
-     *
42
-     * @param resource|string $data
43
-     * @param int             $rangeType
44
-     * @param int             $offset
45
-     *
46
-     * @return string|null
47
-     */
48
-    public function patch($data, $rangeType, $offset = null);
20
+	/**
21
+	 * Updates the file based on a range specification.
22
+	 *
23
+	 * The first argument is the data, which is either a readable stream
24
+	 * resource or a string.
25
+	 *
26
+	 * The second argument is the type of update we're doing.
27
+	 * This is either:
28
+	 * * 1. append
29
+	 * * 2. update based on a start byte
30
+	 * * 3. update based on an end byte
31
+	 *;
32
+	 * The third argument is the start or end byte.
33
+	 *
34
+	 * After a successful put operation, you may choose to return an ETag. The
35
+	 * etag must always be surrounded by double-quotes. These quotes must
36
+	 * appear in the actual string you're returning.
37
+	 *
38
+	 * Clients may use the ETag from a PUT request to later on make sure that
39
+	 * when they update the file, the contents haven't changed in the mean
40
+	 * time.
41
+	 *
42
+	 * @param resource|string $data
43
+	 * @param int             $rangeType
44
+	 * @param int             $offset
45
+	 *
46
+	 * @return string|null
47
+	 */
48
+	public function patch($data, $rangeType, $offset = null);
49 49
 }
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/Browser/Plugin.php 2 patches
Indentation   +722 added lines, -722 removed lines patch added patch discarded remove patch
@@ -26,404 +26,404 @@  discard block
 block discarded – undo
26 26
  */
27 27
 class Plugin extends DAV\ServerPlugin
28 28
 {
29
-    /**
30
-     * reference to server class.
31
-     *
32
-     * @var DAV\Server
33
-     */
34
-    protected $server;
35
-
36
-    /**
37
-     * enablePost turns on the 'actions' panel, which allows people to create
38
-     * folders and upload files straight from a browser.
39
-     *
40
-     * @var bool
41
-     */
42
-    protected $enablePost = true;
43
-
44
-    /**
45
-     * A list of properties that are usually not interesting. This can cut down
46
-     * the browser output a bit by removing the properties that most people
47
-     * will likely not want to see.
48
-     *
49
-     * @var array
50
-     */
51
-    public $uninterestingProperties = [
52
-        '{DAV:}supportedlock',
53
-        '{DAV:}acl-restrictions',
29
+	/**
30
+	 * reference to server class.
31
+	 *
32
+	 * @var DAV\Server
33
+	 */
34
+	protected $server;
35
+
36
+	/**
37
+	 * enablePost turns on the 'actions' panel, which allows people to create
38
+	 * folders and upload files straight from a browser.
39
+	 *
40
+	 * @var bool
41
+	 */
42
+	protected $enablePost = true;
43
+
44
+	/**
45
+	 * A list of properties that are usually not interesting. This can cut down
46
+	 * the browser output a bit by removing the properties that most people
47
+	 * will likely not want to see.
48
+	 *
49
+	 * @var array
50
+	 */
51
+	public $uninterestingProperties = [
52
+		'{DAV:}supportedlock',
53
+		'{DAV:}acl-restrictions',
54 54
 //        '{DAV:}supported-privilege-set',
55
-        '{DAV:}supported-method-set',
56
-    ];
57
-
58
-    /**
59
-     * Creates the object.
60
-     *
61
-     * By default it will allow file creation and uploads.
62
-     * Specify the first argument as false to disable this
63
-     *
64
-     * @param bool $enablePost
65
-     */
66
-    public function __construct($enablePost = true)
67
-    {
68
-        $this->enablePost = $enablePost;
69
-    }
70
-
71
-    /**
72
-     * Initializes the plugin and subscribes to events.
73
-     */
74
-    public function initialize(DAV\Server $server)
75
-    {
76
-        $this->server = $server;
77
-        $this->server->on('method:GET', [$this, 'httpGetEarly'], 90);
78
-        $this->server->on('method:GET', [$this, 'httpGet'], 200);
79
-        $this->server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel'], 200);
80
-        if ($this->enablePost) {
81
-            $this->server->on('method:POST', [$this, 'httpPOST']);
82
-        }
83
-    }
84
-
85
-    /**
86
-     * This method intercepts GET requests that have ?sabreAction=info
87
-     * appended to the URL.
88
-     */
89
-    public function httpGetEarly(RequestInterface $request, ResponseInterface $response)
90
-    {
91
-        $params = $request->getQueryParameters();
92
-        if (isset($params['sabreAction']) && 'info' === $params['sabreAction']) {
93
-            return $this->httpGet($request, $response);
94
-        }
95
-    }
96
-
97
-    /**
98
-     * This method intercepts GET requests to collections and returns the html.
99
-     *
100
-     * @return bool
101
-     */
102
-    public function httpGet(RequestInterface $request, ResponseInterface $response)
103
-    {
104
-        // We're not using straight-up $_GET, because we want everything to be
105
-        // unit testable.
106
-        $getVars = $request->getQueryParameters();
107
-
108
-        // CSP headers
109
-        $response->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
110
-
111
-        $sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null;
112
-
113
-        switch ($sabreAction) {
114
-            case 'asset':
115
-                // Asset handling, such as images
116
-                $this->serveAsset(isset($getVars['assetName']) ? $getVars['assetName'] : null);
117
-
118
-                return false;
119
-            default:
120
-            case 'info':
121
-                try {
122
-                    $this->server->tree->getNodeForPath($request->getPath());
123
-                } catch (DAV\Exception\NotFound $e) {
124
-                    // We're simply stopping when the file isn't found to not interfere
125
-                    // with other plugins.
126
-                    return;
127
-                }
128
-
129
-                $response->setStatus(200);
130
-                $response->setHeader('Content-Type', 'text/html; charset=utf-8');
131
-
132
-                $response->setBody(
133
-                    $this->generateDirectoryIndex($request->getPath())
134
-                );
135
-
136
-                return false;
137
-
138
-            case 'plugins':
139
-                $response->setStatus(200);
140
-                $response->setHeader('Content-Type', 'text/html; charset=utf-8');
141
-
142
-                $response->setBody(
143
-                    $this->generatePluginListing()
144
-                );
145
-
146
-                return false;
147
-        }
148
-    }
149
-
150
-    /**
151
-     * Handles POST requests for tree operations.
152
-     *
153
-     * @return bool
154
-     */
155
-    public function httpPOST(RequestInterface $request, ResponseInterface $response)
156
-    {
157
-        $contentType = $request->getHeader('Content-Type');
158
-        if (!\is_string($contentType)) {
159
-            return;
160
-        }
161
-        list($contentType) = explode(';', $contentType);
162
-        if ('application/x-www-form-urlencoded' !== $contentType &&
163
-            'multipart/form-data' !== $contentType) {
164
-            return;
165
-        }
166
-        $postVars = $request->getPostData();
167
-
168
-        if (!isset($postVars['sabreAction'])) {
169
-            return;
170
-        }
171
-
172
-        $uri = $request->getPath();
173
-
174
-        if ($this->server->emit('onBrowserPostAction', [$uri, $postVars['sabreAction'], $postVars])) {
175
-            switch ($postVars['sabreAction']) {
176
-                case 'mkcol':
177
-                    if (isset($postVars['name']) && trim($postVars['name'])) {
178
-                        // Using basename() because we won't allow slashes
179
-                        list(, $folderName) = Uri\split(trim($postVars['name']));
180
-
181
-                        if (isset($postVars['resourceType'])) {
182
-                            $resourceType = explode(',', $postVars['resourceType']);
183
-                        } else {
184
-                            $resourceType = ['{DAV:}collection'];
185
-                        }
186
-
187
-                        $properties = [];
188
-                        foreach ($postVars as $varName => $varValue) {
189
-                            // Any _POST variable in clark notation is treated
190
-                            // like a property.
191
-                            if ('{' === $varName[0]) {
192
-                                // PHP will convert any dots to underscores.
193
-                                // This leaves us with no way to differentiate
194
-                                // the two.
195
-                                // Therefore we replace the string *DOT* with a
196
-                                // real dot. * is not allowed in uris so we
197
-                                // should be good.
198
-                                $varName = str_replace('*DOT*', '.', $varName);
199
-                                $properties[$varName] = $varValue;
200
-                            }
201
-                        }
202
-
203
-                        $mkCol = new MkCol(
204
-                            $resourceType,
205
-                            $properties
206
-                        );
207
-                        $this->server->createCollection($uri.'/'.$folderName, $mkCol);
208
-                    }
209
-                    break;
210
-
211
-                // @codeCoverageIgnoreStart
212
-                case 'put':
213
-                    if ($_FILES) {
214
-                        $file = current($_FILES);
215
-                    } else {
216
-                        break;
217
-                    }
218
-
219
-                    list(, $newName) = Uri\split(trim($file['name']));
220
-                    if (isset($postVars['name']) && trim($postVars['name'])) {
221
-                        $newName = trim($postVars['name']);
222
-                    }
223
-
224
-                    // Making sure we only have a 'basename' component
225
-                    list(, $newName) = Uri\split($newName);
226
-
227
-                    if (is_uploaded_file($file['tmp_name'])) {
228
-                        $this->server->createFile($uri.'/'.$newName, fopen($file['tmp_name'], 'r'));
229
-                    }
230
-                    break;
231
-                // @codeCoverageIgnoreEnd
232
-            }
233
-        }
234
-        $response->setHeader('Location', $request->getUrl());
235
-        $response->setStatus(302);
236
-
237
-        return false;
238
-    }
239
-
240
-    /**
241
-     * Escapes a string for html.
242
-     *
243
-     * @param string $value
244
-     *
245
-     * @return string
246
-     */
247
-    public function escapeHTML($value)
248
-    {
249
-        return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
250
-    }
251
-
252
-    /**
253
-     * Generates the html directory index for a given url.
254
-     *
255
-     * @param string $path
256
-     *
257
-     * @return string
258
-     */
259
-    public function generateDirectoryIndex($path)
260
-    {
261
-        $html = $this->generateHeader($path ? $path : '/', $path);
262
-
263
-        $node = $this->server->tree->getNodeForPath($path);
264
-        if ($node instanceof DAV\ICollection) {
265
-            $html .= "<section><h1>Nodes</h1>\n";
266
-            $html .= '<table class="nodeTable">';
267
-
268
-            $subNodes = $this->server->getPropertiesForChildren($path, [
269
-                '{DAV:}displayname',
270
-                '{DAV:}resourcetype',
271
-                '{DAV:}getcontenttype',
272
-                '{DAV:}getcontentlength',
273
-                '{DAV:}getlastmodified',
274
-            ]);
275
-
276
-            foreach ($subNodes as $subPath => $subProps) {
277
-                $subNode = $this->server->tree->getNodeForPath($subPath);
278
-                $fullPath = $this->server->getBaseUri().HTTP\encodePath($subPath);
279
-                list(, $displayPath) = Uri\split($subPath);
280
-
281
-                $subNodes[$subPath]['subNode'] = $subNode;
282
-                $subNodes[$subPath]['fullPath'] = $fullPath;
283
-                $subNodes[$subPath]['displayPath'] = $displayPath;
284
-            }
285
-            uasort($subNodes, [$this, 'compareNodes']);
286
-
287
-            foreach ($subNodes as $subProps) {
288
-                $type = [
289
-                    'string' => 'Unknown',
290
-                    'icon' => 'cog',
291
-                ];
292
-                if (isset($subProps['{DAV:}resourcetype'])) {
293
-                    $type = $this->mapResourceType($subProps['{DAV:}resourcetype']->getValue(), $subProps['subNode']);
294
-                }
295
-
296
-                $html .= '<tr>';
297
-                $html .= '<td class="nameColumn"><a href="'.$this->escapeHTML($subProps['fullPath']).'"><span class="oi" data-glyph="'.$this->escapeHTML($type['icon']).'"></span> '.$this->escapeHTML($subProps['displayPath']).'</a></td>';
298
-                $html .= '<td class="typeColumn">'.$this->escapeHTML($type['string']).'</td>';
299
-                $html .= '<td>';
300
-                if (isset($subProps['{DAV:}getcontentlength'])) {
301
-                    $html .= $this->escapeHTML($subProps['{DAV:}getcontentlength'].' bytes');
302
-                }
303
-                $html .= '</td><td>';
304
-                if (isset($subProps['{DAV:}getlastmodified'])) {
305
-                    $lastMod = $subProps['{DAV:}getlastmodified']->getTime();
306
-                    $html .= $this->escapeHTML($lastMod->format('F j, Y, g:i a'));
307
-                }
308
-                $html .= '</td><td>';
309
-                if (isset($subProps['{DAV:}displayname'])) {
310
-                    $html .= $this->escapeHTML($subProps['{DAV:}displayname']);
311
-                }
312
-                $html .= '</td>';
313
-
314
-                $buttonActions = '';
315
-                if ($subProps['subNode'] instanceof DAV\IFile) {
316
-                    $buttonActions = '<a href="'.$this->escapeHTML($subProps['fullPath']).'?sabreAction=info"><span class="oi" data-glyph="info"></span></a>';
317
-                }
318
-                $this->server->emit('browserButtonActions', [$subProps['fullPath'], $subProps['subNode'], &$buttonActions]);
319
-
320
-                $html .= '<td>'.$buttonActions.'</td>';
321
-                $html .= '</tr>';
322
-            }
323
-
324
-            $html .= '</table>';
325
-        }
326
-
327
-        $html .= '</section>';
328
-        $html .= '<section><h1>Properties</h1>';
329
-        $html .= '<table class="propTable">';
330
-
331
-        // Allprops request
332
-        $propFind = new PropFindAll($path);
333
-        $properties = $this->server->getPropertiesByNode($propFind, $node);
334
-
335
-        $properties = $propFind->getResultForMultiStatus()[200];
336
-
337
-        foreach ($properties as $propName => $propValue) {
338
-            if (!in_array($propName, $this->uninterestingProperties)) {
339
-                $html .= $this->drawPropertyRow($propName, $propValue);
340
-            }
341
-        }
342
-
343
-        $html .= '</table>';
344
-        $html .= '</section>';
345
-
346
-        /* Start of generating actions */
347
-
348
-        $output = '';
349
-        if ($this->enablePost) {
350
-            $this->server->emit('onHTMLActionsPanel', [$node, &$output, $path]);
351
-        }
352
-
353
-        if ($output) {
354
-            $html .= '<section><h1>Actions</h1>';
355
-            $html .= "<div class=\"actions\">\n";
356
-            $html .= $output;
357
-            $html .= "</div>\n";
358
-            $html .= "</section>\n";
359
-        }
360
-
361
-        $html .= $this->generateFooter();
362
-
363
-        $this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
364
-
365
-        return $html;
366
-    }
367
-
368
-    /**
369
-     * Generates the 'plugins' page.
370
-     *
371
-     * @return string
372
-     */
373
-    public function generatePluginListing()
374
-    {
375
-        $html = $this->generateHeader('Plugins');
376
-
377
-        $html .= '<section><h1>Plugins</h1>';
378
-        $html .= '<table class="propTable">';
379
-        foreach ($this->server->getPlugins() as $plugin) {
380
-            $info = $plugin->getPluginInfo();
381
-            $html .= '<tr><th>'.$info['name'].'</th>';
382
-            $html .= '<td>'.$info['description'].'</td>';
383
-            $html .= '<td>';
384
-            if (isset($info['link']) && $info['link']) {
385
-                $html .= '<a href="'.$this->escapeHTML($info['link']).'"><span class="oi" data-glyph="book"></span></a>';
386
-            }
387
-            $html .= '</td></tr>';
388
-        }
389
-        $html .= '</table>';
390
-        $html .= '</section>';
391
-
392
-        /* Start of generating actions */
393
-
394
-        $html .= $this->generateFooter();
395
-
396
-        return $html;
397
-    }
398
-
399
-    /**
400
-     * Generates the first block of HTML, including the <head> tag and page
401
-     * header.
402
-     *
403
-     * Returns footer.
404
-     *
405
-     * @param string $title
406
-     * @param string $path
407
-     *
408
-     * @return string
409
-     */
410
-    public function generateHeader($title, $path = null)
411
-    {
412
-        $version = '';
413
-        if (DAV\Server::$exposeVersion) {
414
-            $version = DAV\Version::VERSION;
415
-        }
416
-
417
-        $vars = [
418
-            'title' => $this->escapeHTML($title),
419
-            'favicon' => $this->escapeHTML($this->getAssetUrl('favicon.ico')),
420
-            'style' => $this->escapeHTML($this->getAssetUrl('sabredav.css')),
421
-            'iconstyle' => $this->escapeHTML($this->getAssetUrl('openiconic/open-iconic.css')),
422
-            'logo' => $this->escapeHTML($this->getAssetUrl('sabredav.png')),
423
-            'baseUrl' => $this->server->getBaseUri(),
424
-        ];
425
-
426
-        $html = <<<HTML
55
+		'{DAV:}supported-method-set',
56
+	];
57
+
58
+	/**
59
+	 * Creates the object.
60
+	 *
61
+	 * By default it will allow file creation and uploads.
62
+	 * Specify the first argument as false to disable this
63
+	 *
64
+	 * @param bool $enablePost
65
+	 */
66
+	public function __construct($enablePost = true)
67
+	{
68
+		$this->enablePost = $enablePost;
69
+	}
70
+
71
+	/**
72
+	 * Initializes the plugin and subscribes to events.
73
+	 */
74
+	public function initialize(DAV\Server $server)
75
+	{
76
+		$this->server = $server;
77
+		$this->server->on('method:GET', [$this, 'httpGetEarly'], 90);
78
+		$this->server->on('method:GET', [$this, 'httpGet'], 200);
79
+		$this->server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel'], 200);
80
+		if ($this->enablePost) {
81
+			$this->server->on('method:POST', [$this, 'httpPOST']);
82
+		}
83
+	}
84
+
85
+	/**
86
+	 * This method intercepts GET requests that have ?sabreAction=info
87
+	 * appended to the URL.
88
+	 */
89
+	public function httpGetEarly(RequestInterface $request, ResponseInterface $response)
90
+	{
91
+		$params = $request->getQueryParameters();
92
+		if (isset($params['sabreAction']) && 'info' === $params['sabreAction']) {
93
+			return $this->httpGet($request, $response);
94
+		}
95
+	}
96
+
97
+	/**
98
+	 * This method intercepts GET requests to collections and returns the html.
99
+	 *
100
+	 * @return bool
101
+	 */
102
+	public function httpGet(RequestInterface $request, ResponseInterface $response)
103
+	{
104
+		// We're not using straight-up $_GET, because we want everything to be
105
+		// unit testable.
106
+		$getVars = $request->getQueryParameters();
107
+
108
+		// CSP headers
109
+		$response->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
110
+
111
+		$sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null;
112
+
113
+		switch ($sabreAction) {
114
+			case 'asset':
115
+				// Asset handling, such as images
116
+				$this->serveAsset(isset($getVars['assetName']) ? $getVars['assetName'] : null);
117
+
118
+				return false;
119
+			default:
120
+			case 'info':
121
+				try {
122
+					$this->server->tree->getNodeForPath($request->getPath());
123
+				} catch (DAV\Exception\NotFound $e) {
124
+					// We're simply stopping when the file isn't found to not interfere
125
+					// with other plugins.
126
+					return;
127
+				}
128
+
129
+				$response->setStatus(200);
130
+				$response->setHeader('Content-Type', 'text/html; charset=utf-8');
131
+
132
+				$response->setBody(
133
+					$this->generateDirectoryIndex($request->getPath())
134
+				);
135
+
136
+				return false;
137
+
138
+			case 'plugins':
139
+				$response->setStatus(200);
140
+				$response->setHeader('Content-Type', 'text/html; charset=utf-8');
141
+
142
+				$response->setBody(
143
+					$this->generatePluginListing()
144
+				);
145
+
146
+				return false;
147
+		}
148
+	}
149
+
150
+	/**
151
+	 * Handles POST requests for tree operations.
152
+	 *
153
+	 * @return bool
154
+	 */
155
+	public function httpPOST(RequestInterface $request, ResponseInterface $response)
156
+	{
157
+		$contentType = $request->getHeader('Content-Type');
158
+		if (!\is_string($contentType)) {
159
+			return;
160
+		}
161
+		list($contentType) = explode(';', $contentType);
162
+		if ('application/x-www-form-urlencoded' !== $contentType &&
163
+			'multipart/form-data' !== $contentType) {
164
+			return;
165
+		}
166
+		$postVars = $request->getPostData();
167
+
168
+		if (!isset($postVars['sabreAction'])) {
169
+			return;
170
+		}
171
+
172
+		$uri = $request->getPath();
173
+
174
+		if ($this->server->emit('onBrowserPostAction', [$uri, $postVars['sabreAction'], $postVars])) {
175
+			switch ($postVars['sabreAction']) {
176
+				case 'mkcol':
177
+					if (isset($postVars['name']) && trim($postVars['name'])) {
178
+						// Using basename() because we won't allow slashes
179
+						list(, $folderName) = Uri\split(trim($postVars['name']));
180
+
181
+						if (isset($postVars['resourceType'])) {
182
+							$resourceType = explode(',', $postVars['resourceType']);
183
+						} else {
184
+							$resourceType = ['{DAV:}collection'];
185
+						}
186
+
187
+						$properties = [];
188
+						foreach ($postVars as $varName => $varValue) {
189
+							// Any _POST variable in clark notation is treated
190
+							// like a property.
191
+							if ('{' === $varName[0]) {
192
+								// PHP will convert any dots to underscores.
193
+								// This leaves us with no way to differentiate
194
+								// the two.
195
+								// Therefore we replace the string *DOT* with a
196
+								// real dot. * is not allowed in uris so we
197
+								// should be good.
198
+								$varName = str_replace('*DOT*', '.', $varName);
199
+								$properties[$varName] = $varValue;
200
+							}
201
+						}
202
+
203
+						$mkCol = new MkCol(
204
+							$resourceType,
205
+							$properties
206
+						);
207
+						$this->server->createCollection($uri.'/'.$folderName, $mkCol);
208
+					}
209
+					break;
210
+
211
+				// @codeCoverageIgnoreStart
212
+				case 'put':
213
+					if ($_FILES) {
214
+						$file = current($_FILES);
215
+					} else {
216
+						break;
217
+					}
218
+
219
+					list(, $newName) = Uri\split(trim($file['name']));
220
+					if (isset($postVars['name']) && trim($postVars['name'])) {
221
+						$newName = trim($postVars['name']);
222
+					}
223
+
224
+					// Making sure we only have a 'basename' component
225
+					list(, $newName) = Uri\split($newName);
226
+
227
+					if (is_uploaded_file($file['tmp_name'])) {
228
+						$this->server->createFile($uri.'/'.$newName, fopen($file['tmp_name'], 'r'));
229
+					}
230
+					break;
231
+				// @codeCoverageIgnoreEnd
232
+			}
233
+		}
234
+		$response->setHeader('Location', $request->getUrl());
235
+		$response->setStatus(302);
236
+
237
+		return false;
238
+	}
239
+
240
+	/**
241
+	 * Escapes a string for html.
242
+	 *
243
+	 * @param string $value
244
+	 *
245
+	 * @return string
246
+	 */
247
+	public function escapeHTML($value)
248
+	{
249
+		return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
250
+	}
251
+
252
+	/**
253
+	 * Generates the html directory index for a given url.
254
+	 *
255
+	 * @param string $path
256
+	 *
257
+	 * @return string
258
+	 */
259
+	public function generateDirectoryIndex($path)
260
+	{
261
+		$html = $this->generateHeader($path ? $path : '/', $path);
262
+
263
+		$node = $this->server->tree->getNodeForPath($path);
264
+		if ($node instanceof DAV\ICollection) {
265
+			$html .= "<section><h1>Nodes</h1>\n";
266
+			$html .= '<table class="nodeTable">';
267
+
268
+			$subNodes = $this->server->getPropertiesForChildren($path, [
269
+				'{DAV:}displayname',
270
+				'{DAV:}resourcetype',
271
+				'{DAV:}getcontenttype',
272
+				'{DAV:}getcontentlength',
273
+				'{DAV:}getlastmodified',
274
+			]);
275
+
276
+			foreach ($subNodes as $subPath => $subProps) {
277
+				$subNode = $this->server->tree->getNodeForPath($subPath);
278
+				$fullPath = $this->server->getBaseUri().HTTP\encodePath($subPath);
279
+				list(, $displayPath) = Uri\split($subPath);
280
+
281
+				$subNodes[$subPath]['subNode'] = $subNode;
282
+				$subNodes[$subPath]['fullPath'] = $fullPath;
283
+				$subNodes[$subPath]['displayPath'] = $displayPath;
284
+			}
285
+			uasort($subNodes, [$this, 'compareNodes']);
286
+
287
+			foreach ($subNodes as $subProps) {
288
+				$type = [
289
+					'string' => 'Unknown',
290
+					'icon' => 'cog',
291
+				];
292
+				if (isset($subProps['{DAV:}resourcetype'])) {
293
+					$type = $this->mapResourceType($subProps['{DAV:}resourcetype']->getValue(), $subProps['subNode']);
294
+				}
295
+
296
+				$html .= '<tr>';
297
+				$html .= '<td class="nameColumn"><a href="'.$this->escapeHTML($subProps['fullPath']).'"><span class="oi" data-glyph="'.$this->escapeHTML($type['icon']).'"></span> '.$this->escapeHTML($subProps['displayPath']).'</a></td>';
298
+				$html .= '<td class="typeColumn">'.$this->escapeHTML($type['string']).'</td>';
299
+				$html .= '<td>';
300
+				if (isset($subProps['{DAV:}getcontentlength'])) {
301
+					$html .= $this->escapeHTML($subProps['{DAV:}getcontentlength'].' bytes');
302
+				}
303
+				$html .= '</td><td>';
304
+				if (isset($subProps['{DAV:}getlastmodified'])) {
305
+					$lastMod = $subProps['{DAV:}getlastmodified']->getTime();
306
+					$html .= $this->escapeHTML($lastMod->format('F j, Y, g:i a'));
307
+				}
308
+				$html .= '</td><td>';
309
+				if (isset($subProps['{DAV:}displayname'])) {
310
+					$html .= $this->escapeHTML($subProps['{DAV:}displayname']);
311
+				}
312
+				$html .= '</td>';
313
+
314
+				$buttonActions = '';
315
+				if ($subProps['subNode'] instanceof DAV\IFile) {
316
+					$buttonActions = '<a href="'.$this->escapeHTML($subProps['fullPath']).'?sabreAction=info"><span class="oi" data-glyph="info"></span></a>';
317
+				}
318
+				$this->server->emit('browserButtonActions', [$subProps['fullPath'], $subProps['subNode'], &$buttonActions]);
319
+
320
+				$html .= '<td>'.$buttonActions.'</td>';
321
+				$html .= '</tr>';
322
+			}
323
+
324
+			$html .= '</table>';
325
+		}
326
+
327
+		$html .= '</section>';
328
+		$html .= '<section><h1>Properties</h1>';
329
+		$html .= '<table class="propTable">';
330
+
331
+		// Allprops request
332
+		$propFind = new PropFindAll($path);
333
+		$properties = $this->server->getPropertiesByNode($propFind, $node);
334
+
335
+		$properties = $propFind->getResultForMultiStatus()[200];
336
+
337
+		foreach ($properties as $propName => $propValue) {
338
+			if (!in_array($propName, $this->uninterestingProperties)) {
339
+				$html .= $this->drawPropertyRow($propName, $propValue);
340
+			}
341
+		}
342
+
343
+		$html .= '</table>';
344
+		$html .= '</section>';
345
+
346
+		/* Start of generating actions */
347
+
348
+		$output = '';
349
+		if ($this->enablePost) {
350
+			$this->server->emit('onHTMLActionsPanel', [$node, &$output, $path]);
351
+		}
352
+
353
+		if ($output) {
354
+			$html .= '<section><h1>Actions</h1>';
355
+			$html .= "<div class=\"actions\">\n";
356
+			$html .= $output;
357
+			$html .= "</div>\n";
358
+			$html .= "</section>\n";
359
+		}
360
+
361
+		$html .= $this->generateFooter();
362
+
363
+		$this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
364
+
365
+		return $html;
366
+	}
367
+
368
+	/**
369
+	 * Generates the 'plugins' page.
370
+	 *
371
+	 * @return string
372
+	 */
373
+	public function generatePluginListing()
374
+	{
375
+		$html = $this->generateHeader('Plugins');
376
+
377
+		$html .= '<section><h1>Plugins</h1>';
378
+		$html .= '<table class="propTable">';
379
+		foreach ($this->server->getPlugins() as $plugin) {
380
+			$info = $plugin->getPluginInfo();
381
+			$html .= '<tr><th>'.$info['name'].'</th>';
382
+			$html .= '<td>'.$info['description'].'</td>';
383
+			$html .= '<td>';
384
+			if (isset($info['link']) && $info['link']) {
385
+				$html .= '<a href="'.$this->escapeHTML($info['link']).'"><span class="oi" data-glyph="book"></span></a>';
386
+			}
387
+			$html .= '</td></tr>';
388
+		}
389
+		$html .= '</table>';
390
+		$html .= '</section>';
391
+
392
+		/* Start of generating actions */
393
+
394
+		$html .= $this->generateFooter();
395
+
396
+		return $html;
397
+	}
398
+
399
+	/**
400
+	 * Generates the first block of HTML, including the <head> tag and page
401
+	 * header.
402
+	 *
403
+	 * Returns footer.
404
+	 *
405
+	 * @param string $title
406
+	 * @param string $path
407
+	 *
408
+	 * @return string
409
+	 */
410
+	public function generateHeader($title, $path = null)
411
+	{
412
+		$version = '';
413
+		if (DAV\Server::$exposeVersion) {
414
+			$version = DAV\Version::VERSION;
415
+		}
416
+
417
+		$vars = [
418
+			'title' => $this->escapeHTML($title),
419
+			'favicon' => $this->escapeHTML($this->getAssetUrl('favicon.ico')),
420
+			'style' => $this->escapeHTML($this->getAssetUrl('sabredav.css')),
421
+			'iconstyle' => $this->escapeHTML($this->getAssetUrl('openiconic/open-iconic.css')),
422
+			'logo' => $this->escapeHTML($this->getAssetUrl('sabredav.png')),
423
+			'baseUrl' => $this->server->getBaseUri(),
424
+		];
425
+
426
+		$html = <<<HTML
427 427
 <!DOCTYPE html>
428 428
 <html>
429 429
 <head>
@@ -443,67 +443,67 @@  discard block
 block discarded – undo
443 443
     <nav>
444 444
 HTML;
445 445
 
446
-        // If the path is empty, there's no parent.
447
-        if ($path) {
448
-            list($parentUri) = Uri\split($path);
449
-            $fullPath = $this->server->getBaseUri().HTTP\encodePath($parentUri);
450
-            $html .= '<a href="'.$fullPath.'" class="btn">⇤ Go to parent</a>';
451
-        } else {
452
-            $html .= '<span class="btn disabled">⇤ Go to parent</span>';
453
-        }
454
-
455
-        $html .= ' <a href="?sabreAction=plugins" class="btn"><span class="oi" data-glyph="puzzle-piece"></span> Plugins</a>';
456
-
457
-        $html .= '</nav>';
458
-
459
-        return $html;
460
-    }
461
-
462
-    /**
463
-     * Generates the page footer.
464
-     *
465
-     * Returns html.
466
-     *
467
-     * @return string
468
-     */
469
-    public function generateFooter()
470
-    {
471
-        $version = '';
472
-        if (DAV\Server::$exposeVersion) {
473
-            $version = DAV\Version::VERSION;
474
-        }
475
-        $year = date('Y');
476
-
477
-        return <<<HTML
446
+		// If the path is empty, there's no parent.
447
+		if ($path) {
448
+			list($parentUri) = Uri\split($path);
449
+			$fullPath = $this->server->getBaseUri().HTTP\encodePath($parentUri);
450
+			$html .= '<a href="'.$fullPath.'" class="btn">⇤ Go to parent</a>';
451
+		} else {
452
+			$html .= '<span class="btn disabled">⇤ Go to parent</span>';
453
+		}
454
+
455
+		$html .= ' <a href="?sabreAction=plugins" class="btn"><span class="oi" data-glyph="puzzle-piece"></span> Plugins</a>';
456
+
457
+		$html .= '</nav>';
458
+
459
+		return $html;
460
+	}
461
+
462
+	/**
463
+	 * Generates the page footer.
464
+	 *
465
+	 * Returns html.
466
+	 *
467
+	 * @return string
468
+	 */
469
+	public function generateFooter()
470
+	{
471
+		$version = '';
472
+		if (DAV\Server::$exposeVersion) {
473
+			$version = DAV\Version::VERSION;
474
+		}
475
+		$year = date('Y');
476
+
477
+		return <<<HTML
478 478
 <footer>Generated by SabreDAV $version (c)2007-$year <a href="http://sabre.io/">http://sabre.io/</a></footer>
479 479
 </body>
480 480
 </html>
481 481
 HTML;
482
-    }
483
-
484
-    /**
485
-     * This method is used to generate the 'actions panel' output for
486
-     * collections.
487
-     *
488
-     * This specifically generates the interfaces for creating new files, and
489
-     * creating new directories.
490
-     *
491
-     * @param mixed  $output
492
-     * @param string $path
493
-     */
494
-    public function htmlActionsPanel(DAV\INode $node, &$output, $path)
495
-    {
496
-        if (!$node instanceof DAV\ICollection) {
497
-            return;
498
-        }
499
-
500
-        // We also know fairly certain that if an object is a non-extended
501
-        // SimpleCollection, we won't need to show the panel either.
502
-        if ('Sabre\\DAV\\SimpleCollection' === get_class($node)) {
503
-            return;
504
-        }
505
-
506
-        $output .= <<<HTML
482
+	}
483
+
484
+	/**
485
+	 * This method is used to generate the 'actions panel' output for
486
+	 * collections.
487
+	 *
488
+	 * This specifically generates the interfaces for creating new files, and
489
+	 * creating new directories.
490
+	 *
491
+	 * @param mixed  $output
492
+	 * @param string $path
493
+	 */
494
+	public function htmlActionsPanel(DAV\INode $node, &$output, $path)
495
+	{
496
+		if (!$node instanceof DAV\ICollection) {
497
+			return;
498
+		}
499
+
500
+		// We also know fairly certain that if an object is a non-extended
501
+		// SimpleCollection, we won't need to show the panel either.
502
+		if ('Sabre\\DAV\\SimpleCollection' === get_class($node)) {
503
+			return;
504
+		}
505
+
506
+		$output .= <<<HTML
507 507
 <form method="post" action="">
508 508
 <h3>Create new folder</h3>
509 509
 <input type="hidden" name="sabreAction" value="mkcol" />
@@ -518,272 +518,272 @@  discard block
 block discarded – undo
518 518
 <input type="submit" value="upload" />
519 519
 </form>
520 520
 HTML;
521
-    }
522
-
523
-    /**
524
-     * This method takes a path/name of an asset and turns it into url
525
-     * suiteable for http access.
526
-     *
527
-     * @param string $assetName
528
-     *
529
-     * @return string
530
-     */
531
-    protected function getAssetUrl($assetName)
532
-    {
533
-        return $this->server->getBaseUri().'?sabreAction=asset&assetName='.urlencode($assetName);
534
-    }
535
-
536
-    /**
537
-     * This method returns a local pathname to an asset.
538
-     *
539
-     * @param string $assetName
540
-     *
541
-     * @throws DAV\Exception\NotFound
542
-     *
543
-     * @return string
544
-     */
545
-    protected function getLocalAssetPath($assetName)
546
-    {
547
-        $assetDir = __DIR__.'/assets/';
548
-        $path = $assetDir.$assetName;
549
-
550
-        // Making sure people aren't trying to escape from the base path.
551
-        $path = str_replace('\\', '/', $path);
552
-        if (false !== strpos($path, '/../') || '/..' === strrchr($path, '/')) {
553
-            throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected');
554
-        }
555
-        $realPath = realpath($path);
556
-        if ($realPath && 0 === strpos($realPath, realpath($assetDir)) && file_exists($path)) {
557
-            return $path;
558
-        }
559
-        throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected');
560
-    }
561
-
562
-    /**
563
-     * This method reads an asset from disk and generates a full http response.
564
-     *
565
-     * @param string $assetName
566
-     */
567
-    protected function serveAsset($assetName)
568
-    {
569
-        $assetPath = $this->getLocalAssetPath($assetName);
570
-
571
-        // Rudimentary mime type detection
572
-        $mime = 'application/octet-stream';
573
-        $map = [
574
-            'ico' => 'image/vnd.microsoft.icon',
575
-            'png' => 'image/png',
576
-            'css' => 'text/css',
577
-        ];
578
-
579
-        $ext = substr($assetName, strrpos($assetName, '.') + 1);
580
-        if (isset($map[$ext])) {
581
-            $mime = $map[$ext];
582
-        }
583
-
584
-        $this->server->httpResponse->setHeader('Content-Type', $mime);
585
-        $this->server->httpResponse->setHeader('Content-Length', filesize($assetPath));
586
-        $this->server->httpResponse->setHeader('Cache-Control', 'public, max-age=1209600');
587
-        $this->server->httpResponse->setStatus(200);
588
-        $this->server->httpResponse->setBody(fopen($assetPath, 'r'));
589
-    }
590
-
591
-    /**
592
-     * Sort helper function: compares two directory entries based on type and
593
-     * display name. Collections sort above other types.
594
-     *
595
-     * @param array $a
596
-     * @param array $b
597
-     *
598
-     * @return int
599
-     */
600
-    protected function compareNodes($a, $b)
601
-    {
602
-        $typeA = (isset($a['{DAV:}resourcetype']))
603
-            ? (in_array('{DAV:}collection', $a['{DAV:}resourcetype']->getValue()))
604
-            : false;
605
-
606
-        $typeB = (isset($b['{DAV:}resourcetype']))
607
-            ? (in_array('{DAV:}collection', $b['{DAV:}resourcetype']->getValue()))
608
-            : false;
609
-
610
-        // If same type, sort alphabetically by filename:
611
-        if ($typeA === $typeB) {
612
-            return strnatcasecmp($a['displayPath'], $b['displayPath']);
613
-        }
614
-
615
-        return ($typeA < $typeB) ? 1 : -1;
616
-    }
617
-
618
-    /**
619
-     * Maps a resource type to a human-readable string and icon.
620
-     *
621
-     * @param DAV\INode $node
622
-     *
623
-     * @return array
624
-     */
625
-    private function mapResourceType(array $resourceTypes, $node)
626
-    {
627
-        if (!$resourceTypes) {
628
-            if ($node instanceof DAV\IFile) {
629
-                return [
630
-                    'string' => 'File',
631
-                    'icon' => 'file',
632
-                ];
633
-            } else {
634
-                return [
635
-                    'string' => 'Unknown',
636
-                    'icon' => 'cog',
637
-                ];
638
-            }
639
-        }
640
-
641
-        $types = [
642
-            '{http://calendarserver.org/ns/}calendar-proxy-write' => [
643
-                'string' => 'Proxy-Write',
644
-                'icon' => 'people',
645
-            ],
646
-            '{http://calendarserver.org/ns/}calendar-proxy-read' => [
647
-                'string' => 'Proxy-Read',
648
-                'icon' => 'people',
649
-            ],
650
-            '{urn:ietf:params:xml:ns:caldav}schedule-outbox' => [
651
-                'string' => 'Outbox',
652
-                'icon' => 'inbox',
653
-            ],
654
-            '{urn:ietf:params:xml:ns:caldav}schedule-inbox' => [
655
-                'string' => 'Inbox',
656
-                'icon' => 'inbox',
657
-            ],
658
-            '{urn:ietf:params:xml:ns:caldav}calendar' => [
659
-                'string' => 'Calendar',
660
-                'icon' => 'calendar',
661
-            ],
662
-            '{http://calendarserver.org/ns/}shared-owner' => [
663
-                'string' => 'Shared',
664
-                'icon' => 'calendar',
665
-            ],
666
-            '{http://calendarserver.org/ns/}subscribed' => [
667
-                'string' => 'Subscription',
668
-                'icon' => 'calendar',
669
-            ],
670
-            '{urn:ietf:params:xml:ns:carddav}directory' => [
671
-                'string' => 'Directory',
672
-                'icon' => 'globe',
673
-            ],
674
-            '{urn:ietf:params:xml:ns:carddav}addressbook' => [
675
-                'string' => 'Address book',
676
-                'icon' => 'book',
677
-            ],
678
-            '{DAV:}principal' => [
679
-                'string' => 'Principal',
680
-                'icon' => 'person',
681
-            ],
682
-            '{DAV:}collection' => [
683
-                'string' => 'Collection',
684
-                'icon' => 'folder',
685
-            ],
686
-        ];
687
-
688
-        $info = [
689
-            'string' => [],
690
-            'icon' => 'cog',
691
-        ];
692
-        foreach ($resourceTypes as $k => $resourceType) {
693
-            if (isset($types[$resourceType])) {
694
-                $info['string'][] = $types[$resourceType]['string'];
695
-            } else {
696
-                $info['string'][] = $resourceType;
697
-            }
698
-        }
699
-        foreach ($types as $key => $resourceInfo) {
700
-            if (in_array($key, $resourceTypes)) {
701
-                $info['icon'] = $resourceInfo['icon'];
702
-                break;
703
-            }
704
-        }
705
-        $info['string'] = implode(', ', $info['string']);
706
-
707
-        return $info;
708
-    }
709
-
710
-    /**
711
-     * Draws a table row for a property.
712
-     *
713
-     * @param string $name
714
-     * @param mixed  $value
715
-     *
716
-     * @return string
717
-     */
718
-    private function drawPropertyRow($name, $value)
719
-    {
720
-        $html = new HtmlOutputHelper(
721
-            $this->server->getBaseUri(),
722
-            $this->server->xml->namespaceMap
723
-        );
724
-
725
-        return '<tr><th>'.$html->xmlName($name).'</th><td>'.$this->drawPropertyValue($html, $value).'</td></tr>';
726
-    }
727
-
728
-    /**
729
-     * Draws a table row for a property.
730
-     *
731
-     * @param HtmlOutputHelper $html
732
-     * @param mixed            $value
733
-     *
734
-     * @return string
735
-     */
736
-    private function drawPropertyValue($html, $value)
737
-    {
738
-        if (is_scalar($value)) {
739
-            return $html->h($value);
740
-        } elseif ($value instanceof HtmlOutput) {
741
-            return $value->toHtml($html);
742
-        } elseif ($value instanceof \Sabre\Xml\XmlSerializable) {
743
-            // There's no default html output for this property, we're going
744
-            // to output the actual xml serialization instead.
745
-            $xml = $this->server->xml->write('{DAV:}root', $value, $this->server->getBaseUri());
746
-            // removing first and last line, as they contain our root
747
-            // element.
748
-            $xml = explode("\n", $xml);
749
-            $xml = array_slice($xml, 2, -2);
750
-
751
-            return '<pre>'.$html->h(implode("\n", $xml)).'</pre>';
752
-        } else {
753
-            return '<em>unknown</em>';
754
-        }
755
-    }
756
-
757
-    /**
758
-     * Returns a plugin name.
759
-     *
760
-     * Using this name other plugins will be able to access other plugins;
761
-     * using \Sabre\DAV\Server::getPlugin
762
-     *
763
-     * @return string
764
-     */
765
-    public function getPluginName()
766
-    {
767
-        return 'browser';
768
-    }
769
-
770
-    /**
771
-     * Returns a bunch of meta-data about the plugin.
772
-     *
773
-     * Providing this information is optional, and is mainly displayed by the
774
-     * Browser plugin.
775
-     *
776
-     * The description key in the returned array may contain html and will not
777
-     * be sanitized.
778
-     *
779
-     * @return array
780
-     */
781
-    public function getPluginInfo()
782
-    {
783
-        return [
784
-            'name' => $this->getPluginName(),
785
-            'description' => 'Generates HTML indexes and debug information for your sabre/dav server',
786
-            'link' => 'http://sabre.io/dav/browser-plugin/',
787
-        ];
788
-    }
521
+	}
522
+
523
+	/**
524
+	 * This method takes a path/name of an asset and turns it into url
525
+	 * suiteable for http access.
526
+	 *
527
+	 * @param string $assetName
528
+	 *
529
+	 * @return string
530
+	 */
531
+	protected function getAssetUrl($assetName)
532
+	{
533
+		return $this->server->getBaseUri().'?sabreAction=asset&assetName='.urlencode($assetName);
534
+	}
535
+
536
+	/**
537
+	 * This method returns a local pathname to an asset.
538
+	 *
539
+	 * @param string $assetName
540
+	 *
541
+	 * @throws DAV\Exception\NotFound
542
+	 *
543
+	 * @return string
544
+	 */
545
+	protected function getLocalAssetPath($assetName)
546
+	{
547
+		$assetDir = __DIR__.'/assets/';
548
+		$path = $assetDir.$assetName;
549
+
550
+		// Making sure people aren't trying to escape from the base path.
551
+		$path = str_replace('\\', '/', $path);
552
+		if (false !== strpos($path, '/../') || '/..' === strrchr($path, '/')) {
553
+			throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected');
554
+		}
555
+		$realPath = realpath($path);
556
+		if ($realPath && 0 === strpos($realPath, realpath($assetDir)) && file_exists($path)) {
557
+			return $path;
558
+		}
559
+		throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected');
560
+	}
561
+
562
+	/**
563
+	 * This method reads an asset from disk and generates a full http response.
564
+	 *
565
+	 * @param string $assetName
566
+	 */
567
+	protected function serveAsset($assetName)
568
+	{
569
+		$assetPath = $this->getLocalAssetPath($assetName);
570
+
571
+		// Rudimentary mime type detection
572
+		$mime = 'application/octet-stream';
573
+		$map = [
574
+			'ico' => 'image/vnd.microsoft.icon',
575
+			'png' => 'image/png',
576
+			'css' => 'text/css',
577
+		];
578
+
579
+		$ext = substr($assetName, strrpos($assetName, '.') + 1);
580
+		if (isset($map[$ext])) {
581
+			$mime = $map[$ext];
582
+		}
583
+
584
+		$this->server->httpResponse->setHeader('Content-Type', $mime);
585
+		$this->server->httpResponse->setHeader('Content-Length', filesize($assetPath));
586
+		$this->server->httpResponse->setHeader('Cache-Control', 'public, max-age=1209600');
587
+		$this->server->httpResponse->setStatus(200);
588
+		$this->server->httpResponse->setBody(fopen($assetPath, 'r'));
589
+	}
590
+
591
+	/**
592
+	 * Sort helper function: compares two directory entries based on type and
593
+	 * display name. Collections sort above other types.
594
+	 *
595
+	 * @param array $a
596
+	 * @param array $b
597
+	 *
598
+	 * @return int
599
+	 */
600
+	protected function compareNodes($a, $b)
601
+	{
602
+		$typeA = (isset($a['{DAV:}resourcetype']))
603
+			? (in_array('{DAV:}collection', $a['{DAV:}resourcetype']->getValue()))
604
+			: false;
605
+
606
+		$typeB = (isset($b['{DAV:}resourcetype']))
607
+			? (in_array('{DAV:}collection', $b['{DAV:}resourcetype']->getValue()))
608
+			: false;
609
+
610
+		// If same type, sort alphabetically by filename:
611
+		if ($typeA === $typeB) {
612
+			return strnatcasecmp($a['displayPath'], $b['displayPath']);
613
+		}
614
+
615
+		return ($typeA < $typeB) ? 1 : -1;
616
+	}
617
+
618
+	/**
619
+	 * Maps a resource type to a human-readable string and icon.
620
+	 *
621
+	 * @param DAV\INode $node
622
+	 *
623
+	 * @return array
624
+	 */
625
+	private function mapResourceType(array $resourceTypes, $node)
626
+	{
627
+		if (!$resourceTypes) {
628
+			if ($node instanceof DAV\IFile) {
629
+				return [
630
+					'string' => 'File',
631
+					'icon' => 'file',
632
+				];
633
+			} else {
634
+				return [
635
+					'string' => 'Unknown',
636
+					'icon' => 'cog',
637
+				];
638
+			}
639
+		}
640
+
641
+		$types = [
642
+			'{http://calendarserver.org/ns/}calendar-proxy-write' => [
643
+				'string' => 'Proxy-Write',
644
+				'icon' => 'people',
645
+			],
646
+			'{http://calendarserver.org/ns/}calendar-proxy-read' => [
647
+				'string' => 'Proxy-Read',
648
+				'icon' => 'people',
649
+			],
650
+			'{urn:ietf:params:xml:ns:caldav}schedule-outbox' => [
651
+				'string' => 'Outbox',
652
+				'icon' => 'inbox',
653
+			],
654
+			'{urn:ietf:params:xml:ns:caldav}schedule-inbox' => [
655
+				'string' => 'Inbox',
656
+				'icon' => 'inbox',
657
+			],
658
+			'{urn:ietf:params:xml:ns:caldav}calendar' => [
659
+				'string' => 'Calendar',
660
+				'icon' => 'calendar',
661
+			],
662
+			'{http://calendarserver.org/ns/}shared-owner' => [
663
+				'string' => 'Shared',
664
+				'icon' => 'calendar',
665
+			],
666
+			'{http://calendarserver.org/ns/}subscribed' => [
667
+				'string' => 'Subscription',
668
+				'icon' => 'calendar',
669
+			],
670
+			'{urn:ietf:params:xml:ns:carddav}directory' => [
671
+				'string' => 'Directory',
672
+				'icon' => 'globe',
673
+			],
674
+			'{urn:ietf:params:xml:ns:carddav}addressbook' => [
675
+				'string' => 'Address book',
676
+				'icon' => 'book',
677
+			],
678
+			'{DAV:}principal' => [
679
+				'string' => 'Principal',
680
+				'icon' => 'person',
681
+			],
682
+			'{DAV:}collection' => [
683
+				'string' => 'Collection',
684
+				'icon' => 'folder',
685
+			],
686
+		];
687
+
688
+		$info = [
689
+			'string' => [],
690
+			'icon' => 'cog',
691
+		];
692
+		foreach ($resourceTypes as $k => $resourceType) {
693
+			if (isset($types[$resourceType])) {
694
+				$info['string'][] = $types[$resourceType]['string'];
695
+			} else {
696
+				$info['string'][] = $resourceType;
697
+			}
698
+		}
699
+		foreach ($types as $key => $resourceInfo) {
700
+			if (in_array($key, $resourceTypes)) {
701
+				$info['icon'] = $resourceInfo['icon'];
702
+				break;
703
+			}
704
+		}
705
+		$info['string'] = implode(', ', $info['string']);
706
+
707
+		return $info;
708
+	}
709
+
710
+	/**
711
+	 * Draws a table row for a property.
712
+	 *
713
+	 * @param string $name
714
+	 * @param mixed  $value
715
+	 *
716
+	 * @return string
717
+	 */
718
+	private function drawPropertyRow($name, $value)
719
+	{
720
+		$html = new HtmlOutputHelper(
721
+			$this->server->getBaseUri(),
722
+			$this->server->xml->namespaceMap
723
+		);
724
+
725
+		return '<tr><th>'.$html->xmlName($name).'</th><td>'.$this->drawPropertyValue($html, $value).'</td></tr>';
726
+	}
727
+
728
+	/**
729
+	 * Draws a table row for a property.
730
+	 *
731
+	 * @param HtmlOutputHelper $html
732
+	 * @param mixed            $value
733
+	 *
734
+	 * @return string
735
+	 */
736
+	private function drawPropertyValue($html, $value)
737
+	{
738
+		if (is_scalar($value)) {
739
+			return $html->h($value);
740
+		} elseif ($value instanceof HtmlOutput) {
741
+			return $value->toHtml($html);
742
+		} elseif ($value instanceof \Sabre\Xml\XmlSerializable) {
743
+			// There's no default html output for this property, we're going
744
+			// to output the actual xml serialization instead.
745
+			$xml = $this->server->xml->write('{DAV:}root', $value, $this->server->getBaseUri());
746
+			// removing first and last line, as they contain our root
747
+			// element.
748
+			$xml = explode("\n", $xml);
749
+			$xml = array_slice($xml, 2, -2);
750
+
751
+			return '<pre>'.$html->h(implode("\n", $xml)).'</pre>';
752
+		} else {
753
+			return '<em>unknown</em>';
754
+		}
755
+	}
756
+
757
+	/**
758
+	 * Returns a plugin name.
759
+	 *
760
+	 * Using this name other plugins will be able to access other plugins;
761
+	 * using \Sabre\DAV\Server::getPlugin
762
+	 *
763
+	 * @return string
764
+	 */
765
+	public function getPluginName()
766
+	{
767
+		return 'browser';
768
+	}
769
+
770
+	/**
771
+	 * Returns a bunch of meta-data about the plugin.
772
+	 *
773
+	 * Providing this information is optional, and is mainly displayed by the
774
+	 * Browser plugin.
775
+	 *
776
+	 * The description key in the returned array may contain html and will not
777
+	 * be sanitized.
778
+	 *
779
+	 * @return array
780
+	 */
781
+	public function getPluginInfo()
782
+	{
783
+		return [
784
+			'name' => $this->getPluginName(),
785
+			'description' => 'Generates HTML indexes and debug information for your sabre/dav server',
786
+			'link' => 'http://sabre.io/dav/browser-plugin/',
787
+		];
788
+	}
789 789
 }
Please login to merge, or discard this patch.
Upper-Lower-Casing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
     </header>
442 442
 
443 443
     <nav>
444
-HTML;
444
+html;
445 445
 
446 446
         // If the path is empty, there's no parent.
447 447
         if ($path) {
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
 <footer>Generated by SabreDAV $version (c)2007-$year <a href="http://sabre.io/">http://sabre.io/</a></footer>
479 479
 </body>
480 480
 </html>
481
-HTML;
481
+html;
482 482
     }
483 483
 
484 484
     /**
@@ -517,7 +517,7 @@  discard block
 block discarded – undo
517 517
 <label>File:</label> <input type="file" name="file" /><br />
518 518
 <input type="submit" value="upload" />
519 519
 </form>
520
-HTML;
520
+html;
521 521
     }
522 522
 
523 523
     /**
Please login to merge, or discard this patch.
htdocs/includes/sabre/sabre/dav/lib/DAV/Browser/HtmlOutput.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -17,18 +17,18 @@
 block discarded – undo
17 17
  */
18 18
 interface HtmlOutput
19 19
 {
20
-    /**
21
-     * Generate html representation for this value.
22
-     *
23
-     * The html output is 100% trusted, and no effort is being made to sanitize
24
-     * it. It's up to the implementor to sanitize user provided values.
25
-     *
26
-     * The output must be in UTF-8.
27
-     *
28
-     * The baseUri parameter is a url to the root of the application, and can
29
-     * be used to construct local links.
30
-     *
31
-     * @return string
32
-     */
33
-    public function toHtml(HtmlOutputHelper $html);
20
+	/**
21
+	 * Generate html representation for this value.
22
+	 *
23
+	 * The html output is 100% trusted, and no effort is being made to sanitize
24
+	 * it. It's up to the implementor to sanitize user provided values.
25
+	 *
26
+	 * The output must be in UTF-8.
27
+	 *
28
+	 * The baseUri parameter is a url to the root of the application, and can
29
+	 * be used to construct local links.
30
+	 *
31
+	 * @return string
32
+	 */
33
+	public function toHtml(HtmlOutputHelper $html);
34 34
 }
Please login to merge, or discard this patch.