ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Sabre\DAV\Server Class Reference

Main DAV server class. More...

+ Inheritance diagram for Sabre\DAV\Server:
+ Collaboration diagram for Sabre\DAV\Server:

Public Member Functions

 __construct ($treeOrNode=null)
 Sets up the server. More...
 
 exec ()
 Starts the DAV Server. More...
 
 setBaseUri ($uri)
 Sets the base server uri. More...
 
 getBaseUri ()
 Returns the base responding uri. More...
 
 guessBaseUri ()
 This method attempts to detect the base uri. More...
 
 addPlugin (ServerPlugin $plugin)
 Adds a plugin to the server. More...
 
 getPlugin ($name)
 Returns an initialized plugin by it's name. More...
 
 getPlugins ()
 Returns all plugins. More...
 
 getLogger ()
 Returns the PSR-3 logger object. More...
 
 invokeMethod (RequestInterface $request, ResponseInterface $response, $sendResponse=true)
 Handles a http request, and execute a method based on its name. More...
 
 getAllowedMethods ($path)
 Returns an array with all the supported HTTP methods for a specific uri. More...
 
 getRequestUri ()
 Gets the uri for the request, keeping the base uri into consideration. More...
 
 calculateUri ($uri)
 Turns a URI such as the REQUEST_URI into a local path. More...
 
 getHTTPDepth ($default=self::DEPTH_INFINITY)
 Returns the HTTP depth header. More...
 
 getHTTPRange ()
 Returns the HTTP range header. More...
 
 getHTTPPrefer ()
 Returns the HTTP Prefer header information. More...
 
 getCopyAndMoveInfo (RequestInterface $request)
 Returns information about Copy and Move requests. More...
 
 getProperties ($path, $propertyNames)
 Returns a list of properties for a path. More...
 
 getPropertiesForChildren ($path, $propertyNames)
 A kid-friendly way to fetch properties for a node's children. More...
 
 getHTTPHeaders ($path)
 Returns a list of HTTP headers for a particular resource. More...
 
 getPropertiesForPath ($path, $propertyNames=[], $depth=0)
 Returns a list of properties for a given path. More...
 
 getPropertiesIteratorForPath ($path, $propertyNames=[], $depth=0)
 Returns a list of properties for a given path. More...
 
 getPropertiesForMultiplePaths (array $paths, array $propertyNames=[])
 Returns a list of properties for a list of paths. More...
 
 getPropertiesByNode (PropFind $propFind, INode $node)
 Determines all properties for a node. More...
 
 createFile ($uri, $data, &$etag=null)
 This method is invoked by sub-systems creating a new file. More...
 
 updateFile ($uri, $data, &$etag=null)
 This method is invoked by sub-systems updating a file. More...
 
 createDirectory ($uri)
 This method is invoked by sub-systems creating a new directory. More...
 
 createCollection ($uri, MkCol $mkCol)
 Use this method to create a new collection. More...
 
 updateProperties ($path, array $properties)
 This method updates a resource's properties. More...
 
 checkPreconditions (RequestInterface $request, ResponseInterface $response)
 This method checks the main HTTP preconditions. More...
 
 getIfConditions (RequestInterface $request)
 This method is created to extract information from the WebDAV HTTP 'If:' header. More...
 
 getResourceTypeForNode (INode $node)
 Returns an array with resourcetypes for a node. More...
 
 generateMultiStatus ($fileProperties, $strip404s=false)
 Generates a WebDAV propfind response body based on a list of nodes. More...
 
- Public Member Functions inherited from Sabre\Event\EventEmitterInterface
 on ($eventName, callable $callBack, $priority=100)
 Subscribe to an event. More...
 
 once ($eventName, callable $callBack, $priority=100)
 Subscribe to an event exactly once. More...
 
 emit ($eventName, array $arguments=[], callable $continueCallBack=null)
 Emits an event. More...
 
 listeners ($eventName)
 Returns the list of listeners for an event. More...
 
 removeListener ($eventName, callable $listener)
 Removes a specific listener from an event. More...
 
 removeAllListeners ($eventName=null)
 Removes all listeners. More...
 
- Public Member Functions inherited from Psr\Log\LoggerAwareInterface
 setLogger (LoggerInterface $logger)
 Sets a logger instance on the object. More...
 

Data Fields

const DEPTH_INFINITY = -1
 Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree. More...
 
const NS_SABREDAV = 'http://sabredav.org/ns'
 XML namespace for all SabreDAV related elements. More...
 
 $tree
 
 $httpResponse
 
 $httpRequest
 
 $sapi
 
 $transactionType
 
 $protectedProperties
 
 $debugExceptions = false
 
 $resourceTypeMapping
 
 $enablePropfindDepthInfinity = false
 
 $xml
 

Static Public Attributes

static $exposeVersion = true
 

Protected Attributes

 $baseUri = null
 
 $plugins = []
 

Private Member Functions

 generatePathNodes (PropFind $propFind, array $yieldFirst=null)
 Small helper to support PROPFIND with DEPTH_INFINITY. More...
 

Detailed Description

Main DAV server class.

Author
Evert Pot (http://evertpot.com/) @license http://sabre.io/license/ Modified BSD License

Definition at line 23 of file Server.php.

Constructor & Destructor Documentation

◆ __construct()

Sabre\DAV\Server::__construct (   $treeOrNode = null)

Sets up the server.

If a Sabre\DAV\Tree object is passed as an argument, it will use it as the directory tree. If a Sabre\DAV\INode is passed, it will create a Sabre\DAV\Tree and use the node as the root.

If nothing is passed, a Sabre\DAV\SimpleCollection is created in a Sabre\DAV\Tree.

If an array is passed, we automatically create a root node, and use the nodes in the array as top-level children.

Parameters
Tree | INode | array | null$treeOrNodeThe tree object

Definition at line 201 of file Server.php.

201 {
202
203 if ($treeOrNode instanceof Tree) {
204 $this->tree = $treeOrNode;
205 } elseif ($treeOrNode instanceof INode) {
206 $this->tree = new Tree($treeOrNode);
207 } elseif (is_array($treeOrNode)) {
208
209 // If it's an array, a list of nodes was passed, and we need to
210 // create the root node.
211 foreach ($treeOrNode as $node) {
212 if (!($node instanceof INode)) {
213 throw new Exception('Invalid argument passed to constructor. If you\'re passing an array, all the values must implement Sabre\\DAV\\INode');
214 }
215 }
216
217 $root = new SimpleCollection('root', $treeOrNode);
218 $this->tree = new Tree($root);
219
220 } elseif (is_null($treeOrNode)) {
221 $root = new SimpleCollection('root');
222 $this->tree = new Tree($root);
223 } else {
224 throw new Exception('Invalid argument passed to constructor. Argument must either be an instance of Sabre\\DAV\\Tree, Sabre\\DAV\\INode, an array or null');
225 }
226
227 $this->xml = new Xml\Service();
228 $this->sapi = new HTTP\Sapi();
229 $this->httpResponse = new HTTP\Response();
230 $this->httpRequest = $this->sapi->getRequest();
231 $this->addPlugin(new CorePlugin());
232
233 }
addPlugin(ServerPlugin $plugin)
Adds a plugin to the server.
Definition: Server.php:404
$root
Definition: sabredav.php:45

References $root, and Sabre\DAV\Server\addPlugin().

+ Here is the call graph for this function:

Member Function Documentation

◆ addPlugin()

Sabre\DAV\Server::addPlugin ( ServerPlugin  $plugin)

Adds a plugin to the server.

For more information, console the documentation of Sabre\DAV\ServerPlugin

Parameters
ServerPlugin$plugin
Returns
void

Definition at line 404 of file Server.php.

404 {
405
406 $this->plugins[$plugin->getPluginName()] = $plugin;
407 $plugin->initialize($this);
408
409 }
getPluginName()
Returns a plugin name.
initialize(Server $server)
This initializes the plugin.

References Sabre\DAV\ServerPlugin\getPluginName(), and Sabre\DAV\ServerPlugin\initialize().

Referenced by Sabre\DAV\Server\__construct().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculateUri()

Sabre\DAV\Server::calculateUri (   $uri)

Turns a URI such as the REQUEST_URI into a local path.

This method:

  • strips off the base path
  • normalizes the path
  • uri-decodes the path
Parameters
string$uri
Exceptions
Exception

Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri

Returns
string

Definition at line 565 of file Server.php.

565 {
566
567 if ($uri[0] != '/' && strpos($uri, '://')) {
568
569 $uri = parse_url($uri, PHP_URL_PATH);
570
571 }
572
573 $uri = Uri\normalize(str_replace('//', '/', $uri));
575
576 if (strpos($uri, $baseUri) === 0) {
577
578 return trim(URLUtil::decodePath(substr($uri, strlen($baseUri))), '/');
579
580 // A special case, if the baseUri was accessed without a trailing
581 // slash, we'll accept it as well.
582 } elseif ($uri . '/' === $baseUri) {
583
584 return '';
585
586 } else {
587
588 throw new Exception\Forbidden('Requested uri (' . $uri . ') is out of base uri (' . $this->getBaseUri() . ')');
589
590 }
591
592 }
getBaseUri()
Returns the base responding uri.
Definition: Server.php:347
static decodePath($path)
Decodes a url-encoded path.
Definition: URLUtil.php:57
normalize($uri)
Takes a URI or partial URI as its argument, and normalizes it.
Definition: functions.php:114

References Sabre\DAV\Server\$baseUri, Sabre\HTTP\URLUtil\decodePath(), Sabre\DAV\Server\getBaseUri(), and Sabre\Uri\normalize().

Referenced by Sabre\DAV\Server\getCopyAndMoveInfo(), Sabre\DAV\Server\getIfConditions(), and Sabre\DAV\Server\getRequestUri().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkPreconditions()

Sabre\DAV\Server::checkPreconditions ( RequestInterface  $request,
ResponseInterface  $response 
)

This method checks the main HTTP preconditions.

Currently these are:

  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-Since

The method will return true if all preconditions are met The method will return false, or throw an exception if preconditions failed. If false is returned the operation should be aborted, and the appropriate HTTP response headers are already set.

Normally this method will throw 412 Precondition Failed for failures related to If-None-Match, If-Match and If-Unmodified Since. It will set the status to 304 Not Modified for If-Modified_since.

Parameters
RequestInterface$request
ResponseInterface$response
Returns
bool

Definition at line 1293 of file Server.php.

1293 {
1294
1295 $path = $request->getPath();
1296 $node = null;
1297 $lastMod = null;
1298 $etag = null;
1299
1300 if ($ifMatch = $request->getHeader('If-Match')) {
1301
1302 // If-Match contains an entity tag. Only if the entity-tag
1303 // matches we are allowed to make the request succeed.
1304 // If the entity-tag is '*' we are only allowed to make the
1305 // request succeed if a resource exists at that url.
1306 try {
1307 $node = $this->tree->getNodeForPath($path);
1308 } catch (Exception\NotFound $e) {
1309 throw new Exception\PreconditionFailed('An If-Match header was specified and the resource did not exist', 'If-Match');
1310 }
1311
1312 // Only need to check entity tags if they are not *
1313 if ($ifMatch !== '*') {
1314
1315 // There can be multiple ETags
1316 $ifMatch = explode(',', $ifMatch);
1317 $haveMatch = false;
1318 foreach ($ifMatch as $ifMatchItem) {
1319
1320 // Stripping any extra spaces
1321 $ifMatchItem = trim($ifMatchItem, ' ');
1322
1323 $etag = $node instanceof IFile ? $node->getETag() : null;
1324 if ($etag === $ifMatchItem) {
1325 $haveMatch = true;
1326 } else {
1327 // Evolution has a bug where it sometimes prepends the "
1328 // with a \. This is our workaround.
1329 if (str_replace('\\"', '"', $ifMatchItem) === $etag) {
1330 $haveMatch = true;
1331 }
1332 }
1333
1334 }
1335 if (!$haveMatch) {
1336 if ($etag) $response->setHeader('ETag', $etag);
1337 throw new Exception\PreconditionFailed('An If-Match header was specified, but none of the specified the ETags matched.', 'If-Match');
1338 }
1339 }
1340 }
1341
1342 if ($ifNoneMatch = $request->getHeader('If-None-Match')) {
1343
1344 // The If-None-Match header contains an ETag.
1345 // Only if the ETag does not match the current ETag, the request will succeed
1346 // The header can also contain *, in which case the request
1347 // will only succeed if the entity does not exist at all.
1348 $nodeExists = true;
1349 if (!$node) {
1350 try {
1351 $node = $this->tree->getNodeForPath($path);
1352 } catch (Exception\NotFound $e) {
1353 $nodeExists = false;
1354 }
1355 }
1356 if ($nodeExists) {
1357 $haveMatch = false;
1358 if ($ifNoneMatch === '*') $haveMatch = true;
1359 else {
1360
1361 // There might be multiple ETags
1362 $ifNoneMatch = explode(',', $ifNoneMatch);
1363 $etag = $node instanceof IFile ? $node->getETag() : null;
1364
1365 foreach ($ifNoneMatch as $ifNoneMatchItem) {
1366
1367 // Stripping any extra spaces
1368 $ifNoneMatchItem = trim($ifNoneMatchItem, ' ');
1369
1370 if ($etag === $ifNoneMatchItem) $haveMatch = true;
1371
1372 }
1373
1374 }
1375
1376 if ($haveMatch) {
1377 if ($etag) $response->setHeader('ETag', $etag);
1378 if ($request->getMethod() === 'GET') {
1379 $response->setStatus(304);
1380 return false;
1381 } else {
1382 throw new Exception\PreconditionFailed('An If-None-Match header was specified, but the ETag matched (or * was specified).', 'If-None-Match');
1383 }
1384 }
1385 }
1386
1387 }
1388
1389 if (!$ifNoneMatch && ($ifModifiedSince = $request->getHeader('If-Modified-Since'))) {
1390
1391 // The If-Modified-Since header contains a date. We
1392 // will only return the entity if it has been changed since
1393 // that date. If it hasn't been changed, we return a 304
1394 // header
1395 // Note that this header only has to be checked if there was no If-None-Match header
1396 // as per the HTTP spec.
1397 $date = HTTP\Util::parseHTTPDate($ifModifiedSince);
1398
1399 if ($date) {
1400 if (is_null($node)) {
1401 $node = $this->tree->getNodeForPath($path);
1402 }
1403 $lastMod = $node->getLastModified();
1404 if ($lastMod) {
1405 $lastMod = new \DateTime('@' . $lastMod);
1406 if ($lastMod <= $date) {
1407 $response->setStatus(304);
1408 $response->setHeader('Last-Modified', HTTP\Util::toHTTPDate($lastMod));
1409 return false;
1410 }
1411 }
1412 }
1413 }
1414
1415 if ($ifUnmodifiedSince = $request->getHeader('If-Unmodified-Since')) {
1416
1417 // The If-Unmodified-Since will allow allow the request if the
1418 // entity has not changed since the specified date.
1419 $date = HTTP\Util::parseHTTPDate($ifUnmodifiedSince);
1420
1421 // We must only check the date if it's valid
1422 if ($date) {
1423 if (is_null($node)) {
1424 $node = $this->tree->getNodeForPath($path);
1425 }
1426 $lastMod = $node->getLastModified();
1427 if ($lastMod) {
1428 $lastMod = new \DateTime('@' . $lastMod);
1429 if ($lastMod > $date) {
1430 throw new Exception\PreconditionFailed('An If-Unmodified-Since header was specified, but the entity has been changed since the specified date.', 'If-Unmodified-Since');
1431 }
1432 }
1433 }
1434
1435 }
1436
1437 // Now the hardest, the If: header. The If: header can contain multiple
1438 // urls, ETags and so-called 'state tokens'.
1439 //
1440 // Examples of state tokens include lock-tokens (as defined in rfc4918)
1441 // and sync-tokens (as defined in rfc6578).
1442 //
1443 // The only proper way to deal with these, is to emit events, that a
1444 // Sync and Lock plugin can pick up.
1445 $ifConditions = $this->getIfConditions($request);
1446
1447 foreach ($ifConditions as $kk => $ifCondition) {
1448 foreach ($ifCondition['tokens'] as $ii => $token) {
1449 $ifConditions[$kk]['tokens'][$ii]['validToken'] = false;
1450 }
1451 }
1452
1453 // Plugins are responsible for validating all the tokens.
1454 // If a plugin deemed a token 'valid', it will set 'validToken' to
1455 // true.
1456 $this->emit('validateTokens', [$request, &$ifConditions]);
1457
1458 // Now we're going to analyze the result.
1459
1460 // Every ifCondition needs to validate to true, so we exit as soon as
1461 // we have an invalid condition.
1462 foreach ($ifConditions as $ifCondition) {
1463
1464 $uri = $ifCondition['uri'];
1465 $tokens = $ifCondition['tokens'];
1466
1467 // We only need 1 valid token for the condition to succeed.
1468 foreach ($tokens as $token) {
1469
1470 $tokenValid = $token['validToken'] || !$token['token'];
1471
1472 $etagValid = false;
1473 if (!$token['etag']) {
1474 $etagValid = true;
1475 }
1476 // Checking the ETag, only if the token was already deemed
1477 // valid and there is one.
1478 if ($token['etag'] && $tokenValid) {
1479
1480 // The token was valid, and there was an ETag. We must
1481 // grab the current ETag and check it.
1482 $node = $this->tree->getNodeForPath($uri);
1483 $etagValid = $node instanceof IFile && $node->getETag() == $token['etag'];
1484
1485 }
1486
1487
1488 if (($tokenValid && $etagValid) ^ $token['negate']) {
1489 // Both were valid, so we can go to the next condition.
1490 continue 2;
1491 }
1492
1493
1494 }
1495
1496 // If we ended here, it means there was no valid ETag + token
1497 // combination found for the current condition. This means we fail!
1498 throw new Exception\PreconditionFailed('Failed to find a valid token/etag combination for ' . $uri, 'If');
1499
1500 }
1501
1502 return true;
1503
1504 }
$path
Definition: aliased.php:25
foreach($paths as $path) $request
Definition: asyncclient.php:32
getIfConditions(RequestInterface $request)
This method is created to extract information from the WebDAV HTTP 'If:' header.
Definition: Server.php:1577
static parseHTTPDate($dateHeader)
Parses a RFC2616-compatible date string.
Definition: Util.php:53
static toHTTPDate(\DateTime $dateTime)
Transforms a DateTime object to HTTP's most common date format.
Definition: Util.php:69
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
$response

References $ii, $path, $request, $response, PHPMailer\PHPMailer\$token, Sabre\Event\EventEmitterInterface\emit(), Sabre\DAV\IFile\getETag(), Sabre\DAV\Server\getIfConditions(), Sabre\HTTP\Util\parseHTTPDate(), and Sabre\HTTP\Util\toHTTPDate().

Referenced by Sabre\DAV\Server\invokeMethod().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createCollection()

Sabre\DAV\Server::createCollection (   $uri,
MkCol  $mkCol 
)

Use this method to create a new collection.

Parameters
string$uriThe new uri
MkCol$mkCol
Returns
array|null

If the parent is an instance of IExtendedCollection, it means that we can pass the MkCol object directly as it may be able to store properties immediately.

If the parent is a standard ICollection, it means only 'standard' collections can be created, so we should fail any MKCOL operation that carries extra resourcetypes.

Definition at line 1157 of file Server.php.

1157 {
1158
1159 list($parentUri, $newName) = URLUtil::splitPath($uri);
1160
1161 // Making sure the parent exists
1162 try {
1163 $parent = $this->tree->getNodeForPath($parentUri);
1164
1165 } catch (Exception\NotFound $e) {
1166 throw new Exception\Conflict('Parent node does not exist');
1167
1168 }
1169
1170 // Making sure the parent is a collection
1171 if (!$parent instanceof ICollection) {
1172 throw new Exception\Conflict('Parent node is not a collection');
1173 }
1174
1175 // Making sure the child does not already exist
1176 try {
1177 $parent->getChild($newName);
1178
1179 // If we got here.. it means there's already a node on that url, and we need to throw a 405
1180 throw new Exception\MethodNotAllowed('The resource you tried to create already exists');
1181
1182 } catch (Exception\NotFound $e) {
1183 // NotFound is the expected behavior.
1184 }
1185
1186
1187 if (!$this->emit('beforeBind', [$uri])) return;
1188
1189 if ($parent instanceof IExtendedCollection) {
1190
1196 $parent->createExtendedCollection($newName, $mkCol);
1197
1198 } else {
1199
1205 if (count($mkCol->getResourceType()) > 1) {
1206 throw new Exception\InvalidResourceType('The {DAV:}resourcetype you specified is not supported here.');
1207 }
1208
1209 $parent->createDirectory($newName);
1210
1211 }
1212
1213 // If there are any properties that have not been handled/stored,
1214 // we ask the 'propPatch' event to handle them. This will allow for
1215 // example the propertyStorage system to store properties upon MKCOL.
1216 if ($mkCol->getRemainingMutations()) {
1217 $this->emit('propPatch', [$uri, $mkCol]);
1218 }
1219 $success = $mkCol->commit();
1220
1221 if (!$success) {
1222 $result = $mkCol->getResult();
1223
1224 $formattedResult = [
1225 'href' => $uri,
1226 ];
1227
1228 foreach ($result as $propertyName => $status) {
1229
1230 if (!isset($formattedResult[$status])) {
1231 $formattedResult[$status] = [];
1232 }
1233 $formattedResult[$status][$propertyName] = null;
1234
1235 }
1236 return $formattedResult;
1237 }
1238
1239 $this->tree->markDirty($parentUri);
1240 $this->emit('afterBind', [$uri]);
1241
1242 }
$result
$success
Definition: Utf8Test.php:86
getResourceType()
Returns the resourcetype of the new collection.
Definition: MkCol.php:50
commit()
Performs the actual update, and calls all callbacks.
Definition: PropPatch.php:225
getRemainingMutations()
Returns the list of properties that don't have a result code yet.
Definition: PropPatch.php:184
getResult()
Returns the result of the operation.
Definition: PropPatch.php:356
static splitPath($path)
Returns the 'dirname' and 'basename' for a path.
Definition: URLUtil.php:83

References $result, $success, Sabre\DAV\PropPatch\commit(), Sabre\Event\EventEmitterInterface\emit(), Sabre\DAV\PropPatch\getRemainingMutations(), Sabre\DAV\MkCol\getResourceType(), Sabre\DAV\PropPatch\getResult(), and Sabre\HTTP\URLUtil\splitPath().

Referenced by Sabre\DAV\Server\createDirectory().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createDirectory()

Sabre\DAV\Server::createDirectory (   $uri)

This method is invoked by sub-systems creating a new directory.

Parameters
string$uri
Returns
void

Definition at line 1144 of file Server.php.

1144 {
1145
1146 $this->createCollection($uri, new MkCol(['{DAV:}collection'], []));
1147
1148 }
This class represents a MKCOL operation.
Definition: MkCol.php:23
createCollection($uri, MkCol $mkCol)
Use this method to create a new collection.
Definition: Server.php:1157

References Sabre\DAV\Server\createCollection().

+ Here is the call graph for this function:

◆ createFile()

Sabre\DAV\Server::createFile (   $uri,
  $data,
$etag = null 
)

This method is invoked by sub-systems creating a new file.

Currently this is done by HTTP PUT and HTTP LOCK (in the Locks_Plugin). It was important to get this done through a centralized function, allowing plugins to intercept this using the beforeCreateFile event.

This method will return true if the file was actually created

Parameters
string$uri
resource$data
string$etag
Returns
bool

Definition at line 1076 of file Server.php.

1076 {
1077
1078 list($dir, $name) = URLUtil::splitPath($uri);
1079
1080 if (!$this->emit('beforeBind', [$uri])) return false;
1081
1082 $parent = $this->tree->getNodeForPath($dir);
1083 if (!$parent instanceof ICollection) {
1084 throw new Exception\Conflict('Files can only be created as children of collections');
1085 }
1086
1087 // It is possible for an event handler to modify the content of the
1088 // body, before it gets written. If this is the case, $modified
1089 // should be set to true.
1090 //
1091 // If $modified is true, we must not send back an ETag.
1092 $modified = false;
1093 if (!$this->emit('beforeCreateFile', [$uri, &$data, $parent, &$modified])) return false;
1094
1095 $etag = $parent->createFile($name, $data);
1096
1097 if ($modified) $etag = null;
1098
1099 $this->tree->markDirty($dir . '/' . $name);
1100
1101 $this->emit('afterBind', [$uri]);
1102 $this->emit('afterCreateFile', [$uri, $parent]);
1103
1104 return true;
1105 }
$data
Definition: bench.php:6

References $data, $name, Sabre\Event\EventEmitterInterface\emit(), and Sabre\HTTP\URLUtil\splitPath().

+ Here is the call graph for this function:

◆ exec()

Sabre\DAV\Server::exec ( )

Starts the DAV Server.

Returns
void

Definition at line 240 of file Server.php.

240 {
241
242 try {
243
244 // If nginx (pre-1.2) is used as a proxy server, and SabreDAV as an
245 // origin, we must make sure we send back HTTP/1.0 if this was
246 // requested.
247 // This is mainly because nginx doesn't support Chunked Transfer
248 // Encoding, and this forces the webserver SabreDAV is running on,
249 // to buffer entire responses to calculate Content-Length.
250 $this->httpResponse->setHTTPVersion($this->httpRequest->getHTTPVersion());
251
252 // Setting the base url
253 $this->httpRequest->setBaseUrl($this->getBaseUri());
254 $this->invokeMethod($this->httpRequest, $this->httpResponse);
255
256 } catch (\Exception $e) {
257
258 try {
259 $this->emit('exception', [$e]);
260 } catch (\Exception $ignore) {
261 }
262 $DOM = new \DOMDocument('1.0', 'utf-8');
263 $DOM->formatOutput = true;
264
265 $error = $DOM->createElementNS('DAV:', 'd:error');
266 $error->setAttribute('xmlns:s', self::NS_SABREDAV);
267 $DOM->appendChild($error);
268
269 $h = function($v) {
270
271 return htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8');
272
273 };
274
275 if (self::$exposeVersion) {
276 $error->appendChild($DOM->createElement('s:sabredav-version', $h(Version::VERSION)));
277 }
278
279 $error->appendChild($DOM->createElement('s:exception', $h(get_class($e))));
280 $error->appendChild($DOM->createElement('s:message', $h($e->getMessage())));
281 if ($this->debugExceptions) {
282 $error->appendChild($DOM->createElement('s:file', $h($e->getFile())));
283 $error->appendChild($DOM->createElement('s:line', $h($e->getLine())));
284 $error->appendChild($DOM->createElement('s:code', $h($e->getCode())));
285 $error->appendChild($DOM->createElement('s:stacktrace', $h($e->getTraceAsString())));
286 }
287
288 if ($this->debugExceptions) {
289 $previous = $e;
290 while ($previous = $previous->getPrevious()) {
291 $xPrevious = $DOM->createElement('s:previous-exception');
292 $xPrevious->appendChild($DOM->createElement('s:exception', $h(get_class($previous))));
293 $xPrevious->appendChild($DOM->createElement('s:message', $h($previous->getMessage())));
294 $xPrevious->appendChild($DOM->createElement('s:file', $h($previous->getFile())));
295 $xPrevious->appendChild($DOM->createElement('s:line', $h($previous->getLine())));
296 $xPrevious->appendChild($DOM->createElement('s:code', $h($previous->getCode())));
297 $xPrevious->appendChild($DOM->createElement('s:stacktrace', $h($previous->getTraceAsString())));
298 $error->appendChild($xPrevious);
299 }
300 }
301
302
303 if ($e instanceof Exception) {
304
305 $httpCode = $e->getHTTPCode();
306 $e->serialize($this, $error);
307 $headers = $e->getHTTPHeaders($this);
308
309 } else {
310
311 $httpCode = 500;
312 $headers = [];
313
314 }
315 $headers['Content-Type'] = 'application/xml; charset=utf-8';
316
317 $this->httpResponse->setStatus($httpCode);
318 $this->httpResponse->setHeaders($headers);
319 $this->httpResponse->setBody($DOM->saveXML());
320 $this->sapi->sendResponse($this->httpResponse);
321
322 }
323
324 }
while(false !==( $line=fgets( $in))) if(! $columns) $ignore
Definition: Utf8Test.php:63
invokeMethod(RequestInterface $request, ResponseInterface $response, $sendResponse=true)
Handles a http request, and execute a method based on its name.
Definition: Server.php:461
const VERSION
Full version number.
Definition: Version.php:17
$h

References $h, $ignore, Sabre\Event\EventEmitterInterface\emit(), Sabre\DAV\Server\getBaseUri(), Sabre\DAV\Exception\getHTTPCode(), Sabre\DAV\Exception\getHTTPHeaders(), Sabre\DAV\Server\invokeMethod(), Sabre\DAV\Exception\serialize(), and Sabre\DAV\Version\VERSION.

+ Here is the call graph for this function:

◆ generateMultiStatus()

Sabre\DAV\Server::generateMultiStatus (   $fileProperties,
  $strip404s = false 
)

Generates a WebDAV propfind response body based on a list of nodes.

If 'strip404s' is set to true, all 404 responses will be removed.

Parameters
array | \Traversable$filePropertiesThe list with nodes
bool$strip404s
Returns
string

Definition at line 1656 of file Server.php.

1656 {
1657
1658 $w = $this->xml->getWriter();
1659 $w->openMemory();
1660 $w->contextUri = $this->baseUri;
1661 $w->startDocument();
1662
1663 $w->startElement('{DAV:}multistatus');
1664
1665 foreach ($fileProperties as $entry) {
1666
1667 $href = $entry['href'];
1668 unset($entry['href']);
1669 if ($strip404s) {
1670 unset($entry[404]);
1671 }
1672 $response = new Xml\Element\Response(
1673 ltrim($href, '/'),
1674 $entry
1675 );
1676 $w->write([
1677 'name' => '{DAV:}response',
1678 'value' => $response
1679 ]);
1680 }
1681 $w->endElement();
1682
1683 return $w->outputMemory();
1684
1685 }
$w

References Sabre\DAV\Server\$baseUri, $response, and $w.

◆ generatePathNodes()

Sabre\DAV\Server::generatePathNodes ( PropFind  $propFind,
array  $yieldFirst = null 
)
private

Small helper to support PROPFIND with DEPTH_INFINITY.

Parameters
PropFind$propFind
array$yieldFirst
Returns
\Iterator

Definition at line 885 of file Server.php.

885 {
886 if ($yieldFirst !== null) {
887 yield $yieldFirst;
888 }
889 $newDepth = $propFind->getDepth();
890 $path = $propFind->getPath();
891
892 if ($newDepth !== self::DEPTH_INFINITY) {
893 $newDepth--;
894 }
895
896 foreach ($this->tree->getChildren($path) as $childNode) {
897 $subPropFind = clone $propFind;
898 $subPropFind->setDepth($newDepth);
899 if ($path !== '') {
900 $subPath = $path . '/' . $childNode->getName();
901 } else {
902 $subPath = $childNode->getName();
903 }
904 $subPropFind->setPath($subPath);
905
906 yield [
907 $subPropFind,
908 $childNode
909 ];
910
911 if (($newDepth === self::DEPTH_INFINITY || $newDepth >= 1) && $childNode instanceof ICollection) {
912 foreach ($this->generatePathNodes($subPropFind) as $subItem) {
913 yield $subItem;
914 }
915 }
916
917 }
918 }
getDepth()
Returns the depth of this propfind request.
Definition: PropFind.php:198
getPath()
Returns the path this PROPFIND request is for.
Definition: PropFind.php:187
setDepth($depth)
Updates the depth of this propfind request.
Definition: PropFind.php:210
generatePathNodes(PropFind $propFind, array $yieldFirst=null)
Small helper to support PROPFIND with DEPTH_INFINITY.
Definition: Server.php:885

References $path, Sabre\DAV\Server\generatePathNodes(), Sabre\DAV\PropFind\getDepth(), Sabre\DAV\PropFind\getPath(), and Sabre\DAV\PropFind\setDepth().

Referenced by Sabre\DAV\Server\generatePathNodes(), and Sabre\DAV\Server\getPropertiesIteratorForPath().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAllowedMethods()

Sabre\DAV\Server::getAllowedMethods (   $path)

Returns an array with all the supported HTTP methods for a specific uri.

Parameters
string$path
Returns
array

Definition at line 512 of file Server.php.

512 {
513
514 $methods = [
515 'OPTIONS',
516 'GET',
517 'HEAD',
518 'DELETE',
519 'PROPFIND',
520 'PUT',
521 'PROPPATCH',
522 'COPY',
523 'MOVE',
524 'REPORT'
525 ];
526
527 // The MKCOL is only allowed on an unmapped uri
528 try {
529 $this->tree->getNodeForPath($path);
530 } catch (Exception\NotFound $e) {
531 $methods[] = 'MKCOL';
532 }
533
534 // We're also checking if any of the plugins register any new methods
535 foreach ($this->plugins as $plugin) $methods = array_merge($methods, $plugin->getHTTPMethods($path));
536 array_unique($methods);
537
538 return $methods;
539
540 }

References $path.

◆ getBaseUri()

Sabre\DAV\Server::getBaseUri ( )

Returns the base responding uri.

Returns
string

Definition at line 347 of file Server.php.

347 {
348
349 if (is_null($this->baseUri)) $this->baseUri = $this->guessBaseUri();
350 return $this->baseUri;
351
352 }
guessBaseUri()
This method attempts to detect the base uri.
Definition: Server.php:362

References Sabre\DAV\Server\$baseUri, and Sabre\DAV\Server\guessBaseUri().

Referenced by Sabre\DAV\Server\calculateUri(), and Sabre\DAV\Server\exec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCopyAndMoveInfo()

Sabre\DAV\Server::getCopyAndMoveInfo ( RequestInterface  $request)

Returns information about Copy and Move requests.

This function is created to help getting information about the source and the destination for the WebDAV MOVE and COPY HTTP request. It also validates a lot of information and throws proper exceptions

The returned value is an array with the following keys:

  • destination - Destination path
  • destinationExists - Whether or not the destination is an existing url (and should therefore be overwritten)
Parameters
RequestInterface$request
Exceptions
Exception

BadRequest upon missing or broken request headers

Exceptions
Exception

UnsupportedMediaType when trying to copy into a non-collection.

Exceptions
Exception

PreconditionFailed If overwrite is set to false, but the destination exists.

Exceptions
Exception

Forbidden when source and destination paths are identical.

Exceptions
Exception

Conflict When trying to copy a node into its own subtree.

Returns
array

Definition at line 729 of file Server.php.

729 {
730
731 // Collecting the relevant HTTP headers
732 if (!$request->getHeader('Destination')) throw new Exception\BadRequest('The destination header was not supplied');
733 $destination = $this->calculateUri($request->getHeader('Destination'));
734 $overwrite = $request->getHeader('Overwrite');
735 if (!$overwrite) $overwrite = 'T';
736 if (strtoupper($overwrite) == 'T') $overwrite = true;
737 elseif (strtoupper($overwrite) == 'F') $overwrite = false;
738 // We need to throw a bad request exception, if the header was invalid
739 else throw new Exception\BadRequest('The HTTP Overwrite header should be either T or F');
740
741 list($destinationDir) = URLUtil::splitPath($destination);
742
743 try {
744 $destinationParent = $this->tree->getNodeForPath($destinationDir);
745 if (!($destinationParent instanceof ICollection)) throw new Exception\UnsupportedMediaType('The destination node is not a collection');
746 } catch (Exception\NotFound $e) {
747
748 // If the destination parent node is not found, we throw a 409
749 throw new Exception\Conflict('The destination node is not found');
750 }
751
752 try {
753
754 $destinationNode = $this->tree->getNodeForPath($destination);
755
756 // If this succeeded, it means the destination already exists
757 // we'll need to throw precondition failed in case overwrite is false
758 if (!$overwrite) throw new Exception\PreconditionFailed('The destination node already exists, and the overwrite header is set to false', 'Overwrite');
759
760 } catch (Exception\NotFound $e) {
761
762 // Destination didn't exist, we're all good
763 $destinationNode = false;
764
765 }
766
767 $requestPath = $request->getPath();
768 if ($destination === $requestPath) {
769 throw new Exception\Forbidden('Source and destination uri are identical.');
770 }
771 if (substr($destination, 0, strlen($requestPath) + 1) === $requestPath . '/') {
772 throw new Exception\Conflict('The destination may not be part of the same subtree as the source path.');
773 }
774
775 // These are the three relevant properties we need to return
776 return [
777 'destination' => $destination,
778 'destinationExists' => !!$destinationNode,
779 'destinationNode' => $destinationNode,
780 ];
781
782 }
if($out) else
calculateUri($uri)
Turns a URI such as the REQUEST_URI into a local path.
Definition: Server.php:565
try
Definition: cron.php:22
getHeader($name)
Returns a specific HTTP header, based on it's name.
$destination

References $destination, $request, Sabre\DAV\Server\calculateUri(), Sabre\HTTP\MessageInterface\getHeader(), and Sabre\HTTP\URLUtil\splitPath().

+ Here is the call graph for this function:

◆ getHTTPDepth()

Sabre\DAV\Server::getHTTPDepth (   $default = self::DEPTH_INFINITY)

Returns the HTTP depth header.

This method returns the contents of the HTTP depth request header. If the depth header was 'infinity' it will return the Sabre\DAV\Server::DEPTH_INFINITY object It is possible to supply a default depth value, which is used when the depth header has invalid content, or is completely non-existent

Parameters
mixed$default
Returns
int

Definition at line 603 of file Server.php.

603 {
604
605 // If its not set, we'll grab the default
606 $depth = $this->httpRequest->getHeader('Depth');
607
608 if (is_null($depth)) return $default;
609
610 if ($depth == 'infinity') return self::DEPTH_INFINITY;
611
612
613 // If its an unknown value. we'll grab the default
614 if (!ctype_digit($depth)) return $default;
615
616 return (int)$depth;
617
618 }
$default
Definition: build.php:20
const DEPTH_INFINITY
Infinity is used for some request supporting the HTTP Depth header and indicates that the operation s...
Definition: Server.php:30

References $default, and Sabre\DAV\Server\DEPTH_INFINITY.

◆ getHTTPHeaders()

Sabre\DAV\Server::getHTTPHeaders (   $path)

Returns a list of HTTP headers for a particular resource.

The generated http headers are based on properties provided by the resource. The method basically provides a simple mapping between DAV property and HTTP header.

The headers are intended to be used for HEAD and GET requests.

Parameters
string$path
Returns
array

Definition at line 849 of file Server.php.

849 {
850
851 $propertyMap = [
852 '{DAV:}getcontenttype' => 'Content-Type',
853 '{DAV:}getcontentlength' => 'Content-Length',
854 '{DAV:}getlastmodified' => 'Last-Modified',
855 '{DAV:}getetag' => 'ETag',
856 ];
857
858 $properties = $this->getProperties($path, array_keys($propertyMap));
859
860 $headers = [];
861 foreach ($propertyMap as $property => $header) {
862 if (!isset($properties[$property])) continue;
863
864 if (is_scalar($properties[$property])) {
865 $headers[$header] = $properties[$property];
866
867 // GetLastModified gets special cased
868 } elseif ($properties[$property] instanceof Xml\Property\GetLastModified) {
869 $headers[$header] = HTTP\Util::toHTTPDate($properties[$property]->getTime());
870 }
871
872 }
873
874 return $headers;
875
876 }
getTime()
Definition: MetaLoader.php:492
getProperties($path, $propertyNames)
Returns a list of properties for a path.
Definition: Server.php:799

References $header, $path, Sabre\DAV\Server\getProperties(), getTime(), and Sabre\HTTP\Util\toHTTPDate().

+ Here is the call graph for this function:

◆ getHTTPPrefer()

Sabre\DAV\Server::getHTTPPrefer ( )

Returns the HTTP Prefer header information.

The prefer header is defined in: http://tools.ietf.org/html/draft-snell-http-prefer-14

This method will return an array with options.

Currently, the following options may be returned: [ 'return-asynch' => true, 'return-minimal' => true, 'return-representation' => true, 'wait' => 30, 'strict' => true, 'lenient' => true, ]

This method also supports the Brief header, and will also return 'return-minimal' if the brief header was set to 't'.

For the boolean options, false will be returned if the headers are not specified. For the integer options it will be 'null'.

Returns
array

Definition at line 678 of file Server.php.

678 {
679
680 $result = [
681 // can be true or false
682 'respond-async' => false,
683 // Could be set to 'representation' or 'minimal'.
684 'return' => null,
685 // Used as a timeout, is usually a number.
686 'wait' => null,
687 // can be 'strict' or 'lenient'.
688 'handling' => false,
689 ];
690
691 if ($prefer = $this->httpRequest->getHeader('Prefer')) {
692
693 $result = array_merge(
694 $result,
695 HTTP\parsePrefer($prefer)
696 );
697
698 } elseif ($this->httpRequest->getHeader('Brief') == 't') {
699 $result['return'] = 'minimal';
700 }
701
702 return $result;
703
704 }
parsePrefer($input)
Parses the Prefer header, as defined in RFC7240.
Definition: functions.php:222

References $result, and Sabre\HTTP\parsePrefer().

+ Here is the call graph for this function:

◆ getHTTPRange()

Sabre\DAV\Server::getHTTPRange ( )

Returns the HTTP range header.

This method returns null if there is no well-formed HTTP range request header or array($start, $end).

The first number is the offset of the first byte in the range. The second number is the offset of the last byte in the range.

If the second offset is null, it should be treated as the offset of the last byte of the entity If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity

Returns
array|null

Definition at line 634 of file Server.php.

634 {
635
636 $range = $this->httpRequest->getHeader('range');
637 if (is_null($range)) return null;
638
639 // Matching "Range: bytes=1234-5678: both numbers are optional
640
641 if (!preg_match('/^bytes=([0-9]*)-([0-9]*)$/i', $range, $matches)) return null;
642
643 if ($matches[1] === '' && $matches[2] === '') return null;
644
645 return [
646 $matches[1] !== '' ? $matches[1] : null,
647 $matches[2] !== '' ? $matches[2] : null,
648 ];
649
650 }

◆ getIfConditions()

Sabre\DAV\Server::getIfConditions ( RequestInterface  $request)

This method is created to extract information from the WebDAV HTTP 'If:' header.

The If header can be quite complex, and has a bunch of features. We're using a regex to extract all relevant information The function will return an array, containing structs with the following keys

  • uri - the uri the condition applies to.
  • tokens - The lock token. another 2 dimensional array containing 3 elements

Example 1:

If: (<opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)

Would result in:

[ [ 'uri' => '/request/uri', 'tokens' => [ [ [ 'negate' => false, 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2', 'etag' => "" ] ] ], ] ]

Example 2:

If: </path> (Not <opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> ["Im An ETag"]) (["Another ETag"]) </path2> (Not ["Path2 ETag"])

Would result in:

[ [ 'uri' => 'path', 'tokens' => [ [ [ 'negate' => true, 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2', 'etag' => '"Im An ETag"' ], [ 'negate' => false, 'token' => '', 'etag' => '"Another ETag"' ] ] ], ], [ 'uri' => 'path2', 'tokens' => [ [ [ 'negate' => true, 'token' => '', 'etag' => '"Path2 ETag"' ] ] ], ], ]

Parameters
RequestInterface$request
Returns
array

Definition at line 1577 of file Server.php.

1577 {
1578
1579 $header = $request->getHeader('If');
1580 if (!$header) return [];
1581
1582 $matches = [];
1583
1584 $regex = '/(?:<(?P<uri>.*?)>\s)?\‍((?P<not>Not\s)?(?:<(?P<token>[^>]*)>)?(?:\s?)(?:\[(?P<etag>[^\]]*)\])?\‍)/im';
1585 preg_match_all($regex, $header, $matches, PREG_SET_ORDER);
1586
1587 $conditions = [];
1588
1589 foreach ($matches as $match) {
1590
1591 // If there was no uri specified in this match, and there were
1592 // already conditions parsed, we add the condition to the list of
1593 // conditions for the previous uri.
1594 if (!$match['uri'] && count($conditions)) {
1595 $conditions[count($conditions) - 1]['tokens'][] = [
1596 'negate' => $match['not'] ? true : false,
1597 'token' => $match['token'],
1598 'etag' => isset($match['etag']) ? $match['etag'] : ''
1599 ];
1600 } else {
1601
1602 if (!$match['uri']) {
1603 $realUri = $request->getPath();
1604 } else {
1605 $realUri = $this->calculateUri($match['uri']);
1606 }
1607
1608 $conditions[] = [
1609 'uri' => $realUri,
1610 'tokens' => [
1611 [
1612 'negate' => $match['not'] ? true : false,
1613 'token' => $match['token'],
1614 'etag' => isset($match['etag']) ? $match['etag'] : ''
1615 ]
1616 ],
1617
1618 ];
1619 }
1620
1621 }
1622
1623 return $conditions;
1624
1625 }

References $header, $request, and Sabre\DAV\Server\calculateUri().

Referenced by Sabre\DAV\Server\checkPreconditions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getLogger()

Sabre\DAV\Server::getLogger ( )

Returns the PSR-3 logger object.

Returns
LoggerInterface

Definition at line 444 of file Server.php.

444 {
445
446 if (!$this->logger) {
447 $this->logger = new NullLogger();
448 }
449 return $this->logger;
450
451 }

◆ getPlugin()

Sabre\DAV\Server::getPlugin (   $name)

Returns an initialized plugin by it's name.

This function returns null if the plugin was not found.

Parameters
string$name
Returns
ServerPlugin

Definition at line 419 of file Server.php.

419 {
420
421 if (isset($this->plugins[$name]))
422 return $this->plugins[$name];
423
424 return null;
425
426 }

References $name.

◆ getPlugins()

Sabre\DAV\Server::getPlugins ( )

Returns all plugins.

Returns
array

Definition at line 433 of file Server.php.

433 {
434
435 return $this->plugins;
436
437 }

References Sabre\DAV\Server\$plugins.

◆ getProperties()

Sabre\DAV\Server::getProperties (   $path,
  $propertyNames 
)

Returns a list of properties for a path.

This is a simplified version getPropertiesForPath. If you aren't interested in status codes, but you just want to have a flat list of properties, use this method.

Please note though that any problems related to retrieving properties, such as permission issues will just result in an empty array being returned.

Parameters
string$path
array$propertyNames
Returns
array

Definition at line 799 of file Server.php.

799 {
800
801 $result = $this->getPropertiesForPath($path, $propertyNames, 0);
802 if (isset($result[0][200])) {
803 return $result[0][200];
804 } else {
805 return [];
806 }
807
808 }
getPropertiesForPath($path, $propertyNames=[], $depth=0)
Returns a list of properties for a given path.
Definition: Server.php:937

References $path, $result, and Sabre\DAV\Server\getPropertiesForPath().

Referenced by Sabre\DAV\Server\getHTTPHeaders().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPropertiesByNode()

Sabre\DAV\Server::getPropertiesByNode ( PropFind  $propFind,
INode  $node 
)

Determines all properties for a node.

This method tries to grab all properties for a node. This method is used internally getPropertiesForPath and a few others.

It could be useful to call this, if you already have an instance of your target node and simply want to run through the system to get a correct list of properties.

Parameters
PropFind$propFind
INode$node
Returns
bool

Definition at line 1056 of file Server.php.

1056 {
1057
1058 return $this->emit('propFind', [$propFind, $node]);
1059
1060 }

References Sabre\Event\EventEmitterInterface\emit().

Referenced by Sabre\DAV\Server\getPropertiesForMultiplePaths(), and Sabre\DAV\Server\getPropertiesIteratorForPath().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPropertiesForChildren()

Sabre\DAV\Server::getPropertiesForChildren (   $path,
  $propertyNames 
)

A kid-friendly way to fetch properties for a node's children.

The returned array will be indexed by the path of the of child node. Only properties that are actually found will be returned.

The parent node will not be returned.

Parameters
string$path
array$propertyNames
Returns
array

Definition at line 822 of file Server.php.

822 {
823
824 $result = [];
825 foreach ($this->getPropertiesForPath($path, $propertyNames, 1) as $k => $row) {
826
827 // Skipping the parent path
828 if ($k === 0) continue;
829
830 $result[$row['href']] = $row[200];
831
832 }
833 return $result;
834
835 }
$row

References $path, $result, $row, and Sabre\DAV\Server\getPropertiesForPath().

+ Here is the call graph for this function:

◆ getPropertiesForMultiplePaths()

Sabre\DAV\Server::getPropertiesForMultiplePaths ( array  $paths,
array  $propertyNames = [] 
)

Returns a list of properties for a list of paths.

The path that should be supplied should have the baseUrl stripped out The list of properties should be supplied in Clark notation. If the list is empty 'allprops' is assumed.

The result is returned as an array, with paths for it's keys. The result may be returned out of order.

Parameters
array$paths
array$propertyNames
Returns
array

Definition at line 1014 of file Server.php.

1014 {
1015
1016 $result = [
1017 ];
1018
1019 $nodes = $this->tree->getMultipleNodes($paths);
1020
1021 foreach ($nodes as $path => $node) {
1022
1023 $propFind = new PropFind($path, $propertyNames);
1024 $r = $this->getPropertiesByNode($propFind, $node);
1025 if ($r) {
1026 $result[$path] = $propFind->getResultForMultiStatus();
1027 $result[$path]['href'] = $path;
1028
1029 $resourceType = $this->getResourceTypeForNode($node);
1030 if (in_array('{DAV:}collection', $resourceType) || in_array('{DAV:}principal', $resourceType)) {
1031 $result[$path]['href'] .= '/';
1032 }
1033 }
1034
1035 }
1036
1037 return $result;
1038
1039 }
This class holds all the information about a PROPFIND request.
Definition: PropFind.php:11
getPropertiesByNode(PropFind $propFind, INode $node)
Determines all properties for a node.
Definition: Server.php:1056
getResourceTypeForNode(INode $node)
Returns an array with resourcetypes for a node.
Definition: Server.php:1633
$r
Definition: example_031.php:79
if($argc< 2) $paths
Definition: migrateto20.php:44

References $nodes, $path, $paths, $r, $result, Sabre\DAV\Server\getPropertiesByNode(), and Sabre\DAV\Server\getResourceTypeForNode().

+ Here is the call graph for this function:

◆ getPropertiesForPath()

Sabre\DAV\Server::getPropertiesForPath (   $path,
  $propertyNames = [],
  $depth = 0 
)

Returns a list of properties for a given path.

The path that should be supplied should have the baseUrl stripped out The list of properties should be supplied in Clark notation. If the list is empty 'allprops' is assumed.

If a depth of 1 is requested child elements will also be returned.

Parameters
string$path
array$propertyNames
int$depth
Returns
array
Deprecated:
Use getPropertiesIteratorForPath() instead (as it's more memory efficient)
See also
getPropertiesIteratorForPath()

Definition at line 937 of file Server.php.

937 {
938
939 return iterator_to_array($this->getPropertiesIteratorForPath($path, $propertyNames, $depth));
940
941 }
getPropertiesIteratorForPath($path, $propertyNames=[], $depth=0)
Returns a list of properties for a given path.
Definition: Server.php:956

References $path, and Sabre\DAV\Server\getPropertiesIteratorForPath().

Referenced by Sabre\DAV\Server\getProperties(), and Sabre\DAV\Server\getPropertiesForChildren().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPropertiesIteratorForPath()

Sabre\DAV\Server::getPropertiesIteratorForPath (   $path,
  $propertyNames = [],
  $depth = 0 
)

Returns a list of properties for a given path.

The path that should be supplied should have the baseUrl stripped out The list of properties should be supplied in Clark notation. If the list is empty 'allprops' is assumed.

If a depth of 1 is requested child elements will also be returned.

Parameters
string$path
array$propertyNames
int$depth
Returns
\Iterator

Definition at line 956 of file Server.php.

956 {
957
958 // The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled
959 if (!$this->enablePropfindDepthInfinity && $depth != 0) $depth = 1;
960
961 $path = trim($path, '/');
962
963 $propFindType = $propertyNames ? PropFind::NORMAL : PropFind::ALLPROPS;
964 $propFind = new PropFind($path, (array)$propertyNames, $depth, $propFindType);
965
966 $parentNode = $this->tree->getNodeForPath($path);
967
968 $propFindRequests = [[
969 $propFind,
970 $parentNode
971 ]];
972
973 if (($depth > 0 || $depth === self::DEPTH_INFINITY) && $parentNode instanceof ICollection) {
974 $propFindRequests = $this->generatePathNodes(clone $propFind, current($propFindRequests));
975 }
976
977 foreach ($propFindRequests as $propFindRequest) {
978
979 list($propFind, $node) = $propFindRequest;
980 $r = $this->getPropertiesByNode($propFind, $node);
981 if ($r) {
982 $result = $propFind->getResultForMultiStatus();
983 $result['href'] = $propFind->getPath();
984
985 // WebDAV recommends adding a slash to the path, if the path is
986 // a collection.
987 // Furthermore, iCal also demands this to be the case for
988 // principals. This is non-standard, but we support it.
989 $resourceType = $this->getResourceTypeForNode($node);
990 if (in_array('{DAV:}collection', $resourceType) || in_array('{DAV:}principal', $resourceType)) {
991 $result['href'] .= '/';
992 }
993 yield $result;
994 }
995
996 }
997
998 }
const NORMAL
A normal propfind.
Definition: PropFind.php:16
const ALLPROPS
An allprops request.
Definition: PropFind.php:27

References $path, $r, $result, Sabre\DAV\PropFind\ALLPROPS, Sabre\DAV\Server\generatePathNodes(), Sabre\DAV\Server\getPropertiesByNode(), Sabre\DAV\Server\getResourceTypeForNode(), and Sabre\DAV\PropFind\NORMAL.

Referenced by Sabre\DAV\Server\getPropertiesForPath().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRequestUri()

Sabre\DAV\Server::getRequestUri ( )

Gets the uri for the request, keeping the base uri into consideration.

Returns
string

Definition at line 547 of file Server.php.

547 {
548
549 return $this->calculateUri($this->httpRequest->getUrl());
550
551 }

References Sabre\DAV\Server\calculateUri().

+ Here is the call graph for this function:

◆ getResourceTypeForNode()

Sabre\DAV\Server::getResourceTypeForNode ( INode  $node)

Returns an array with resourcetypes for a node.

Parameters
INode$node
Returns
array

Definition at line 1633 of file Server.php.

1633 {
1634
1635 $result = [];
1636 foreach ($this->resourceTypeMapping as $className => $resourceType) {
1637 if ($node instanceof $className) $result[] = $resourceType;
1638 }
1639 return $result;
1640
1641 }

References $result.

Referenced by Sabre\DAV\Server\getPropertiesForMultiplePaths(), and Sabre\DAV\Server\getPropertiesIteratorForPath().

+ Here is the caller graph for this function:

◆ guessBaseUri()

Sabre\DAV\Server::guessBaseUri ( )

This method attempts to detect the base uri.

Only the PATH_INFO variable is considered.

If this variable is not set, the root (/) is assumed.

Returns
string

Definition at line 362 of file Server.php.

362 {
363
364 $pathInfo = $this->httpRequest->getRawServerValue('PATH_INFO');
365 $uri = $this->httpRequest->getRawServerValue('REQUEST_URI');
366
367 // If PATH_INFO is found, we can assume it's accurate.
368 if (!empty($pathInfo)) {
369
370 // We need to make sure we ignore the QUERY_STRING part
371 if ($pos = strpos($uri, '?'))
372 $uri = substr($uri, 0, $pos);
373
374 // PATH_INFO is only set for urls, such as: /example.php/path
375 // in that case PATH_INFO contains '/path'.
376 // Note that REQUEST_URI is percent encoded, while PATH_INFO is
377 // not, Therefore they are only comparable if we first decode
378 // REQUEST_INFO as well.
379 $decodedUri = URLUtil::decodePath($uri);
380
381 // A simple sanity check:
382 if (substr($decodedUri, strlen($decodedUri) - strlen($pathInfo)) === $pathInfo) {
383 $baseUri = substr($decodedUri, 0, strlen($decodedUri) - strlen($pathInfo));
384 return rtrim($baseUri, '/') . '/';
385 }
386
387 throw new Exception('The REQUEST_URI (' . $uri . ') did not end with the contents of PATH_INFO (' . $pathInfo . '). This server might be misconfigured.');
388
389 }
390
391 // The last fallback is that we're just going to assume the server root.
392 return '/';
393
394 }

References Sabre\DAV\Server\$baseUri, and Sabre\HTTP\URLUtil\decodePath().

Referenced by Sabre\DAV\Server\getBaseUri().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ invokeMethod()

Sabre\DAV\Server::invokeMethod ( RequestInterface  $request,
ResponseInterface  $response,
  $sendResponse = true 
)

Handles a http request, and execute a method based on its name.

Parameters
RequestInterface$request
ResponseInterface$response
bool$sendResponseWhether to send the HTTP response to the DAV client.
Returns
void

Definition at line 461 of file Server.php.

461 {
462
463 $method = $request->getMethod();
464
465 if (!$this->emit('beforeMethod:' . $method, [$request, $response])) return;
466 if (!$this->emit('beforeMethod', [$request, $response])) return;
467
468 if (self::$exposeVersion) {
469 $response->setHeader('X-Sabre-Version', Version::VERSION);
470 }
471
472 $this->transactionType = strtolower($method);
473
474 if (!$this->checkPreconditions($request, $response)) {
475 $this->sapi->sendResponse($response);
476 return;
477 }
478
479 if ($this->emit('method:' . $method, [$request, $response])) {
480 if ($this->emit('method', [$request, $response])) {
481 $exMessage = "There was no plugin in the system that was willing to handle this " . $method . " method.";
482 if ($method === "GET") {
483 $exMessage .= " Enable the Browser plugin to get a better result here.";
484 }
485
486 // Unsupported method
487 throw new Exception\NotImplemented($exMessage);
488 }
489 }
490
491 if (!$this->emit('afterMethod:' . $method, [$request, $response])) return;
492 if (!$this->emit('afterMethod', [$request, $response])) return;
493
494 if ($response->getStatus() === null) {
495 throw new Exception('No subsystem set a valid HTTP status code. Something must have interrupted the request without providing further detail.');
496 }
497 if ($sendResponse) {
498 $this->sapi->sendResponse($response);
499 $this->emit('afterResponse', [$request, $response]);
500 }
501
502 }
checkPreconditions(RequestInterface $request, ResponseInterface $response)
This method checks the main HTTP preconditions.
Definition: Server.php:1293

References $request, $response, Sabre\DAV\Server\checkPreconditions(), Sabre\Event\EventEmitterInterface\emit(), and Sabre\DAV\Version\VERSION.

Referenced by Sabre\DAV\Server\exec().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setBaseUri()

Sabre\DAV\Server::setBaseUri (   $uri)

Sets the base server uri.

Parameters
string$uri
Returns
void

Definition at line 332 of file Server.php.

332 {
333
334 // If the baseUri does not end with a slash, we must add it
335 if ($uri[strlen($uri) - 1] !== '/')
336 $uri .= '/';
337
338 $this->baseUri = $uri;
339
340 }

◆ updateFile()

Sabre\DAV\Server::updateFile (   $uri,
  $data,
$etag = null 
)

This method is invoked by sub-systems updating a file.

This method will return true if the file was actually updated

Parameters
string$uri
resource$data
string$etag
Returns
bool

Definition at line 1117 of file Server.php.

1117 {
1118
1119 $node = $this->tree->getNodeForPath($uri);
1120
1121 // It is possible for an event handler to modify the content of the
1122 // body, before it gets written. If this is the case, $modified
1123 // should be set to true.
1124 //
1125 // If $modified is true, we must not send back an ETag.
1126 $modified = false;
1127 if (!$this->emit('beforeWriteContent', [$uri, $node, &$data, &$modified])) return false;
1128
1129 $etag = $node->put($data);
1130 if ($modified) $etag = null;
1131 $this->emit('afterWriteContent', [$uri, $node]);
1132
1133 return true;
1134 }

References $data, and Sabre\Event\EventEmitterInterface\emit().

+ Here is the call graph for this function:

◆ updateProperties()

Sabre\DAV\Server::updateProperties (   $path,
array  $properties 
)

This method updates a resource's properties.

The properties array must be a list of properties. Array-keys are property names in clarknotation, array-values are it's values. If a property must be deleted, the value should be null.

Note that this request should either completely succeed, or completely fail.

The response is an array with properties for keys, and http status codes as their values.

Parameters
string$path
array$properties
Returns
array

Definition at line 1261 of file Server.php.

1261 {
1262
1263 $propPatch = new PropPatch($properties);
1264 $this->emit('propPatch', [$path, $propPatch]);
1265 $propPatch->commit();
1266
1267 return $propPatch->getResult();
1268
1269 }

References $path, and Sabre\Event\EventEmitterInterface\emit().

+ Here is the call graph for this function:

Field Documentation

◆ $baseUri

Sabre\DAV\Server::$baseUri = null
protected

◆ $debugExceptions

Sabre\DAV\Server::$debugExceptions = false

Definition at line 141 of file Server.php.

◆ $enablePropfindDepthInfinity

Sabre\DAV\Server::$enablePropfindDepthInfinity = false

Definition at line 167 of file Server.php.

◆ $exposeVersion

◆ $httpRequest

Sabre\DAV\Server::$httpRequest

Definition at line 63 of file Server.php.

◆ $httpResponse

Sabre\DAV\Server::$httpResponse

Definition at line 56 of file Server.php.

◆ $plugins

Sabre\DAV\Server::$plugins = []
protected

Definition at line 77 of file Server.php.

Referenced by Sabre\DAV\Server\getPlugins().

◆ $protectedProperties

Sabre\DAV\Server::$protectedProperties

Definition at line 100 of file Server.php.

◆ $resourceTypeMapping

Sabre\DAV\Server::$resourceTypeMapping
Initial value:
= [
'Sabre\\DAV\\ICollection' => '{DAV:}collection',
]

Definition at line 152 of file Server.php.

◆ $sapi

Sabre\DAV\Server::$sapi

Definition at line 70 of file Server.php.

◆ $transactionType

Sabre\DAV\Server::$transactionType

Definition at line 90 of file Server.php.

◆ $tree

Sabre\DAV\Server::$tree

Definition at line 42 of file Server.php.

◆ $xml

Sabre\DAV\Server::$xml

Definition at line 174 of file Server.php.

◆ DEPTH_INFINITY

const Sabre\DAV\Server::DEPTH_INFINITY = -1

Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree.

Definition at line 30 of file Server.php.

Referenced by Sabre\DAV\Server\getHTTPDepth(), Sabre\DAV\Xml\Request\SyncCollectionTest\testDeserializeInfinity(), Sabre\DAV\Locks\Backend\AbstractTest\testGetLocksParent(), Sabre\DAV\Xml\Request\SyncCollectionReport\xmlDeserialize(), and Sabre\DAV\Xml\Property\LockDiscovery\xmlSerialize().

◆ NS_SABREDAV

const Sabre\DAV\Server::NS_SABREDAV = 'http://sabredav.org/ns'

XML namespace for all SabreDAV related elements.

Definition at line 35 of file Server.php.


The documentation for this class was generated from the following file: