49 '{DAV:}supportedlock',
50 '{DAV:}acl-restrictions',
52 '{DAV:}supported-method-set',
78 $this->server->on(
'method:GET', [$this,
'httpGetEarly'], 90);
79 $this->server->on(
'method:GET', [$this,
'httpGet'], 200);
80 $this->server->on(
'onHTMLActionsPanel', [$this,
'htmlActionsPanel'], 200);
81 if ($this->enablePost) $this->server->on(
'method:POST', [$this,
'httpPOST']);
95 if (isset(
$params[
'sabreAction']) &&
$params[
'sabreAction'] ===
'info') {
96 return $this->
httpGet($request, $response);
115 $response->
setHeader(
'Content-Security-Policy',
"default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
117 $sabreAction = isset($getVars[
'sabreAction']) ? $getVars[
'sabreAction'] : null;
119 switch ($sabreAction) {
123 $this->
serveAsset(isset($getVars[
'assetName']) ? $getVars[
'assetName'] : null);
128 $this->server->tree->getNodeForPath($request->
getPath());
136 $response->
setHeader(
'Content-Type',
'text/html; charset=utf-8');
146 $response->
setHeader(
'Content-Type',
'text/html; charset=utf-8');
169 if (
$contentType !==
'application/x-www-form-urlencoded' &&
175 if (!isset($postVars[
'sabreAction']))
180 if ($this->server->emit(
'onBrowserPostAction', [$uri, $postVars[
'sabreAction'], $postVars])) {
182 switch ($postVars[
'sabreAction']) {
185 if (isset($postVars[
'name']) && trim($postVars[
'name'])) {
189 if (isset($postVars[
'resourceType'])) {
190 $resourceType = explode(
',', $postVars[
'resourceType']);
192 $resourceType = [
'{DAV:}collection'];
196 foreach ($postVars as $varName => $varValue) {
199 if ($varName[0] ===
'{') {
206 $varName = str_replace(
'*DOT*',
'.', $varName);
207 $properties[$varName] = $varValue;
215 $this->server->createCollection($uri .
'/' . $folderName, $mkCol);
222 if ($_FILES) $file = current($_FILES);
226 if (isset($postVars[
'name']) && trim($postVars[
'name']))
227 $newName = trim($postVars[
'name']);
232 if (is_uploaded_file($file[
'tmp_name'])) {
233 $this->server->createFile($uri .
'/' . $newName,
fopen($file[
'tmp_name'],
'r'));
255 return htmlspecialchars($value, ENT_QUOTES,
'UTF-8');
269 $node = $this->server->tree->getNodeForPath($path);
272 $html .=
"<section><h1>Nodes</h1>\n";
273 $html .=
"<table class=\"nodeTable\">";
275 $subNodes = $this->server->getPropertiesForChildren($path, [
277 '{DAV:}resourcetype',
278 '{DAV:}getcontenttype',
279 '{DAV:}getcontentlength',
280 '{DAV:}getlastmodified',
283 foreach ($subNodes as $subPath => $subProps) {
285 $subNode = $this->server->tree->getNodeForPath($subPath);
289 $subNodes[$subPath][
'subNode'] = $subNode;
290 $subNodes[$subPath][
'fullPath'] = $fullPath;
291 $subNodes[$subPath][
'displayPath'] = $displayPath;
293 uasort($subNodes, [$this,
'compareNodes']);
295 foreach ($subNodes as $subProps) {
297 'string' =>
'Unknown',
300 if (isset($subProps[
'{DAV:}resourcetype'])) {
301 $type = $this->
mapResourceType($subProps[
'{DAV:}resourcetype']->getValue(), $subProps[
'subNode']);
305 $html .=
'<td class="nameColumn"><a href="' . $this->
escapeHTML($subProps[
'fullPath']) .
'"><span class="oi" data-glyph="' . $this->
escapeHTML(
$type[
'icon']) .
'"></span> ' . $this->
escapeHTML($subProps[
'displayPath']) .
'</a></td>';
308 if (isset($subProps[
'{DAV:}getcontentlength'])) {
309 $html .= $this->
escapeHTML($subProps[
'{DAV:}getcontentlength'] .
' bytes');
311 $html .=
'</td><td>';
312 if (isset($subProps[
'{DAV:}getlastmodified'])) {
313 $lastMod = $subProps[
'{DAV:}getlastmodified']->getTime();
319 if ($subProps[
'subNode'] instanceof DAV\
IFile) {
320 $buttonActions =
'<a href="' . $this->
escapeHTML($subProps[
'fullPath']) .
'?sabreAction=info"><span class="oi" data-glyph="info"></span></a>';
322 $this->server->emit(
'browserButtonActions', [$subProps[
'fullPath'], $subProps[
'subNode'], &$buttonActions]);
324 $html .=
'<td>' . $buttonActions .
'</td>';
332 $html .=
"</section>";
333 $html .=
"<section><h1>Properties</h1>";
334 $html .=
"<table class=\"propTable\">";
338 $properties = $this->server->getPropertiesByNode($propFind, $node);
340 $properties = $propFind->getResultForMultiStatus()[200];
342 foreach ($properties as $propName => $propValue) {
343 if (!in_array($propName, $this->uninterestingProperties)) {
351 $html .=
"</section>";
356 if ($this->enablePost) {
357 $this->server->emit(
'onHTMLActionsPanel', [$node, &
$output, $path]);
362 $html .=
"<section><h1>Actions</h1>";
363 $html .=
"<div class=\"actions\">\n";
366 $html .=
"</section>\n";
371 $this->server->httpResponse->setHeader(
'Content-Security-Policy',
"default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
386 $html .=
"<section><h1>Plugins</h1>";
387 $html .=
"<table class=\"propTable\">";
388 foreach ($this->server->getPlugins() as $plugin) {
389 $info = $plugin->getPluginInfo();
390 $html .=
'<tr><th>' .
$info[
'name'] .
'</th>';
391 $html .=
'<td>' .
$info[
'description'] .
'</td>';
394 $html .=
'<a href="' . $this->
escapeHTML(
$info[
'link']) .
'"><span class="oi" data-glyph="book"></span></a>';
396 $html .=
'</td></tr>';
399 $html .=
"</section>";
432 'baseUrl' => $this->server->getBaseUri(),
439 <title>$vars[title] - sabre/dav
$version</title>
440 <link rel=
"shortcut icon" href=
"$vars[favicon]" type=
"image/vnd.microsoft.icon" />
441 <link rel=
"stylesheet" href=
"$vars[style]" type=
"text/css" />
442 <link rel=
"stylesheet" href=
"$vars[iconstyle]" type=
"text/css" />
448 <
a href=
"$vars[baseUrl]"><img src=
"$vars[logo]" alt=
"sabre/dav" /> $vars[title]</
a>
459 $html .=
'<a href="' . $fullPath .
'" class="btn">⇤ Go to parent</a>';
461 $html .=
'<span class="btn disabled">⇤ Go to parent</span>';
464 $html .=
' <a href="?sabreAction=plugins" class="btn"><span class="oi" data-glyph="puzzle-piece"></span> Plugins</a>';
486 <footer>Generated by SabreDAV
$version (c)2007-2016 <
a href=
"http://sabre.io/">
http:
512 if (get_class($node) ===
'Sabre\\DAV\\SimpleCollection')
516 <form method=
"post" action=
"">
517 <h3>Create
new folder</h3>
518 <
input type=
"hidden" name=
"sabreAction" value=
"mkcol" />
519 <label>Name:</label> <
input type=
"text" name=
"name" /><br />
520 <
input type=
"submit" value=
"create" />
522 <form method=
"post" action=
"" enctype=
"multipart/form-data">
524 <
input type=
"hidden" name=
"sabreAction" value=
"put" />
525 <label>Name (optional):</label> <
input type=
"text" name=
"name" /><br />
526 <label>
File:</label> <
input type=
"file" name=
"file" /><br />
527 <
input type=
"submit" value=
"upload" />
542 return $this->server->getBaseUri() .
'?sabreAction=asset&assetName=' . urlencode($assetName);
555 $assetDir = __DIR__ .
'/assets/';
556 $path = $assetDir . $assetName;
560 if (strpos(
$path,
'/../') !==
false || strrchr(
$path,
'/') ===
'/..') {
561 throw new DAV\Exception\NotFound(
'Path does not exist, or escaping from the base path was detected');
563 if (strpos(realpath(
$path), realpath($assetDir)) === 0 && file_exists(
$path)) {
566 throw new DAV\Exception\NotFound(
'Path does not exist, or escaping from the base path was detected');
580 $mime =
'application/octet-stream';
582 'ico' =>
'image/vnd.microsoft.icon',
583 'png' =>
'image/png',
587 $ext = substr($assetName, strrpos($assetName,
'.') + 1);
588 if (isset(
$map[$ext])) {
592 $this->server->httpResponse->setHeader(
'Content-Type', $mime);
593 $this->server->httpResponse->setHeader(
'Content-Length', filesize($assetPath));
594 $this->server->httpResponse->setHeader(
'Cache-Control',
'public, max-age=1209600');
595 $this->server->httpResponse->setStatus(200);
596 $this->server->httpResponse->setBody(
fopen($assetPath,
'r'));
610 $typeA = (isset($a[
'{DAV:}resourcetype']))
611 ? (in_array(
'{DAV:}collection', $a[
'{DAV:}resourcetype']->getValue()))
614 $typeB = (isset($b[
'{DAV:}resourcetype']))
615 ? (in_array(
'{DAV:}collection', $b[
'{DAV:}resourcetype']->getValue()))
619 if ($typeA === $typeB) {
620 return strnatcasecmp($a[
'displayPath'], $b[
'displayPath']);
622 return (($typeA < $typeB) ? 1 : -1);
635 if (!$resourceTypes) {
636 if ($node instanceof DAV\
IFile) {
643 'string' =>
'Unknown',
650 '{http://calendarserver.org/ns/}calendar-proxy-write' => [
651 'string' =>
'Proxy-Write',
654 '{http://calendarserver.org/ns/}calendar-proxy-read' => [
655 'string' =>
'Proxy-Read',
658 '{urn:ietf:params:xml:ns:caldav}schedule-outbox' => [
659 'string' =>
'Outbox',
662 '{urn:ietf:params:xml:ns:caldav}schedule-inbox' => [
666 '{urn:ietf:params:xml:ns:caldav}calendar' => [
667 'string' =>
'Calendar',
668 'icon' =>
'calendar',
670 '{http://calendarserver.org/ns/}shared-owner' => [
671 'string' =>
'Shared',
672 'icon' =>
'calendar',
674 '{http://calendarserver.org/ns/}subscribed' => [
675 'string' =>
'Subscription',
676 'icon' =>
'calendar',
678 '{urn:ietf:params:xml:ns:carddav}directory' => [
679 'string' =>
'Directory',
682 '{urn:ietf:params:xml:ns:carddav}addressbook' => [
683 'string' =>
'Address book',
686 '{DAV:}principal' => [
687 'string' =>
'Principal',
690 '{DAV:}collection' => [
691 'string' =>
'Collection',
700 foreach ($resourceTypes as $k => $resourceType) {
701 if (isset($types[$resourceType])) {
702 $info[
'string'][] = $types[$resourceType][
'string'];
704 $info[
'string'][] = $resourceType;
707 foreach ($types as
$key => $resourceInfo) {
708 if (in_array(
$key, $resourceTypes)) {
709 $info[
'icon'] = $resourceInfo[
'icon'];
713 $info[
'string'] = implode(
', ',
$info[
'string']);
729 $this->server->getBaseUri(),
730 $this->server->xml->namespaceMap
746 if (is_scalar($value)) {
747 return $html->h($value);
749 return $value->toHtml(
$html);
750 } elseif ($value instanceof \
Sabre\Xml\XmlSerializable) {
754 $xml = $this->server->xml->write(
'{DAV:}root', $value, $this->server->getBaseUri());
759 return "<pre>" .
$html->h(implode(
"\n",
$xml)) .
"</pre>";
762 return "<em>unknown</em>";
796 'description' =>
'Generates HTML indexes and debug information for your sabre/dav server',
797 'link' =>
'http://sabre.io/dav/browser-plugin/',
This interface represents a HTTP response.
The RequestInterface represents a HTTP request.
The baseclass for all server plugins.
drawPropertyValue($html, $value)
Draws a table row for a property.
setBody($body)
Updates the body resource with a new stream.
__construct($enablePost=true)
Creates the object.
htmlActionsPanel(DAV\INode $node, &$output, $path)
This method is used to generate the 'actions panel' output for collections.
escapeHTML($value)
Escapes a string for html.
foreach($paths as $path) $request
httpPOST(RequestInterface $request, ResponseInterface $response)
Handles POST requests for tree operations.
This class is used by the browser plugin to trick the system in returning every defined property...
compareNodes($a, $b)
Sort helper function: compares two directory entries based on type and display name.
generateDirectoryIndex($path)
Generates the html directory index for a given url.
const VERSION
Full version number.
initialize(DAV\Server $server)
Initializes the plugin and subscribes to events.
generatePluginListing()
Generates the 'plugins' page.
The ICollection Interface.
getAssetUrl($assetName)
This method takes a path/name of an asset and turns it into url suiteable for http access...
static http()
Fetches the global http state from ILIAS.
getQueryParameters()
Returns the list of query parameters.
setStatus($status)
Sets the HTTP status code.
getUrl()
Returns the request url.
WebDAV properties that implement this interface are able to generate their own html output for the br...
getHeader($name)
Returns a specific HTTP header, based on it's name.
getPluginName()
Returns a plugin name.
This interface represents a file in the directory tree.
getLocalAssetPath($assetName)
This method returns a local pathname to an asset.
The INode interface is the base interface, and the parent class of both ICollection and IFile...
serveAsset($assetName)
This method reads an asset from disk and generates a full http response.
mapResourceType(array $resourceTypes, $node)
Maps a resource type to a human-readable string and icon.
httpGetEarly(RequestInterface $request, ResponseInterface $response)
This method intercepts GET requests that have ?sabreAction=info appended to the URL.
getPath()
Returns the relative path.
This class represents a MKCOL operation.
httpGet(RequestInterface $request, ResponseInterface $response)
This method intercepts GET requests to collections and returns the html.
generateHeader($title, $path=null)
Generates the first block of HTML, including the <head> tag and page header.
getPluginInfo()
Returns a bunch of meta-data about the plugin.
drawPropertyRow($name, $value)
Draws a table row for a property.
if($path[strlen($path) - 1]==='/') if(is_dir($path)) if(!file_exists($path)) if(preg_match('#\.php$#D', mb_strtolower($path, 'UTF-8'))) $contentType
static encodePath($path)
Encodes the path of a url.
getPostData()
Returns the POST data.
static splitPath($path)
Returns the 'dirname' and 'basename' for a path.
setHeader($name, $value)
Updates a HTTP header.
generateFooter()
Generates the page footer.
This class provides a few utility functions for easily generating HTML for the browser plugin...