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/) 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 object is passed as an argument, it will use it as the directory tree. If a Sabre is passed, it will create a Sabre and use the node as the root.

If nothing is passed, a Sabre is created in a Sabre.

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.

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

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
+ 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

Parameters
ServerPlugin$plugin
Returns
void

Definition at line 404 of file Server.php.

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

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

404  {
405 
406  $this->plugins[$plugin->getPluginName()] = $plugin;
407  $plugin->initialize($this);
408 
409  }
+ 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

Definition at line 565 of file Server.php.

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().

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));
574  $baseUri = Uri\normalize($this->getBaseUri());
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
+ 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.

References $ii, $path, PHPMailer\PHPMailer\$token, Sabre\Event\EventEmitterInterface\emit(), Sabre\DAV\IFile\getETag(), Sabre\HTTP\MessageInterface\getHeader(), Sabre\DAV\Server\getIfConditions(), Sabre\HTTP\RequestInterface\getMethod(), Sabre\HTTP\RequestInterface\getPath(), Sabre\HTTP\Util\parseHTTPDate(), Sabre\HTTP\MessageInterface\setHeader(), Sabre\HTTP\ResponseInterface\setStatus(), and Sabre\HTTP\Util\toHTTPDate().

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

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
static toHTTPDate(\DateTime $dateTime)
Transforms a DateTime object to HTTP&#39;s most common date format.
Definition: Util.php:69
static parseHTTPDate($dateHeader)
Parses a RFC2616-compatible date string.
Definition: Util.php:53
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
$response
getIfConditions(RequestInterface $request)
This method is created to extract information from the WebDAV HTTP &#39;If:&#39; header.
Definition: Server.php:1577
+ 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.

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().

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
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
static splitPath($path)
Returns the &#39;dirname&#39; and &#39;basename&#39; for a path.
Definition: URLUtil.php:83
+ 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.

References Sabre\DAV\Server\createCollection().

1144  {
1145 
1146  $this->createCollection($uri, new MkCol(['{DAV:}collection'], []));
1147 
1148  }
createCollection($uri, MkCol $mkCol)
Use this method to create a new collection.
Definition: Server.php:1157
+ 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.

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

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  }
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
static splitPath($path)
Returns the &#39;dirname&#39; and &#39;basename&#39; for a path.
Definition: URLUtil.php:83
$data
Definition: bench.php:6
+ 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.

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.

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  }
$h
getBaseUri()
Returns the base responding uri.
Definition: Server.php:347
const VERSION
Full version number.
Definition: Version.php:17
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
invokeMethod(RequestInterface $request, ResponseInterface $response, $sendResponse=true)
Handles a http request, and execute a method based on its name.
Definition: Server.php:461
while(false !==($line=fgets($in))) if(! $columns) $ignore
Definition: Utf8Test.php:63
+ 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.

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

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
$response

◆ 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

Definition at line 885 of file Server.php.

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

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

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  }
$path
Definition: aliased.php:25
generatePathNodes(PropFind $propFind, array $yieldFirst=null)
Small helper to support PROPFIND with DEPTH_INFINITY.
Definition: Server.php:885
+ 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.

References $path.

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  }
$path
Definition: aliased.php:25

◆ getBaseUri()

Sabre\DAV\Server::getBaseUri ( )

Returns the base responding uri.

Returns
string

Definition at line 347 of file Server.php.

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

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

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
+ 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

Definition at line 729 of file Server.php.

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

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  }
foreach($paths as $path) $request
Definition: asyncclient.php:32
$destination
if($out) else
try
Definition: cron.php:22
calculateUri($uri)
Turns a URI such as the REQUEST_URI into a local path.
Definition: Server.php:565
+ 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::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.

References $default.

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

◆ 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.

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

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  }
$path
Definition: aliased.php:25
getProperties($path, $propertyNames)
Returns a list of properties for a path.
Definition: Server.php:799
static toHTTPDate(\DateTime $dateTime)
Transforms a DateTime object to HTTP&#39;s most common date format.
Definition: Util.php:69
+ 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.

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

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  }
$result
parsePrefer($input)
Parses the Prefer header, as defined in RFC7240.
Definition: functions.php:222
+ 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.

References $header, Sabre\DAV\Server\calculateUri(), Sabre\HTTP\MessageInterface\getHeader(), and Sabre\HTTP\RequestInterface\getPath().

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

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  }
foreach($paths as $path) $request
Definition: asyncclient.php:32
calculateUri($uri)
Turns a URI such as the REQUEST_URI into a local path.
Definition: Server.php:565
+ 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.

References $name.

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

◆ getPlugins()

Sabre\DAV\Server::getPlugins ( )

Returns all plugins.

Returns
array

Definition at line 433 of file Server.php.

References Sabre\DAV\Server\$plugins.

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

◆ 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.

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

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

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  }
$path
Definition: aliased.php:25
$result
getPropertiesForPath($path, $propertyNames=[], $depth=0)
Returns a list of properties for a given path.
Definition: Server.php:937
+ 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.

References Sabre\Event\EventEmitterInterface\emit().

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

1056  {
1057 
1058  return $this->emit('propFind', [$propFind, $node]);
1059 
1060  }
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
+ 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.

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

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  }
$path
Definition: aliased.php:25
$result
getPropertiesForPath($path, $propertyNames=[], $depth=0)
Returns a list of properties for a given path.
Definition: Server.php:937
$row
+ 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.

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

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  }
$path
Definition: aliased.php:25
getResourceTypeForNode(INode $node)
Returns an array with resourcetypes for a node.
Definition: Server.php:1633
$result
if($argc< 2) $paths
Definition: migrateto20.php:44
$r
Definition: example_031.php:79
getPropertiesByNode(PropFind $propFind, INode $node)
Determines all properties for a node.
Definition: Server.php:1056
+ 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.

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

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

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

Definition at line 956 of file Server.php.

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().

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  }
$path
Definition: aliased.php:25
getResourceTypeForNode(INode $node)
Returns an array with resourcetypes for a node.
Definition: Server.php:1633
generatePathNodes(PropFind $propFind, array $yieldFirst=null)
Small helper to support PROPFIND with DEPTH_INFINITY.
Definition: Server.php:885
$result
$r
Definition: example_031.php:79
const ALLPROPS
An allprops request.
Definition: PropFind.php:27
const NORMAL
A normal propfind.
Definition: PropFind.php:16
getPropertiesByNode(PropFind $propFind, INode $node)
Determines all properties for a node.
Definition: Server.php:1056
+ 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.

References Sabre\DAV\Server\calculateUri().

547  {
548 
549  return $this->calculateUri($this->httpRequest->getUrl());
550 
551  }
calculateUri($uri)
Turns a URI such as the REQUEST_URI into a local path.
Definition: Server.php:565
+ 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.

References $result.

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

1633  {
1634 
1635  $result = [];
1636  foreach ($this->resourceTypeMapping as $className => $resourceType) {
1637  if ($node instanceof $className) $result[] = $resourceType;
1638  }
1639  return $result;
1640 
1641  }
$result
+ 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.

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

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

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  }
static decodePath($path)
Decodes a url-encoded path.
Definition: URLUtil.php:57
+ 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.

References Sabre\DAV\Server\checkPreconditions(), Sabre\Event\EventEmitterInterface\emit(), Sabre\HTTP\RequestInterface\getMethod(), Sabre\HTTP\ResponseInterface\getStatus(), Sabre\HTTP\MessageInterface\setHeader(), and Sabre\DAV\Version\VERSION.

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

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  }
foreach($paths as $path) $request
Definition: asyncclient.php:32
const VERSION
Full version number.
Definition: Version.php:17
checkPreconditions(RequestInterface $request, ResponseInterface $response)
This method checks the main HTTP preconditions.
Definition: Server.php:1293
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
$response
+ 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.

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

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  }
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
$data
Definition: bench.php:6
+ 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.

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

1261  {
1262 
1263  $propPatch = new PropPatch($properties);
1264  $this->emit('propPatch', [$path, $propPatch]);
1265  $propPatch->commit();
1266 
1267  return $propPatch->getResult();
1268 
1269  }
$path
Definition: aliased.php:25
emit($eventName, array $arguments=[], callable $continueCallBack=null)
Emits an event.
+ 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\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.

Referenced by Sabre\DAV\TemporaryFileFilterPlugin\httpPropfind().


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