diff options
Diffstat (limited to 'lib/private/files/node')
-rw-r--r-- | lib/private/files/node/file.php | 155 | ||||
-rw-r--r-- | lib/private/files/node/folder.php | 382 | ||||
-rw-r--r-- | lib/private/files/node/node.php | 245 | ||||
-rw-r--r-- | lib/private/files/node/nonexistingfile.php | 89 | ||||
-rw-r--r-- | lib/private/files/node/nonexistingfolder.php | 113 | ||||
-rw-r--r-- | lib/private/files/node/root.php | 337 |
6 files changed, 1321 insertions, 0 deletions
diff --git a/lib/private/files/node/file.php b/lib/private/files/node/file.php new file mode 100644 index 00000000000..75d5e0166b6 --- /dev/null +++ b/lib/private/files/node/file.php @@ -0,0 +1,155 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OCP\Files\NotPermittedException; + +class File extends Node implements \OCP\Files\File { + /** + * @return string + * @throws \OCP\Files\NotPermittedException + */ + public function getContent() { + if ($this->checkPermissions(\OCP\PERMISSION_READ)) { + /** + * @var \OC\Files\Storage\Storage $storage; + */ + return $this->view->file_get_contents($this->path); + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $data + * @throws \OCP\Files\NotPermittedException + */ + public function putContent($data) { + if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) { + $this->sendHooks(array('preWrite')); + $this->view->file_put_contents($this->path, $data); + $this->sendHooks(array('postWrite')); + } else { + throw new NotPermittedException(); + } + } + + /** + * @return string + */ + public function getMimeType() { + return $this->view->getMimeType($this->path); + } + + /** + * @param string $mode + * @return resource + * @throws \OCP\Files\NotPermittedException + */ + public function fopen($mode) { + $preHooks = array(); + $postHooks = array(); + $requiredPermissions = \OCP\PERMISSION_READ; + switch ($mode) { + case 'r+': + case 'rb+': + case 'w+': + case 'wb+': + case 'x+': + case 'xb+': + case 'a+': + case 'ab+': + case 'w': + case 'wb': + case 'x': + case 'xb': + case 'a': + case 'ab': + $preHooks[] = 'preWrite'; + $postHooks[] = 'postWrite'; + $requiredPermissions |= \OCP\PERMISSION_UPDATE; + break; + } + + if ($this->checkPermissions($requiredPermissions)) { + $this->sendHooks($preHooks); + $result = $this->view->fopen($this->path, $mode); + $this->sendHooks($postHooks); + return $result; + } else { + throw new NotPermittedException(); + } + } + + public function delete() { + if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) { + $this->sendHooks(array('preDelete')); + $this->view->unlink($this->path); + $nonExisting = new NonExistingFile($this->root, $this->view, $this->path); + $this->root->emit('\OC\Files', 'postDelete', array($nonExisting)); + $this->exists = false; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function copy($targetPath) { + $targetPath = $this->normalizePath($targetPath); + $parent = $this->root->get(dirname($targetPath)); + if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) { + $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath); + $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting)); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->view->copy($this->path, $targetPath); + $targetNode = $this->root->get($targetPath); + $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode)); + $this->root->emit('\OC\Files', 'postWrite', array($targetNode)); + return $targetNode; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function move($targetPath) { + $targetPath = $this->normalizePath($targetPath); + $parent = $this->root->get(dirname($targetPath)); + if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) { + $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath); + $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting)); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->view->rename($this->path, $targetPath); + $targetNode = $this->root->get($targetPath); + $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode)); + $this->root->emit('\OC\Files', 'postWrite', array($targetNode)); + $this->path = $targetPath; + return $targetNode; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $type + * @param bool $raw + * @return string + */ + public function hash($type, $raw = false) { + return $this->view->hash($type, $this->path, $raw); + } +} diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php new file mode 100644 index 00000000000..923f53821b2 --- /dev/null +++ b/lib/private/files/node/folder.php @@ -0,0 +1,382 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OC\Files\Cache\Cache; +use OC\Files\Cache\Scanner; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; + +class Folder extends Node implements \OCP\Files\Folder { + /** + * @param string $path path relative to the folder + * @return string + * @throws \OCP\Files\NotPermittedException + */ + public function getFullPath($path) { + if (!$this->isValidPath($path)) { + throw new NotPermittedException(); + } + return $this->path . $this->normalizePath($path); + } + + /** + * @param string $path + * @throws \OCP\Files\NotFoundException + * @return string + */ + public function getRelativePath($path) { + if ($this->path === '' or $this->path === '/') { + return $this->normalizePath($path); + } + if (strpos($path, $this->path) !== 0) { + throw new NotFoundException(); + } else { + $path = substr($path, strlen($this->path)); + if (strlen($path) === 0) { + return '/'; + } else { + return $this->normalizePath($path); + } + } + } + + /** + * check if a node is a (grand-)child of the folder + * + * @param \OC\Files\Node\Node $node + * @return bool + */ + public function isSubNode($node) { + return strpos($node->getPath(), $this->path . '/') === 0; + } + + /** + * get the content of this directory + * + * @throws \OCP\Files\NotFoundException + * @return Node[] + */ + public function getDirectoryListing() { + $result = array(); + + /** + * @var \OC\Files\Storage\Storage $storage + */ + list($storage, $internalPath) = $this->view->resolvePath($this->path); + if ($storage) { + $cache = $storage->getCache($internalPath); + $permissionsCache = $storage->getPermissionsCache($internalPath); + + //trigger cache update check + $this->view->getFileInfo($this->path); + + $files = $cache->getFolderContents($internalPath); + $permissions = $permissionsCache->getDirectoryPermissions($this->getId(), $this->root->getUser()->getUID()); + } else { + $files = array(); + } + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mounts = $this->root->getMountsIn($this->path); + $dirLength = strlen($this->path); + foreach ($mounts as $mount) { + $subStorage = $mount->getStorage(); + if ($subStorage) { + $subCache = $subStorage->getCache(''); + + if ($subCache->getStatus('') === Cache::NOT_FOUND) { + $subScanner = $subStorage->getScanner(''); + $subScanner->scanFile(''); + } + + $rootEntry = $subCache->get(''); + if ($rootEntry) { + $relativePath = trim(substr($mount->getMountPoint(), $dirLength), '/'); + if ($pos = strpos($relativePath, '/')) { + //mountpoint inside subfolder add size to the correct folder + $entryName = substr($relativePath, 0, $pos); + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { + if ($rootEntry['size'] >= 0) { + $entry['size'] += $rootEntry['size']; + } else { + $entry['size'] = -1; + } + } + } + } else { //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $rootEntry['storageObject'] = $subStorage; + + //remove any existing entry with the same name + foreach ($files as $i => $file) { + if ($file['name'] === $rootEntry['name']) { + $files[$i] = null; + break; + } + } + $files[] = $rootEntry; + } + } + } + } + + foreach ($files as $file) { + if ($file) { + if (isset($permissions[$file['fileid']])) { + $file['permissions'] = $permissions[$file['fileid']]; + } + $node = $this->createNode($this->path . '/' . $file['name'], $file); + $result[] = $node; + } + } + + return $result; + } + + /** + * @param string $path + * @param array $info + * @return File|Folder + */ + protected function createNode($path, $info = array()) { + if (!isset($info['mimetype'])) { + $isDir = $this->view->is_dir($path); + } else { + $isDir = $info['mimetype'] === 'httpd/unix-directory'; + } + if ($isDir) { + return new Folder($this->root, $this->view, $path); + } else { + return new File($this->root, $this->view, $path); + } + } + + /** + * Get the node at $path + * + * @param string $path + * @return \OC\Files\Node\Node + * @throws \OCP\Files\NotFoundException + */ + public function get($path) { + return $this->root->get($this->getFullPath($path)); + } + + /** + * @param string $path + * @return bool + */ + public function nodeExists($path) { + try { + $this->get($path); + return true; + } catch (NotFoundException $e) { + return false; + } + } + + /** + * @param string $path + * @return \OC\Files\Node\Folder + * @throws \OCP\Files\NotPermittedException + */ + public function newFolder($path) { + if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) { + $fullPath = $this->getFullPath($path); + $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->root->emit('\OC\Files', 'preCreate', array($nonExisting)); + $this->view->mkdir($fullPath); + $node = new Folder($this->root, $this->view, $fullPath); + $this->root->emit('\OC\Files', 'postWrite', array($node)); + $this->root->emit('\OC\Files', 'postCreate', array($node)); + return $node; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $path + * @return \OC\Files\Node\File + * @throws \OCP\Files\NotPermittedException + */ + public function newFile($path) { + if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) { + $fullPath = $this->getFullPath($path); + $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->root->emit('\OC\Files', 'preCreate', array($nonExisting)); + $this->view->touch($fullPath); + $node = new File($this->root, $this->view, $fullPath); + $this->root->emit('\OC\Files', 'postWrite', array($node)); + $this->root->emit('\OC\Files', 'postCreate', array($node)); + return $node; + } else { + throw new NotPermittedException(); + } + } + + /** + * search for files with the name matching $query + * + * @param string $query + * @return \OC\Files\Node\Node[] + */ + public function search($query) { + return $this->searchCommon('%' . $query . '%', 'search'); + } + + /** + * search for files by mimetype + * + * @param string $mimetype + * @return Node[] + */ + public function searchByMime($mimetype) { + return $this->searchCommon($mimetype, 'searchByMime'); + } + + /** + * @param string $query + * @param string $method + * @return \OC\Files\Node\Node[] + */ + private function searchCommon($query, $method) { + $files = array(); + $rootLength = strlen($this->path); + /** + * @var \OC\Files\Storage\Storage $storage + */ + list($storage, $internalPath) = $this->view->resolvePath($this->path); + $internalRootLength = strlen($internalPath); + + $cache = $storage->getCache(''); + + $results = $cache->$method($query); + foreach ($results as $result) { + if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) { + $result['internalPath'] = $result['path']; + $result['path'] = substr($result['path'], $internalRootLength); + $result['storage'] = $storage; + $files[] = $result; + } + } + + $mounts = $this->root->getMountsIn($this->path); + foreach ($mounts as $mount) { + $storage = $mount->getStorage(); + if ($storage) { + $cache = $storage->getCache(''); + + $relativeMountPoint = substr($mount->getMountPoint(), $rootLength); + $results = $cache->$method($query); + foreach ($results as $result) { + $result['internalPath'] = $result['path']; + $result['path'] = $relativeMountPoint . $result['path']; + $result['storage'] = $storage; + $files[] = $result; + } + } + } + + $result = array(); + foreach ($files as $file) { + $result[] = $this->createNode($this->normalizePath($this->path . '/' . $file['path']), $file); + } + + return $result; + } + + /** + * @param $id + * @return \OC\Files\Node\Node[] + */ + public function getById($id) { + $nodes = $this->root->getById($id); + $result = array(); + foreach ($nodes as $node) { + $pathPart = substr($node->getPath(), 0, strlen($this->getPath()) + 1); + if ($this->path === '/' or $pathPart === $this->getPath() . '/') { + $result[] = $node; + } + } + return $result; + } + + public function getFreeSpace() { + return $this->view->free_space($this->path); + } + + /** + * @return bool + */ + public function isCreatable() { + return $this->checkPermissions(\OCP\PERMISSION_CREATE); + } + + public function delete() { + if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) { + $this->sendHooks(array('preDelete')); + $this->view->rmdir($this->path); + $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path); + $this->root->emit('\OC\Files', 'postDelete', array($nonExisting)); + $this->exists = false; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function copy($targetPath) { + $targetPath = $this->normalizePath($targetPath); + $parent = $this->root->get(dirname($targetPath)); + if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) { + $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath); + $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting)); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->view->copy($this->path, $targetPath); + $targetNode = $this->root->get($targetPath); + $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode)); + $this->root->emit('\OC\Files', 'postWrite', array($targetNode)); + return $targetNode; + } else { + throw new NotPermittedException(); + } + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function move($targetPath) { + $targetPath = $this->normalizePath($targetPath); + $parent = $this->root->get(dirname($targetPath)); + if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) { + $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath); + $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting)); + $this->root->emit('\OC\Files', 'preWrite', array($nonExisting)); + $this->view->rename($this->path, $targetPath); + $targetNode = $this->root->get($targetPath); + $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode)); + $this->root->emit('\OC\Files', 'postWrite', array($targetNode)); + $this->path = $targetPath; + return $targetNode; + } else { + throw new NotPermittedException(); + } + } +} diff --git a/lib/private/files/node/node.php b/lib/private/files/node/node.php new file mode 100644 index 00000000000..063e2424a64 --- /dev/null +++ b/lib/private/files/node/node.php @@ -0,0 +1,245 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OC\Files\Cache\Cache; +use OC\Files\Cache\Scanner; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; + +class Node implements \OCP\Files\Node { + /** + * @var \OC\Files\View $view + */ + protected $view; + + /** + * @var \OC\Files\Node\Root $root + */ + protected $root; + + /** + * @var string $path + */ + protected $path; + + /** + * @param \OC\Files\View $view + * @param \OC\Files\Node\Root Root $root + * @param string $path + */ + public function __construct($root, $view, $path) { + $this->view = $view; + $this->root = $root; + $this->path = $path; + } + + /** + * @param string[] $hooks + */ + protected function sendHooks($hooks) { + foreach ($hooks as $hook) { + $this->root->emit('\OC\Files', $hook, array($this)); + } + } + + /** + * @param int $permissions + * @return bool + */ + protected function checkPermissions($permissions) { + return ($this->getPermissions() & $permissions) === $permissions; + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function move($targetPath) { + return; + } + + public function delete() { + return; + } + + /** + * @param string $targetPath + * @return \OC\Files\Node\Node + */ + public function copy($targetPath) { + return; + } + + /** + * @param int $mtime + * @throws \OCP\Files\NotPermittedException + */ + public function touch($mtime = null) { + if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) { + $this->sendHooks(array('preTouch')); + $this->view->touch($this->path, $mtime); + $this->sendHooks(array('postTouch')); + } else { + throw new NotPermittedException(); + } + } + + /** + * @return \OC\Files\Storage\Storage + * @throws \OCP\Files\NotFoundException + */ + public function getStorage() { + list($storage,) = $this->view->resolvePath($this->path); + return $storage; + } + + /** + * @return string + */ + public function getPath() { + return $this->path; + } + + /** + * @return string + */ + public function getInternalPath() { + list(, $internalPath) = $this->view->resolvePath($this->path); + return $internalPath; + } + + /** + * @return int + */ + public function getId() { + $info = $this->view->getFileInfo($this->path); + return $info['fileid']; + } + + /** + * @return array + */ + public function stat() { + return $this->view->stat($this->path); + } + + /** + * @return int + */ + public function getMTime() { + return $this->view->filemtime($this->path); + } + + /** + * @return int + */ + public function getSize() { + return $this->view->filesize($this->path); + } + + /** + * @return string + */ + public function getEtag() { + $info = $this->view->getFileInfo($this->path); + return $info['etag']; + } + + /** + * @return int + */ + public function getPermissions() { + $info = $this->view->getFileInfo($this->path); + return $info['permissions']; + } + + /** + * @return bool + */ + public function isReadable() { + return $this->checkPermissions(\OCP\PERMISSION_READ); + } + + /** + * @return bool + */ + public function isUpdateable() { + return $this->checkPermissions(\OCP\PERMISSION_UPDATE); + } + + /** + * @return bool + */ + public function isDeletable() { + return $this->checkPermissions(\OCP\PERMISSION_DELETE); + } + + /** + * @return bool + */ + public function isShareable() { + return $this->checkPermissions(\OCP\PERMISSION_SHARE); + } + + /** + * @return Node + */ + public function getParent() { + return $this->root->get(dirname($this->path)); + } + + /** + * @return string + */ + public function getName() { + return basename($this->path); + } + + /** + * @param string $path + * @return string + */ + protected function normalizePath($path) { + if ($path === '' or $path === '/') { + return '/'; + } + //no windows style slashes + $path = str_replace('\\', '/', $path); + //add leading slash + if ($path[0] !== '/') { + $path = '/' . $path; + } + //remove duplicate slashes + while (strpos($path, '//') !== false) { + $path = str_replace('//', '/', $path); + } + //remove trailing slash + $path = rtrim($path, '/'); + + return $path; + } + + /** + * check if the requested path is valid + * + * @param string $path + * @return bool + */ + public function isValidPath($path) { + if (!$path || $path[0] !== '/') { + $path = '/' . $path; + } + if (strstr($path, '/../') || strrchr($path, '/') === '/..') { + return false; + } + return true; + } +} diff --git a/lib/private/files/node/nonexistingfile.php b/lib/private/files/node/nonexistingfile.php new file mode 100644 index 00000000000..d45076f7fee --- /dev/null +++ b/lib/private/files/node/nonexistingfile.php @@ -0,0 +1,89 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OCP\Files\NotFoundException; + +class NonExistingFile extends File { + /** + * @param string $newPath + * @throws \OCP\Files\NotFoundException + */ + public function rename($newPath) { + throw new NotFoundException(); + } + + public function delete() { + throw new NotFoundException(); + } + + public function copy($newPath) { + throw new NotFoundException(); + } + + public function touch($mtime = null) { + throw new NotFoundException(); + } + + public function getId() { + throw new NotFoundException(); + } + + public function stat() { + throw new NotFoundException(); + } + + public function getMTime() { + throw new NotFoundException(); + } + + public function getSize() { + throw new NotFoundException(); + } + + public function getEtag() { + throw new NotFoundException(); + } + + public function getPermissions() { + throw new NotFoundException(); + } + + public function isReadable() { + throw new NotFoundException(); + } + + public function isUpdateable() { + throw new NotFoundException(); + } + + public function isDeletable() { + throw new NotFoundException(); + } + + public function isShareable() { + throw new NotFoundException(); + } + + public function getContent() { + throw new NotFoundException(); + } + + public function putContent($data) { + throw new NotFoundException(); + } + + public function getMimeType() { + throw new NotFoundException(); + } + + public function fopen($mode) { + throw new NotFoundException(); + } +} diff --git a/lib/private/files/node/nonexistingfolder.php b/lib/private/files/node/nonexistingfolder.php new file mode 100644 index 00000000000..0346cbf1e21 --- /dev/null +++ b/lib/private/files/node/nonexistingfolder.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OCP\Files\NotFoundException; + +class NonExistingFolder extends Folder { + /** + * @param string $newPath + * @throws \OCP\Files\NotFoundException + */ + public function rename($newPath) { + throw new NotFoundException(); + } + + public function delete() { + throw new NotFoundException(); + } + + public function copy($newPath) { + throw new NotFoundException(); + } + + public function touch($mtime = null) { + throw new NotFoundException(); + } + + public function getId() { + throw new NotFoundException(); + } + + public function stat() { + throw new NotFoundException(); + } + + public function getMTime() { + throw new NotFoundException(); + } + + public function getSize() { + throw new NotFoundException(); + } + + public function getEtag() { + throw new NotFoundException(); + } + + public function getPermissions() { + throw new NotFoundException(); + } + + public function isReadable() { + throw new NotFoundException(); + } + + public function isUpdateable() { + throw new NotFoundException(); + } + + public function isDeletable() { + throw new NotFoundException(); + } + + public function isShareable() { + throw new NotFoundException(); + } + + public function get($path) { + throw new NotFoundException(); + } + + public function getDirectoryListing() { + throw new NotFoundException(); + } + + public function nodeExists($path) { + return false; + } + + public function newFolder($path) { + throw new NotFoundException(); + } + + public function newFile($path) { + throw new NotFoundException(); + } + + public function search($pattern) { + throw new NotFoundException(); + } + + public function searchByMime($mime) { + throw new NotFoundException(); + } + + public function getById($id) { + throw new NotFoundException(); + } + + public function getFreeSpace() { + throw new NotFoundException(); + } + + public function isCreatable() { + throw new NotFoundException(); + } +} diff --git a/lib/private/files/node/root.php b/lib/private/files/node/root.php new file mode 100644 index 00000000000..e3d58476e9c --- /dev/null +++ b/lib/private/files/node/root.php @@ -0,0 +1,337 @@ +<?php +/** + * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Node; + +use OC\Files\Cache\Cache; +use OC\Files\Cache\Scanner; +use OC\Files\Mount\Manager; +use OC\Files\Mount\Mount; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OC\Hooks\Emitter; +use OC\Hooks\PublicEmitter; + +/** + * Class Root + * + * Hooks available in scope \OC\Files + * - preWrite(\OCP\Files\Node $node) + * - postWrite(\OCP\Files\Node $node) + * - preCreate(\OCP\Files\Node $node) + * - postCreate(\OCP\Files\Node $node) + * - preDelete(\OCP\Files\Node $node) + * - postDelete(\OCP\Files\Node $node) + * - preTouch(\OC\FilesP\Node $node, int $mtime) + * - postTouch(\OCP\Files\Node $node) + * - preCopy(\OCP\Files\Node $source, \OCP\Files\Node $target) + * - postCopy(\OCP\Files\Node $source, \OCP\Files\Node $target) + * - preRename(\OCP\Files\Node $source, \OCP\Files\Node $target) + * - postRename(\OCP\Files\Node $source, \OCP\Files\Node $target) + * + * @package OC\Files\Node + */ +class Root extends Folder implements Emitter { + + /** + * @var \OC\Files\Mount\Manager $mountManager + */ + private $mountManager; + + /** + * @var \OC\Hooks\PublicEmitter + */ + private $emitter; + + /** + * @var \OC\User\User $user + */ + private $user; + + /** + * @param \OC\Files\Mount\Manager $manager + * @param \OC\Files\View $view + * @param \OC\User\User $user + */ + public function __construct($manager, $view, $user) { + parent::__construct($this, $view, ''); + $this->mountManager = $manager; + $this->user = $user; + $this->emitter = new PublicEmitter(); + } + + /** + * Get the user for which the filesystem is setup + * + * @return \OC\User\User + */ + public function getUser() { + return $this->user; + } + + /** + * @param string $scope + * @param string $method + * @param callable $callback + */ + public function listen($scope, $method, $callback) { + $this->emitter->listen($scope, $method, $callback); + } + + /** + * @param string $scope optional + * @param string $method optional + * @param callable $callback optional + */ + public function removeListener($scope = null, $method = null, $callback = null) { + $this->emitter->removeListener($scope, $method, $callback); + } + + /** + * @param string $scope + * @param string $method + * @param array $arguments + */ + public function emit($scope, $method, $arguments = array()) { + $this->emitter->emit($scope, $method, $arguments); + } + + /** + * @param \OC\Files\Storage\Storage $storage + * @param string $mountPoint + * @param array $arguments + */ + public function mount($storage, $mountPoint, $arguments = array()) { + $mount = new Mount($storage, $mountPoint, $arguments); + $this->mountManager->addMount($mount); + } + + /** + * @param string $mountPoint + * @return \OC\Files\Mount\Mount + */ + public function getMount($mountPoint) { + return $this->mountManager->find($mountPoint); + } + + /** + * @param string $mountPoint + * @return \OC\Files\Mount\Mount[] + */ + public function getMountsIn($mountPoint) { + return $this->mountManager->findIn($mountPoint); + } + + /** + * @param string $storageId + * @return \OC\Files\Mount\Mount[] + */ + public function getMountByStorageId($storageId) { + return $this->mountManager->findByStorageId($storageId); + } + + /** + * @param int $numericId + * @return Mount[] + */ + public function getMountByNumericStorageId($numericId) { + return $this->mountManager->findByNumericId($numericId); + } + + /** + * @param \OC\Files\Mount\Mount $mount + */ + public function unMount($mount) { + $this->mountManager->remove($mount); + } + + /** + * @param string $path + * @throws \OCP\Files\NotFoundException + * @throws \OCP\Files\NotPermittedException + * @return Node + */ + public function get($path) { + $path = $this->normalizePath($path); + if ($this->isValidPath($path)) { + $fullPath = $this->getFullPath($path); + if ($this->view->file_exists($fullPath)) { + return $this->createNode($fullPath); + } else { + throw new NotFoundException(); + } + } else { + throw new NotPermittedException(); + } + } + + /** + * search file by id + * + * An array is returned because in the case where a single storage is mounted in different places the same file + * can exist in different places + * + * @param int $id + * @throws \OCP\Files\NotFoundException + * @return Node[] + */ + public function getById($id) { + $result = Cache::getById($id); + if (is_null($result)) { + throw new NotFoundException(); + } else { + list($storageId, $internalPath) = $result; + $nodes = array(); + $mounts = $this->mountManager->findByStorageId($storageId); + foreach ($mounts as $mount) { + $nodes[] = $this->get($mount->getMountPoint() . $internalPath); + } + return $nodes; + } + + } + + //most operations cant be done on the root + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function rename($targetPath) { + throw new NotPermittedException(); + } + + public function delete() { + throw new NotPermittedException(); + } + + /** + * @param string $targetPath + * @throws \OCP\Files\NotPermittedException + * @return \OC\Files\Node\Node + */ + public function copy($targetPath) { + throw new NotPermittedException(); + } + + /** + * @param int $mtime + * @throws \OCP\Files\NotPermittedException + */ + public function touch($mtime = null) { + throw new NotPermittedException(); + } + + /** + * @return \OC\Files\Storage\Storage + * @throws \OCP\Files\NotFoundException + */ + public function getStorage() { + throw new NotFoundException(); + } + + /** + * @return string + */ + public function getPath() { + return '/'; + } + + /** + * @return string + */ + public function getInternalPath() { + return ''; + } + + /** + * @return int + */ + public function getId() { + return null; + } + + /** + * @return array + */ + public function stat() { + return null; + } + + /** + * @return int + */ + public function getMTime() { + return null; + } + + /** + * @return int + */ + public function getSize() { + return null; + } + + /** + * @return string + */ + public function getEtag() { + return null; + } + + /** + * @return int + */ + public function getPermissions() { + return \OCP\PERMISSION_CREATE; + } + + /** + * @return bool + */ + public function isReadable() { + return false; + } + + /** + * @return bool + */ + public function isUpdateable() { + return false; + } + + /** + * @return bool + */ + public function isDeletable() { + return false; + } + + /** + * @return bool + */ + public function isShareable() { + return false; + } + + /** + * @return Node + * @throws \OCP\Files\NotFoundException + */ + public function getParent() { + throw new NotFoundException(); + } + + /** + * @return string + */ + public function getName() { + return ''; + } +} |