/** * This method is called before any HTTP method and validates there is enough free space to store the file * * @param string $method * @throws Sabre_DAV_Exception * @return bool */ public function checkQuota($uri, $data = null) { $length = $this->getLength(); if ($length) { if (substr($uri, 0, 1) !== '/') { $uri = '/' . $uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); $req = $this->server->httpRequest; if ($req->getHeader('OC-Chunked')) { $info = OC_FileChunking::decodeName($newName); $chunkHandler = new OC_FileChunking($info); // substract the already uploaded size to see whether // there is still enough space for the remaining chunks $length -= $chunkHandler->getCurrentSize(); } $freeSpace = $this->getFreeSpace($parentUri); if ($freeSpace !== \OC\Files\SPACE_UNKNOWN && $length > $freeSpace) { if (isset($chunkHandler)) { $chunkHandler->cleanup(); } throw new Sabre_DAV_Exception_InsufficientStorage(); } } return true; }
/** * serialize * * @param Sabre_DAV_Server $server * @param DOMElement $dom * @return void */ public function serialize(Sabre_DAV_Server $server, DOMElement $dom) { $document = $dom->ownerDocument; $properties = $this->responseProperties; $xresponse = $document->createElement('d:response'); $dom->appendChild($xresponse); $uri = Sabre_DAV_URLUtil::encodePath($this->href); // Adding the baseurl to the beginning of the url $uri = $server->getBaseUri() . $uri; $xresponse->appendChild($document->createElement('d:href', $uri)); // The properties variable is an array containing properties, grouped by // HTTP status foreach ($properties as $httpStatus => $propertyGroup) { // The 'href' is also in this array, and it's special cased. // We will ignore it if ($httpStatus == 'href') { continue; } // If there are no properties in this group, we can also just carry on if (!count($propertyGroup)) { continue; } $xpropstat = $document->createElement('d:propstat'); $xresponse->appendChild($xpropstat); $xprop = $document->createElement('d:prop'); $xpropstat->appendChild($xprop); $nsList = $server->xmlNamespaces; foreach ($propertyGroup as $propertyName => $propertyValue) { $propName = null; preg_match('/^{([^}]*)}(.*)$/', $propertyName, $propName); // special case for empty namespaces if ($propName[1] == '') { $currentProperty = $document->createElement($propName[2]); $xprop->appendChild($currentProperty); $currentProperty->setAttribute('xmlns', ''); } else { if (!isset($nsList[$propName[1]])) { $nsList[$propName[1]] = 'x' . count($nsList); } // If the namespace was defined in the top-level xml namespaces, it means // there was already a namespace declaration, and we don't have to worry about it. if (isset($server->xmlNamespaces[$propName[1]])) { $currentProperty = $document->createElement($nsList[$propName[1]] . ':' . $propName[2]); } else { $currentProperty = $document->createElementNS($propName[1], $nsList[$propName[1]] . ':' . $propName[2]); } $xprop->appendChild($currentProperty); } if (is_scalar($propertyValue)) { $text = $document->createTextNode($propertyValue); $currentProperty->appendChild($text); } elseif ($propertyValue instanceof Sabre_DAV_PropertyInterface) { $propertyValue->serialize($server, $currentProperty); } elseif (!is_null($propertyValue)) { throw new Sabre_DAV_Exception('Unknown property value type: ' . gettype($propertyValue) . ' for property: ' . $propertyName); } } $xpropstat->appendChild($document->createElement('d:status', $server->httpResponse->getStatusMessage($httpStatus))); } }
function testSplitPath() { $strings = array('/foo/bar' => array('/foo', 'bar'), '/foo/bar/' => array('/foo', 'bar'), 'foo/bar/' => array('foo', 'bar'), 'foo/bar' => array('foo', 'bar'), 'foo/bar/baz' => array('foo/bar', 'baz'), 'foo/bar/baz/' => array('foo/bar', 'baz'), 'foo' => array('', 'foo'), 'foo/' => array('', 'foo'), '/foo/' => array('', 'foo'), '/foo' => array('', 'foo'), '' => array(null, null), "/àfoó/bar" => array("/àfoó", 'bar'), "/àfoo/bür/" => array("/àfoo", "bür"), "foo/àür" => array("foo", "àür")); foreach ($strings as $input => $expected) { $output = Sabre_DAV_URLUtil::splitPath($input); $this->assertEquals($expected, $output, 'The expected output for \'' . $input . '\' was incorrect'); } }
/** * Renames the node * * @param string $name The new name * @return void */ public function setName($name) { list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; rename($this->path, $newPath); $this->path = $newPath; }
/** * Renames the node * * @throws Sabre_DAV_Exception_Forbidden * @param string $name The new name * @return void */ public function setName($name) { self::checkForbiddenFile($name); if (!Tinebase_Core::getUser()->hasGrant($this->_getContainer(), Tinebase_Model_Grants::GRANT_EDIT)) { throw new Sabre_DAV_Exception_Forbidden('Forbidden to rename file: ' . $this->_path); } list($dirname, $basename) = Sabre_DAV_URLUtil::splitPath($this->_path); Tinebase_FileSystem::getInstance()->rename($this->_path, $dirname . '/' . $name); }
/** * This function allows you to check if a node exists. * * @param string $path * @return bool */ public function nodeExists($path) { try { list($parent, $base) = Sabre_DAV_URLUtil::splitPath($path); $parentNode = $this->getNodeForPath($parent); return $parentNode->childExists($base); } catch (Sabre_DAV_Exception_FileNotFound $e) { return false; } }
/** * Renames the node * * @param string $name The new name * @return void */ public function setName($name) { list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; $oldPath = $this->path; OC_Filesystem::rename($this->path, $newPath); $this->path = $newPath; $query = OC_DB::prepare('UPDATE *PREFIX*properties SET propertypath = ? WHERE userid = ? AND propertypath = ?'); $query->execute(array($newPath, OC_User::getUser(), $oldPath)); }
/** * Handler for teh afterGetProperties event * * @param string $path * @param array $properties * @return void */ public function afterGetProperties($path, &$properties) { if (array_key_exists('{DAV:}getcontenttype', $properties[404])) { list(, $fileName) = Sabre_DAV_URLUtil::splitPath($path); $contentType = $this->getContentType($fileName); if ($contentType) { $properties[200]['{DAV:}getcontenttype'] = $contentType; unset($properties[404]['{DAV:}getcontenttype']); } } }
/** * Moves a file from one location to another * * @param string $sourcePath The path to the file which should be moved * @param string $destinationPath The full destination path, so not just the destination parent node * @return int */ public function move($sourcePath, $destinationPath) { list($sourceDir, $sourceName) = Sabre_DAV_URLUtil::splitPath($sourcePath); list($destinationDir, $destinationName) = Sabre_DAV_URLUtil::splitPath($destinationPath); if ($sourceDir === $destinationDir) { $renameable = $this->getNodeForPath($sourcePath); $renameable->setName($destinationName); } else { $this->copy($sourcePath, $destinationPath); $this->getNodeForPath($sourcePath)->delete(); } }
/** * (non-PHPdoc) * @see Sabre_DAVACL_IPrincipalBackend::getGroupMembership() */ public function getGroupMembership($principal) { $result = array(); list(, $contactId) = Sabre_DAV_URLUtil::splitPath($principal); $user = Tinebase_User::getInstance()->getUserByProperty('contactId', $contactId); $groupIds = Tinebase_Group::getInstance()->getGroupMemberships($user); $groups = Tinebase_Group::getInstance()->getMultiple($groupIds); foreach ($groups as $group) { $result[] = 'principals/groups/' . $group->list_id; } return $result; }
/** * Returns a specific principal, specified by it's path. * The returned structure should be the exact same as from * getPrincipalsByPrefix. * * @param string $path * @return array */ public function getPrincipalByPath($path) { list($prefixPath, $userName) = Sabre_DAV_URLUtil::splitPath($path); // This backend only support principals in one collection if ($prefixPath !== $this->prefix) { return null; } $r = q("SELECT `nickname` FROM `user` WHERE `nickname` = '%s'", escape_tags($userName)); if (count($r) == 0) { return array(); } return array('uri' => $this->prefix . '/' . strtolower($r[0]['nickname']), '{DAV:}displayname' => $r[0]['nickname']); }
/** * Returns the list of groups a principal is a member of * * @param string $principal * @return array */ public function getGroupMembership($principal) { list($prefix, $name) = Sabre_DAV_URLUtil::splitPath($principal); $group_membership = array(); if ($prefix == 'principals') { $principal = $this->getPrincipalByPath($principal); if (!$principal) { throw new Sabre_DAV_Exception('Principal not found'); } // TODO: for now the user principal has only its own groups return array('principals/' . $name . '/calendar-proxy-read', 'principals/' . $name . '/calendar-proxy-write'); } return $group_membership; }
/** * Returns a list of principals based on a prefix. * * This prefix will often contain something like 'principals'. You are only * expected to return principals that are in this base path. * * You are expected to return at least a 'uri' for every user, you can * return any additional properties if you wish so. Common properties are: * {DAV:}displayname * {http://sabredav.org/ns}email-address - This is a custom SabreDAV * field that's actualy injected in a number of other properties. If * you have an email address, use this property. * * @param string $prefixPath * @return array */ public function getPrincipalsByPrefix($prefixPath) { $result = $this->pdo->query('SELECT uri, email, displayname FROM `' . $this->tableName . '`'); $principals = array(); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { // Checking if the principal is in the prefix list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']); if ($rowPrefix !== $prefixPath) { continue; } $principals[] = array('uri' => $row['uri'], '{DAV:}displayname' => $row['displayname'] ? $row['displayname'] : basename($row['uri']), '{http://sabredav.org/ns}email-address' => $row['email']); } return $principals; }
/** * This method is called before any HTTP method and validates there is enough free space to store the file * * @param string $method * @throws Sabre_DAV_Exception * @return bool */ public function checkQuota($uri, $data = null) { $length = $this->getLength(); if ($length) { if (substr($uri, 0, 1) !== '/') { $uri = '/' . $uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); $freeSpace = $this->getFreeSpace($parentUri); if ($freeSpace !== \OC\Files\SPACE_UNKNOWN && $length > $freeSpace) { throw new Sabre_DAV_Exception_InsufficientStorage(); } } return true; }
/** * Use this method to tell the server this plugin defines additional * HTTP methods. * * This method is passed a uri. It should only return HTTP methods that are * available for the specified uri. * * @param string $uri * @return array */ public function getHTTPMethods($uri) { // The MKCALENDAR is only available on unmapped uri's, whose // parents extend IExtendedCollection list($parent, $name) = Sabre_DAV_URLUtil::splitPath($uri); $node = $this->server->tree->getNodeForPath($parent); if ($node instanceof Sabre_DAV_IExtendedCollection) { try { $node->getChild($name); } catch (Sabre_DAV_Exception_FileNotFound $e) { return array('MKCALENDAR'); } } return array(); }
/** * Returns a list of principals based on a prefix. * * This prefix will often contain something like 'principals'. You are only * expected to return principals that are in this base path. * * You are expected to return at least a 'uri' for every user, you can * return any additional properties if you wish so. Common properties are: * {DAV:}displayname * * @param string $prefixPath * @return array */ public function getPrincipalsByPrefix($prefixPath) { $query = OC_DB::prepare('SELECT * FROM *PREFIX*principals'); $result = $query->execute(); $principals = array(); while ($row = $result->fetchRow()) { // Checking if the principal is in the prefix list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']); if ($rowPrefix !== $prefixPath) { continue; } $principals[] = array('uri' => $row['uri'], '{DAV:}displayname' => $row['displayname'] ? $row['displayname'] : basename($row['uri'])); } return $principals; }
/** * @brief Renames the node * @param string $name The new name * @return void */ public function setName($name) { // rename is only allowed if the update privilege is granted if (!\OC\Files\Filesystem::isUpdatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); } list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; $oldPath = $this->path; \OC\Files\Filesystem::rename($this->path, $newPath); $this->path = $newPath; $query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?' . ' WHERE `userid` = ? AND `propertypath` = ?'); $query->execute(array($newPath, OC_User::getUser(), $oldPath)); }
/** * This method is called before any HTTP method and forces users to be authenticated * * @param string $method * @throws Sabre_DAV_Exception * @return bool */ public function checkQuota($uri, $data = null) { $expected = $this->server->httpRequest->getHeader('X-Expected-Entity-Length'); $length = $expected ? $expected : $this->server->httpRequest->getHeader('Content-Length'); if ($length) { if (substr($uri, 0, 1) !== '/') { $uri = '/' . $uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); if ($length > OC_Filesystem::free_space($parentUri)) { throw new Sabre_DAV_Exception('Quota exceeded. File is too big.'); } } return true; }
/** * Returns a list of calendars for a principal. * * Every project is an array with the following keys: * * id, a unique id that will be used by other functions to modify the * calendar. This can be the same as the uri or a database key. * * uri, which the basename of the uri with which the calendar is * accessed. * * principaluri. The owner of the calendar. Almost always the same as * principalUri passed to this method. * * Furthermore it can contain webdav properties in clark notation. A very * common one is '{DAV:}displayname'. * * @param string $principalUri * @return array */ public function getCalendarsForUser($principalUri) { list(, $name) = Sabre_DAV_URLUtil::splitPath($principalUri); $user_id = dav_compat_username2id($name); $cals = q("SELECT * FROM %s%scalendars WHERE `uid`=%d AND `namespace` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $user_id, $this->getNamespace()); $ret = array(); foreach ($cals as $cal) { $dat = array("id" => $cal["namespace"] . "-" . $cal["namespace_id"], "uri" => $this->getCalUrlPrefix() . "-" . $cal["namespace_id"], "principaluri" => $principalUri, '{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}getctag' => $cal['ctag'] ? $cal['ctag'] : '0', "calendar_class" => "Sabre_CalDAV_Calendar"); foreach ($this->propertyMap as $key => $field) { $dat[$key] = $cal[$field]; } $ret[] = $dat; } return $ret; }
/** * This method is called before any HTTP method and forces users to be authenticated * * @param string $method * @throws Sabre_DAV_Exception * @return bool */ public function checkQuota($uri, $data = null) { $expected = $this->server->httpRequest->getHeader('X-Expected-Entity-Length'); $length = $expected ? $expected : $this->server->httpRequest->getHeader('Content-Length'); if ($length) { if (substr($uri, 0, 1) !== '/') { $uri = '/' . $uri; } list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); $freeSpace = \OC\Files\Filesystem::free_space($parentUri); if ($freeSpace !== \OC\Files\FREE_SPACE_UNKNOWN && $length > $freeSpace) { throw new Sabre_DAV_Exception_InsufficientStorage(); } } return true; }
/** * This function allows you to check if a node exists. * * @param string $path * @return bool */ public function nodeExists($path) { try { // The root always exists if ($path === '') { return true; } list($parent, $base) = Sabre_DAV_URLUtil::splitPath($path); $parentNode = $this->getNodeForPath($parent); if (!$parentNode instanceof Sabre_DAV_ICollection) { return false; } return $parentNode->childExists($base); } catch (Sabre_DAV_Exception_NotFound $e) { return false; } }
/** * Returns a list of principals based on a prefix. * * This prefix will often contain something like 'principals'. You are only * expected to return principals that are in this base path. * * You are expected to return at least a 'uri' for every user, you can * return any additional properties if you wish so. Common properties are: * {DAV:}displayname * {http://sabredav.org/ns}email-address - This is a custom SabreDAV * field that's actualy injected in a number of other properties. If * you have an email address, use this property. * * @param string $prefixPath * @return array */ public function getPrincipalsByPrefix($prefixPath) { $this->logger->info("getPrincipalsByPrefix({$prefixPath})"); // Get connectedUser $connectedUser = $this->bridge->getConnectedUser(); if ($connectedUser == '') { // Not connected $this->logger->warn("Not connected!"); return array(); } // Build principals URIs $uris = array("principals/{$connectedUser}"); $principals = array(); foreach ($uris as $uri) { list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($uri); if ($rowPrefix !== $prefixPath) { continue; } $principals[] = array('uri' => $uri, '{DAV:}displayname' => $connectedUser, '{http://sabredav.org/ns}email-address' => $this->bridge->getConnectedUserMailAddress()); } return $principals; }
/** * @param $filePath * @param Sabre_DAV_INode $node * @throws Sabre_DAV_Exception_BadRequest */ public function sendFileIdHeader($filePath, Sabre_DAV_INode $node = null) { // chunked upload handling if (isset($_SERVER['HTTP_OC_CHUNKED'])) { list($path, $name) = \Sabre_DAV_URLUtil::splitPath($filePath); $info = OC_FileChunking::decodeName($name); if (!empty($info)) { $filePath = $path . '/' . $info['name']; } } // we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder if (!$this->server->tree->nodeExists($filePath)) { return; } $node = $this->server->tree->getNodeForPath($filePath); if ($node instanceof OC_Connector_Sabre_Node) { $fileId = $node->getFileId(); if (!is_null($fileId)) { $this->server->httpResponse->setHeader('OC-FileId', $fileId); } } }
/** * Generates the html directory index for a given url * * @param string $path * @return string */ public function generateDirectoryIndex($path) { $version = ''; if (Sabre_DAV_Server::$exposeVersion) { $version = Sabre_DAV_Version::VERSION . "-" . Sabre_DAV_Version::STABILITY; } $html = "<html>\n<head>\n <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . $version . "</title>\n <style type=\"text/css\">\n body { Font-family: arial}\n h1 { font-size: 150% }\n </style>\n "; if ($this->enableAssets) { $html .= '<link rel="shortcut icon" href="' . $this->getAssetUrl('favicon.ico') . '" type="image/vnd.microsoft.icon" />'; } $html .= "</head>\n<body>\n <h1>Index for " . $this->escapeHTML($path) . "/</h1>\n <table>\n <tr><th width=\"24\"></th><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>\n <tr><td colspan=\"5\"><hr /></td></tr>"; $files = $this->server->getPropertiesForPath($path, array('{DAV:}displayname', '{DAV:}resourcetype', '{DAV:}getcontenttype', '{DAV:}getcontentlength', '{DAV:}getlastmodified'), 1); $parent = $this->server->tree->getNodeForPath($path); if ($path) { list($parentUri) = Sabre_DAV_URLUtil::splitPath($path); $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri); $icon = $this->enableAssets ? '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl('icons/parent' . $this->iconExtension) . '" width="24" alt="Parent" /></a>' : ''; $html .= "<tr>\n <td>{$icon}</td>\n <td><a href=\"{$fullPath}\">..</a></td>\n <td>[parent]</td>\n <td></td>\n <td></td>\n </tr>"; } foreach ($files as $file) { // This is the current directory, we can skip it if (rtrim($file['href'], '/') == $path) { continue; } list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']); $type = null; if (isset($file[200]['{DAV:}resourcetype'])) { $type = $file[200]['{DAV:}resourcetype']->getValue(); // resourcetype can have multiple values if (!is_array($type)) { $type = array($type); } foreach ($type as $k => $v) { // Some name mapping is preferred switch ($v) { case '{DAV:}collection': $type[$k] = 'Collection'; break; case '{DAV:}principal': $type[$k] = 'Principal'; break; case '{urn:ietf:params:xml:ns:carddav}addressbook': $type[$k] = 'Addressbook'; break; case '{urn:ietf:params:xml:ns:caldav}calendar': $type[$k] = 'Calendar'; break; case '{urn:ietf:params:xml:ns:caldav}schedule-inbox': $type[$k] = 'Schedule Inbox'; break; case '{urn:ietf:params:xml:ns:caldav}schedule-outbox': $type[$k] = 'Schedule Outbox'; break; case '{http://calendarserver.org/ns/}calendar-proxy-read': $type[$k] = 'Proxy-Read'; break; case '{http://calendarserver.org/ns/}calendar-proxy-write': $type[$k] = 'Proxy-Write'; break; } } $type = implode(', ', $type); } // If no resourcetype was found, we attempt to use // the contenttype property if (!$type && isset($file[200]['{DAV:}getcontenttype'])) { $type = $file[200]['{DAV:}getcontenttype']; } if (!$type) { $type = 'Unknown'; } $size = isset($file[200]['{DAV:}getcontentlength']) ? (int) $file[200]['{DAV:}getcontentlength'] : ''; $lastmodified = isset($file[200]['{DAV:}getlastmodified']) ? $file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM) : ''; $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path ? $path . '/' : '') . $name, '/')); $displayName = isset($file[200]['{DAV:}displayname']) ? $file[200]['{DAV:}displayname'] : $name; $displayName = $this->escapeHTML($displayName); $type = $this->escapeHTML($type); $icon = ''; if ($this->enableAssets) { $node = $this->server->tree->getNodeForPath(($path ? $path . '/' : '') . $name); foreach (array_reverse($this->iconMap) as $class => $iconName) { if ($node instanceof $class) { $icon = '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl($iconName . $this->iconExtension) . '" alt="" width="24" /></a>'; break; } } } $html .= "<tr>\n <td>{$icon}</td>\n <td><a href=\"{$fullPath}\">{$displayName}</a></td>\n <td>{$type}</td>\n <td>{$size}</td>\n <td>{$lastmodified}</td>\n </tr>"; } $html .= "<tr><td colspan=\"5\"><hr /></td></tr>"; $output = ''; if ($this->enablePost) { $this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output)); } $html .= $output; $html .= "</table>\n <address>Generated by SabreDAV " . $version . " (c)2007-2013 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>\n </body>\n </html>"; return $html; }
/** * @brief gets the userid from a principal path * @return string */ public static function extractUserID($principaluri) { list($prefix, $userid) = Sabre_DAV_URLUtil::splitPath($principaluri); return $userid; }
/** * Returns this principals name. * * @return string */ public function getName() { $uri = $this->principalProperties['uri']; list(, $name) = Sabre_DAV_URLUtil::splitPath($uri); return $name; }
/** * Use this method to create a new collection * * The {DAV:}resourcetype is specified using the resourceType array. * At the very least it must contain {DAV:}collection. * * The properties array can contain a list of additional properties. * * @param string $uri The new uri * @param array $resourceType The resourceType(s) * @param array $properties A list of properties * @return array|null */ public function createCollection($uri, array $resourceType, array $properties) { list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); // Making sure {DAV:}collection was specified as resourceType if (!in_array('{DAV:}collection', $resourceType)) { throw new Sabre_DAV_Exception_InvalidResourceType('The resourceType for this collection must at least include {DAV:}collection'); } // Making sure the parent exists try { $parent = $this->tree->getNodeForPath($parentUri); } catch (Sabre_DAV_Exception_NotFound $e) { throw new Sabre_DAV_Exception_Conflict('Parent node does not exist'); } // Making sure the parent is a collection if (!$parent instanceof Sabre_DAV_ICollection) { throw new Sabre_DAV_Exception_Conflict('Parent node is not a collection'); } // Making sure the child does not already exist try { $parent->getChild($newName); // If we got here.. it means there's already a node on that url, and we need to throw a 405 throw new Sabre_DAV_Exception_MethodNotAllowed('The resource you tried to create already exists'); } catch (Sabre_DAV_Exception_NotFound $e) { // This is correct } if (!$this->broadcastEvent('beforeBind', array($uri))) { return; } // There are 2 modes of operation. The standard collection // creates the directory, and then updates properties // the extended collection can create it directly. if ($parent instanceof Sabre_DAV_IExtendedCollection) { $parent->createExtendedCollection($newName, $resourceType, $properties); } else { // No special resourcetypes are supported if (count($resourceType) > 1) { throw new Sabre_DAV_Exception_InvalidResourceType('The {DAV:}resourcetype you specified is not supported here.'); } $parent->createDirectory($newName); $rollBack = false; $exception = null; $errorResult = null; if (count($properties) > 0) { try { $errorResult = $this->updateProperties($uri, $properties); if (!isset($errorResult[200])) { $rollBack = true; } } catch (Sabre_DAV_Exception $e) { $rollBack = true; $exception = $e; } } if ($rollBack) { if (!$this->broadcastEvent('beforeUnbind', array($uri))) { return; } $this->tree->delete($uri); // Re-throwing exception if ($exception) { throw $exception; } return $errorResult; } } $this->tree->markDirty($parentUri); $this->broadcastEvent('afterBind', array($uri)); }
/** * Renames the node * * @param string $name The new name * @return void */ public function setName($name) { list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path); list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; // We're deleting the existing resourcedata, and recreating it // for the new path. $resourceData = $this->getResourceData(); $this->deleteResourceData(); rename($this->path, $newPath); $this->path = $newPath; $this->putResourceData($resourceData); }
/** * Generates the html directory index for a given url * * @param string $path * @return string */ public function generateDirectoryIndex($path) { $html = "<html>\n<head>\n <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . Sabre_DAV_Version::VERSION . "</title>\n <style type=\"text/css\"> body { Font-family: arial}</style>\n</head>\n<body>\n <h1>Index for " . $this->escapeHTML($path) . "/</h1>\n <table>\n <tr><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>\n <tr><td colspan=\"4\"><hr /></td></tr>"; $files = $this->server->getPropertiesForPath($path, array('{DAV:}displayname', '{DAV:}resourcetype', '{DAV:}getcontenttype', '{DAV:}getcontentlength', '{DAV:}getlastmodified'), 1); $parent = $this->server->tree->getNodeForPath($path); if ($path) { list($parentUri) = Sabre_DAV_URLUtil::splitPath($path); $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri); $html .= "<tr>\n<td><a href=\"{$fullPath}\">..</a></td>\n<td>[parent]</td>\n<td></td>\n<td></td>\n</tr>"; } foreach ($files as $k => $file) { // This is the current directory, we can skip it if (rtrim($file['href'], '/') == $path) { continue; } list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']); $type = null; if (isset($file[200]['{DAV:}resourcetype'])) { $type = $file[200]['{DAV:}resourcetype']->getValue(); // resourcetype can have multiple values if (!is_array($type)) { $type = array($type); } foreach ($type as $k => $v) { // Some name mapping is preferred switch ($v) { case '{DAV:}collection': $type[$k] = 'Collection'; break; case '{DAV:}principal': $type[$k] = 'Principal'; break; case '{urn:ietf:params:xml:ns:carddav}addressbook': $type[$k] = 'Addressbook'; break; case '{urn:ietf:params:xml:ns:caldav}calendar': $type[$k] = 'Calendar'; break; } } $type = implode(', ', $type); } // If no resourcetype was found, we attempt to use // the contenttype property if (!$type && isset($file[200]['{DAV:}getcontenttype'])) { $type = $file[200]['{DAV:}getcontenttype']; } if (!$type) { $type = 'Unknown'; } $size = isset($file[200]['{DAV:}getcontentlength']) ? (int) $file[200]['{DAV:}getcontentlength'] : ''; $lastmodified = isset($file[200]['{DAV:}getlastmodified']) ? $file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM) : ''; $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path ? $path . '/' : '') . $name, '/')); $displayName = isset($file[200]['{DAV:}displayname']) ? $file[200]['{DAV:}displayname'] : $name; $name = $this->escapeHTML($name); $displayName = $this->escapeHTML($displayName); $type = $this->escapeHTML($type); $html .= "<tr>\n<td><a href=\"{$fullPath}\">{$displayName}</a></td>\n<td>{$type}</td>\n<td>{$size}</td>\n<td>{$lastmodified}</td>\n</tr>"; } $html .= "<tr><td colspan=\"4\"><hr /></td></tr>"; if ($this->enablePost && $parent instanceof Sabre_DAV_ICollection) { $html .= '<tr><td><form method="post" action=""> <h3>Create new folder</h3> <input type="hidden" name="sabreAction" value="mkcol" /> Name: <input type="text" name="name" /><br /> <input type="submit" value="create" /> </form> <form method="post" action="" enctype="multipart/form-data"> <h3>Upload file</h3> <input type="hidden" name="sabreAction" value="put" /> Name (optional): <input type="text" name="name" /><br /> File: <input type="file" name="file" /><br /> <input type="submit" value="upload" /> </form> </td></tr>'; } $html .= "</table>\n <address>Generated by SabreDAV " . Sabre_DAV_Version::VERSION . "-" . Sabre_DAV_Version::STABILITY . " (c)2007-2012 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>\n</body>\n</html>"; return $html; }
/** * This method will check if the url matches the temporary file pattern * if it does, it will return an path based on $this->dataDir for the * temporary file storage. * * @param string $path * @return boolean|string */ protected function isTempFile($path) { // We're only interested in the basename. list(, $tempPath) = Sabre_DAV_URLUtil::splitPath($path); foreach ($this->temporaryFilePatterns as $tempFile) { if (preg_match($tempFile, $tempPath)) { return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile'; } } return false; }