From 3a21755963d8d9897a48ab58292345c0b710e239 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind@owncloud.com>
Date: Tue, 25 Feb 2014 16:23:09 +0100
Subject: [PATCH] Pass the filesystem view as argument in the sabredav
 connectors and use the fileinfo object

---
 apps/files/appinfo/remote.php                 |  22 ++-
 .../sabre/aborteduploaddetectionplugin.php    |  33 ++--
 lib/private/connector/sabre/directory.php     |  35 ++--
 lib/private/connector/sabre/file.php          |  64 +++----
 lib/private/connector/sabre/node.php          | 166 ++++++------------
 lib/private/connector/sabre/objecttree.php    |  78 ++++----
 lib/private/connector/sabre/quotaplugin.php   |  30 ++--
 lib/private/connector/sabre/server.php        |  80 ++++++---
 8 files changed, 231 insertions(+), 277 deletions(-)

diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index ef22fe9218..1922bc4fcd 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -34,12 +34,8 @@ $authBackend = new OC_Connector_Sabre_Auth();
 $lockBackend = new OC_Connector_Sabre_Locks();
 $requestBackend = new OC_Connector_Sabre_Request();
 
-// Create ownCloud Dir
-$rootDir = new OC_Connector_Sabre_Directory('');
-$objectTree = new \OC\Connector\Sabre\ObjectTree($rootDir);
-
 // Fire up server
-$server = new OC_Connector_Sabre_Server($objectTree);
+$server = new OC_Connector_Sabre_Server();
 $server->httpRequest = $requestBackend;
 $server->setBaseUri($baseuri);
 
@@ -49,10 +45,22 @@ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend, $defaults->getName())
 $server->addPlugin(new Sabre_DAV_Locks_Plugin($lockBackend));
 $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload
 $server->addPlugin(new OC_Connector_Sabre_FilesPlugin());
-$server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin());
-$server->addPlugin(new OC_Connector_Sabre_QuotaPlugin());
 $server->addPlugin(new OC_Connector_Sabre_MaintenancePlugin());
 $server->addPlugin(new OC_Connector_Sabre_ExceptionLoggerPlugin('webdav'));
 
+// wait with registering these until auth is handled and the filesystem is setup
+$server->subscribeEvent('beforeMethod', function () use ($server) {
+	$view = \OC\Files\Filesystem::getView();
+	$rootInfo = $view->getFileInfo('');
+
+	// Create ownCloud Dir
+	$rootDir = new OC_Connector_Sabre_Directory($view, $rootInfo);
+	$objectTree = new \OC\Connector\Sabre\ObjectTree($rootDir, $view);
+	$server->setObjectTree($objectTree);
+
+	$server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin($view));
+	$server->addPlugin(new OC_Connector_Sabre_QuotaPlugin($view));
+}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
+
 // And off we go!
 $server->exec();
diff --git a/lib/private/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
index ad759d1d84..1a092a59a8 100644
--- a/lib/private/connector/sabre/aborteduploaddetectionplugin.php
+++ b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
@@ -22,11 +22,16 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
 	private $server;
 
 	/**
-	 * is kept public to allow overwrite for unit testing
-	 *
 	 * @var \OC\Files\View
 	 */
-	public $fileView;
+	private $fileView;
+
+	/**
+	 * @param \OC\Files\View $view
+	 */
+	public function __construct($view) {
+		$this->fileView = $view;
+	}
 
 	/**
 	 * This initializes the plugin.
@@ -55,7 +60,7 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
 
 		// we should only react on PUT which is used for upload
 		// e.g. with LOCK this will not work, but LOCK uses createFile() as well
-		if ($this->server->httpRequest->getMethod() !== 'PUT' ) {
+		if ($this->server->httpRequest->getMethod() !== 'PUT') {
 			return;
 		}
 
@@ -70,9 +75,9 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
 		if (!$expected) {
 			return;
 		}
-		$actual = $this->getFileView()->filesize($filePath);
+		$actual = $this->fileView->filesize($filePath);
 		if ($actual != $expected) {
-			$this->getFileView()->unlink($filePath);
+			$this->fileView->unlink($filePath);
 			throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual);
 		}
 
@@ -81,8 +86,7 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
 	/**
 	 * @return string
 	 */
-	public function getLength()
-	{
+	public function getLength() {
 		$req = $this->server->httpRequest;
 		$length = $req->getHeader('X-Expected-Entity-Length');
 		if (!$length) {
@@ -91,17 +95,4 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
 
 		return $length;
 	}
-
-	/**
-	 * @return \OC\Files\View
-	 */
-	public function getFileView()
-	{
-		if (is_null($this->fileView)) {
-			// initialize fileView
-			$this->fileView = \OC\Files\Filesystem::getView();
-		}
-
-		return $this->fileView;
-	}
 }
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 02d1a9f4ba..619aec21ea 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -60,20 +60,22 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 
 			// exit if we can't create a new file and we don't updatable existing file
 			$info = OC_FileChunking::decodeName($name);
-			if (!\OC\Files\Filesystem::isCreatable($this->path) &&
-					!\OC\Files\Filesystem::isUpdatable($this->path . '/' . $info['name'])) {
+			if (!$this->fileView->isCreatable($this->path) &&
+					!$this->fileView->isUpdatable($this->path . '/' . $info['name'])) {
 				throw new \Sabre_DAV_Exception_Forbidden();
 			}
 
 		} else {
 			// For non-chunked upload it is enough to check if we can create a new file
-			if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+			if (!$this->fileView->isCreatable($this->path)) {
 				throw new \Sabre_DAV_Exception_Forbidden();
 			}
 		}
 
 		$path = $this->path . '/' . $name;
-		$node = new OC_Connector_Sabre_File($path);
+		// using a dummy FileInfo is acceptable here since it will be refreshed after the put is complete
+		$info = new \OC\Files\FileInfo($path, null, null, array());
+		$node = new OC_Connector_Sabre_File($this->fileView, $info);
 		return $node->put($data);
 	}
 
@@ -90,12 +92,12 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
-		if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+		if (!$this->fileView->isCreatable($this->path)) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
 		$newPath = $this->path . '/' . $name;
-		if(!\OC\Files\Filesystem::mkdir($newPath)) {
+		if(!$this->fileView->mkdir($newPath)) {
 			throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath);
 		}
 
@@ -105,6 +107,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 	 * Returns a specific child node, referenced by its name
 	 *
 	 * @param string $name
+	 * @param \OCP\Files\FileInfo $info
 	 * @throws Sabre_DAV_Exception_FileNotFound
 	 * @return Sabre_DAV_INode
 	 */
@@ -112,7 +115,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 
 		$path = $this->path . '/' . $name;
 		if (is_null($info)) {
-			$info = \OC\Files\Filesystem::getFileInfo($path);
+			$info = $this->fileView->getFileInfo($path);
 		}
 
 		if (!$info) {
@@ -120,12 +123,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 		}
 
 		if ($info['mimetype'] == 'httpd/unix-directory') {
-			$node = new OC_Connector_Sabre_Directory($path);
+			$node = new OC_Connector_Sabre_Directory($this->fileView, $info);
 		} else {
-			$node = new OC_Connector_Sabre_File($path);
+			$node = new OC_Connector_Sabre_File($this->fileView, $info);
 		}
-
-		$node->setFileinfoCache($info);
 		return $node;
 	}
 
@@ -136,7 +137,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 	 */
 	public function getChildren() {
 
-		$folder_content = \OC\Files\Filesystem::getDirectoryContent($this->path);
+		$folder_content = $this->fileView->getDirectoryContent($this->path);
 		$paths = array();
 		foreach($folder_content as $info) {
 			$paths[] = $this->path.'/'.$info['name'];
@@ -167,7 +168,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 
 		$nodes = array();
 		foreach($folder_content as $info) {
-			$node = $this->getChild($info['name'], $info);
+			$node = $this->getChild($info->getName(), $info);
 			$node->setPropertyCache($properties[$this->path.'/'.$info['name']]);
 			$nodes[] = $node;
 		}
@@ -183,7 +184,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 	public function childExists($name) {
 
 		$path = $this->path . '/' . $name;
-		return \OC\Files\Filesystem::file_exists($path);
+		return $this->fileView->file_exists($path);
 
 	}
 
@@ -199,11 +200,11 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
-		if (!\OC\Files\Filesystem::isDeletable($this->path)) {
+		if (!$this->info->isDeletable()) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
-		\OC\Files\Filesystem::rmdir($this->path);
+		$this->fileView->rmdir($this->path);
 
 	}
 
@@ -235,7 +236,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
 	public function getProperties($properties) {
 		$props = parent::getProperties($properties);
 		if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) {
-			$props[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path);
+			$props[self::GETETAG_PROPERTYNAME] = $this->info->getEtag();
 		}
 		return $props;
 	}
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index ef6caaf22a..cbecd90b7d 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -45,11 +45,8 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 	 * @return string|null
 	 */
 	public function put($data) {
-
-		$fs = $this->getFS();
-
-		if ($fs->file_exists($this->path) &&
-			!$fs->isUpdatable($this->path)) {
+		if ($this->info && $this->fileView->file_exists($this->path) &&
+			!$this->info->isUpdateable()) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
@@ -79,10 +76,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 		}
 
 		try {
-			$putOkay = $fs->file_put_contents($partpath, $data);
+			$putOkay = $this->fileView->file_put_contents($partpath, $data);
 			if ($putOkay === false) {
 				\OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR);
-				$fs->unlink($partpath);
+				$this->fileView->unlink($partpath);
 				// because we have no clue about the cause we can only throw back a 500/Internal Server Error
 				throw new Sabre_DAV_Exception('Could not write file contents');
 			}
@@ -105,29 +102,30 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 		}
 
 		// rename to correct path
-		$renameOkay = $fs->rename($partpath, $this->path);
-		$fileExists = $fs->file_exists($this->path);
+		$renameOkay = $this->fileView->rename($partpath, $this->path);
+		$fileExists = $this->fileView->file_exists($this->path);
 		if ($renameOkay === false || $fileExists === false) {
 			\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
-			$fs->unlink($partpath);
+			$this->fileView->unlink($partpath);
 			throw new Sabre_DAV_Exception('Could not rename part file to final file');
 		}
 
 		// allow sync clients to send the mtime along in a header
 		$mtime = OC_Request::hasModificationTime();
 		if ($mtime !== false) {
-			if($fs->touch($this->path, $mtime)) {
+			if($this->fileView->touch($this->path, $mtime)) {
 				header('X-OC-MTime: accepted');
 			}
 		}
+		$this->refreshInfo();
 
-		return $this->getETagPropertyForPath($this->path);
+		return '"' . $this->info->getEtag() . '"';
 	}
 
 	/**
 	 * Returns the data
 	 *
-	 * @return string
+	 * @return string | resource
 	 */
 	public function get() {
 
@@ -135,7 +133,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 		if (\OC_Util::encryptedFiles()) {
 			throw new \Sabre_DAV_Exception_ServiceUnavailable();
 		} else {
-			return \OC\Files\Filesystem::fopen($this->path, 'rb');
+			return $this->fileView->fopen($this->path, 'rb');
 		}
 
 	}
@@ -147,16 +145,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 	 * @throws Sabre_DAV_Exception_Forbidden
 	 */
 	public function delete() {
-		$fs = $this->getFS();
-
 		if ($this->path === 'Shared') {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
-		if (!$fs->isDeletable($this->path)) {
+		if (!$this->info->isDeletable()) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
-		$fs->unlink($this->path);
+		$this->fileView->unlink($this->path);
 
 		// remove properties
 		$this->removeProperties();
@@ -169,12 +165,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 	 * @return int
 	 */
 	public function getSize() {
-		$this->getFileinfoCache();
-		if ($this->fileinfo_cache['size'] > -1) {
-			return $this->fileinfo_cache['size'];
-		} else {
-			return null;
-		}
+		return $this->info->getSize();
 	}
 
 	/**
@@ -189,11 +180,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 	 * @return mixed
 	 */
 	public function getETag() {
-		$properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME));
-		if (isset($properties[self::GETETAG_PROPERTYNAME])) {
-			return $properties[self::GETETAG_PROPERTYNAME];
-		}
-		return null;
+		return $this->info->getEtag();
 	}
 
 	/**
@@ -204,12 +191,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 	 * @return mixed
 	 */
 	public function getContentType() {
-		if (isset($this->fileinfo_cache['mimetype'])) {
-			return $this->fileinfo_cache['mimetype'];
-		}
-
-		return \OC\Files\Filesystem::getMimeType($this->path);
-
+		return $this->info->getMimetype();
 	}
 
 	/**
@@ -245,15 +227,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 			$chunk_handler->file_assemble($partFile);
 
 			// here is the final atomic rename
-			$fs = $this->getFS();
 			$targetPath = $path . '/' . $info['name'];
-			$renameOkay = $fs->rename($partFile, $targetPath);
-			$fileExists = $fs->file_exists($targetPath);
+			$renameOkay = $this->fileView->rename($partFile, $targetPath);
+			$fileExists = $this->fileView->file_exists($targetPath);
 			if ($renameOkay === false || $fileExists === false) {
 				\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
 				// only delete if an error occurred and the target file was already created
 				if ($fileExists) {
-					$fs->unlink($targetPath);
+					$this->fileView->unlink($targetPath);
 				}
 				throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks');
 			}
@@ -261,12 +242,13 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
 			// allow sync clients to send the mtime along in a header
 			$mtime = OC_Request::hasModificationTime();
 			if ($mtime !== false) {
-				if($fs->touch($targetPath, $mtime)) {
+				if($this->fileView->touch($targetPath, $mtime)) {
 					header('X-OC-MTime: accepted');
 				}
 			}
 
-			return OC_Connector_Sabre_Node::getETagPropertyForPath($targetPath);
+			$info = $this->fileView->getFileInfo($targetPath);
+			return $info->getEtag();
 		}
 
 		return null;
diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php
index 5807c5c7f7..3a5c721dda 100644
--- a/lib/private/connector/sabre/node.php
+++ b/lib/private/connector/sabre/node.php
@@ -20,7 +20,6 @@
  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-
 abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
 	const GETETAG_PROPERTYNAME = '{DAV:}getetag';
 	const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
@@ -29,15 +28,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 * Allow configuring the method used to generate Etags
 	 *
 	 * @var array(class_name, function_name)
-	*/
+	 */
 	public static $ETagFunction = null;
 
 	/**
-	 * is kept public to allow overwrite for unit testing
-	 *
 	 * @var \OC\Files\View
 	 */
-	public $fileView;
+	protected $fileView;
 
 	/**
 	 * The path to the current node
@@ -46,53 +43,53 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 */
 	protected $path;
 
-	/**
-	 * node fileinfo cache
-	 * @var array
-	 */
-	protected $fileinfo_cache;
 	/**
 	 * node properties cache
+	 *
 	 * @var array
 	 */
 	protected $property_cache = null;
 
+	/**
+	 * @var \OCP\Files\FileInfo
+	 */
+	protected $info;
+
 	/**
 	 * @brief Sets up the node, expects a full path name
-	 * @param string $path
-	 * @return void
+	 * @param \OC\Files\View $view
+	 * @param \OCP\Files\FileInfo $info
 	 */
-	public function __construct($path) {
-		$this->path = $path;
+	public function __construct($view, $info) {
+		$this->fileView = $view;
+		$this->path = $this->fileView->getRelativePath($info->getPath());
+		$this->info = $info;
 	}
 
-
+	protected function refreshInfo() {
+		$this->info = $this->fileView->getFileInfo($this->path);
+	}
 
 	/**
 	 * @brief  Returns the name of the node
 	 * @return string
 	 */
 	public function getName() {
-
-		list(, $name)  = Sabre_DAV_URLUtil::splitPath($this->path);
-		return $name;
-
+		return $this->info->getName();
 	}
 
 	/**
 	 * @brief Renames the node
 	 * @param string $name The new name
-	 * @return void
 	 */
 	public function setName($name) {
-		$fs = $this->getFS();
 
 		// rename is only allowed if the update privilege is granted
-		if (!$fs->isUpdatable($this->path)) {
+		if (!$this->info->isUpdateable()) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 
-		list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
+		list($parentPath,) = Sabre_DAV_URLUtil::splitPath($this->path);
 		list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
 
 		if (!\OCP\Util::isValidFileName($newName)) {
@@ -102,38 +99,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 		$newPath = $parentPath . '/' . $newName;
 		$oldPath = $this->path;
 
-		$fs->rename($this->path, $newPath);
+		$this->fileView->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 ));
-
+		$query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?'
+			. ' WHERE `userid` = ? AND `propertypath` = ?');
+		$query->execute(array($newPath, OC_User::getUser(), $oldPath));
+		$this->refreshInfo();
 	}
 
-	public function setFileinfoCache($fileinfo_cache)
-	{
-		$this->fileinfo_cache = $fileinfo_cache;
-	}
-
-	/**
-	 * @brief Ensure that the fileinfo cache is filled
-	 * @note Uses OC_FileCache or a direct stat
-	 */
-	protected function getFileinfoCache() {
-		if (!isset($this->fileinfo_cache)) {
-			if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) {
-			} else {
-				$fileinfo_cache = \OC\Files\Filesystem::stat($this->path);
-			}
-
-			$this->fileinfo_cache = $fileinfo_cache;
-		}
-	}
-
-	public function setPropertyCache($property_cache)
-	{
+	public function setPropertyCache($property_cache) {
 		$this->property_cache = $property_cache;
 	}
 
@@ -142,8 +118,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 * @return int
 	 */
 	public function getLastModified() {
-		$this->getFileinfoCache();
-		return $this->fileinfo_cache['mtime'];
+		return $this->info->getMtime();
 
 	}
 
@@ -153,7 +128,8 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 *  Even if the modification time is set to a custom value the access time is set to now.
 	 */
 	public function touch($mtime) {
-		\OC\Files\Filesystem::touch($this->path, $mtime);
+		$this->fileView->touch($this->path, $mtime);
+		$this->refreshInfo();
 	}
 
 	/**
@@ -163,29 +139,28 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 */
 	public function updateProperties($properties) {
 		$existing = $this->getProperties(array());
-		foreach($properties as $propertyName => $propertyValue) {
+		foreach ($properties as $propertyName => $propertyValue) {
 			// If it was null, we need to delete the property
 			if (is_null($propertyValue)) {
-				if(array_key_exists( $propertyName, $existing )) {
-					$query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
-						.' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
-					$query->execute( array( OC_User::getUser(), $this->path, $propertyName ));
+				if (array_key_exists($propertyName, $existing)) {
+					$query = OC_DB::prepare('DELETE FROM `*PREFIX*properties`'
+						. ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?');
+					$query->execute(array(OC_User::getUser(), $this->path, $propertyName));
 				}
-			}
-			else {
-				if( strcmp( $propertyName, self::GETETAG_PROPERTYNAME) === 0 ) {
-					\OC\Files\Filesystem::putFileInfo($this->path, array('etag'=> $propertyValue));
-				} elseif( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0 ) {
+			} else {
+				if (strcmp($propertyName, self::GETETAG_PROPERTYNAME) === 0) {
+					\OC\Files\Filesystem::putFileInfo($this->path, array('etag' => $propertyValue));
+				} elseif (strcmp($propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0) {
 					$this->touch($propertyValue);
 				} else {
-					if(!array_key_exists( $propertyName, $existing )) {
-						$query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties`'
-							.' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
-						$query->execute( array( OC_User::getUser(), $this->path, $propertyName,$propertyValue ));
+					if (!array_key_exists($propertyName, $existing)) {
+						$query = OC_DB::prepare('INSERT INTO `*PREFIX*properties`'
+							. ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)');
+						$query->execute(array(OC_User::getUser(), $this->path, $propertyName, $propertyValue));
 					} else {
-						$query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'
-							.' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
-						$query->execute( array( $propertyValue,OC_User::getUser(), $this->path, $propertyName ));
+						$query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'
+							. ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?');
+						$query->execute(array($propertyValue, OC_User::getUser(), $this->path, $propertyName));
 					}
 				}
 			}
@@ -199,9 +174,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 	 * removes all properties for this node and user
 	 */
 	public function removeProperties() {
-		$query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
-		.' WHERE `userid` = ? AND `propertypath` = ?' );
-		$query->execute( array( OC_User::getUser(), $this->path));
+		$query = OC_DB::prepare('DELETE FROM `*PREFIX*properties`'
+			. ' WHERE `userid` = ? AND `propertypath` = ?');
+		$query->execute(array(OC_User::getUser(), $this->path));
 
 		$this->setPropertyCache(null);
 	}
@@ -219,29 +194,23 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 
 		if (is_null($this->property_cache)) {
 			$sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
-			$result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) );
+			$result = OC_DB::executeAudited($sql, array(OC_User::getUser(), $this->path));
 
 			$this->property_cache = array();
-			while( $row = $result->fetchRow()) {
+			while ($row = $result->fetchRow()) {
 				$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
 			}
 
-			// Don't call the static getETagPropertyForPath, its result is not cached
-			$this->getFileinfoCache();
-			if ($this->fileinfo_cache['etag']) {
-				$this->property_cache[self::GETETAG_PROPERTYNAME] = '"'.$this->fileinfo_cache['etag'].'"';
-			} else {
-				$this->property_cache[self::GETETAG_PROPERTYNAME] = null;
-			}
+			$this->property_cache[self::GETETAG_PROPERTYNAME] = '"' . $this->info->getEtag() . '"';
 		}
 
 		// if the array was empty, we need to return everything
-		if(count($properties) == 0) {
+		if (count($properties) == 0) {
 			return $this->property_cache;
 		}
 
 		$props = array();
-		foreach($properties as $property) {
+		foreach ($properties as $property) {
 			if (isset($this->property_cache[$property])) {
 				$props[$property] = $this->property_cache[$property];
 			}
@@ -250,36 +219,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
 		return $props;
 	}
 
-	/**
-	 * Returns the ETag surrounded by double-quotes for this path.
-	 * @param string $path Path of the file
-	 * @return string|null Returns null if the ETag can not effectively be determined
-	 */
-	protected function getETagPropertyForPath($path) {
-		$data = $this->getFS()->getFileInfo($path);
-		if (isset($data['etag'])) {
-			return '"'.$data['etag'].'"';
-		}
-		return null;
-	}
-
-	protected function getFS() {
-		if (is_null($this->fileView)) {
-			$this->fileView = \OC\Files\Filesystem::getView();
-		}
-		return $this->fileView;
-	}
-
 	/**
 	 * @return string|null
 	 */
-	public function getFileId()
-	{
-		$this->getFileinfoCache();
-
-		if (isset($this->fileinfo_cache['fileid'])) {
+	public function getFileId() {
+		if ($this->info->getId()) {
 			$instanceId = OC_Util::getInstanceId();
-			$id = sprintf('%08d', $this->fileinfo_cache['fileid']);
+			$id = sprintf('%08d', $this->info->getId());
 			return $id . $instanceId;
 		}
 
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index d2fa425b22..d176d3333f 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -8,16 +8,28 @@
 
 namespace OC\Connector\Sabre;
 
+use OC\Files\FileInfo;
 use OC\Files\Filesystem;
 
 class ObjectTree extends \Sabre_DAV_ObjectTree {
 
 	/**
-	 * keep this public to allow mock injection during unit test
-	 *
 	 * @var \OC\Files\View
 	 */
-	public $fileView;
+	protected $fileView;
+
+	/**
+	 * Creates the object
+	 *
+	 * This method expects the rootObject to be passed as a parameter
+	 *
+	 * @param \Sabre_DAV_ICollection $rootNode
+	 * @param \OC\Files\View $view
+	 */
+	public function __construct(\Sabre_DAV_ICollection $rootNode, $view) {
+		parent::__construct($rootNode);
+		$this->fileView = $view;
+	}
 
 	/**
 	 * Returns the INode object for the requested path
@@ -40,31 +52,34 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
 
 		if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
 			// read from storage
-			$absPath = $this->getFileView()->getAbsolutePath($path);
+			$absPath = $this->fileView->getAbsolutePath($path);
 			list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath);
 			if ($storage) {
+				/**
+				 * @var \OC\Files\Storage\Storage $storage
+				 */
 				$scanner = $storage->getScanner($internalPath);
 				// get data directly
-				$info = $scanner->getData($internalPath);
+				$data = $scanner->getData($internalPath);
+				$info = new FileInfo($absPath, $storage, $internalPath, $data);
+			} else {
+				$info = null;
 			}
-		}
-		else {
+		} else {
 			// read from cache
-			$info = $this->getFileView()->getFileInfo($path);
+			$info = $this->fileView->getFileInfo($path);
 		}
 
 		if (!$info) {
 			throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
 		}
 
-		if ($info['mimetype'] === 'httpd/unix-directory') {
-			$node = new \OC_Connector_Sabre_Directory($path);
+		if ($info->getType() === 'dir') {
+			$node = new \OC_Connector_Sabre_Directory($this->fileView, $info);
 		} else {
-			$node = new \OC_Connector_Sabre_File($path);
+			$node = new \OC_Connector_Sabre_File($this->fileView, $info);
 		}
 
-		$node->setFileinfoCache($info);
-
 		$this->cache[$path] = $node;
 		return $node;
 
@@ -88,19 +103,18 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
 		list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath);
 
 		// check update privileges
-		$fs = $this->getFileView();
-		if (!$fs->isUpdatable($sourcePath)) {
+		if (!$this->fileView->isUpdatable($sourcePath)) {
 			throw new \Sabre_DAV_Exception_Forbidden();
 		}
 		if ($sourceDir !== $destinationDir) {
 			// for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
-			if (!$fs->isUpdatable($sourceDir)) {
+			if (!$this->fileView->isUpdatable($sourceDir)) {
 				throw new \Sabre_DAV_Exception_Forbidden();
 			}
-			if (!$fs->isUpdatable($destinationDir)) {
+			if (!$this->fileView->isUpdatable($destinationDir)) {
 				throw new \Sabre_DAV_Exception_Forbidden();
 			}
-			if (!$fs->isDeletable($sourcePath)) {
+			if (!$this->fileView->isDeletable($sourcePath)) {
 				throw new \Sabre_DAV_Exception_Forbidden();
 			}
 		}
@@ -110,15 +124,15 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
 			throw new \Sabre_DAV_Exception_BadRequest();
 		}
 
-		$renameOkay = $fs->rename($sourcePath, $destinationPath);
+		$renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
 		if (!$renameOkay) {
 			throw new \Sabre_DAV_Exception_Forbidden('');
 		}
 
 		// update properties
-		$query = \OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?'
-		.' WHERE `userid` = ? AND `propertypath` = ?' );
-		$query->execute( array( $destinationPath, \OC_User::getUser(), $sourcePath ));
+		$query = \OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?'
+			. ' WHERE `userid` = ? AND `propertypath` = ?');
+		$query->execute(array($destinationPath, \OC_User::getUser(), $sourcePath));
 
 		$this->markDirty($sourceDir);
 		$this->markDirty($destinationDir);
@@ -137,12 +151,12 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
 	 */
 	public function copy($source, $destination) {
 
-		if (Filesystem::is_file($source)) {
-			Filesystem::copy($source, $destination);
+		if ($this->fileView->is_file($source)) {
+			$this->fileView->copy($source, $destination);
 		} else {
-			Filesystem::mkdir($destination);
-			$dh = Filesystem::opendir($source);
-			if(is_resource($dh)) {
+			$this->fileView->mkdir($destination);
+			$dh = $this->fileView->opendir($source);
+			if (is_resource($dh)) {
 				while (($subnode = readdir($dh)) !== false) {
 
 					if ($subnode == '.' || $subnode == '..') continue;
@@ -155,14 +169,4 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
 		list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destination);
 		$this->markDirty($destinationDir);
 	}
-
-	/**
-	 * @return \OC\Files\View
-	 */
-	public function getFileView() {
-		if (is_null($this->fileView)) {
-			$this->fileView = \OC\Files\Filesystem::getView();
-		}
-		return $this->fileView;
-	}
 }
diff --git a/lib/private/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php
index 8099794f67..13fb187eed 100644
--- a/lib/private/connector/sabre/quotaplugin.php
+++ b/lib/private/connector/sabre/quotaplugin.php
@@ -9,6 +9,11 @@
  */
 class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
 
+	/**
+	 * @var \OC\Files\View
+	 */
+	private $view;
+
 	/**
 	 * Reference to main server object
 	 *
@@ -17,11 +22,11 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
 	private $server;
 
 	/**
-	 * is kept public to allow overwrite for unit testing
-	 *
-	 * @var \OC\Files\View
+	 * @param \OC\Files\View $view
 	 */
-	public $fileView;
+	public function __construct($view) {
+		$this->view = $view;
+	}
 
 	/**
 	 * This initializes the plugin.
@@ -52,8 +57,8 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
 	public function checkQuota($uri, $data = null) {
 		$length = $this->getLength();
 		if ($length) {
-			if (substr($uri, 0, 1)!=='/') {
-				$uri='/'.$uri;
+			if (substr($uri, 0, 1) !== '/') {
+				$uri = '/' . $uri;
 			}
 			list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri);
 			$freeSpace = $this->getFreeSpace($parentUri);
@@ -64,8 +69,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
 		return true;
 	}
 
-	public function getLength()
-	{
+	public function getLength() {
 		$req = $this->server->httpRequest;
 		$length = $req->getHeader('X-Expected-Entity-Length');
 		if (!$length) {
@@ -84,14 +88,8 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
 	 * @param $parentUri
 	 * @return mixed
 	 */
-	public function getFreeSpace($parentUri)
-	{
-		if (is_null($this->fileView)) {
-			// initialize fileView
-			$this->fileView = \OC\Files\Filesystem::getView();
-		}
-
-		$freeSpace = $this->fileView->free_space($parentUri);
+	public function getFreeSpace($parentUri) {
+		$freeSpace = $this->view->free_space($parentUri);
 		return $freeSpace;
 	}
 }
diff --git a/lib/private/connector/sabre/server.php b/lib/private/connector/sabre/server.php
index 2660b043f4..bb7a7171d1 100644
--- a/lib/private/connector/sabre/server.php
+++ b/lib/private/connector/sabre/server.php
@@ -27,6 +27,22 @@
  * @see Sabre_DAV_Server
  */
 class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
+	/**
+	 * Sets up the server
+	 *
+	 * Unlike Sabre_DAV_Server's constructor this does not take an INode or ObjectTree as argument,
+	 * the object tree needs to be set later with setObjectTree
+	 */
+	public function __construct() {
+		$this->httpResponse = new Sabre_HTTP_Response();
+		$this->httpRequest = new Sabre_HTTP_Request();
+
+	}
+
+	public function setObjectTree($tree) {
+		$this->tree = $tree;
+	}
+
 
 	/**
 	 * @see Sabre_DAV_Server
@@ -40,22 +56,22 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 		// The only two options for the depth of a propfind is 0 or 1
 		// if ($depth!=0) $depth = 1;
 
-		$newProperties = $this->getPropertiesForPath($uri,$requestedProperties,$depth);
+		$newProperties = $this->getPropertiesForPath($uri, $requestedProperties, $depth);
 
 		// This is a multi-status response
 		$this->httpResponse->sendStatus(207);
-		$this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
-		$this->httpResponse->setHeader('Vary','Brief,Prefer');
+		$this->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
+		$this->httpResponse->setHeader('Vary', 'Brief,Prefer');
 
 		// Normally this header is only needed for OPTIONS responses, however..
 		// iCal seems to also depend on these being set for PROPFIND. Since
 		// this is not harmful, we'll add it.
-		$features = array('1','3', 'extended-mkcol');
-		foreach($this->plugins as $plugin) {
-			$features = array_merge($features,$plugin->getFeatures());
+		$features = array('1', '3', 'extended-mkcol');
+		foreach ($this->plugins as $plugin) {
+			$features = array_merge($features, $plugin->getFeatures());
 		}
 
-		$this->httpResponse->setHeader('DAV',implode(', ',$features));
+		$this->httpResponse->setHeader('DAV', implode(', ', $features));
 
 		$prefer = $this->getHTTPPrefer();
 		$minimal = $prefer['return-minimal'];
@@ -67,10 +83,11 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 
 	/**
 	 * Small helper to support PROPFIND with DEPTH_INFINITY.
+	 *
 	 * @param string $path
 	 */
 	private function addPathNodesRecursively(&$nodes, $path) {
-		foreach($this->tree->getChildren($path) as $childNode) {
+		foreach ($this->tree->getChildren($path) as $childNode) {
 			$nodes[$path . '/' . $childNode->getName()] = $childNode;
 			if ($childNode instanceof Sabre_DAV_ICollection)
 				$this->addPathNodesRecursively($nodes, $path . '/' . $childNode->getName());
@@ -81,7 +98,7 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 
 		//	if ($depth!=0) $depth = 1;
 
-		$path = rtrim($path,'/');
+		$path = rtrim($path, '/');
 
 		$returnPropertyList = array();
 
@@ -89,9 +106,10 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 		$nodes = array(
 			$path => $parentNode
 		);
-		if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) {
-			foreach($this->tree->getChildren($path) as $childNode)
+		if ($depth == 1 && $parentNode instanceof Sabre_DAV_ICollection) {
+			foreach ($this->tree->getChildren($path) as $childNode) {
 				$nodes[$path . '/' . $childNode->getName()] = $childNode;
+			}
 		} else if ($depth == self::DEPTH_INFINITY && $parentNode instanceof Sabre_DAV_ICollection) {
 			$this->addPathNodesRecursively($nodes, $path);
 		}
@@ -99,9 +117,9 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 		// If the propertyNames array is empty, it means all properties are requested.
 		// We shouldn't actually return everything we know though, and only return a
 		// sensible list.
-		$allProperties = count($propertyNames)==0;
+		$allProperties = count($propertyNames) == 0;
 
-		foreach($nodes as $myPath=>$node) {
+		foreach ($nodes as $myPath => $node) {
 
 			$currentPropertyNames = $propertyNames;
 
@@ -128,15 +146,15 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 			// to make certain decisions about the entry.
 			// WebDAV dictates we should add a / and the end of href's for collections
 			$removeRT = false;
-			if (!in_array('{DAV:}resourcetype',$currentPropertyNames)) {
+			if (!in_array('{DAV:}resourcetype', $currentPropertyNames)) {
 				$currentPropertyNames[] = '{DAV:}resourcetype';
 				$removeRT = true;
 			}
 
-			$result = $this->broadcastEvent('beforeGetProperties',array($myPath, $node, &$currentPropertyNames, &$newProperties));
+			$result = $this->broadcastEvent('beforeGetProperties', array($myPath, $node, &$currentPropertyNames, &$newProperties));
 			// If this method explicitly returned false, we must ignore this
 			// node as it is inaccessible.
-			if ($result===false) continue;
+			if ($result === false) continue;
 
 			if (count($currentPropertyNames) > 0) {
 
@@ -149,7 +167,7 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 					// So as we loop through this list, we will only take the
 					// properties that were actually requested and discard the
 					// rest.
-					foreach($currentPropertyNames as $k=>$currentPropertyName) {
+					foreach ($currentPropertyNames as $k => $currentPropertyName) {
 						if (isset($nodeProperties[$currentPropertyName])) {
 							unset($currentPropertyNames[$k]);
 							$newProperties[200][$currentPropertyName] = $nodeProperties[$currentPropertyName];
@@ -160,12 +178,14 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 
 			}
 
-			foreach($currentPropertyNames as $prop) {
+			foreach ($currentPropertyNames as $prop) {
 
 				if (isset($newProperties[200][$prop])) continue;
 
-				switch($prop) {
-					case '{DAV:}getlastmodified'       : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break;
+				switch ($prop) {
+					case '{DAV:}getlastmodified'       :
+						if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified());
+						break;
 					case '{DAV:}getcontentlength'      :
 						if ($node instanceof Sabre_DAV_IFile) {
 							$size = $node->getSize();
@@ -186,18 +206,22 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 							$newProperties[200][$prop] = $quotaInfo[1];
 						}
 						break;
-					case '{DAV:}getetag'               : if ($node instanceof Sabre_DAV_IFile && $etag = $node->getETag())  $newProperties[200][$prop] = $etag; break;
-					case '{DAV:}getcontenttype'        : if ($node instanceof Sabre_DAV_IFile && $ct = $node->getContentType())  $newProperties[200][$prop] = $ct; break;
+					case '{DAV:}getetag'               :
+						if ($node instanceof Sabre_DAV_IFile && $etag = $node->getETag()) $newProperties[200][$prop] = $etag;
+						break;
+					case '{DAV:}getcontenttype'        :
+						if ($node instanceof Sabre_DAV_IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct;
+						break;
 					case '{DAV:}supported-report-set'  :
 						$reports = array();
-						foreach($this->plugins as $plugin) {
+						foreach ($this->plugins as $plugin) {
 							$reports = array_merge($reports, $plugin->getSupportedReportSet($myPath));
 						}
 						$newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports);
 						break;
 					case '{DAV:}resourcetype' :
 						$newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType();
-						foreach($this->resourceTypeMapping as $className => $resourceType) {
+						foreach ($this->resourceTypeMapping as $className => $resourceType) {
 							if ($node instanceof $className) $newProperties[200]['{DAV:}resourcetype']->add($resourceType);
 						}
 						break;
@@ -209,16 +233,16 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server {
 
 			}
 
-			$this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties, $node));
+			$this->broadcastEvent('afterGetProperties', array(trim($myPath, '/'), &$newProperties, $node));
 
-			$newProperties['href'] = trim($myPath,'/');
+			$newProperties['href'] = trim($myPath, '/');
 
 			// Its is a WebDAV recommendation to add a trailing slash to collectionnames.
 			// Apple's iCal also requires a trailing slash for principals (rfc 3744), though this is non-standard.
-			if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype'])) {
+			if ($myPath != '' && isset($newProperties[200]['{DAV:}resourcetype'])) {
 				$rt = $newProperties[200]['{DAV:}resourcetype'];
 				if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) {
-					$newProperties['href'] .='/';
+					$newProperties['href'] .= '/';
 				}
 			}
 
-- 
GitLab