@@ -18,56 +18,56 @@ |
||
18 | 18 | */ |
19 | 19 | class NeedPrivileges extends DAV\Exception\Forbidden |
20 | 20 | { |
21 | - /** |
|
22 | - * The relevant uri. |
|
23 | - * |
|
24 | - * @var string |
|
25 | - */ |
|
26 | - protected $uri; |
|
21 | + /** |
|
22 | + * The relevant uri. |
|
23 | + * |
|
24 | + * @var string |
|
25 | + */ |
|
26 | + protected $uri; |
|
27 | 27 | |
28 | - /** |
|
29 | - * The privileges the user didn't have. |
|
30 | - * |
|
31 | - * @var array |
|
32 | - */ |
|
33 | - protected $privileges; |
|
28 | + /** |
|
29 | + * The privileges the user didn't have. |
|
30 | + * |
|
31 | + * @var array |
|
32 | + */ |
|
33 | + protected $privileges; |
|
34 | 34 | |
35 | - /** |
|
36 | - * Constructor. |
|
37 | - * |
|
38 | - * @param string $uri |
|
39 | - */ |
|
40 | - public function __construct($uri, array $privileges) |
|
41 | - { |
|
42 | - $this->uri = $uri; |
|
43 | - $this->privileges = $privileges; |
|
35 | + /** |
|
36 | + * Constructor. |
|
37 | + * |
|
38 | + * @param string $uri |
|
39 | + */ |
|
40 | + public function __construct($uri, array $privileges) |
|
41 | + { |
|
42 | + $this->uri = $uri; |
|
43 | + $this->privileges = $privileges; |
|
44 | 44 | |
45 | - parent::__construct('User did not have the required privileges ('.implode(',', $privileges).') for path "'.$uri.'"'); |
|
46 | - } |
|
45 | + parent::__construct('User did not have the required privileges ('.implode(',', $privileges).') for path "'.$uri.'"'); |
|
46 | + } |
|
47 | 47 | |
48 | - /** |
|
49 | - * Adds in extra information in the xml response. |
|
50 | - * |
|
51 | - * This method adds the {DAV:}need-privileges element as defined in rfc3744 |
|
52 | - */ |
|
53 | - public function serialize(DAV\Server $server, \DOMElement $errorNode) |
|
54 | - { |
|
55 | - $doc = $errorNode->ownerDocument; |
|
48 | + /** |
|
49 | + * Adds in extra information in the xml response. |
|
50 | + * |
|
51 | + * This method adds the {DAV:}need-privileges element as defined in rfc3744 |
|
52 | + */ |
|
53 | + public function serialize(DAV\Server $server, \DOMElement $errorNode) |
|
54 | + { |
|
55 | + $doc = $errorNode->ownerDocument; |
|
56 | 56 | |
57 | - $np = $doc->createElementNS('DAV:', 'd:need-privileges'); |
|
58 | - $errorNode->appendChild($np); |
|
57 | + $np = $doc->createElementNS('DAV:', 'd:need-privileges'); |
|
58 | + $errorNode->appendChild($np); |
|
59 | 59 | |
60 | - foreach ($this->privileges as $privilege) { |
|
61 | - $resource = $doc->createElementNS('DAV:', 'd:resource'); |
|
62 | - $np->appendChild($resource); |
|
60 | + foreach ($this->privileges as $privilege) { |
|
61 | + $resource = $doc->createElementNS('DAV:', 'd:resource'); |
|
62 | + $np->appendChild($resource); |
|
63 | 63 | |
64 | - $resource->appendChild($doc->createElementNS('DAV:', 'd:href', $server->getBaseUri().$this->uri)); |
|
64 | + $resource->appendChild($doc->createElementNS('DAV:', 'd:href', $server->getBaseUri().$this->uri)); |
|
65 | 65 | |
66 | - $priv = $doc->createElementNS('DAV:', 'd:privilege'); |
|
67 | - $resource->appendChild($priv); |
|
66 | + $priv = $doc->createElementNS('DAV:', 'd:privilege'); |
|
67 | + $resource->appendChild($priv); |
|
68 | 68 | |
69 | - preg_match('/^{([^}]*)}(.*)$/', $privilege, $privilegeParts); |
|
70 | - $priv->appendChild($doc->createElementNS($privilegeParts[1], 'd:'.$privilegeParts[2])); |
|
71 | - } |
|
72 | - } |
|
69 | + preg_match('/^{([^}]*)}(.*)$/', $privilege, $privilegeParts); |
|
70 | + $priv->appendChild($doc->createElementNS($privilegeParts[1], 'd:'.$privilegeParts[2])); |
|
71 | + } |
|
72 | + } |
|
73 | 73 | } |
@@ -18,47 +18,47 @@ |
||
18 | 18 | */ |
19 | 19 | interface IPrincipalCollection extends DAV\ICollection |
20 | 20 | { |
21 | - /** |
|
22 | - * This method is used to search for principals matching a set of |
|
23 | - * properties. |
|
24 | - * |
|
25 | - * This search is specifically used by RFC3744's principal-property-search |
|
26 | - * REPORT. You should at least allow searching on |
|
27 | - * http://sabredav.org/ns}email-address. |
|
28 | - * |
|
29 | - * The actual search should be a unicode-non-case-sensitive search. The |
|
30 | - * keys in searchProperties are the WebDAV property names, while the values |
|
31 | - * are the property values to search on. |
|
32 | - * |
|
33 | - * By default, if multiple properties are submitted to this method, the |
|
34 | - * various properties should be combined with 'AND'. If $test is set to |
|
35 | - * 'anyof', it should be combined using 'OR'. |
|
36 | - * |
|
37 | - * This method should simply return a list of 'child names', which may be |
|
38 | - * used to call $this->getChild in the future. |
|
39 | - * |
|
40 | - * @param string $test |
|
41 | - * |
|
42 | - * @return array |
|
43 | - */ |
|
44 | - public function searchPrincipals(array $searchProperties, $test = 'allof'); |
|
21 | + /** |
|
22 | + * This method is used to search for principals matching a set of |
|
23 | + * properties. |
|
24 | + * |
|
25 | + * This search is specifically used by RFC3744's principal-property-search |
|
26 | + * REPORT. You should at least allow searching on |
|
27 | + * http://sabredav.org/ns}email-address. |
|
28 | + * |
|
29 | + * The actual search should be a unicode-non-case-sensitive search. The |
|
30 | + * keys in searchProperties are the WebDAV property names, while the values |
|
31 | + * are the property values to search on. |
|
32 | + * |
|
33 | + * By default, if multiple properties are submitted to this method, the |
|
34 | + * various properties should be combined with 'AND'. If $test is set to |
|
35 | + * 'anyof', it should be combined using 'OR'. |
|
36 | + * |
|
37 | + * This method should simply return a list of 'child names', which may be |
|
38 | + * used to call $this->getChild in the future. |
|
39 | + * |
|
40 | + * @param string $test |
|
41 | + * |
|
42 | + * @return array |
|
43 | + */ |
|
44 | + public function searchPrincipals(array $searchProperties, $test = 'allof'); |
|
45 | 45 | |
46 | - /** |
|
47 | - * Finds a principal by its URI. |
|
48 | - * |
|
49 | - * This method may receive any type of uri, but mailto: addresses will be |
|
50 | - * the most common. |
|
51 | - * |
|
52 | - * Implementation of this API is optional. It is currently used by the |
|
53 | - * CalDAV system to find principals based on their email addresses. If this |
|
54 | - * API is not implemented, some features may not work correctly. |
|
55 | - * |
|
56 | - * This method must return a relative principal path, or null, if the |
|
57 | - * principal was not found or you refuse to find it. |
|
58 | - * |
|
59 | - * @param string $uri |
|
60 | - * |
|
61 | - * @return string |
|
62 | - */ |
|
63 | - public function findByUri($uri); |
|
46 | + /** |
|
47 | + * Finds a principal by its URI. |
|
48 | + * |
|
49 | + * This method may receive any type of uri, but mailto: addresses will be |
|
50 | + * the most common. |
|
51 | + * |
|
52 | + * Implementation of this API is optional. It is currently used by the |
|
53 | + * CalDAV system to find principals based on their email addresses. If this |
|
54 | + * API is not implemented, some features may not work correctly. |
|
55 | + * |
|
56 | + * This method must return a relative principal path, or null, if the |
|
57 | + * principal was not found or you refuse to find it. |
|
58 | + * |
|
59 | + * @param string $uri |
|
60 | + * |
|
61 | + * @return string |
|
62 | + */ |
|
63 | + public function findByUri($uri); |
|
64 | 64 | } |
@@ -16,14 +16,14 @@ |
||
16 | 16 | */ |
17 | 17 | interface CreatePrincipalSupport extends BackendInterface |
18 | 18 | { |
19 | - /** |
|
20 | - * Creates a new principal. |
|
21 | - * |
|
22 | - * This method receives a full path for the new principal. The mkCol object |
|
23 | - * contains any additional webdav properties specified during the creation |
|
24 | - * of the principal. |
|
25 | - * |
|
26 | - * @param string $path |
|
27 | - */ |
|
28 | - public function createPrincipal($path, MkCol $mkCol); |
|
19 | + /** |
|
20 | + * Creates a new principal. |
|
21 | + * |
|
22 | + * This method receives a full path for the new principal. The mkCol object |
|
23 | + * contains any additional webdav properties specified during the creation |
|
24 | + * of the principal. |
|
25 | + * |
|
26 | + * @param string $path |
|
27 | + */ |
|
28 | + public function createPrincipal($path, MkCol $mkCol); |
|
29 | 29 | } |
@@ -17,38 +17,38 @@ |
||
17 | 17 | */ |
18 | 18 | abstract class AbstractBackend implements BackendInterface |
19 | 19 | { |
20 | - /** |
|
21 | - * Finds a principal by its URI. |
|
22 | - * |
|
23 | - * This method may receive any type of uri, but mailto: addresses will be |
|
24 | - * the most common. |
|
25 | - * |
|
26 | - * Implementation of this API is optional. It is currently used by the |
|
27 | - * CalDAV system to find principals based on their email addresses. If this |
|
28 | - * API is not implemented, some features may not work correctly. |
|
29 | - * |
|
30 | - * This method must return a relative principal path, or null, if the |
|
31 | - * principal was not found or you refuse to find it. |
|
32 | - * |
|
33 | - * @param string $uri |
|
34 | - * @param string $principalPrefix |
|
35 | - * |
|
36 | - * @return string|null |
|
37 | - */ |
|
38 | - public function findByUri($uri, $principalPrefix) |
|
39 | - { |
|
40 | - // Note that the default implementation here is a bit slow and could |
|
41 | - // likely be optimized. |
|
42 | - if ('mailto:' !== substr($uri, 0, 7)) { |
|
43 | - return; |
|
44 | - } |
|
45 | - $result = $this->searchPrincipals( |
|
46 | - $principalPrefix, |
|
47 | - ['{http://sabredav.org/ns}email-address' => substr($uri, 7)] |
|
48 | - ); |
|
20 | + /** |
|
21 | + * Finds a principal by its URI. |
|
22 | + * |
|
23 | + * This method may receive any type of uri, but mailto: addresses will be |
|
24 | + * the most common. |
|
25 | + * |
|
26 | + * Implementation of this API is optional. It is currently used by the |
|
27 | + * CalDAV system to find principals based on their email addresses. If this |
|
28 | + * API is not implemented, some features may not work correctly. |
|
29 | + * |
|
30 | + * This method must return a relative principal path, or null, if the |
|
31 | + * principal was not found or you refuse to find it. |
|
32 | + * |
|
33 | + * @param string $uri |
|
34 | + * @param string $principalPrefix |
|
35 | + * |
|
36 | + * @return string|null |
|
37 | + */ |
|
38 | + public function findByUri($uri, $principalPrefix) |
|
39 | + { |
|
40 | + // Note that the default implementation here is a bit slow and could |
|
41 | + // likely be optimized. |
|
42 | + if ('mailto:' !== substr($uri, 0, 7)) { |
|
43 | + return; |
|
44 | + } |
|
45 | + $result = $this->searchPrincipals( |
|
46 | + $principalPrefix, |
|
47 | + ['{http://sabredav.org/ns}email-address' => substr($uri, 7)] |
|
48 | + ); |
|
49 | 49 | |
50 | - if ($result) { |
|
51 | - return $result[0]; |
|
52 | - } |
|
53 | - } |
|
50 | + if ($result) { |
|
51 | + return $result[0]; |
|
52 | + } |
|
53 | + } |
|
54 | 54 | } |
@@ -20,424 +20,424 @@ |
||
20 | 20 | */ |
21 | 21 | class PDO extends AbstractBackend implements CreatePrincipalSupport |
22 | 22 | { |
23 | - /** |
|
24 | - * PDO table name for 'principals'. |
|
25 | - * |
|
26 | - * @var string |
|
27 | - */ |
|
28 | - public $tableName = 'principals'; |
|
29 | - |
|
30 | - /** |
|
31 | - * PDO table name for 'group members'. |
|
32 | - * |
|
33 | - * @var string |
|
34 | - */ |
|
35 | - public $groupMembersTableName = 'groupmembers'; |
|
36 | - |
|
37 | - /** |
|
38 | - * pdo. |
|
39 | - * |
|
40 | - * @var PDO |
|
41 | - */ |
|
42 | - protected $pdo; |
|
43 | - |
|
44 | - /** |
|
45 | - * A list of additional fields to support. |
|
46 | - * |
|
47 | - * @var array |
|
48 | - */ |
|
49 | - protected $fieldMap = [ |
|
50 | - /* |
|
23 | + /** |
|
24 | + * PDO table name for 'principals'. |
|
25 | + * |
|
26 | + * @var string |
|
27 | + */ |
|
28 | + public $tableName = 'principals'; |
|
29 | + |
|
30 | + /** |
|
31 | + * PDO table name for 'group members'. |
|
32 | + * |
|
33 | + * @var string |
|
34 | + */ |
|
35 | + public $groupMembersTableName = 'groupmembers'; |
|
36 | + |
|
37 | + /** |
|
38 | + * pdo. |
|
39 | + * |
|
40 | + * @var PDO |
|
41 | + */ |
|
42 | + protected $pdo; |
|
43 | + |
|
44 | + /** |
|
45 | + * A list of additional fields to support. |
|
46 | + * |
|
47 | + * @var array |
|
48 | + */ |
|
49 | + protected $fieldMap = [ |
|
50 | + /* |
|
51 | 51 | * This property can be used to display the users' real name. |
52 | 52 | */ |
53 | - '{DAV:}displayname' => [ |
|
54 | - 'dbField' => 'displayname', |
|
55 | - ], |
|
53 | + '{DAV:}displayname' => [ |
|
54 | + 'dbField' => 'displayname', |
|
55 | + ], |
|
56 | 56 | |
57 | - /* |
|
57 | + /* |
|
58 | 58 | * This is the users' primary email-address. |
59 | 59 | */ |
60 | - '{http://sabredav.org/ns}email-address' => [ |
|
61 | - 'dbField' => 'email', |
|
62 | - ], |
|
63 | - ]; |
|
64 | - |
|
65 | - /** |
|
66 | - * Sets up the backend. |
|
67 | - */ |
|
68 | - public function __construct(\PDO $pdo) |
|
69 | - { |
|
70 | - $this->pdo = $pdo; |
|
71 | - } |
|
72 | - |
|
73 | - /** |
|
74 | - * Returns a list of principals based on a prefix. |
|
75 | - * |
|
76 | - * This prefix will often contain something like 'principals'. You are only |
|
77 | - * expected to return principals that are in this base path. |
|
78 | - * |
|
79 | - * You are expected to return at least a 'uri' for every user, you can |
|
80 | - * return any additional properties if you wish so. Common properties are: |
|
81 | - * {DAV:}displayname |
|
82 | - * {http://sabredav.org/ns}email-address - This is a custom SabreDAV |
|
83 | - * field that's actualy injected in a number of other properties. If |
|
84 | - * you have an email address, use this property. |
|
85 | - * |
|
86 | - * @param string $prefixPath |
|
87 | - * |
|
88 | - * @return array |
|
89 | - */ |
|
90 | - public function getPrincipalsByPrefix($prefixPath) |
|
91 | - { |
|
92 | - $fields = [ |
|
93 | - 'uri', |
|
94 | - ]; |
|
95 | - |
|
96 | - foreach ($this->fieldMap as $key => $value) { |
|
97 | - $fields[] = $value['dbField']; |
|
98 | - } |
|
99 | - $result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '.$this->tableName); |
|
100 | - |
|
101 | - $principals = []; |
|
102 | - |
|
103 | - while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { |
|
104 | - // Checking if the principal is in the prefix |
|
105 | - list($rowPrefix) = Uri\split($row['uri']); |
|
106 | - if ($rowPrefix !== $prefixPath) { |
|
107 | - continue; |
|
108 | - } |
|
109 | - |
|
110 | - $principal = [ |
|
111 | - 'uri' => $row['uri'], |
|
112 | - ]; |
|
113 | - foreach ($this->fieldMap as $key => $value) { |
|
114 | - if ($row[$value['dbField']]) { |
|
115 | - $principal[$key] = $row[$value['dbField']]; |
|
116 | - } |
|
117 | - } |
|
118 | - $principals[] = $principal; |
|
119 | - } |
|
120 | - |
|
121 | - return $principals; |
|
122 | - } |
|
123 | - |
|
124 | - /** |
|
125 | - * Returns a specific principal, specified by it's path. |
|
126 | - * The returned structure should be the exact same as from |
|
127 | - * getPrincipalsByPrefix. |
|
128 | - * |
|
129 | - * @param string $path |
|
130 | - * |
|
131 | - * @return array |
|
132 | - */ |
|
133 | - public function getPrincipalByPath($path) |
|
134 | - { |
|
135 | - $fields = [ |
|
136 | - 'id', |
|
137 | - 'uri', |
|
138 | - ]; |
|
139 | - |
|
140 | - foreach ($this->fieldMap as $key => $value) { |
|
141 | - $fields[] = $value['dbField']; |
|
142 | - } |
|
143 | - $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '.$this->tableName.' WHERE uri = ?'); |
|
144 | - $stmt->execute([$path]); |
|
145 | - |
|
146 | - $row = $stmt->fetch(\PDO::FETCH_ASSOC); |
|
147 | - if (!$row) { |
|
148 | - return; |
|
149 | - } |
|
150 | - |
|
151 | - $principal = [ |
|
152 | - 'id' => $row['id'], |
|
153 | - 'uri' => $row['uri'], |
|
154 | - ]; |
|
155 | - foreach ($this->fieldMap as $key => $value) { |
|
156 | - if ($row[$value['dbField']]) { |
|
157 | - $principal[$key] = $row[$value['dbField']]; |
|
158 | - } |
|
159 | - } |
|
160 | - |
|
161 | - return $principal; |
|
162 | - } |
|
163 | - |
|
164 | - /** |
|
165 | - * Updates one ore more webdav properties on a principal. |
|
166 | - * |
|
167 | - * The list of mutations is stored in a Sabre\DAV\PropPatch object. |
|
168 | - * To do the actual updates, you must tell this object which properties |
|
169 | - * you're going to process with the handle() method. |
|
170 | - * |
|
171 | - * Calling the handle method is like telling the PropPatch object "I |
|
172 | - * promise I can handle updating this property". |
|
173 | - * |
|
174 | - * Read the PropPatch documentation for more info and examples. |
|
175 | - * |
|
176 | - * @param string $path |
|
177 | - */ |
|
178 | - public function updatePrincipal($path, DAV\PropPatch $propPatch) |
|
179 | - { |
|
180 | - $propPatch->handle(array_keys($this->fieldMap), function ($properties) use ($path) { |
|
181 | - $query = 'UPDATE '.$this->tableName.' SET '; |
|
182 | - $first = true; |
|
183 | - |
|
184 | - $values = []; |
|
185 | - |
|
186 | - foreach ($properties as $key => $value) { |
|
187 | - $dbField = $this->fieldMap[$key]['dbField']; |
|
188 | - |
|
189 | - if (!$first) { |
|
190 | - $query .= ', '; |
|
191 | - } |
|
192 | - $first = false; |
|
193 | - $query .= $dbField.' = :'.$dbField; |
|
194 | - $values[$dbField] = $value; |
|
195 | - } |
|
196 | - |
|
197 | - $query .= ' WHERE uri = :uri'; |
|
198 | - $values['uri'] = $path; |
|
199 | - |
|
200 | - $stmt = $this->pdo->prepare($query); |
|
201 | - $stmt->execute($values); |
|
202 | - |
|
203 | - return true; |
|
204 | - }); |
|
205 | - } |
|
206 | - |
|
207 | - /** |
|
208 | - * This method is used to search for principals matching a set of |
|
209 | - * properties. |
|
210 | - * |
|
211 | - * This search is specifically used by RFC3744's principal-property-search |
|
212 | - * REPORT. |
|
213 | - * |
|
214 | - * The actual search should be a unicode-non-case-sensitive search. The |
|
215 | - * keys in searchProperties are the WebDAV property names, while the values |
|
216 | - * are the property values to search on. |
|
217 | - * |
|
218 | - * By default, if multiple properties are submitted to this method, the |
|
219 | - * various properties should be combined with 'AND'. If $test is set to |
|
220 | - * 'anyof', it should be combined using 'OR'. |
|
221 | - * |
|
222 | - * This method should simply return an array with full principal uri's. |
|
223 | - * |
|
224 | - * If somebody attempted to search on a property the backend does not |
|
225 | - * support, you should simply return 0 results. |
|
226 | - * |
|
227 | - * You can also just return 0 results if you choose to not support |
|
228 | - * searching at all, but keep in mind that this may stop certain features |
|
229 | - * from working. |
|
230 | - * |
|
231 | - * @param string $prefixPath |
|
232 | - * @param string $test |
|
233 | - * |
|
234 | - * @return array |
|
235 | - */ |
|
236 | - public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') |
|
237 | - { |
|
238 | - if (0 == count($searchProperties)) { |
|
239 | - return []; |
|
240 | - } //No criteria |
|
241 | - |
|
242 | - $query = 'SELECT uri FROM '.$this->tableName.' WHERE '; |
|
243 | - $values = []; |
|
244 | - foreach ($searchProperties as $property => $value) { |
|
245 | - switch ($property) { |
|
246 | - case '{DAV:}displayname': |
|
247 | - $column = 'displayname'; |
|
248 | - break; |
|
249 | - case '{http://sabredav.org/ns}email-address': |
|
250 | - $column = 'email'; |
|
251 | - break; |
|
252 | - default: |
|
253 | - // Unsupported property |
|
254 | - return []; |
|
255 | - } |
|
256 | - if (count($values) > 0) { |
|
257 | - $query .= (0 == strcmp($test, 'anyof') ? ' OR ' : ' AND '); |
|
258 | - } |
|
259 | - $query .= 'lower('.$column.') LIKE lower(?)'; |
|
260 | - $values[] = '%'.$value.'%'; |
|
261 | - } |
|
262 | - $stmt = $this->pdo->prepare($query); |
|
263 | - $stmt->execute($values); |
|
264 | - |
|
265 | - $principals = []; |
|
266 | - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
267 | - // Checking if the principal is in the prefix |
|
268 | - list($rowPrefix) = Uri\split($row['uri']); |
|
269 | - if ($rowPrefix !== $prefixPath) { |
|
270 | - continue; |
|
271 | - } |
|
272 | - |
|
273 | - $principals[] = $row['uri']; |
|
274 | - } |
|
275 | - |
|
276 | - return $principals; |
|
277 | - } |
|
278 | - |
|
279 | - /** |
|
280 | - * Finds a principal by its URI. |
|
281 | - * |
|
282 | - * This method may receive any type of uri, but mailto: addresses will be |
|
283 | - * the most common. |
|
284 | - * |
|
285 | - * Implementation of this API is optional. It is currently used by the |
|
286 | - * CalDAV system to find principals based on their email addresses. If this |
|
287 | - * API is not implemented, some features may not work correctly. |
|
288 | - * |
|
289 | - * This method must return a relative principal path, or null, if the |
|
290 | - * principal was not found or you refuse to find it. |
|
291 | - * |
|
292 | - * @param string $uri |
|
293 | - * @param string $principalPrefix |
|
294 | - * |
|
295 | - * @return string |
|
296 | - */ |
|
297 | - public function findByUri($uri, $principalPrefix) |
|
298 | - { |
|
299 | - $uriParts = Uri\parse($uri); |
|
300 | - |
|
301 | - // Only two types of uri are supported : |
|
302 | - // - the "mailto:" scheme with some non-empty address |
|
303 | - // - a principals uri, in the form "principals/NAME" |
|
304 | - // In both cases, `path` must not be empty. |
|
305 | - if (empty($uriParts['path'])) { |
|
306 | - return null; |
|
307 | - } |
|
308 | - |
|
309 | - $uri = null; |
|
310 | - if ('mailto' === $uriParts['scheme']) { |
|
311 | - $query = 'SELECT uri FROM '.$this->tableName.' WHERE lower(email)=lower(?)'; |
|
312 | - $stmt = $this->pdo->prepare($query); |
|
313 | - $stmt->execute([$uriParts['path']]); |
|
314 | - |
|
315 | - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
316 | - // Checking if the principal is in the prefix |
|
317 | - list($rowPrefix) = Uri\split($row['uri']); |
|
318 | - if ($rowPrefix !== $principalPrefix) { |
|
319 | - continue; |
|
320 | - } |
|
321 | - |
|
322 | - $uri = $row['uri']; |
|
323 | - break; //Stop on first match |
|
324 | - } |
|
325 | - } else { |
|
326 | - $pathParts = Uri\split($uriParts['path']); // We can do this since $uriParts['path'] is not null |
|
327 | - |
|
328 | - if (2 === count($pathParts) && $pathParts[0] === $principalPrefix) { |
|
329 | - // Checking that this uri exists |
|
330 | - $query = 'SELECT * FROM '.$this->tableName.' WHERE uri = ?'; |
|
331 | - $stmt = $this->pdo->prepare($query); |
|
332 | - $stmt->execute([$uriParts['path']]); |
|
333 | - $rows = $stmt->fetchAll(); |
|
334 | - |
|
335 | - if (count($rows) > 0) { |
|
336 | - $uri = $uriParts['path']; |
|
337 | - } |
|
338 | - } |
|
339 | - } |
|
340 | - |
|
341 | - return $uri; |
|
342 | - } |
|
343 | - |
|
344 | - /** |
|
345 | - * Returns the list of members for a group-principal. |
|
346 | - * |
|
347 | - * @param string $principal |
|
348 | - * |
|
349 | - * @return array |
|
350 | - */ |
|
351 | - public function getGroupMemberSet($principal) |
|
352 | - { |
|
353 | - $principal = $this->getPrincipalByPath($principal); |
|
354 | - if (!$principal) { |
|
355 | - throw new DAV\Exception('Principal not found'); |
|
356 | - } |
|
357 | - $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?'); |
|
358 | - $stmt->execute([$principal['id']]); |
|
359 | - |
|
360 | - $result = []; |
|
361 | - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
362 | - $result[] = $row['uri']; |
|
363 | - } |
|
364 | - |
|
365 | - return $result; |
|
366 | - } |
|
367 | - |
|
368 | - /** |
|
369 | - * Returns the list of groups a principal is a member of. |
|
370 | - * |
|
371 | - * @param string $principal |
|
372 | - * |
|
373 | - * @return array |
|
374 | - */ |
|
375 | - public function getGroupMembership($principal) |
|
376 | - { |
|
377 | - $principal = $this->getPrincipalByPath($principal); |
|
378 | - if (!$principal) { |
|
379 | - throw new DAV\Exception('Principal not found'); |
|
380 | - } |
|
381 | - $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?'); |
|
382 | - $stmt->execute([$principal['id']]); |
|
383 | - |
|
384 | - $result = []; |
|
385 | - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
386 | - $result[] = $row['uri']; |
|
387 | - } |
|
388 | - |
|
389 | - return $result; |
|
390 | - } |
|
391 | - |
|
392 | - /** |
|
393 | - * Updates the list of group members for a group principal. |
|
394 | - * |
|
395 | - * The principals should be passed as a list of uri's. |
|
396 | - * |
|
397 | - * @param string $principal |
|
398 | - */ |
|
399 | - public function setGroupMemberSet($principal, array $members) |
|
400 | - { |
|
401 | - // Grabbing the list of principal id's. |
|
402 | - $stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? '.str_repeat(', ? ', count($members)).');'); |
|
403 | - $stmt->execute(array_merge([$principal], $members)); |
|
404 | - |
|
405 | - $memberIds = []; |
|
406 | - $principalId = null; |
|
407 | - |
|
408 | - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
409 | - if ($row['uri'] == $principal) { |
|
410 | - $principalId = $row['id']; |
|
411 | - } else { |
|
412 | - $memberIds[] = $row['id']; |
|
413 | - } |
|
414 | - } |
|
415 | - if (!$principalId) { |
|
416 | - throw new DAV\Exception('Principal not found'); |
|
417 | - } |
|
418 | - // Wiping out old members |
|
419 | - $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;'); |
|
420 | - $stmt->execute([$principalId]); |
|
421 | - |
|
422 | - foreach ($memberIds as $memberId) { |
|
423 | - $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);'); |
|
424 | - $stmt->execute([$principalId, $memberId]); |
|
425 | - } |
|
426 | - } |
|
427 | - |
|
428 | - /** |
|
429 | - * Creates a new principal. |
|
430 | - * |
|
431 | - * This method receives a full path for the new principal. The mkCol object |
|
432 | - * contains any additional webdav properties specified during the creation |
|
433 | - * of the principal. |
|
434 | - * |
|
435 | - * @param string $path |
|
436 | - */ |
|
437 | - public function createPrincipal($path, MkCol $mkCol) |
|
438 | - { |
|
439 | - $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (uri) VALUES (?)'); |
|
440 | - $stmt->execute([$path]); |
|
441 | - $this->updatePrincipal($path, $mkCol); |
|
442 | - } |
|
60 | + '{http://sabredav.org/ns}email-address' => [ |
|
61 | + 'dbField' => 'email', |
|
62 | + ], |
|
63 | + ]; |
|
64 | + |
|
65 | + /** |
|
66 | + * Sets up the backend. |
|
67 | + */ |
|
68 | + public function __construct(\PDO $pdo) |
|
69 | + { |
|
70 | + $this->pdo = $pdo; |
|
71 | + } |
|
72 | + |
|
73 | + /** |
|
74 | + * Returns a list of principals based on a prefix. |
|
75 | + * |
|
76 | + * This prefix will often contain something like 'principals'. You are only |
|
77 | + * expected to return principals that are in this base path. |
|
78 | + * |
|
79 | + * You are expected to return at least a 'uri' for every user, you can |
|
80 | + * return any additional properties if you wish so. Common properties are: |
|
81 | + * {DAV:}displayname |
|
82 | + * {http://sabredav.org/ns}email-address - This is a custom SabreDAV |
|
83 | + * field that's actualy injected in a number of other properties. If |
|
84 | + * you have an email address, use this property. |
|
85 | + * |
|
86 | + * @param string $prefixPath |
|
87 | + * |
|
88 | + * @return array |
|
89 | + */ |
|
90 | + public function getPrincipalsByPrefix($prefixPath) |
|
91 | + { |
|
92 | + $fields = [ |
|
93 | + 'uri', |
|
94 | + ]; |
|
95 | + |
|
96 | + foreach ($this->fieldMap as $key => $value) { |
|
97 | + $fields[] = $value['dbField']; |
|
98 | + } |
|
99 | + $result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '.$this->tableName); |
|
100 | + |
|
101 | + $principals = []; |
|
102 | + |
|
103 | + while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { |
|
104 | + // Checking if the principal is in the prefix |
|
105 | + list($rowPrefix) = Uri\split($row['uri']); |
|
106 | + if ($rowPrefix !== $prefixPath) { |
|
107 | + continue; |
|
108 | + } |
|
109 | + |
|
110 | + $principal = [ |
|
111 | + 'uri' => $row['uri'], |
|
112 | + ]; |
|
113 | + foreach ($this->fieldMap as $key => $value) { |
|
114 | + if ($row[$value['dbField']]) { |
|
115 | + $principal[$key] = $row[$value['dbField']]; |
|
116 | + } |
|
117 | + } |
|
118 | + $principals[] = $principal; |
|
119 | + } |
|
120 | + |
|
121 | + return $principals; |
|
122 | + } |
|
123 | + |
|
124 | + /** |
|
125 | + * Returns a specific principal, specified by it's path. |
|
126 | + * The returned structure should be the exact same as from |
|
127 | + * getPrincipalsByPrefix. |
|
128 | + * |
|
129 | + * @param string $path |
|
130 | + * |
|
131 | + * @return array |
|
132 | + */ |
|
133 | + public function getPrincipalByPath($path) |
|
134 | + { |
|
135 | + $fields = [ |
|
136 | + 'id', |
|
137 | + 'uri', |
|
138 | + ]; |
|
139 | + |
|
140 | + foreach ($this->fieldMap as $key => $value) { |
|
141 | + $fields[] = $value['dbField']; |
|
142 | + } |
|
143 | + $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '.$this->tableName.' WHERE uri = ?'); |
|
144 | + $stmt->execute([$path]); |
|
145 | + |
|
146 | + $row = $stmt->fetch(\PDO::FETCH_ASSOC); |
|
147 | + if (!$row) { |
|
148 | + return; |
|
149 | + } |
|
150 | + |
|
151 | + $principal = [ |
|
152 | + 'id' => $row['id'], |
|
153 | + 'uri' => $row['uri'], |
|
154 | + ]; |
|
155 | + foreach ($this->fieldMap as $key => $value) { |
|
156 | + if ($row[$value['dbField']]) { |
|
157 | + $principal[$key] = $row[$value['dbField']]; |
|
158 | + } |
|
159 | + } |
|
160 | + |
|
161 | + return $principal; |
|
162 | + } |
|
163 | + |
|
164 | + /** |
|
165 | + * Updates one ore more webdav properties on a principal. |
|
166 | + * |
|
167 | + * The list of mutations is stored in a Sabre\DAV\PropPatch object. |
|
168 | + * To do the actual updates, you must tell this object which properties |
|
169 | + * you're going to process with the handle() method. |
|
170 | + * |
|
171 | + * Calling the handle method is like telling the PropPatch object "I |
|
172 | + * promise I can handle updating this property". |
|
173 | + * |
|
174 | + * Read the PropPatch documentation for more info and examples. |
|
175 | + * |
|
176 | + * @param string $path |
|
177 | + */ |
|
178 | + public function updatePrincipal($path, DAV\PropPatch $propPatch) |
|
179 | + { |
|
180 | + $propPatch->handle(array_keys($this->fieldMap), function ($properties) use ($path) { |
|
181 | + $query = 'UPDATE '.$this->tableName.' SET '; |
|
182 | + $first = true; |
|
183 | + |
|
184 | + $values = []; |
|
185 | + |
|
186 | + foreach ($properties as $key => $value) { |
|
187 | + $dbField = $this->fieldMap[$key]['dbField']; |
|
188 | + |
|
189 | + if (!$first) { |
|
190 | + $query .= ', '; |
|
191 | + } |
|
192 | + $first = false; |
|
193 | + $query .= $dbField.' = :'.$dbField; |
|
194 | + $values[$dbField] = $value; |
|
195 | + } |
|
196 | + |
|
197 | + $query .= ' WHERE uri = :uri'; |
|
198 | + $values['uri'] = $path; |
|
199 | + |
|
200 | + $stmt = $this->pdo->prepare($query); |
|
201 | + $stmt->execute($values); |
|
202 | + |
|
203 | + return true; |
|
204 | + }); |
|
205 | + } |
|
206 | + |
|
207 | + /** |
|
208 | + * This method is used to search for principals matching a set of |
|
209 | + * properties. |
|
210 | + * |
|
211 | + * This search is specifically used by RFC3744's principal-property-search |
|
212 | + * REPORT. |
|
213 | + * |
|
214 | + * The actual search should be a unicode-non-case-sensitive search. The |
|
215 | + * keys in searchProperties are the WebDAV property names, while the values |
|
216 | + * are the property values to search on. |
|
217 | + * |
|
218 | + * By default, if multiple properties are submitted to this method, the |
|
219 | + * various properties should be combined with 'AND'. If $test is set to |
|
220 | + * 'anyof', it should be combined using 'OR'. |
|
221 | + * |
|
222 | + * This method should simply return an array with full principal uri's. |
|
223 | + * |
|
224 | + * If somebody attempted to search on a property the backend does not |
|
225 | + * support, you should simply return 0 results. |
|
226 | + * |
|
227 | + * You can also just return 0 results if you choose to not support |
|
228 | + * searching at all, but keep in mind that this may stop certain features |
|
229 | + * from working. |
|
230 | + * |
|
231 | + * @param string $prefixPath |
|
232 | + * @param string $test |
|
233 | + * |
|
234 | + * @return array |
|
235 | + */ |
|
236 | + public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') |
|
237 | + { |
|
238 | + if (0 == count($searchProperties)) { |
|
239 | + return []; |
|
240 | + } //No criteria |
|
241 | + |
|
242 | + $query = 'SELECT uri FROM '.$this->tableName.' WHERE '; |
|
243 | + $values = []; |
|
244 | + foreach ($searchProperties as $property => $value) { |
|
245 | + switch ($property) { |
|
246 | + case '{DAV:}displayname': |
|
247 | + $column = 'displayname'; |
|
248 | + break; |
|
249 | + case '{http://sabredav.org/ns}email-address': |
|
250 | + $column = 'email'; |
|
251 | + break; |
|
252 | + default: |
|
253 | + // Unsupported property |
|
254 | + return []; |
|
255 | + } |
|
256 | + if (count($values) > 0) { |
|
257 | + $query .= (0 == strcmp($test, 'anyof') ? ' OR ' : ' AND '); |
|
258 | + } |
|
259 | + $query .= 'lower('.$column.') LIKE lower(?)'; |
|
260 | + $values[] = '%'.$value.'%'; |
|
261 | + } |
|
262 | + $stmt = $this->pdo->prepare($query); |
|
263 | + $stmt->execute($values); |
|
264 | + |
|
265 | + $principals = []; |
|
266 | + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
267 | + // Checking if the principal is in the prefix |
|
268 | + list($rowPrefix) = Uri\split($row['uri']); |
|
269 | + if ($rowPrefix !== $prefixPath) { |
|
270 | + continue; |
|
271 | + } |
|
272 | + |
|
273 | + $principals[] = $row['uri']; |
|
274 | + } |
|
275 | + |
|
276 | + return $principals; |
|
277 | + } |
|
278 | + |
|
279 | + /** |
|
280 | + * Finds a principal by its URI. |
|
281 | + * |
|
282 | + * This method may receive any type of uri, but mailto: addresses will be |
|
283 | + * the most common. |
|
284 | + * |
|
285 | + * Implementation of this API is optional. It is currently used by the |
|
286 | + * CalDAV system to find principals based on their email addresses. If this |
|
287 | + * API is not implemented, some features may not work correctly. |
|
288 | + * |
|
289 | + * This method must return a relative principal path, or null, if the |
|
290 | + * principal was not found or you refuse to find it. |
|
291 | + * |
|
292 | + * @param string $uri |
|
293 | + * @param string $principalPrefix |
|
294 | + * |
|
295 | + * @return string |
|
296 | + */ |
|
297 | + public function findByUri($uri, $principalPrefix) |
|
298 | + { |
|
299 | + $uriParts = Uri\parse($uri); |
|
300 | + |
|
301 | + // Only two types of uri are supported : |
|
302 | + // - the "mailto:" scheme with some non-empty address |
|
303 | + // - a principals uri, in the form "principals/NAME" |
|
304 | + // In both cases, `path` must not be empty. |
|
305 | + if (empty($uriParts['path'])) { |
|
306 | + return null; |
|
307 | + } |
|
308 | + |
|
309 | + $uri = null; |
|
310 | + if ('mailto' === $uriParts['scheme']) { |
|
311 | + $query = 'SELECT uri FROM '.$this->tableName.' WHERE lower(email)=lower(?)'; |
|
312 | + $stmt = $this->pdo->prepare($query); |
|
313 | + $stmt->execute([$uriParts['path']]); |
|
314 | + |
|
315 | + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
316 | + // Checking if the principal is in the prefix |
|
317 | + list($rowPrefix) = Uri\split($row['uri']); |
|
318 | + if ($rowPrefix !== $principalPrefix) { |
|
319 | + continue; |
|
320 | + } |
|
321 | + |
|
322 | + $uri = $row['uri']; |
|
323 | + break; //Stop on first match |
|
324 | + } |
|
325 | + } else { |
|
326 | + $pathParts = Uri\split($uriParts['path']); // We can do this since $uriParts['path'] is not null |
|
327 | + |
|
328 | + if (2 === count($pathParts) && $pathParts[0] === $principalPrefix) { |
|
329 | + // Checking that this uri exists |
|
330 | + $query = 'SELECT * FROM '.$this->tableName.' WHERE uri = ?'; |
|
331 | + $stmt = $this->pdo->prepare($query); |
|
332 | + $stmt->execute([$uriParts['path']]); |
|
333 | + $rows = $stmt->fetchAll(); |
|
334 | + |
|
335 | + if (count($rows) > 0) { |
|
336 | + $uri = $uriParts['path']; |
|
337 | + } |
|
338 | + } |
|
339 | + } |
|
340 | + |
|
341 | + return $uri; |
|
342 | + } |
|
343 | + |
|
344 | + /** |
|
345 | + * Returns the list of members for a group-principal. |
|
346 | + * |
|
347 | + * @param string $principal |
|
348 | + * |
|
349 | + * @return array |
|
350 | + */ |
|
351 | + public function getGroupMemberSet($principal) |
|
352 | + { |
|
353 | + $principal = $this->getPrincipalByPath($principal); |
|
354 | + if (!$principal) { |
|
355 | + throw new DAV\Exception('Principal not found'); |
|
356 | + } |
|
357 | + $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?'); |
|
358 | + $stmt->execute([$principal['id']]); |
|
359 | + |
|
360 | + $result = []; |
|
361 | + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
362 | + $result[] = $row['uri']; |
|
363 | + } |
|
364 | + |
|
365 | + return $result; |
|
366 | + } |
|
367 | + |
|
368 | + /** |
|
369 | + * Returns the list of groups a principal is a member of. |
|
370 | + * |
|
371 | + * @param string $principal |
|
372 | + * |
|
373 | + * @return array |
|
374 | + */ |
|
375 | + public function getGroupMembership($principal) |
|
376 | + { |
|
377 | + $principal = $this->getPrincipalByPath($principal); |
|
378 | + if (!$principal) { |
|
379 | + throw new DAV\Exception('Principal not found'); |
|
380 | + } |
|
381 | + $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?'); |
|
382 | + $stmt->execute([$principal['id']]); |
|
383 | + |
|
384 | + $result = []; |
|
385 | + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
386 | + $result[] = $row['uri']; |
|
387 | + } |
|
388 | + |
|
389 | + return $result; |
|
390 | + } |
|
391 | + |
|
392 | + /** |
|
393 | + * Updates the list of group members for a group principal. |
|
394 | + * |
|
395 | + * The principals should be passed as a list of uri's. |
|
396 | + * |
|
397 | + * @param string $principal |
|
398 | + */ |
|
399 | + public function setGroupMemberSet($principal, array $members) |
|
400 | + { |
|
401 | + // Grabbing the list of principal id's. |
|
402 | + $stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? '.str_repeat(', ? ', count($members)).');'); |
|
403 | + $stmt->execute(array_merge([$principal], $members)); |
|
404 | + |
|
405 | + $memberIds = []; |
|
406 | + $principalId = null; |
|
407 | + |
|
408 | + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
|
409 | + if ($row['uri'] == $principal) { |
|
410 | + $principalId = $row['id']; |
|
411 | + } else { |
|
412 | + $memberIds[] = $row['id']; |
|
413 | + } |
|
414 | + } |
|
415 | + if (!$principalId) { |
|
416 | + throw new DAV\Exception('Principal not found'); |
|
417 | + } |
|
418 | + // Wiping out old members |
|
419 | + $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;'); |
|
420 | + $stmt->execute([$principalId]); |
|
421 | + |
|
422 | + foreach ($memberIds as $memberId) { |
|
423 | + $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);'); |
|
424 | + $stmt->execute([$principalId, $memberId]); |
|
425 | + } |
|
426 | + } |
|
427 | + |
|
428 | + /** |
|
429 | + * Creates a new principal. |
|
430 | + * |
|
431 | + * This method receives a full path for the new principal. The mkCol object |
|
432 | + * contains any additional webdav properties specified during the creation |
|
433 | + * of the principal. |
|
434 | + * |
|
435 | + * @param string $path |
|
436 | + */ |
|
437 | + public function createPrincipal($path, MkCol $mkCol) |
|
438 | + { |
|
439 | + $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (uri) VALUES (?)'); |
|
440 | + $stmt->execute([$path]); |
|
441 | + $this->updatePrincipal($path, $mkCol); |
|
442 | + } |
|
443 | 443 | } |
@@ -177,7 +177,7 @@ |
||
177 | 177 | */ |
178 | 178 | public function updatePrincipal($path, DAV\PropPatch $propPatch) |
179 | 179 | { |
180 | - $propPatch->handle(array_keys($this->fieldMap), function ($properties) use ($path) { |
|
180 | + $propPatch->handle(array_keys($this->fieldMap), function($properties) use ($path) { |
|
181 | 181 | $query = 'UPDATE '.$this->tableName.' SET '; |
182 | 182 | $first = true; |
183 | 183 |
@@ -20,77 +20,77 @@ |
||
20 | 20 | */ |
21 | 21 | class PrincipalCollection extends AbstractPrincipalCollection implements IExtendedCollection, IACL |
22 | 22 | { |
23 | - use ACLTrait; |
|
23 | + use ACLTrait; |
|
24 | 24 | |
25 | - /** |
|
26 | - * This method returns a node for a principal. |
|
27 | - * |
|
28 | - * The passed array contains principal information, and is guaranteed to |
|
29 | - * at least contain a uri item. Other properties may or may not be |
|
30 | - * supplied by the authentication backend. |
|
31 | - * |
|
32 | - * @return \Sabre\DAV\INode |
|
33 | - */ |
|
34 | - public function getChildForPrincipal(array $principal) |
|
35 | - { |
|
36 | - return new Principal($this->principalBackend, $principal); |
|
37 | - } |
|
25 | + /** |
|
26 | + * This method returns a node for a principal. |
|
27 | + * |
|
28 | + * The passed array contains principal information, and is guaranteed to |
|
29 | + * at least contain a uri item. Other properties may or may not be |
|
30 | + * supplied by the authentication backend. |
|
31 | + * |
|
32 | + * @return \Sabre\DAV\INode |
|
33 | + */ |
|
34 | + public function getChildForPrincipal(array $principal) |
|
35 | + { |
|
36 | + return new Principal($this->principalBackend, $principal); |
|
37 | + } |
|
38 | 38 | |
39 | - /** |
|
40 | - * Creates a new collection. |
|
41 | - * |
|
42 | - * This method will receive a MkCol object with all the information about |
|
43 | - * the new collection that's being created. |
|
44 | - * |
|
45 | - * The MkCol object contains information about the resourceType of the new |
|
46 | - * collection. If you don't support the specified resourceType, you should |
|
47 | - * throw Exception\InvalidResourceType. |
|
48 | - * |
|
49 | - * The object also contains a list of WebDAV properties for the new |
|
50 | - * collection. |
|
51 | - * |
|
52 | - * You should call the handle() method on this object to specify exactly |
|
53 | - * which properties you are storing. This allows the system to figure out |
|
54 | - * exactly which properties you didn't store, which in turn allows other |
|
55 | - * plugins (such as the propertystorage plugin) to handle storing the |
|
56 | - * property for you. |
|
57 | - * |
|
58 | - * @param string $name |
|
59 | - * |
|
60 | - * @throws InvalidResourceType |
|
61 | - */ |
|
62 | - public function createExtendedCollection($name, MkCol $mkCol) |
|
63 | - { |
|
64 | - if (!$mkCol->hasResourceType('{DAV:}principal')) { |
|
65 | - throw new InvalidResourceType('Only resources of type {DAV:}principal may be created here'); |
|
66 | - } |
|
39 | + /** |
|
40 | + * Creates a new collection. |
|
41 | + * |
|
42 | + * This method will receive a MkCol object with all the information about |
|
43 | + * the new collection that's being created. |
|
44 | + * |
|
45 | + * The MkCol object contains information about the resourceType of the new |
|
46 | + * collection. If you don't support the specified resourceType, you should |
|
47 | + * throw Exception\InvalidResourceType. |
|
48 | + * |
|
49 | + * The object also contains a list of WebDAV properties for the new |
|
50 | + * collection. |
|
51 | + * |
|
52 | + * You should call the handle() method on this object to specify exactly |
|
53 | + * which properties you are storing. This allows the system to figure out |
|
54 | + * exactly which properties you didn't store, which in turn allows other |
|
55 | + * plugins (such as the propertystorage plugin) to handle storing the |
|
56 | + * property for you. |
|
57 | + * |
|
58 | + * @param string $name |
|
59 | + * |
|
60 | + * @throws InvalidResourceType |
|
61 | + */ |
|
62 | + public function createExtendedCollection($name, MkCol $mkCol) |
|
63 | + { |
|
64 | + if (!$mkCol->hasResourceType('{DAV:}principal')) { |
|
65 | + throw new InvalidResourceType('Only resources of type {DAV:}principal may be created here'); |
|
66 | + } |
|
67 | 67 | |
68 | - $this->principalBackend->createPrincipal( |
|
69 | - $this->principalPrefix.'/'.$name, |
|
70 | - $mkCol |
|
71 | - ); |
|
72 | - } |
|
68 | + $this->principalBackend->createPrincipal( |
|
69 | + $this->principalPrefix.'/'.$name, |
|
70 | + $mkCol |
|
71 | + ); |
|
72 | + } |
|
73 | 73 | |
74 | - /** |
|
75 | - * Returns a list of ACE's for this node. |
|
76 | - * |
|
77 | - * Each ACE has the following properties: |
|
78 | - * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are |
|
79 | - * currently the only supported privileges |
|
80 | - * * 'principal', a url to the principal who owns the node |
|
81 | - * * 'protected' (optional), indicating that this ACE is not allowed to |
|
82 | - * be updated. |
|
83 | - * |
|
84 | - * @return array |
|
85 | - */ |
|
86 | - public function getACL() |
|
87 | - { |
|
88 | - return [ |
|
89 | - [ |
|
90 | - 'principal' => '{DAV:}authenticated', |
|
91 | - 'privilege' => '{DAV:}read', |
|
92 | - 'protected' => true, |
|
93 | - ], |
|
94 | - ]; |
|
95 | - } |
|
74 | + /** |
|
75 | + * Returns a list of ACE's for this node. |
|
76 | + * |
|
77 | + * Each ACE has the following properties: |
|
78 | + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are |
|
79 | + * currently the only supported privileges |
|
80 | + * * 'principal', a url to the principal who owns the node |
|
81 | + * * 'protected' (optional), indicating that this ACE is not allowed to |
|
82 | + * be updated. |
|
83 | + * |
|
84 | + * @return array |
|
85 | + */ |
|
86 | + public function getACL() |
|
87 | + { |
|
88 | + return [ |
|
89 | + [ |
|
90 | + 'principal' => '{DAV:}authenticated', |
|
91 | + 'privilege' => '{DAV:}read', |
|
92 | + 'protected' => true, |
|
93 | + ], |
|
94 | + ]; |
|
95 | + } |
|
96 | 96 | } |
@@ -17,22 +17,22 @@ |
||
17 | 17 | */ |
18 | 18 | interface ICopyTarget extends ICollection |
19 | 19 | { |
20 | - /** |
|
21 | - * Copies a node into this collection. |
|
22 | - * |
|
23 | - * It is up to the implementors to: |
|
24 | - * 1. Create the new resource. |
|
25 | - * 2. Copy the data and any properties. |
|
26 | - * |
|
27 | - * If you return true from this function, the assumption |
|
28 | - * is that the copy was successful. |
|
29 | - * If you return false, sabre/dav will handle the copy itself. |
|
30 | - * |
|
31 | - * @param string $targetName new local file/collection name |
|
32 | - * @param string $sourcePath Full path to source node |
|
33 | - * @param INode $sourceNode Source node itself |
|
34 | - * |
|
35 | - * @return bool |
|
36 | - */ |
|
37 | - public function copyInto($targetName, $sourcePath, INode $sourceNode); |
|
20 | + /** |
|
21 | + * Copies a node into this collection. |
|
22 | + * |
|
23 | + * It is up to the implementors to: |
|
24 | + * 1. Create the new resource. |
|
25 | + * 2. Copy the data and any properties. |
|
26 | + * |
|
27 | + * If you return true from this function, the assumption |
|
28 | + * is that the copy was successful. |
|
29 | + * If you return false, sabre/dav will handle the copy itself. |
|
30 | + * |
|
31 | + * @param string $targetName new local file/collection name |
|
32 | + * @param string $sourcePath Full path to source node |
|
33 | + * @param INode $sourceNode Source node itself |
|
34 | + * |
|
35 | + * @return bool |
|
36 | + */ |
|
37 | + public function copyInto($targetName, $sourcePath, INode $sourceNode); |
|
38 | 38 | } |
@@ -21,26 +21,26 @@ |
||
21 | 21 | */ |
22 | 22 | interface IMoveTarget extends ICollection |
23 | 23 | { |
24 | - /** |
|
25 | - * Moves a node into this collection. |
|
26 | - * |
|
27 | - * It is up to the implementors to: |
|
28 | - * 1. Create the new resource. |
|
29 | - * 2. Remove the old resource. |
|
30 | - * 3. Transfer any properties or other data. |
|
31 | - * |
|
32 | - * Generally you should make very sure that your collection can easily move |
|
33 | - * the move. |
|
34 | - * |
|
35 | - * If you don't, just return false, which will trigger sabre/dav to handle |
|
36 | - * the move itself. If you return true from this function, the assumption |
|
37 | - * is that the move was successful. |
|
38 | - * |
|
39 | - * @param string $targetName new local file/collection name |
|
40 | - * @param string $sourcePath Full path to source node |
|
41 | - * @param INode $sourceNode Source node itself |
|
42 | - * |
|
43 | - * @return bool |
|
44 | - */ |
|
45 | - public function moveInto($targetName, $sourcePath, INode $sourceNode); |
|
24 | + /** |
|
25 | + * Moves a node into this collection. |
|
26 | + * |
|
27 | + * It is up to the implementors to: |
|
28 | + * 1. Create the new resource. |
|
29 | + * 2. Remove the old resource. |
|
30 | + * 3. Transfer any properties or other data. |
|
31 | + * |
|
32 | + * Generally you should make very sure that your collection can easily move |
|
33 | + * the move. |
|
34 | + * |
|
35 | + * If you don't, just return false, which will trigger sabre/dav to handle |
|
36 | + * the move itself. If you return true from this function, the assumption |
|
37 | + * is that the move was successful. |
|
38 | + * |
|
39 | + * @param string $targetName new local file/collection name |
|
40 | + * @param string $sourcePath Full path to source node |
|
41 | + * @param INode $sourceNode Source node itself |
|
42 | + * |
|
43 | + * @return bool |
|
44 | + */ |
|
45 | + public function moveInto($targetName, $sourcePath, INode $sourceNode); |
|
46 | 46 | } |
@@ -18,92 +18,92 @@ |
||
18 | 18 | */ |
19 | 19 | class SimpleCollection extends Collection |
20 | 20 | { |
21 | - /** |
|
22 | - * List of childnodes. |
|
23 | - * |
|
24 | - * @var INode[] |
|
25 | - */ |
|
26 | - protected $children = []; |
|
21 | + /** |
|
22 | + * List of childnodes. |
|
23 | + * |
|
24 | + * @var INode[] |
|
25 | + */ |
|
26 | + protected $children = []; |
|
27 | 27 | |
28 | - /** |
|
29 | - * Name of this resource. |
|
30 | - * |
|
31 | - * @var string |
|
32 | - */ |
|
33 | - protected $name; |
|
28 | + /** |
|
29 | + * Name of this resource. |
|
30 | + * |
|
31 | + * @var string |
|
32 | + */ |
|
33 | + protected $name; |
|
34 | 34 | |
35 | - /** |
|
36 | - * Creates this node. |
|
37 | - * |
|
38 | - * The name of the node must be passed, child nodes can also be passed. |
|
39 | - * This nodes must be instances of INode |
|
40 | - * |
|
41 | - * @param string $name |
|
42 | - * @param INode[] $children |
|
43 | - */ |
|
44 | - public function __construct($name, array $children = []) |
|
45 | - { |
|
46 | - $this->name = $name; |
|
47 | - foreach ($children as $key => $child) { |
|
48 | - if (is_string($child)) { |
|
49 | - $child = new SimpleFile($key, $child); |
|
50 | - } elseif (is_array($child)) { |
|
51 | - $child = new self($key, $child); |
|
52 | - } elseif (!$child instanceof INode) { |
|
53 | - throw new InvalidArgumentException('Children must be specified as strings, arrays or instances of Sabre\DAV\INode'); |
|
54 | - } |
|
55 | - $this->addChild($child); |
|
56 | - } |
|
57 | - } |
|
35 | + /** |
|
36 | + * Creates this node. |
|
37 | + * |
|
38 | + * The name of the node must be passed, child nodes can also be passed. |
|
39 | + * This nodes must be instances of INode |
|
40 | + * |
|
41 | + * @param string $name |
|
42 | + * @param INode[] $children |
|
43 | + */ |
|
44 | + public function __construct($name, array $children = []) |
|
45 | + { |
|
46 | + $this->name = $name; |
|
47 | + foreach ($children as $key => $child) { |
|
48 | + if (is_string($child)) { |
|
49 | + $child = new SimpleFile($key, $child); |
|
50 | + } elseif (is_array($child)) { |
|
51 | + $child = new self($key, $child); |
|
52 | + } elseif (!$child instanceof INode) { |
|
53 | + throw new InvalidArgumentException('Children must be specified as strings, arrays or instances of Sabre\DAV\INode'); |
|
54 | + } |
|
55 | + $this->addChild($child); |
|
56 | + } |
|
57 | + } |
|
58 | 58 | |
59 | - /** |
|
60 | - * Adds a new childnode to this collection. |
|
61 | - */ |
|
62 | - public function addChild(INode $child) |
|
63 | - { |
|
64 | - $this->children[$child->getName()] = $child; |
|
65 | - } |
|
59 | + /** |
|
60 | + * Adds a new childnode to this collection. |
|
61 | + */ |
|
62 | + public function addChild(INode $child) |
|
63 | + { |
|
64 | + $this->children[$child->getName()] = $child; |
|
65 | + } |
|
66 | 66 | |
67 | - /** |
|
68 | - * Returns the name of the collection. |
|
69 | - * |
|
70 | - * @return string |
|
71 | - */ |
|
72 | - public function getName() |
|
73 | - { |
|
74 | - return $this->name; |
|
75 | - } |
|
67 | + /** |
|
68 | + * Returns the name of the collection. |
|
69 | + * |
|
70 | + * @return string |
|
71 | + */ |
|
72 | + public function getName() |
|
73 | + { |
|
74 | + return $this->name; |
|
75 | + } |
|
76 | 76 | |
77 | - /** |
|
78 | - * Returns a child object, by its name. |
|
79 | - * |
|
80 | - * This method makes use of the getChildren method to grab all the child nodes, and compares the name. |
|
81 | - * Generally its wise to override this, as this can usually be optimized |
|
82 | - * |
|
83 | - * This method must throw Sabre\DAV\Exception\NotFound if the node does not |
|
84 | - * exist. |
|
85 | - * |
|
86 | - * @param string $name |
|
87 | - * |
|
88 | - * @throws Exception\NotFound |
|
89 | - * |
|
90 | - * @return INode |
|
91 | - */ |
|
92 | - public function getChild($name) |
|
93 | - { |
|
94 | - if (isset($this->children[$name])) { |
|
95 | - return $this->children[$name]; |
|
96 | - } |
|
97 | - throw new Exception\NotFound('File not found: '.$name.' in \''.$this->getName().'\''); |
|
98 | - } |
|
77 | + /** |
|
78 | + * Returns a child object, by its name. |
|
79 | + * |
|
80 | + * This method makes use of the getChildren method to grab all the child nodes, and compares the name. |
|
81 | + * Generally its wise to override this, as this can usually be optimized |
|
82 | + * |
|
83 | + * This method must throw Sabre\DAV\Exception\NotFound if the node does not |
|
84 | + * exist. |
|
85 | + * |
|
86 | + * @param string $name |
|
87 | + * |
|
88 | + * @throws Exception\NotFound |
|
89 | + * |
|
90 | + * @return INode |
|
91 | + */ |
|
92 | + public function getChild($name) |
|
93 | + { |
|
94 | + if (isset($this->children[$name])) { |
|
95 | + return $this->children[$name]; |
|
96 | + } |
|
97 | + throw new Exception\NotFound('File not found: '.$name.' in \''.$this->getName().'\''); |
|
98 | + } |
|
99 | 99 | |
100 | - /** |
|
101 | - * Returns a list of children for this collection. |
|
102 | - * |
|
103 | - * @return INode[] |
|
104 | - */ |
|
105 | - public function getChildren() |
|
106 | - { |
|
107 | - return array_values($this->children); |
|
108 | - } |
|
100 | + /** |
|
101 | + * Returns a list of children for this collection. |
|
102 | + * |
|
103 | + * @return INode[] |
|
104 | + */ |
|
105 | + public function getChildren() |
|
106 | + { |
|
107 | + return array_values($this->children); |
|
108 | + } |
|
109 | 109 | } |