diff options
Diffstat (limited to 'lib/files')
37 files changed, 0 insertions, 8317 deletions
diff --git a/lib/files/cache/backgroundwatcher.php b/lib/files/cache/backgroundwatcher.php deleted file mode 100644 index 923804f48d0..00000000000 --- a/lib/files/cache/backgroundwatcher.php +++ /dev/null @@ -1,104 +0,0 @@ -<?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\Cache; - -use \OC\Files\Mount; -use \OC\Files\Filesystem; - -class BackgroundWatcher { - static $folderMimetype = null; - - static private function getFolderMimetype() { - if (!is_null(self::$folderMimetype)) { - return self::$folderMimetype; - } - $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'; - $result = \OC_DB::executeAudited($sql, array('httpd/unix-directory')); - $row = $result->fetchRow(); - return $row['id']; - } - - static private function checkUpdate($id) { - $cacheItem = Cache::getById($id); - if (is_null($cacheItem)) { - return; - } - list($storageId, $internalPath) = $cacheItem; - $mounts = Filesystem::getMountByStorageId($storageId); - - if (count($mounts) === 0) { - //if the storage we need isn't mounted on default, try to find a user that has access to the storage - $permissionsCache = new Permissions($storageId); - $users = $permissionsCache->getUsers($id); - if (count($users) === 0) { - return; - } - Filesystem::initMountPoints($users[0]); - $mounts = Filesystem::getMountByStorageId($storageId); - if (count($mounts) === 0) { - return; - } - } - $storage = $mounts[0]->getStorage(); - $watcher = new Watcher($storage); - $watcher->checkUpdate($internalPath); - } - - /** - * get the next fileid in the cache - * - * @param int $previous - * @param bool $folder - * @return int - */ - static private function getNextFileId($previous, $folder) { - if ($folder) { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` = ? ORDER BY `fileid` ASC', 1); - } else { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` != ? ORDER BY `fileid` ASC', 1); - } - $result = \OC_DB::executeAudited($stmt, array($previous,self::getFolderMimetype())); - if ($row = $result->fetchRow()) { - return $row['fileid']; - } else { - return 0; - } - } - - static public function checkNext() { - // check both 1 file and 1 folder, this way new files are detected quicker because there are less folders than files usually - $previousFile = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_file', 0); - $previousFolder = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_folder', 0); - $nextFile = self::getNextFileId($previousFile, false); - $nextFolder = self::getNextFileId($previousFolder, true); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_file', $nextFile); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_folder', $nextFolder); - if ($nextFile > 0) { - self::checkUpdate($nextFile); - } - if ($nextFolder > 0) { - self::checkUpdate($nextFolder); - } - } - - static public function checkAll() { - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, true); - self::checkUpdate($next); - } - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, false); - self::checkUpdate($next); - } - } -} diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php deleted file mode 100644 index e69733727af..00000000000 --- a/lib/files/cache/cache.php +++ /dev/null @@ -1,582 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -/** - * Metadata cache for the filesystem - * - * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead - */ -class Cache { - const NOT_FOUND = 0; - const PARTIAL = 1; //only partial data available, file not cached in the database - const SHALLOW = 2; //folder in cache, but not all child files are completely scanned - const COMPLETE = 3; - - /** - * @var array partial data for the cache - */ - private $partial = array(); - - /** - * @var string - */ - private $storageId; - - /** - * @var Storage $storageCache - */ - private $storageCache; - - private $mimetypeIds = array(); - private $mimetypes = array(); - - /** - * @param \OC\Files\Storage\Storage|string $storage - */ - public function __construct($storage) { - if ($storage instanceof \OC\Files\Storage\Storage) { - $this->storageId = $storage->getId(); - } else { - $this->storageId = $storage; - } - if (strlen($this->storageId) > 64) { - $this->storageId = md5($this->storageId); - } - - $this->storageCache = new Storage($storage); - } - - public function getNumericStorageId() { - return $this->storageCache->getNumericId(); - } - - /** - * normalize mimetypes - * - * @param string $mime - * @return int - */ - public function getMimetypeId($mime) { - if (!isset($this->mimetypeIds[$mime])) { - $result = \OC_DB::executeAudited('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?', array($mime)); - if ($row = $result->fetchRow()) { - $this->mimetypeIds[$mime] = $row['id']; - } else { - $result = \OC_DB::executeAudited('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)', array($mime)); - $this->mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); - } - $this->mimetypes[$this->mimetypeIds[$mime]] = $mime; - } - return $this->mimetypeIds[$mime]; - } - - public function getMimetype($id) { - if (!isset($this->mimetypes[$id])) { - $sql = 'SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'; - $result = \OC_DB::executeAudited($sql, array($id)); - if ($row = $result->fetchRow()) { - $this->mimetypes[$id] = $row['mimetype']; - } else { - return null; - } - } - return $this->mimetypes[$id]; - } - - /** - * get the stored metadata of a file or folder - * - * @param string/int $file - * @return array | false - */ - public function get($file) { - if (is_string($file) or $file == '') { - // normalize file - $file = $this->normalize($file); - - $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($this->getNumericStorageId(), md5($file)); - } else { //file id - $where = 'WHERE `fileid` = ?'; - $params = array($file); - } - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` ' . $where; - $result = \OC_DB::executeAudited($sql, $params); - $data = $result->fetchRow(); - - //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO - //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false - if ($data === null) { - $data = false; - } - - //merge partial data - if (!$data and is_string($file)) { - if (isset($this->partial[$file])) { - $data = $this->partial[$file]; - } - } else { - //fix types - $data['fileid'] = (int)$data['fileid']; - $data['size'] = (int)$data['size']; - $data['mtime'] = (int)$data['mtime']; - $data['encrypted'] = (bool)$data['encrypted']; - $data['unencrypted_size'] = (int)$data['unencrypted_size']; - $data['storage'] = $this->storageId; - $data['mimetype'] = $this->getMimetype($data['mimetype']); - $data['mimepart'] = $this->getMimetype($data['mimepart']); - if ($data['storage_mtime'] == 0) { - $data['storage_mtime'] = $data['mtime']; - } - } - - return $data; - } - - /** - * get the metadata of all files stored in $folder - * - * @param string $folder - * @return array - */ - public function getFolderContents($folder) { - $fileId = $this->getId($folder); - if ($fileId > -1) { - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'; - $result = \OC_DB::executeAudited($sql,array($fileId)); - $files = $result->fetchAll(); - foreach ($files as &$file) { - $file['mimetype'] = $this->getMimetype($file['mimetype']); - $file['mimepart'] = $this->getMimetype($file['mimepart']); - if ($file['storage_mtime'] == 0) { - $file['storage_mtime'] = $file['mtime']; - } - } - return $files; - } else { - return array(); - } - } - - /** - * store meta data for a file or folder - * - * @param string $file - * @param array $data - * - * @return int file id - */ - public function put($file, array $data) { - if (($id = $this->getId($file)) > -1) { - $this->update($id, $data); - return $id; - } else { - // normalize file - $file = $this->normalize($file); - - if (isset($this->partial[$file])) { //add any saved partial data - $data = array_merge($this->partial[$file], $data); - unset($this->partial[$file]); - } - - $requiredFields = array('size', 'mtime', 'mimetype'); - foreach ($requiredFields as $field) { - if (!isset($data[$field])) { //data not complete save as partial and return - $this->partial[$file] = $data; - return -1; - } - } - - $data['path'] = $file; - $data['parent'] = $this->getParentId($file); - $data['name'] = \OC_Util::basename($file); - - list($queryParts, $params) = $this->buildParts($data); - $queryParts[] = '`storage`'; - $params[] = $this->getNumericStorageId(); - $valuesPlaceholder = array_fill(0, count($queryParts), '?'); - - $sql = 'INSERT INTO `*PREFIX*filecache` (' . implode(', ', $queryParts) . ')' - . ' VALUES (' . implode(', ', $valuesPlaceholder) . ')'; - \OC_DB::executeAudited($sql, $params); - - return (int)\OC_DB::insertid('*PREFIX*filecache'); - } - } - - /** - * update the metadata in the cache - * - * @param int $id - * @param array $data - */ - public function update($id, array $data) { - - if(isset($data['path'])) { - // normalize path - $data['path'] = $this->normalize($data['path']); - } - - if(isset($data['name'])) { - // normalize path - $data['name'] = $this->normalize($data['name']); - } - - list($queryParts, $params) = $this->buildParts($data); - $params[] = $id; - - $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE `fileid` = ?'; - \OC_DB::executeAudited($sql, $params); - } - - /** - * extract query parts and params array from data array - * - * @param array $data - * @return array - */ - function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', 'etag'); - $params = array(); - $queryParts = array(); - foreach ($data as $name => $value) { - if (array_search($name, $fields) !== false) { - if ($name === 'path') { - $params[] = md5($value); - $queryParts[] = '`path_hash`'; - } elseif ($name === 'mimetype') { - $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); - $queryParts[] = '`mimepart`'; - $value = $this->getMimetypeId($value); - } elseif ($name === 'storage_mtime') { - if (!isset($data['mtime'])) { - $params[] = $value; - $queryParts[] = '`mtime`'; - } - } elseif ($name === 'encrypted') { - // Boolean to integer conversion - $value = $value ? 1 : 0; - } - $params[] = $value; - $queryParts[] = '`' . $name . '`'; - } - } - return array($queryParts, $params); - } - - /** - * get the file id for a file - * - * @param string $file - * @return int - */ - public function getId($file) { - // normalize file - $file = $this->normalize($file); - - $pathHash = md5($file); - - $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'; - $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $pathHash)); - if ($row = $result->fetchRow()) { - return $row['fileid']; - } else { - return -1; - } - } - - /** - * get the id of the parent folder of a file - * - * @param string $file - * @return int - */ - public function getParentId($file) { - if ($file === '') { - return -1; - } else { - $parent = dirname($file); - if ($parent === '.') { - $parent = ''; - } - return $this->getId($parent); - } - } - - /** - * check if a file is available in the cache - * - * @param string $file - * @return bool - */ - public function inCache($file) { - return $this->getId($file) != -1; - } - - /** - * remove a file or folder from the cache - * - * @param string $file - */ - public function remove($file) { - $entry = $this->get($file); - if ($entry['mimetype'] === 'httpd/unix-directory') { - $children = $this->getFolderContents($file); - foreach ($children as $child) { - $this->remove($child['path']); - } - } - - $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'; - \OC_DB::executeAudited($sql, array($entry['fileid'])); - - $permissionsCache = new Permissions($this->storageId); - $permissionsCache->remove($entry['fileid']); - } - - /** - * Move a file or folder in the cache - * - * @param string $source - * @param string $target - */ - public function move($source, $target) { - // normalize source and target - $source = $this->normalize($source); - $target = $this->normalize($target); - - $sourceData = $this->get($source); - $sourceId = $sourceData['fileid']; - $newParentId = $this->getParentId($target); - - if ($sourceData['mimetype'] === 'httpd/unix-directory') { - //find all child entries - $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $source . '/%')); - $childEntries = $result->fetchAll(); - $sourceLength = strlen($source); - $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); - - foreach ($childEntries as $child) { - $targetPath = $target . substr($child['path'], $sourceLength); - \OC_DB::executeAudited($query, array($targetPath, md5($targetPath), $child['fileid'])); - } - } - - $sql = 'UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?'; - \OC_DB::executeAudited($sql, array($target, md5($target), basename($target), $newParentId, $sourceId)); - } - - /** - * remove all entries for files that are stored on the storage from the cache - */ - public function clear() { - $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; - \OC_DB::executeAudited($sql, array($this->getNumericStorageId())); - - $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; - \OC_DB::executeAudited($sql, array($this->storageId)); - } - - /** - * @param string $file - * - * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE - */ - public function getStatus($file) { - // normalize file - $file = $this->normalize($file); - - $pathHash = md5($file); - $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'; - $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $pathHash)); - if ($row = $result->fetchRow()) { - if ((int)$row['size'] === -1) { - return self::SHALLOW; - } else { - return self::COMPLETE; - } - } else { - if (isset($this->partial[$file])) { - return self::PARTIAL; - } else { - return self::NOT_FOUND; - } - } - } - - /** - * search for files matching $pattern - * - * @param string $pattern - * @return array of file data - */ - public function search($pattern) { - - // normalize pattern - $pattern = $this->normalize($pattern); - - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'; - $result = \OC_DB::executeAudited($sql, array($pattern, $this->getNumericStorageId())); - $files = array(); - while ($row = $result->fetchRow()) { - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); - $files[] = $row; - } - return $files; - } - - /** - * search for files by mimetype - * - * @param string $mimetype - * @return array - */ - public function searchByMime($mimetype) { - if (strpos($mimetype, '/')) { - $where = '`mimetype` = ?'; - } else { - $where = '`mimepart` = ?'; - } - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; - $mimetype = $this->getMimetypeId($mimetype); - $result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId())); - $files = array(); - while ($row = $result->fetchRow()) { - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); - $files[] = $row; - } - return $files; - } - - /** - * update the folder size and the size of all parent folders - * - * @param $path - */ - public function correctFolderSize($path) { - $this->calculateFolderSize($path); - if ($path !== '') { - $parent = dirname($path); - if ($parent === '.' or $parent === '/') { - $parent = ''; - } - $this->correctFolderSize($parent); - } - } - - /** - * get the size of a folder and set it in the cache - * - * @param string $path - * @return int - */ - public function calculateFolderSize($path) { - $totalSize = 0; - $entry = $this->get($path); - if ($entry && $entry['mimetype'] === 'httpd/unix-directory') { - $id = $entry['fileid']; - $sql = 'SELECT SUM(`size`), MIN(`size`) FROM `*PREFIX*filecache` '. - 'WHERE `parent` = ? AND `storage` = ?'; - $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId())); - if ($row = $result->fetchRow()) { - list($sum, $min) = array_values($row); - $sum = (int)$sum; - $min = (int)$min; - if ($min === -1) { - $totalSize = $min; - } else { - $totalSize = $sum; - } - if ($entry['size'] !== $totalSize) { - $this->update($id, array('size' => $totalSize)); - } - - } - } - return $totalSize; - } - - /** - * get all file ids on the files on the storage - * - * @return int[] - */ - public function getAll() { - $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'; - $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId())); - $ids = array(); - while ($row = $result->fetchRow()) { - $ids[] = $row['fileid']; - } - return $ids; - } - - /** - * find a folder in the cache which has not been fully scanned - * - * If multiply incomplete folders are in the cache, the one with the highest id will be returned, - * use the one with the highest id gives the best result with the background scanner, since that is most - * likely the folder where we stopped scanning previously - * - * @return string|bool the path of the folder or false when no folder matched - */ - public function getIncomplete() { - $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache`' - . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC',1); - $result = \OC_DB::executeAudited($query, array($this->getNumericStorageId())); - if ($row = $result->fetchRow()) { - return $row['path']; - } else { - return false; - } - } - - /** - * get the storage id of the storage for a file and the internal path of the file - * - * @param int $id - * @return array, first element holding the storage id, second the path - */ - static public function getById($id) { - $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($id)); - if ($row = $result->fetchRow()) { - $numericId = $row['storage']; - $path = $row['path']; - } else { - return null; - } - - if ($id = Storage::getStorageId($numericId)) { - return array($id, $path); - } else { - return null; - } - } - - /** - * normalize the given path - * @param $path - * @return string - */ - public function normalize($path) { - - return \OC_Util::normalizeUnicode($path); - } -} diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php deleted file mode 100644 index 8eed1f67a5d..00000000000 --- a/lib/files/cache/legacy.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -/** - * Provide read only support for the old filecache - */ -class Legacy { - private $user; - - private $cacheHasItems = null; - - public function __construct($user) { - $this->user = $user; - } - - /** - * get the numbers of items in the legacy cache - * - * @return int - */ - function getCount() { - $sql = 'SELECT COUNT(`id`) AS `count` FROM `*PREFIX*fscache` WHERE `user` = ?'; - $result = \OC_DB::executeAudited($sql, array($this->user)); - if ($row = $result->fetchRow()) { - return $row['count']; - } else { - return 0; - } - } - - /** - * check if a legacy cache is present and holds items - * - * @return bool - */ - function hasItems() { - if (!is_null($this->cacheHasItems)) { - return $this->cacheHasItems; - } - try { - $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ?',1); - } catch (\Exception $e) { - $this->cacheHasItems = false; - return false; - } - try { - $result = $query->execute(array($this->user)); - } catch (\Exception $e) { - $this->cacheHasItems = false; - return false; - } - - if ($result === false || property_exists($result, 'error_message_prefix')) { - $this->cacheHasItems = false; - return false; - } - - $this->cacheHasItems = (bool)$result->fetchRow(); - return $this->cacheHasItems; - } - - /** - * get an item from the legacy cache - * - * @param string|int $path - * @return array - */ - function get($path) { - if (is_numeric($path)) { - $sql = 'SELECT * FROM `*PREFIX*fscache` WHERE `id` = ?'; - } else { - $sql = 'SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?'; - } - $result = \OC_DB::executeAudited($sql, array($path)); - $data = $result->fetchRow(); - $data['etag'] = $this->getEtag($data['path'], $data['user']); - return $data; - } - - /** - * Get the ETag for the given path - * - * @param type $path - * @return string - */ - function getEtag($path, $user = null) { - static $query = null; - - $pathDetails = explode('/', $path, 4); - if((!$user) && !isset($pathDetails[1])) { - //no user!? Too odd, return empty string. - return ''; - } else if(!$user) { - //guess user from path, if no user passed. - $user = $pathDetails[1]; - } - - if(!isset($pathDetails[3]) || is_null($pathDetails[3])) { - $relativePath = ''; - } else { - $relativePath = $pathDetails[3]; - } - - if(is_null($query)){ - $query = \OC_DB::prepare('SELECT `propertyvalue` FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = \'{DAV:}getetag\''); - } - $result = \OC_DB::executeAudited($query,array($user, '/' . $relativePath)); - if ($row = $result->fetchRow()) { - return trim($row['propertyvalue'], '"'); - } else { - return ''; - } - } - - /** - * get all child items of an item from the legacy cache - * - * @param int $id - * @return array - */ - function getChildren($id) { - $result = \OC_DB::executeAudited('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?', array($id)); - $data = $result->fetchAll(); - foreach ($data as $i => $item) { - $data[$i]['etag'] = $this->getEtag($item['path'], $item['user']); - } - return $data; - } -} diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php deleted file mode 100644 index 2e2bdb20b78..00000000000 --- a/lib/files/cache/permissions.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -class Permissions { - /** - * @var string $storageId - */ - private $storageId; - - /** - * @param \OC\Files\Storage\Storage|string $storage - */ - public function __construct($storage) { - if ($storage instanceof \OC\Files\Storage\Storage) { - $this->storageId = $storage->getId(); - } else { - $this->storageId = $storage; - } - } - - /** - * get the permissions for a single file - * - * @param int $fileId - * @param string $user - * @return int (-1 if file no permissions set) - */ - public function get($fileId, $user) { - $sql = 'SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($user, $fileId)); - if ($row = $result->fetchRow()) { - return $row['permissions']; - } else { - return -1; - } - } - - /** - * set the permissions of a file - * - * @param int $fileId - * @param string $user - * @param int $permissions - */ - public function set($fileId, $user, $permissions) { - if (self::get($fileId, $user) !== -1) { - $sql = 'UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'; - } else { - $sql = 'INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'; - } - \OC_DB::executeAudited($sql, array($permissions, $user, $fileId)); - } - - /** - * get the permissions of multiply files - * - * @param int[] $fileIds - * @param string $user - * @return int[] - */ - public function getMultiple($fileIds, $user) { - if (count($fileIds) === 0) { - return array(); - } - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $sql = 'SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' - . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'; - $result = \OC_DB::executeAudited($sql, $params); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $row['permissions']; - } - return $filePermissions; - } - - /** - * get the permissions for all files in a folder - * - * @param int $parentId - * @param string $user - * @return int[] - */ - public function getDirectoryPermissions($parentId, $user) { - $sql = 'SELECT `*PREFIX*permissions`.`fileid`, `permissions` - FROM `*PREFIX*permissions` - INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid` - WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?'; - - $result = \OC_DB::executeAudited($sql, array($parentId, $user)); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $row['permissions']; - } - return $filePermissions; - } - - /** - * remove the permissions for a file - * - * @param int $fileId - * @param string $user - */ - public function remove($fileId, $user = null) { - if (is_null($user)) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?', array($fileId)); - } else { - $sql = 'DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'; - \OC_DB::executeAudited($sql, array($fileId, $user)); - } - } - - public function removeMultiple($fileIds, $user) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - foreach ($fileIds as $fileId) { - \OC_DB::executeAudited($query, array($fileId, $user)); - } - } - - /** - * get the list of users which have permissions stored for a file - * - * @param int $fileId - */ - public function getUsers($fileId) { - $sql = 'SELECT `user` FROM `*PREFIX*permissions` WHERE `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($fileId)); - $users = array(); - while ($row = $result->fetchRow()) { - $users[] = $row['user']; - } - return $users; - } -} diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php deleted file mode 100644 index 96f84609cf2..00000000000 --- a/lib/files/cache/scanner.php +++ /dev/null @@ -1,258 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -use OC\Files\Filesystem; -use OC\Hooks\BasicEmitter; - -/** - * Class Scanner - * - * Hooks available in scope \OC\Files\Cache\Scanner: - * - scanFile(string $path, string $storageId) - * - scanFolder(string $path, string $storageId) - * - * @package OC\Files\Cache - */ -class Scanner extends BasicEmitter { - /** - * @var \OC\Files\Storage\Storage $storage - */ - private $storage; - - /** - * @var string $storageId - */ - private $storageId; - - /** - * @var \OC\Files\Cache\Cache $cache - */ - private $cache; - - /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - private $permissionsCache; - - const SCAN_RECURSIVE = true; - const SCAN_SHALLOW = false; - - const REUSE_ETAG = 1; - const REUSE_SIZE = 2; - - public function __construct(\OC\Files\Storage\Storage $storage) { - $this->storage = $storage; - $this->storageId = $this->storage->getId(); - $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); - } - - /** - * get all the metadata of a file or folder - * * - * - * @param string $path - * @return array with metadata of the file - */ - public function getData($path) { - $data = array(); - if (!$this->storage->isReadable($path)) return null; //cant read, nothing we can do - $data['mimetype'] = $this->storage->getMimeType($path); - $data['mtime'] = $this->storage->filemtime($path); - if ($data['mimetype'] == 'httpd/unix-directory') { - $data['size'] = -1; //unknown - } else { - $data['size'] = $this->storage->filesize($path); - } - $data['etag'] = $this->storage->getETag($path); - $data['storage_mtime'] = $data['mtime']; - return $data; - } - - /** - * scan a single file and store it in the cache - * - * @param string $file - * @param int $reuseExisting - * @param bool $parentExistsInCache - * @return array with metadata of the scanned file - */ - public function scanFile($file, $reuseExisting = 0, $parentExistsInCache = false) { - if (!self::isPartialFile($file) - and !Filesystem::isFileBlacklisted($file) - ) { - $this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId)); - \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); - $data = $this->getData($file); - if ($data) { - if ($file and !$parentExistsInCache) { - $parent = dirname($file); - if ($parent === '.' or $parent === '/') { - $parent = ''; - } - if (!$this->cache->inCache($parent)) { - $this->scanFile($parent); - } - } - $newData = $data; - $cacheData = $this->cache->get($file); - if ($cacheData) { - $this->permissionsCache->remove($cacheData['fileid']); - if ($reuseExisting) { - // prevent empty etag - $etag = $cacheData['etag']; - $propagateETagChange = false; - if (empty($etag)) { - $etag = $data['etag']; - $propagateETagChange = true; - } - // only reuse data if the file hasn't explicitly changed - if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) { - if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { - $data['size'] = $cacheData['size']; - } - if ($reuseExisting & self::REUSE_ETAG) { - $data['etag'] = $etag; - if ($propagateETagChange) { - $parent = $file; - while ($parent !== '') { - $parent = dirname($parent); - if ($parent === '.') { - $parent = ''; - } - $parentCacheData = $this->cache->get($parent); - $this->cache->update($parentCacheData['fileid'], array( - 'etag' => $this->storage->getETag($parent), - )); - } - } - } - } - // Only update metadata that has changed - $newData = array_diff($data, $cacheData); - } - } - if (!empty($newData)) { - $this->cache->put($file, $newData); - } - } else { - $this->cache->remove($file); - } - return $data; - } - return null; - } - - /** - * scan a folder and all it's children - * - * @param string $path - * @param bool $recursive - * @param int $reuse - * @return int the size of the scanned folder or -1 if the size is unknown at this stage - */ - public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { - if ($reuse === -1) { - $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : 0; - } - $this->scanFile($path, $reuse); - return $this->scanChildren($path, $recursive, $reuse); - } - - /** - * scan all the files and folders in a folder - * - * @param string $path - * @param bool $recursive - * @param int $reuse - * @return int the size of the scanned folder or -1 if the size is unknown at this stage - */ - public function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { - if ($reuse === -1) { - $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : 0; - } - $this->emit('\OC\Files\Cache\Scanner', 'scanFolder', array($path, $this->storageId)); - $size = 0; - $childQueue = array(); - $existingChildren = array(); - if ($this->cache->inCache($path)) { - $children = $this->cache->getFolderContents($path); - foreach ($children as $child) { - $existingChildren[] = $child['name']; - } - } - $newChildren = array(); - if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { - \OC_DB::beginTransaction(); - if (is_resource($dh)) { - while (($file = readdir($dh)) !== false) { - $child = ($path) ? $path . '/' . $file : $file; - if (!Filesystem::isIgnoredDir($file)) { - $newChildren[] = $file; - $data = $this->scanFile($child, $reuse, true); - if ($data) { - if ($data['size'] === -1) { - if ($recursive === self::SCAN_RECURSIVE) { - $childQueue[] = $child; - } else { - $size = -1; - } - } else if ($size !== -1) { - $size += $data['size']; - } - } - } - } - } - $removedChildren = \array_diff($existingChildren, $newChildren); - foreach ($removedChildren as $childName) { - $child = ($path) ? $path . '/' . $childName : $childName; - $this->cache->remove($child); - } - \OC_DB::commit(); - foreach ($childQueue as $child) { - $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); - if ($childSize === -1) { - $size = -1; - } else { - $size += $childSize; - } - } - $this->cache->put($path, array('size' => $size)); - } - return $size; - } - - /** - * @brief check if the file should be ignored when scanning - * NOTE: files with a '.part' extension are ignored as well! - * prevents unfinished put requests to be scanned - * @param String $file - * @return boolean - */ - public static function isPartialFile($file) { - if (pathinfo($file, PATHINFO_EXTENSION) === 'part') { - return true; - } - return false; - } - - /** - * walk over any folders that are not fully scanned yet and scan them - */ - public function backgroundScan() { - $lastPath = null; - while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - $this->scan($path); - $this->cache->correctFolderSize($path); - $lastPath = $path; - } - } -} diff --git a/lib/files/cache/storage.php b/lib/files/cache/storage.php deleted file mode 100644 index 8a9e47ca36d..00000000000 --- a/lib/files/cache/storage.php +++ /dev/null @@ -1,60 +0,0 @@ -<?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\Cache; - -/** - * Class Storage - * - * cache storage specific data - * - * @package OC\Files\Cache - */ -class Storage { - private $storageId; - private $numericId; - - /** - * @param \OC\Files\Storage\Storage|string $storage - */ - public function __construct($storage) { - if ($storage instanceof \OC\Files\Storage\Storage) { - $this->storageId = $storage->getId(); - } else { - $this->storageId = $storage; - } - if (strlen($this->storageId) > 64) { - $this->storageId = md5($this->storageId); - } - - $sql = 'SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'; - $result = \OC_DB::executeAudited($sql, array($this->storageId)); - if ($row = $result->fetchRow()) { - $this->numericId = $row['numeric_id']; - } else { - $sql = 'INSERT INTO `*PREFIX*storages` (`id`) VALUES(?)'; - \OC_DB::executeAudited($sql, array($this->storageId)); - $this->numericId = \OC_DB::insertid('*PREFIX*storages'); - } - } - - public function getNumericId() { - return $this->numericId; - } - - public static function getStorageId($numericId) { - - $sql = 'SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'; - $result = \OC_DB::executeAudited($sql, array($numericId)); - if ($row = $result->fetchRow()) { - return $row['id']; - } else { - return null; - } - } -} diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php deleted file mode 100644 index 1f30173a8f8..00000000000 --- a/lib/files/cache/updater.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; -use OCP\Util; - -/** - * listen to filesystem hooks and change the cache accordingly - */ -class Updater { - - /** - * resolve a path to a storage and internal path - * - * @param string $path the relative path - * @return array consisting of the storage and the internal path - */ - static public function resolvePath($path) { - $view = \OC\Files\Filesystem::getView(); - return $view->resolvePath($path); - } - - /** - * perform a write update - * - * @param string $path the relative path of the file - */ - static public function writeUpdate($path) { - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = self::resolvePath($path); - if ($storage) { - $cache = $storage->getCache($internalPath); - $scanner = $storage->getScanner($internalPath); - $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); - $cache->correctFolderSize($internalPath); - self::correctFolder($path, $storage->filemtime($internalPath)); - } - } - - /** - * perform a delete update - * - * @param string $path the relative path of the file - */ - static public function deleteUpdate($path) { - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = self::resolvePath($path); - if ($storage) { - $cache = $storage->getCache($internalPath); - $cache->remove($internalPath); - $cache->correctFolderSize($internalPath); - self::correctFolder($path, time()); - } - } - - /** - * preform a rename update - * - * @param string $from the relative path of the source file - * @param string $to the relative path of the target file - */ - static public function renameUpdate($from, $to) { - /** - * @var \OC\Files\Storage\Storage $storageFrom - * @var \OC\Files\Storage\Storage $storageTo - * @var string $internalFrom - * @var string $internalTo - */ - list($storageFrom, $internalFrom) = self::resolvePath($from); - list($storageTo, $internalTo) = self::resolvePath($to); - if ($storageFrom && $storageTo) { - if ($storageFrom === $storageTo) { - $cache = $storageFrom->getCache($internalFrom); - $cache->move($internalFrom, $internalTo); - $cache->correctFolderSize($internalFrom); - $cache->correctFolderSize($internalTo); - self::correctFolder($from, time()); - self::correctFolder($to, time()); - } else { - self::deleteUpdate($from); - self::writeUpdate($to); - } - } - } - - /** - * Update the mtime and ETag of all parent folders - * - * @param string $path - * @param string $time - */ - static public function correctFolder($path, $time) { - if ($path !== '' && $path !== '/') { - $parent = dirname($path); - if ($parent === '.' || $parent === '\\') { - $parent = ''; - } - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = self::resolvePath($parent); - if ($storage) { - $cache = $storage->getCache(); - $id = $cache->getId($internalPath); - if ($id !== -1) { - $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); - self::correctFolder($parent, $time); - } else { - Util::writeLog('core', 'Path not in cache: '.$internalPath, Util::ERROR); - } - } - } - } - - /** - * @param array $params - */ - static public function writeHook($params) { - self::writeUpdate($params['path']); - } - - /** - * @param array $params - */ - static public function touchHook($params) { - $path = $params['path']; - list($storage, $internalPath) = self::resolvePath($path); - $cache = $storage->getCache(); - $id = $cache->getId($internalPath); - if ($id !== -1) { - $cache->update($id, array('etag' => $storage->getETag($internalPath))); - } - self::writeUpdate($path); - } - - /** - * @param array $params - */ - static public function renameHook($params) { - self::renameUpdate($params['oldpath'], $params['newpath']); - } - - /** - * @param array $params - */ - static public function deleteHook($params) { - self::deleteUpdate($params['path']); - } -} diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php deleted file mode 100644 index cfb9a117311..00000000000 --- a/lib/files/cache/upgrade.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -class Upgrade { - /** - * @var Legacy $legacy - */ - private $legacy; - - private $numericIds = array(); - - private $mimeTypeIds = array(); - - /** - * @param Legacy $legacy - */ - public function __construct($legacy) { - $this->legacy = $legacy; - } - - /** - * Preform a upgrade a path and it's childs - * - * @param string $path - * @param bool $mode - */ - function upgradePath($path, $mode = Scanner::SCAN_RECURSIVE) { - if (!$this->legacy->hasItems()) { - return; - } - \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $path); - if ($row = $this->legacy->get($path)) { - $data = $this->getNewData($row); - if ($data) { - $this->insert($data); - $this->upgradeChilds($data['id'], $mode); - } - } - } - - /** - * upgrade all child elements of an item - * - * @param int $id - * @param bool $mode - */ - function upgradeChilds($id, $mode = Scanner::SCAN_RECURSIVE) { - $children = $this->legacy->getChildren($id); - foreach ($children as $child) { - $childData = $this->getNewData($child); - \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); - if ($childData) { - $this->insert($childData); - if ($mode == Scanner::SCAN_RECURSIVE) { - $this->upgradeChilds($child['id']); - } - } - } - } - - /** - * insert data into the new cache - * - * @param array $data the data for the new cache - */ - function insert($data) { - static $insertQuery = null; - if(is_null($insertQuery)) { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` - ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - } - if (!$this->inCache($data['storage'], $data['path_hash'], $data['id'])) { - \OC_DB::executeAudited($insertQuery, array($data['id'], $data['storage'], - $data['path'], $data['path_hash'], $data['parent'], $data['name'], - $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'], $data['etag'])); - } - } - - /** - * check if an item is already in the new cache - * - * @param string $storage - * @param string $pathHash - * @param string $id - * @return bool - */ - function inCache($storage, $pathHash, $id) { - static $query = null; - if(is_null($query)) { - $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE (`storage` = ? AND `path_hash` = ?) OR `fileid` = ?'); - } - $result = \OC_DB::executeAudited($query, array($storage, $pathHash, $id)); - return (bool)$result->fetchRow(); - } - - /** - * get the new data array from the old one - * - * @param array $data the data from the old cache - * Example data array - * Array - * ( - * [id] => 418 - * [path] => /tina/files/picture.jpg //relative to datadir - * [path_hash] => 66d4547e372888deed80b24fec9b192b - * [parent] => 234 - * [name] => picture.jpg - * [user] => tina - * [size] => 1265283 - * [ctime] => 1363909709 - * [mtime] => 1363909709 - * [mimetype] => image/jpeg - * [mimepart] => image - * [encrypted] => 0 - * [versioned] => 0 - * [writable] => 1 - * ) - * - * @return array - */ - function getNewData($data) { - //Make sure there is a path, otherwise we can do nothing. - if(!isset($data['path'])) { - return false; - } - $newData = $data; - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath; - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']); - if ($storage) { - $newData['etag'] = $data['etag']; - $newData['path_hash'] = md5($internalPath); - $newData['path'] = $internalPath; - $newData['storage'] = $this->getNumericId($storage); - $newData['parent'] = ($internalPath === '') ? -1 : $data['parent']; - $newData['permissions'] = ($data['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; - $newData['storage_object'] = $storage; - $newData['mimetype'] = $this->getMimetypeId($newData['mimetype'], $storage); - $newData['mimepart'] = $this->getMimetypeId($newData['mimepart'], $storage); - return $newData; - } else { - \OC_Log::write('core', 'Unable to migrate data from old cache for '.$data['path'].' because the storage was not found', \OC_Log::ERROR); - return false; - } - } - - /** - * get the numeric storage id - * - * @param \OC\Files\Storage\Storage $storage - * @return int - */ - function getNumericId($storage) { - $storageId = $storage->getId(); - if (!isset($this->numericIds[$storageId])) { - $cache = $storage->getCache(); - $this->numericIds[$storageId] = $cache->getNumericStorageId(); - } - return $this->numericIds[$storageId]; - } - - /** - * get the numeric id for a mimetype - * - * @param string $mimetype - * @param \OC\Files\Storage\Storage $storage - * @return int - */ - function getMimetypeId($mimetype, $storage) { - if (!isset($this->mimeTypeIds[$mimetype])) { - $cache = new Cache($storage); - $this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype); - } - return $this->mimeTypeIds[$mimetype]; - } - - /** - * check if a cache upgrade is required for $user - * - * @param string $user - * @return bool - */ - static function needUpgrade($user) { - $cacheVersion = (int)\OCP\Config::getUserValue($user, 'files', 'cache_version', 4); - return $cacheVersion < 5; - } - - /** - * mark the filecache as upgrade - * - * @param string $user - */ - static function upgradeDone($user) { - \OCP\Config::setUserValue($user, 'files', 'cache_version', 5); - } - - /** - * Does a "silent" upgrade, i.e. without an Event-Source as triggered - * on User-Login via Ajax. This method is called within the regular - * ownCloud upgrade. - * - * @param string $user a User ID - */ - public static function doSilentUpgrade($user) { - if(!self::needUpgrade($user)) { - return; - } - $legacy = new \OC\Files\Cache\Legacy($user); - if ($legacy->hasItems()) { - \OC_DB::beginTransaction(); - $upgrade = new \OC\Files\Cache\Upgrade($legacy); - $upgrade->upgradePath('/' . $user . '/files'); - \OC_DB::commit(); - } - \OC\Files\Cache\Upgrade::upgradeDone($user); - } -} diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php deleted file mode 100644 index 8bfd4602f3a..00000000000 --- a/lib/files/cache/watcher.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Cache; - -/** - * check the storage backends for updates and change the cache accordingly - */ -class Watcher { - /** - * @var \OC\Files\Storage\Storage $storage - */ - private $storage; - - /** - * @var Cache $cache - */ - private $cache; - - /** - * @var Scanner $scanner; - */ - private $scanner; - - /** - * @param \OC\Files\Storage\Storage $storage - */ - public function __construct(\OC\Files\Storage\Storage $storage) { - $this->storage = $storage; - $this->cache = $storage->getCache(); - $this->scanner = $storage->getScanner(); - } - - /** - * check $path for updates - * - * @param string $path - */ - public function checkUpdate($path) { - $cachedEntry = $this->cache->get($path); - if ($this->storage->hasUpdated($path, $cachedEntry['storage_mtime'])) { - if ($this->storage->is_dir($path)) { - $this->scanner->scan($path, Scanner::SCAN_SHALLOW); - } else { - $this->scanner->scanFile($path); - } - if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { - $this->cleanFolder($path); - } - $this->cache->correctFolderSize($path); - } - } - - /** - * remove deleted files in $path from the cache - * - * @param string $path - */ - public function cleanFolder($path) { - $cachedContent = $this->cache->getFolderContents($path); - foreach ($cachedContent as $entry) { - if (!$this->storage->file_exists($entry['path'])) { - $this->cache->remove($entry['path']); - } - } - } -} diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php deleted file mode 100644 index 10ec5c41d11..00000000000 --- a/lib/files/filesystem.php +++ /dev/null @@ -1,770 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -/** - * Class for abstraction of filesystem functions - * This class won't call any filesystem functions for itself but will pass them to the correct OC_Filestorage object - * this class should also handle all the file permission related stuff - * - * Hooks provided: - * read(path) - * write(path, &run) - * post_write(path) - * create(path, &run) (when a file is created, both create and write will be emitted in that order) - * post_create(path) - * delete(path, &run) - * post_delete(path) - * rename(oldpath,newpath, &run) - * post_rename(oldpath,newpath) - * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order) - * post_rename(oldpath,newpath) - * post_initMountPoints(user, user_dir) - * - * the &run parameter can be set to false to prevent the operation from occurring - */ - -namespace OC\Files; - -use OC\Files\Storage\Loader; -const SPACE_NOT_COMPUTED = -1; -const SPACE_UNKNOWN = -2; -const SPACE_UNLIMITED = -3; - -class Filesystem { - /** - * @var Mount\Manager $mounts - */ - private static $mounts; - - public static $loaded = false; - /** - * @var \OC\Files\View $defaultInstance - */ - static private $defaultInstance; - - - /** - * classname which used for hooks handling - * used as signalclass in OC_Hooks::emit() - */ - const CLASSNAME = 'OC_Filesystem'; - - /** - * signalname emitted before file renaming - * - * @param string $oldpath - * @param string $newpath - */ - const signal_rename = 'rename'; - - /** - * signal emitted after file renaming - * - * @param string $oldpath - * @param string $newpath - */ - const signal_post_rename = 'post_rename'; - - /** - * signal emitted before file/dir creation - * - * @param string $path - * @param bool $run changing this flag to false in hook handler will cancel event - */ - const signal_create = 'create'; - - /** - * signal emitted after file/dir creation - * - * @param string $path - * @param bool $run changing this flag to false in hook handler will cancel event - */ - const signal_post_create = 'post_create'; - - /** - * signal emits before file/dir copy - * - * @param string $oldpath - * @param string $newpath - * @param bool $run changing this flag to false in hook handler will cancel event - */ - const signal_copy = 'copy'; - - /** - * signal emits after file/dir copy - * - * @param string $oldpath - * @param string $newpath - */ - const signal_post_copy = 'post_copy'; - - /** - * signal emits before file/dir save - * - * @param string $path - * @param bool $run changing this flag to false in hook handler will cancel event - */ - const signal_write = 'write'; - - /** - * signal emits after file/dir save - * - * @param string $path - */ - const signal_post_write = 'post_write'; - - /** - * signal emits when reading file/dir - * - * @param string $path - */ - const signal_read = 'read'; - - /** - * signal emits when removing file/dir - * - * @param string $path - */ - const signal_delete = 'delete'; - - /** - * parameters definitions for signals - */ - const signal_param_path = 'path'; - const signal_param_oldpath = 'oldpath'; - const signal_param_newpath = 'newpath'; - - /** - * run - changing this flag to false in hook handler will cancel event - */ - const signal_param_run = 'run'; - - /** - * @var \OC\Files\Storage\Loader $loader - */ - private static $loader; - - /** - * @param callable $wrapper - */ - public static function addStorageWrapper($wrapper) { - self::getLoader()->addStorageWrapper($wrapper); - - $mounts = self::getMountManager()->getAll(); - foreach ($mounts as $mount) { - $mount->wrapStorage($wrapper); - } - } - - public static function getLoader() { - if (!self::$loader) { - self::$loader = new Loader(); - } - return self::$loader; - } - - public static function getMountManager() { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - return self::$mounts; - } - - /** - * get the mountpoint of the storage object for a path - * ( note: because a storage is not always mounted inside the fakeroot, the - * returned mountpoint is relative to the absolute root of the filesystem - * and doesn't take the chroot into account ) - * - * @param string $path - * @return string - */ - static public function getMountPoint($path) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = self::$mounts->find($path); - if ($mount) { - return $mount->getMountPoint(); - } else { - return ''; - } - } - - /** - * get a list of all mount points in a directory - * - * @param string $path - * @return string[] - */ - static public function getMountPoints($path) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $result = array(); - $mounts = self::$mounts->findIn($path); - foreach ($mounts as $mount) { - $result[] = $mount->getMountPoint(); - } - return $result; - } - - /** - * get the storage mounted at $mountPoint - * - * @param string $mountPoint - * @return \OC\Files\Storage\Storage - */ - public static function getStorage($mountPoint) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = self::$mounts->find($mountPoint); - return $mount->getStorage(); - } - - /** - * @param $id - * @return Mount\Mount[] - */ - public static function getMountByStorageId($id) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - return self::$mounts->findByStorageId($id); - } - - /** - * @param $id - * @return Mount\Mount[] - */ - public static function getMountByNumericId($id) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - return self::$mounts->findByNumericId($id); - } - - /** - * resolve a path to a storage and internal path - * - * @param string $path - * @return array consisting of the storage and the internal path - */ - static public function resolvePath($path) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = self::$mounts->find($path); - if ($mount) { - return array($mount->getStorage(), $mount->getInternalPath($path)); - } else { - return array(null, null); - } - } - - static public function init($user, $root) { - if (self::$defaultInstance) { - return false; - } - self::getLoader(); - self::$defaultInstance = new View($root); - - if (!self::$mounts) { - self::$mounts = new Mount\Manager(); - } - - //load custom mount config - self::initMountPoints($user); - - self::$loaded = true; - - return true; - } - - static public function initMounts() { - if (!self::$mounts) { - self::$mounts = new Mount\Manager(); - } - } - - /** - * Initialize system and personal mount points for a user - * - * @param string $user - */ - public static function initMountPoints($user = '') { - if ($user == '') { - $user = \OC_User::getUser(); - } - $parser = new \OC\ArrayParser(); - - $root = \OC_User::getHome($user); - self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); - $datadir = \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data"); - - //move config file to it's new position - if (is_file(\OC::$SERVERROOT . '/config/mount.json')) { - rename(\OC::$SERVERROOT . '/config/mount.json', $datadir . '/mount.json'); - } - // Load system mount points - if (is_file(\OC::$SERVERROOT . '/config/mount.php') or is_file($datadir . '/mount.json')) { - if (is_file($datadir . '/mount.json')) { - $mountConfig = json_decode(file_get_contents($datadir . '/mount.json'), true); - } elseif (is_file(\OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = $parser->parsePHP(file_get_contents(\OC::$SERVERROOT . '/config/mount.php')); - } - if (isset($mountConfig['global'])) { - foreach ($mountConfig['global'] as $mountPoint => $options) { - self::mount($options['class'], $options['options'], $mountPoint); - } - } - if (isset($mountConfig['group'])) { - foreach ($mountConfig['group'] as $group => $mounts) { - if (\OC_Group::inGroup($user, $group)) { - foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($user, $mountPoint); - foreach ($options as &$option) { - $option = self::setUserVars($user, $option); - } - self::mount($options['class'], $options['options'], $mountPoint); - } - } - } - } - if (isset($mountConfig['user'])) { - foreach ($mountConfig['user'] as $mountUser => $mounts) { - if ($mountUser === 'all' or strtolower($mountUser) === strtolower($user)) { - foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($user, $mountPoint); - foreach ($options as &$option) { - $option = self::setUserVars($user, $option); - } - self::mount($options['class'], $options['options'], $mountPoint); - } - } - } - } - } - // Load personal mount points - if (is_file($root . '/mount.php') or is_file($root . '/mount.json')) { - if (is_file($root . '/mount.json')) { - $mountConfig = json_decode(file_get_contents($root . '/mount.json'), true); - } elseif (is_file($root . '/mount.php')) { - $mountConfig = $parser->parsePHP(file_get_contents($root . '/mount.php')); - } - if (isset($mountConfig['user'][$user])) { - foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - self::mount($options['class'], $options['options'], $mountPoint); - } - } - } - - // Chance to mount for other storages - \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); - } - - /** - * fill in the correct values for $user - * - * @param string $user - * @param string $input - * @return string - */ - private static function setUserVars($user, $input) { - return str_replace('$user', $user, $input); - } - - /** - * get the default filesystem view - * - * @return View - */ - static public function getView() { - return self::$defaultInstance; - } - - /** - * tear down the filesystem, removing all storage providers - */ - static public function tearDown() { - self::clearMounts(); - self::$defaultInstance = null; - } - - /** - * @brief get the relative path of the root data directory for the current user - * @return string - * - * Returns path like /admin/files - */ - static public function getRoot() { - return self::$defaultInstance->getRoot(); - } - - /** - * clear all mounts and storage backends - */ - public static function clearMounts() { - if (self::$mounts) { - self::$mounts->clear(); - } - } - - /** - * mount an \OC\Files\Storage\Storage in our virtual filesystem - * - * @param \OC\Files\Storage\Storage|string $class - * @param array $arguments - * @param string $mountpoint - */ - static public function mount($class, $arguments, $mountpoint) { - if (!self::$mounts) { - \OC_Util::setupFS(); - } - $mount = new Mount\Mount($class, $mountpoint, $arguments, self::getLoader()); - self::$mounts->addMount($mount); - } - - /** - * return the path to a local version of the file - * we need this because we can't know if a file is stored local or not from - * outside the filestorage and for some purposes a local file is needed - * - * @param string $path - * @return string - */ - static public function getLocalFile($path) { - return self::$defaultInstance->getLocalFile($path); - } - - /** - * @param string $path - * @return string - */ - static public function getLocalFolder($path) { - return self::$defaultInstance->getLocalFolder($path); - } - - /** - * return path to file which reflects one visible in browser - * - * @param string $path - * @return string - */ - static public function getLocalPath($path) { - $datadir = \OC_User::getHome(\OC_User::getUser()) . '/files'; - $newpath = $path; - if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { - $newpath = substr($path, strlen($datadir)); - } - return $newpath; - } - - /** - * check if the requested path is valid - * - * @param string $path - * @return bool - */ - static public function isValidPath($path) { - $path = self::normalizePath($path); - if (!$path || $path[0] !== '/') { - $path = '/' . $path; - } - if (strstr($path, '/../') || strrchr($path, '/') === '/..') { - return false; - } - return true; - } - - /** - * checks if a file is blacklisted for storage in the filesystem - * Listens to write and rename hooks - * - * @param array $data from hook - */ - static public function isBlacklisted($data) { - if (isset($data['path'])) { - $path = $data['path']; - } else if (isset($data['newpath'])) { - $path = $data['newpath']; - } - if (isset($path)) { - if (self::isFileBlacklisted($path)) { - $data['run'] = false; - } - } - } - - /** - * @param string $filename - * @return bool - */ - static public function isFileBlacklisted($filename) { - $blacklist = \OC_Config::getValue('blacklisted_files', array('.htaccess')); - $filename = strtolower(basename($filename)); - return (in_array($filename, $blacklist)); - } - - /** - * @brief check if the directory should be ignored when scanning - * NOTE: the special directories . and .. would cause never ending recursion - * @param String $dir - * @return boolean - */ - static public function isIgnoredDir($dir) { - if ($dir === '.' || $dir === '..') { - return true; - } - return false; - } - - /** - * following functions are equivalent to their php builtin equivalents for arguments/return values. - */ - static public function mkdir($path) { - return self::$defaultInstance->mkdir($path); - } - - static public function rmdir($path) { - return self::$defaultInstance->rmdir($path); - } - - static public function opendir($path) { - return self::$defaultInstance->opendir($path); - } - - static public function readdir($path) { - return self::$defaultInstance->readdir($path); - } - - static public function is_dir($path) { - return self::$defaultInstance->is_dir($path); - } - - static public function is_file($path) { - return self::$defaultInstance->is_file($path); - } - - static public function stat($path) { - return self::$defaultInstance->stat($path); - } - - static public function filetype($path) { - return self::$defaultInstance->filetype($path); - } - - static public function filesize($path) { - return self::$defaultInstance->filesize($path); - } - - static public function readfile($path) { - return self::$defaultInstance->readfile($path); - } - - static public function isCreatable($path) { - return self::$defaultInstance->isCreatable($path); - } - - static public function isReadable($path) { - return self::$defaultInstance->isReadable($path); - } - - static public function isUpdatable($path) { - return self::$defaultInstance->isUpdatable($path); - } - - static public function isDeletable($path) { - return self::$defaultInstance->isDeletable($path); - } - - static public function isSharable($path) { - return self::$defaultInstance->isSharable($path); - } - - static public function file_exists($path) { - return self::$defaultInstance->file_exists($path); - } - - static public function filemtime($path) { - return self::$defaultInstance->filemtime($path); - } - - static public function touch($path, $mtime = null) { - return self::$defaultInstance->touch($path, $mtime); - } - - static public function file_get_contents($path) { - return self::$defaultInstance->file_get_contents($path); - } - - static public function file_put_contents($path, $data) { - return self::$defaultInstance->file_put_contents($path, $data); - } - - static public function unlink($path) { - return self::$defaultInstance->unlink($path); - } - - static public function rename($path1, $path2) { - return self::$defaultInstance->rename($path1, $path2); - } - - static public function copy($path1, $path2) { - return self::$defaultInstance->copy($path1, $path2); - } - - static public function fopen($path, $mode) { - return self::$defaultInstance->fopen($path, $mode); - } - - static public function toTmpFile($path) { - return self::$defaultInstance->toTmpFile($path); - } - - static public function fromTmpFile($tmpFile, $path) { - return self::$defaultInstance->fromTmpFile($tmpFile, $path); - } - - static public function getMimeType($path) { - return self::$defaultInstance->getMimeType($path); - } - - static public function hash($type, $path, $raw = false) { - return self::$defaultInstance->hash($type, $path, $raw); - } - - static public function free_space($path = '/') { - return self::$defaultInstance->free_space($path); - } - - static public function search($query) { - return self::$defaultInstance->search($query); - } - - static public function searchByMime($query) { - return self::$defaultInstance->searchByMime($query); - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - static public function hasUpdated($path, $time) { - return self::$defaultInstance->hasUpdated($path, $time); - } - - /** - * @brief Fix common problems with a file path - * @param string $path - * @param bool $stripTrailingSlash - * @return string - */ - public static function normalizePath($path, $stripTrailingSlash = true) { - if ($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 - if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { - $path = substr($path, 0, -1); - } - //normalize unicode if possible - $path = \OC_Util::normalizeUnicode($path); - - return $path; - } - - /** - * get the filesystem info - * - * @param string $path - * @return array - * - * returns an associative array with the following keys: - * - size - * - mtime - * - mimetype - * - encrypted - * - versioned - */ - public static function getFileInfo($path) { - return self::$defaultInstance->getFileInfo($path); - } - - /** - * change file metadata - * - * @param string $path - * @param array $data - * @return int - * - * returns the fileid of the updated file - */ - public static function putFileInfo($path, $data) { - return self::$defaultInstance->putFileInfo($path, $data); - } - - /** - * get the content of a directory - * - * @param string $directory path under datadirectory - * @param string $mimetype_filter limit returned content to this mimetype or mimepart - * @return array - */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); - } - - /** - * Get the path of a file by id - * - * Note that the resulting path is not guaranteed to be unique for the id, multiple paths can point to the same file - * - * @param int $id - * @return string - */ - public static function getPath($id) { - return self::$defaultInstance->getPath($id); - } - - /** - * Get the owner for a file or folder - * - * @param string $path - * @return string - */ - public static function getOwner($path) { - return self::$defaultInstance->getOwner($path); - } - - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - static public function getETag($path) { - return self::$defaultInstance->getETag($path); - } -} - -\OC_Util::setupFS(); diff --git a/lib/files/mapper.php b/lib/files/mapper.php deleted file mode 100644 index 47abd4e52fe..00000000000 --- a/lib/files/mapper.php +++ /dev/null @@ -1,239 +0,0 @@ -<?php - -namespace OC\Files; - -/** - * class Mapper is responsible to translate logical paths to physical paths and reverse - */ -class Mapper -{ - private $unchangedPhysicalRoot; - - public function __construct($rootDir) { - $this->unchangedPhysicalRoot = $rootDir; - } - - /** - * @param string $logicPath - * @param bool $create indicates if the generated physical name shall be stored in the database or not - * @return string the physical path - */ - public function logicToPhysical($logicPath, $create) { - $physicalPath = $this->resolveLogicPath($logicPath); - if ($physicalPath !== null) { - return $physicalPath; - } - - return $this->create($logicPath, $create); - } - - /** - * @param string $physicalPath - * @return string - */ - public function physicalToLogic($physicalPath) { - $logicPath = $this->resolvePhysicalPath($physicalPath); - if ($logicPath !== null) { - return $logicPath; - } - - $this->insert($physicalPath, $physicalPath); - return $physicalPath; - } - - /** - * @param string $path - * @param bool $isLogicPath indicates if $path is logical or physical - * @param $recursive - * @return void - */ - public function removePath($path, $isLogicPath, $recursive) { - if ($recursive) { - $path=$path.'%'; - } - - if ($isLogicPath) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?', array($path)); - } else { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?', array($path)); - } - } - - /** - * @param $path1 - * @param $path2 - * @throws \Exception - */ - public function copy($path1, $path2) - { - $path1 = $this->stripLast($path1); - $path2 = $this->stripLast($path2); - $physicPath1 = $this->logicToPhysical($path1, true); - $physicPath2 = $this->logicToPhysical($path2, true); - - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($path1.'%')); - $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' - .' SET `logic_path` = ?' - .' , `logic_path_hash` = ?' - .' , `physic_path` = ?' - .' , `physic_path_hash` = ?' - .' WHERE `logic_path` = ?'); - while( $row = $result->fetchRow()) { - $currentLogic = $row['logic_path']; - $currentPhysic = $row['physic_path']; - $newLogic = $path2.$this->stripRootFolder($currentLogic, $path1); - $newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1); - if ($path1 !== $currentLogic) { - try { - \OC_DB::executeAudited($updateQuery, array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), - $currentLogic)); - } catch (\Exception $e) { - error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e); - throw $e; - } - } - } - } - - /** - * @param $path - * @param $root - * @return bool|string - */ - public function stripRootFolder($path, $root) { - if (strpos($path, $root) !== 0) { - // throw exception ??? - return false; - } - if (strlen($path) > strlen($root)) { - return substr($path, strlen($root)); - } - - return ''; - } - - private function stripLast($path) { - if (substr($path, -1) == '/') { - $path = substr_replace($path, '', -1); - } - return $path; - } - - private function resolveLogicPath($logicPath) { - $logicPath = $this->stripLast($logicPath); - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'; - $result = \OC_DB::executeAudited($sql, array(md5($logicPath))); - $result = $result->fetchRow(); - if ($result === false) { - return null; - } - - return $result['physic_path']; - } - - private function resolvePhysicalPath($physicalPath) { - $physicalPath = $this->stripLast($physicalPath); - $sql = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); - $result = \OC_DB::executeAudited($sql, array(md5($physicalPath))); - $result = $result->fetchRow(); - - return $result['logic_path']; - } - - private function create($logicPath, $store) { - $logicPath = $this->stripLast($logicPath); - $index = 0; - - // create the slugified path - $physicalPath = $this->slugifyPath($logicPath); - - // detect duplicates - while ($this->resolvePhysicalPath($physicalPath) !== null) { - $physicalPath = $this->slugifyPath($logicPath, $index++); - } - - // insert the new path mapping if requested - if ($store) { - $this->insert($logicPath, $physicalPath); - } - - return $physicalPath; - } - - private function insert($logicPath, $physicalPath) { - $sql = 'INSERT INTO `*PREFIX*file_map` (`logic_path`, `physic_path`, `logic_path_hash`, `physic_path_hash`) - VALUES (?, ?, ?, ?)'; - \OC_DB::executeAudited($sql, array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath))); - } - - public function slugifyPath($path, $index=null) { - $path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot); - - $pathElements = explode('/', $path); - $sluggedElements = array(); - - $last= end($pathElements); - - foreach ($pathElements as $pathElement) { - // remove empty elements - if (empty($pathElement)) { - continue; - } - - $sluggedElements[] = self::slugify($pathElement); - } - - // apply index to file name - if ($index !== null) { - $last= array_pop($sluggedElements); - - // if filename contains periods - add index number before last period - if (preg_match('~\.[^\.]+$~i',$last,$extension)){ - array_push($sluggedElements, substr($last,0,-(strlen($extension[0]))).'-'.$index.$extension[0]); - } else { - // if filename doesn't contain periods add index ofter the last char - array_push($sluggedElements, $last.'-'.$index); - } - - } - - $sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements); - return $this->stripLast($sluggedPath); - } - - /** - * Modifies a string to remove all non ASCII characters and spaces. - * - * @param string $text - * @return string - */ - private function slugify($text) - { - // replace non letter or digits or dots by - - $text = preg_replace('~[^\\pL\d\.]+~u', '-', $text); - - // trim - $text = trim($text, '-'); - - // transliterate - if (function_exists('iconv')) { - $text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text); - } - - // lowercase - $text = strtolower($text); - - // remove unwanted characters - $text = preg_replace('~[^-\w\.]+~', '', $text); - - // trim ending dots (for security reasons and win compatibility) - $text = preg_replace('~\.+$~', '', $text); - - if (empty($text)) { - return uniqid(); - } - - return $text; - } -} diff --git a/lib/files/mount/manager.php b/lib/files/mount/manager.php deleted file mode 100644 index 4c432dcf724..00000000000 --- a/lib/files/mount/manager.php +++ /dev/null @@ -1,127 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Mount; - -use \OC\Files\Filesystem; - -class Manager { - /** - * @var Mount[] - */ - private $mounts = array(); - - /** - * @param Mount $mount - */ - public function addMount($mount) { - $this->mounts[$mount->getMountPoint()] = $mount; - } - - /** - * Find the mount for $path - * - * @param $path - * @return Mount - */ - public function find($path) { - \OC_Util::setupFS(); - $path = $this->formatPath($path); - if (isset($this->mounts[$path])) { - return $this->mounts[$path]; - } - - \OC_Hook::emit('OC_Filesystem', 'get_mountpoint', array('path' => $path)); - $foundMountPoint = ''; - $mountPoints = array_keys($this->mounts); - foreach ($mountPoints as $mountpoint) { - if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { - $foundMountPoint = $mountpoint; - } - } - if (isset($this->mounts[$foundMountPoint])) { - return $this->mounts[$foundMountPoint]; - } else { - return null; - } - } - - /** - * Find all mounts in $path - * - * @param $path - * @return Mount[] - */ - public function findIn($path) { - \OC_Util::setupFS(); - $path = $this->formatPath($path); - $result = array(); - $pathLength = strlen($path); - $mountPoints = array_keys($this->mounts); - foreach ($mountPoints as $mountPoint) { - if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { - $result[] = $this->mounts[$mountPoint]; - } - } - return $result; - } - - public function clear() { - $this->mounts = array(); - } - - /** - * Find mounts by storage id - * - * @param string $id - * @return Mount[] - */ - public function findByStorageId($id) { - \OC_Util::setupFS(); - if (strlen($id) > 64) { - $id = md5($id); - } - $result = array(); - foreach ($this->mounts as $mount) { - if ($mount->getStorageId() === $id) { - $result[] = $mount; - } - } - return $result; - } - - /** - * @return Mount[] - */ - public function getAll() { - return $this->mounts; - } - - /** - * Find mounts by numeric storage id - * - * @param string $id - * @return Mount - */ - public function findByNumericId($id) { - $storageId = \OC\Files\Cache\Storage::getStorageId($id); - return $this->findByStorageId($storageId); - } - - /** - * @param string $path - * @return string - */ - private function formatPath($path) { - $path = Filesystem::normalizePath($path); - if (strlen($path) > 1) { - $path .= '/'; - } - return $path; - } -} diff --git a/lib/files/mount/mount.php b/lib/files/mount/mount.php deleted file mode 100644 index 0ce2f5975c7..00000000000 --- a/lib/files/mount/mount.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Mount; - -use \OC\Files\Filesystem; -use OC\Files\Storage\Loader; -use OC\Files\Storage\Storage; - -class Mount { - /** - * @var \OC\Files\Storage\Storage $storage - */ - private $storage = null; - private $class; - private $storageId; - private $arguments = array(); - private $mountPoint; - - /** - * @var \OC\Files\Storage\Loader $loader - */ - private $loader; - - /** - * @param string | \OC\Files\Storage\Storage $storage - * @param string $mountpoint - * @param array $arguments (optional)\ - * @param \OC\Files\Storage\Loader $loader - */ - public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { - if (is_null($arguments)) { - $arguments = array(); - } - if (is_null($loader)) { - $this->loader = new Loader(); - } else { - $this->loader = $loader; - } - - $mountpoint = $this->formatPath($mountpoint); - if ($storage instanceof Storage) { - $this->class = get_class($storage); - $this->storage = $this->loader->wrap($mountpoint, $storage); - } else { - // Update old classes to new namespace - if (strpos($storage, 'OC_Filestorage_') !== false) { - $storage = '\OC\Files\Storage\\' . substr($storage, 15); - } - $this->class = $storage; - $this->arguments = $arguments; - } - $this->mountPoint = $mountpoint; - } - - /** - * @return string - */ - public function getMountPoint() { - return $this->mountPoint; - } - - /** - * create the storage that is mounted - * - * @return \OC\Files\Storage\Storage - */ - private function createStorage() { - if (class_exists($this->class)) { - try { - return $this->loader->load($this->mountPoint, $this->class, $this->arguments); - } catch (\Exception $exception) { - \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); - return null; - } - } else { - \OC_Log::write('core', 'storage backend ' . $this->class . ' not found', \OC_Log::ERROR); - return null; - } - } - - /** - * @return \OC\Files\Storage\Storage - */ - public function getStorage() { - if (is_null($this->storage)) { - $this->storage = $this->createStorage(); - } - return $this->storage; - } - - /** - * @return string - */ - public function getStorageId() { - if (!$this->storageId) { - if (is_null($this->storage)) { - $storage = $this->createStorage(); //FIXME: start using exceptions - if (is_null($storage)) { - return null; - } - $this->storage = $storage; - } - $this->storageId = $this->storage->getId(); - if (strlen($this->storageId) > 64) { - $this->storageId = md5($this->storageId); - } - } - return $this->storageId; - } - - /** - * @param string $path - * @return string - */ - public function getInternalPath($path) { - if ($this->mountPoint === $path or $this->mountPoint . '/' === $path) { - $internalPath = ''; - } else { - $internalPath = substr($path, strlen($this->mountPoint)); - } - return $internalPath; - } - - /** - * @param string $path - * @return string - */ - private function formatPath($path) { - $path = Filesystem::normalizePath($path); - if (strlen($path) > 1) { - $path .= '/'; - } - return $path; - } - - /** - * @param callable $wrapper - */ - public function wrapStorage($wrapper) { - $this->storage = $wrapper($this->mountPoint, $this->storage); - } -} diff --git a/lib/files/node/file.php b/lib/files/node/file.php deleted file mode 100644 index 75d5e0166b6..00000000000 --- a/lib/files/node/file.php +++ /dev/null @@ -1,155 +0,0 @@ -<?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/files/node/folder.php b/lib/files/node/folder.php deleted file mode 100644 index 923f53821b2..00000000000 --- a/lib/files/node/folder.php +++ /dev/null @@ -1,382 +0,0 @@ -<?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/files/node/node.php b/lib/files/node/node.php deleted file mode 100644 index 063e2424a64..00000000000 --- a/lib/files/node/node.php +++ /dev/null @@ -1,245 +0,0 @@ -<?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/files/node/nonexistingfile.php b/lib/files/node/nonexistingfile.php deleted file mode 100644 index d45076f7fee..00000000000 --- a/lib/files/node/nonexistingfile.php +++ /dev/null @@ -1,89 +0,0 @@ -<?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/files/node/nonexistingfolder.php b/lib/files/node/nonexistingfolder.php deleted file mode 100644 index 0346cbf1e21..00000000000 --- a/lib/files/node/nonexistingfolder.php +++ /dev/null @@ -1,113 +0,0 @@ -<?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/files/node/root.php b/lib/files/node/root.php deleted file mode 100644 index e3d58476e9c..00000000000 --- a/lib/files/node/root.php +++ /dev/null @@ -1,337 +0,0 @@ -<?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 ''; - } -} diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php deleted file mode 100644 index a5b79f0e967..00000000000 --- a/lib/files/storage/common.php +++ /dev/null @@ -1,374 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -/** - * Storage backend class for providing common filesystem operation methods - * which are not storage-backend specific. - * - * \OC\Files\Storage\Common is never used directly; it is extended by all other - * storage backends, where its methods may be overridden, and additional - * (backend-specific) methods are defined. - * - * Some \OC\Files\Storage\Common methods call functions which are first defined - * in classes which extend it, e.g. $this->stat() . - */ - -abstract class Common implements \OC\Files\Storage\Storage { - private $cache; - private $scanner; - private $permissioncache; - private $watcher; - private $storageCache; - - public function __construct($parameters) { - } - - public function is_dir($path) { - return $this->filetype($path) == 'dir'; - } - - public function is_file($path) { - return $this->filetype($path) == 'file'; - } - - public function filesize($path) { - if ($this->is_dir($path)) { - return 0; //by definition - } else { - $stat = $this->stat($path); - if (isset($stat['size'])) { - return $stat['size']; - } else { - return 0; - } - } - } - - public function isCreatable($path) { - if ($this->is_dir($path) && $this->isUpdatable($path)) { - return true; - } - return false; - } - - public function isDeletable($path) { - return $this->isUpdatable($path); - } - - public function isSharable($path) { - return $this->isReadable($path); - } - - public function getPermissions($path) { - $permissions = 0; - if ($this->isCreatable($path)) { - $permissions |= \OCP\PERMISSION_CREATE; - } - if ($this->isReadable($path)) { - $permissions |= \OCP\PERMISSION_READ; - } - if ($this->isUpdatable($path)) { - $permissions |= \OCP\PERMISSION_UPDATE; - } - if ($this->isDeletable($path)) { - $permissions |= \OCP\PERMISSION_DELETE; - } - if ($this->isSharable($path)) { - $permissions |= \OCP\PERMISSION_SHARE; - } - return $permissions; - } - - public function filemtime($path) { - $stat = $this->stat($path); - if (isset($stat['mtime'])) { - return $stat['mtime']; - } else { - return 0; - } - } - - public function file_get_contents($path) { - $handle = $this->fopen($path, "r"); - if (!$handle) { - return false; - } - $size = $this->filesize($path); - if ($size == 0) { - return ''; - } - return fread($handle, $size); - } - - public function file_put_contents($path, $data) { - $handle = $this->fopen($path, "w"); - return fwrite($handle, $data); - } - - public function rename($path1, $path2) { - if ($this->copy($path1, $path2)) { - return $this->unlink($path1); - } else { - return false; - } - } - - public function copy($path1, $path2) { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); - list($count, $result) = \OC_Helper::streamCopy($source, $target); - return $result; - } - - /** - * @brief Deletes all files and folders recursively within a directory - * @param string $directory The directory whose contents will be deleted - * @param bool $empty Flag indicating whether directory will be emptied - * @returns bool - * - * @note By default the directory specified by $directory will be - * deleted together with its contents. To avoid this set $empty to true - */ - public function deleteAll($directory, $empty = false) { - $directory = trim($directory, '/'); - if (!$this->is_dir($directory) || !$this->isReadable($directory)) { - return false; - } else { - $directoryHandle = $this->opendir($directory); - if(is_resource($directoryHandle)) { - while (($contents = readdir($directoryHandle)) !== false) { - if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { - $path = $directory . '/' . $contents; - if ($this->is_dir($path)) { - $this->deleteAll($path); - } else { - $this->unlink($path); - } - } - } - } - if ($empty === false) { - if (!$this->rmdir($directory)) { - return false; - } - } - return true; - } - - } - - public function getMimeType($path) { - if (!$this->file_exists($path)) { - return false; - } - if ($this->is_dir($path)) { - return 'httpd/unix-directory'; - } - $source = $this->fopen($path, 'r'); - if (!$source) { - return false; - } - $head = fread($source, 8192); //8kb should suffice to determine a mimetype - if ($pos = strrpos($path, '.')) { - $extension = substr($path, $pos); - } else { - $extension = ''; - } - $tmpFile = \OC_Helper::tmpFile($extension); - file_put_contents($tmpFile, $head); - $mime = \OC_Helper::getMimeType($tmpFile); - unlink($tmpFile); - return $mime; - } - - public function hash($type, $path, $raw = false) { - $tmpFile = $this->getLocalFile($path); - $hash = hash($type, $tmpFile, $raw); - unlink($tmpFile); - return $hash; - } - - public function search($query) { - return $this->searchInDir($query); - } - - public function getLocalFile($path) { - return $this->toTmpFile($path); - } - - private function toTmpFile($path) { //no longer in the storage api, still useful here - $source = $this->fopen($path, 'r'); - if (!$source) { - return false; - } - if ($pos = strrpos($path, '.')) { - $extension = substr($path, $pos); - } else { - $extension = ''; - } - $tmpFile = \OC_Helper::tmpFile($extension); - $target = fopen($tmpFile, 'w'); - \OC_Helper::streamCopy($source, $target); - return $tmpFile; - } - - public function getLocalFolder($path) { - $baseDir = \OC_Helper::tmpFolder(); - $this->addLocalFolder($path, $baseDir); - return $baseDir; - } - - private function addLocalFolder($path, $target) { - $dh = $this->opendir($path); - if(is_resource($dh)) { - while (($file = readdir($dh)) !== false) { - if ($file !== '.' and $file !== '..') { - if ($this->is_dir($path . '/' . $file)) { - mkdir($target . '/' . $file); - $this->addLocalFolder($path . '/' . $file, $target . '/' . $file); - } else { - $tmp = $this->toTmpFile($path . '/' . $file); - rename($tmp, $target . '/' . $file); - } - } - } - } - } - - protected function searchInDir($query, $dir = '') { - $files = array(); - $dh = $this->opendir($dir); - if (is_resource($dh)) { - while (($item = readdir($dh)) !== false) { - if ($item == '.' || $item == '..') continue; - if (strstr(strtolower($item), strtolower($query)) !== false) { - $files[] = $dir . '/' . $item; - } - if ($this->is_dir($dir . '/' . $item)) { - $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); - } - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->filemtime($path) > $time; - } - - public function getCache($path = '') { - if (!isset($this->cache)) { - $this->cache = new \OC\Files\Cache\Cache($this); - } - return $this->cache; - } - - public function getScanner($path = '') { - if (!isset($this->scanner)) { - $this->scanner = new \OC\Files\Cache\Scanner($this); - } - return $this->scanner; - } - - public function getPermissionsCache($path = '') { - if (!isset($this->permissioncache)) { - $this->permissioncache = new \OC\Files\Cache\Permissions($this); - } - return $this->permissioncache; - } - - public function getWatcher($path = '') { - if (!isset($this->watcher)) { - $this->watcher = new \OC\Files\Cache\Watcher($this); - } - return $this->watcher; - } - - public function getStorageCache(){ - if (!isset($this->storageCache)) { - $this->storageCache = new \OC\Files\Cache\Storage($this); - } - return $this->storageCache; - } - - /** - * get the owner of a path - * - * @param string $path The path to get the owner - * @return string uid or false - */ - public function getOwner($path) { - return \OC_User::getUser(); - } - - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path) { - $ETagFunction = \OC_Connector_Sabre_Node::$ETagFunction; - if ($ETagFunction) { - $hash = call_user_func($ETagFunction, $path); - return $hash; - } else { - return uniqid(); - } - } - - /** - * clean a path, i.e. remove all redundant '.' and '..' - * making sure that it can't point to higher than '/' - * - * @param $path The path to clean - * @return string cleaned path - */ - public function cleanPath($path) { - if (strlen($path) == 0 or $path[0] != '/') { - $path = '/' . $path; - } - - $output = array(); - foreach (explode('/', $path) as $chunk) { - if ($chunk == '..') { - array_pop($output); - } else if ($chunk == '.') { - } else { - $output[] = $chunk; - } - } - return implode('/', $output); - } - - public function test() { - if ($this->stat('')) { - return true; - } - return false; - } - - /** - * get the free space in the storage - * - * @param $path - * @return int - */ - public function free_space($path) { - return \OC\Files\SPACE_UNKNOWN; - } -} diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php deleted file mode 100644 index c3f1eb31955..00000000000 --- a/lib/files/storage/commontest.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php - -/** -* ownCloud -* -* @author Robin Appelman -* @copyright 2012 Robin Appelman icewind@owncloud.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * test implementation for \OC\Files\Storage\Common with \OC\Files\Storage\Local - */ - -namespace OC\Files\Storage; - -class CommonTest extends \OC\Files\Storage\Common{ - /** - * underlying local storage used for missing functions - * @var \OC\Files\Storage\Local - */ - private $storage; - - public function __construct($params) { - $this->storage=new \OC\Files\Storage\Local($params); - } - - public function getId(){ - return 'test::'.$this->storage->getId(); - } - public function mkdir($path) { - return $this->storage->mkdir($path); - } - public function rmdir($path) { - return $this->storage->rmdir($path); - } - public function opendir($path) { - return $this->storage->opendir($path); - } - public function stat($path) { - return $this->storage->stat($path); - } - public function filetype($path) { - return $this->storage->filetype($path); - } - public function isReadable($path) { - return $this->storage->isReadable($path); - } - public function isUpdatable($path) { - return $this->storage->isUpdatable($path); - } - public function file_exists($path) { - return $this->storage->file_exists($path); - } - public function unlink($path) { - return $this->storage->unlink($path); - } - public function fopen($path, $mode) { - return $this->storage->fopen($path, $mode); - } - public function free_space($path) { - return $this->storage->free_space($path); - } - public function touch($path, $mtime=null) { - return $this->storage->touch($path, $mtime); - } -} diff --git a/lib/files/storage/loader.php b/lib/files/storage/loader.php deleted file mode 100644 index 2572ef443bc..00000000000 --- a/lib/files/storage/loader.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -class Loader { - /** - * @var callable[] $storageWrappers - */ - private $storageWrappers = array(); - - /** - * allow modifier storage behaviour by adding wrappers around storages - * - * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage - * - * @param callable $callback - */ - public function addStorageWrapper($callback) { - $this->storageWrappers[] = $callback; - } - - public function load($mountPoint, $class, $arguments) { - return $this->wrap($mountPoint, new $class($arguments)); - } - - public function wrap($mountPoint, $storage) { - foreach ($this->storageWrappers as $wrapper) { - $storage = $wrapper($mountPoint, $storage); - } - return $storage; - } -} diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php deleted file mode 100644 index 5209fabc30a..00000000000 --- a/lib/files/storage/local.php +++ /dev/null @@ -1,310 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -if (\OC_Util::runningOnWindows()) { - class Local extends MappedLocal { - - } -} else { - - /** - * for local filestore, we only have to map the paths - */ - class Local extends \OC\Files\Storage\Common { - protected $datadir; - - public function __construct($arguments) { - $this->datadir = $arguments['datadir']; - if (substr($this->datadir, -1) !== '/') { - $this->datadir .= '/'; - } - } - - public function __destruct() { - } - - public function getId() { - return 'local::' . $this->datadir; - } - - public function mkdir($path) { - return @mkdir($this->datadir . $path); - } - - public function rmdir($path) { - try { - $it = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->datadir . $path), - \RecursiveIteratorIterator::CHILD_FIRST - ); - foreach ($it as $file) { - /** - * @var \SplFileInfo $file - */ - if (in_array($file->getBasename(), array('.', '..'))) { - continue; - } elseif ($file->isDir()) { - rmdir($file->getPathname()); - } elseif ($file->isFile() || $file->isLink()) { - unlink($file->getPathname()); - } - } - return rmdir($this->datadir . $path); - } catch (\UnexpectedValueException $e) { - return false; - } - } - - public function opendir($path) { - return opendir($this->datadir . $path); - } - - public function is_dir($path) { - if (substr($path, -1) == '/') { - $path = substr($path, 0, -1); - } - return is_dir($this->datadir . $path); - } - - public function is_file($path) { - return is_file($this->datadir . $path); - } - - public function stat($path) { - $fullPath = $this->datadir . $path; - $statResult = stat($fullPath); - - if ($statResult['size'] < 0) { - $size = self::getFileSizeFromOS($fullPath); - $statResult['size'] = $size; - $statResult[7] = $size; - } - return $statResult; - } - - public function filetype($path) { - $filetype = filetype($this->datadir . $path); - if ($filetype == 'link') { - $filetype = filetype(realpath($this->datadir . $path)); - } - return $filetype; - } - - public function filesize($path) { - if ($this->is_dir($path)) { - return 0; - } else { - $fullPath = $this->datadir . $path; - $fileSize = filesize($fullPath); - if ($fileSize < 0) { - return self::getFileSizeFromOS($fullPath); - } - - return $fileSize; - } - } - - public function isReadable($path) { - return is_readable($this->datadir . $path); - } - - public function isUpdatable($path) { - return is_writable($this->datadir . $path); - } - - public function file_exists($path) { - return file_exists($this->datadir . $path); - } - - public function filemtime($path) { - return filemtime($this->datadir . $path); - } - - public function touch($path, $mtime = null) { - // sets the modification time of the file to the given value. - // If mtime is nil the current time is set. - // note that the access time of the file always changes to the current time. - if ($this->file_exists($path) and !$this->isUpdatable($path)) { - return false; - } - if (!is_null($mtime)) { - $result = touch($this->datadir . $path, $mtime); - } else { - $result = touch($this->datadir . $path); - } - if ($result) { - clearstatcache(true, $this->datadir . $path); - } - - return $result; - } - - public function file_get_contents($path) { - return file_get_contents($this->datadir . $path); - } - - public function file_put_contents($path, $data) { //trigger_error("$path = ".var_export($path, 1)); - return file_put_contents($this->datadir . $path, $data); - } - - public function unlink($path) { - return $this->delTree($path); - } - - public function rename($path1, $path2) { - if (!$this->isUpdatable($path1)) { - \OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \OC_Log::ERROR); - return false; - } - if (!$this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); - return false; - } - - if ($return = rename($this->datadir . $path1, $this->datadir . $path2)) { - } - return $return; - } - - public function copy($path1, $path2) { - if ($this->is_dir($path2)) { - if (!$this->file_exists($path2)) { - $this->mkdir($path2); - } - $source = substr($path1, strrpos($path1, '/') + 1); - $path2 .= $source; - } - return copy($this->datadir . $path1, $this->datadir . $path2); - } - - public function fopen($path, $mode) { - if ($return = fopen($this->datadir . $path, $mode)) { - switch ($mode) { - case 'r': - break; - case 'r+': - case 'w+': - case 'x+': - case 'a+': - break; - case 'w': - case 'x': - case 'a': - break; - } - } - return $return; - } - - public function getMimeType($path) { - if ($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->datadir . $path); - } else { - return false; - } - } - - private function delTree($dir) { - $dirRelative = $dir; - $dir = $this->datadir . $dir; - if (!file_exists($dir)) return true; - if (!is_dir($dir) || is_link($dir)) return unlink($dir); - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') continue; - if (is_file($dir . '/' . $item)) { - if (unlink($dir . '/' . $item)) { - } - } elseif (is_dir($dir . '/' . $item)) { - if (!$this->delTree($dirRelative . "/" . $item)) { - return false; - }; - } - } - if ($return = rmdir($dir)) { - } - return $return; - } - - private static function getFileSizeFromOS($fullPath) { - $name = strtolower(php_uname('s')); - // Windows OS: we use COM to access the filesystem - if (strpos($name, 'win') !== false) { - if (class_exists('COM')) { - $fsobj = new \COM("Scripting.FileSystemObject"); - $f = $fsobj->GetFile($fullPath); - return $f->Size; - } - } else if (strpos($name, 'bsd') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); - } - } else if (strpos($name, 'linux') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); - } - } else { - \OC_Log::write('core', - 'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name, - \OC_Log::ERROR); - } - - return 0; - } - - public function hash($path, $type, $raw = false) { - return hash_file($type, $this->datadir . $path, $raw); - } - - public function free_space($path) { - $space = @disk_free_space($this->datadir . $path); - if ($space === false) { - return \OC\Files\SPACE_UNKNOWN; - } - return $space; - } - - public function search($query) { - return $this->searchInDir($query); - } - - public function getLocalFile($path) { - return $this->datadir . $path; - } - - public function getLocalFolder($path) { - return $this->datadir . $path; - } - - protected function searchInDir($query, $dir = '') { - $files = array(); - foreach (scandir($this->datadir . $dir) as $item) { - if ($item == '.' || $item == '..') continue; - if (strstr(strtolower($item), strtolower($query)) !== false) { - $files[] = $dir . '/' . $item; - } - if (is_dir($this->datadir . $dir . '/' . $item)) { - $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->filemtime($path) > $time; - } - } -} diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php deleted file mode 100644 index ba5ac4191c5..00000000000 --- a/lib/files/storage/mappedlocal.php +++ /dev/null @@ -1,365 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -/** - * for local filestore, we only have to map the paths - */ -class MappedLocal extends \OC\Files\Storage\Common{ - protected $datadir; - private $mapper; - - public function __construct($arguments) { - $this->datadir=$arguments['datadir']; - if(substr($this->datadir, -1)!=='/') { - $this->datadir.='/'; - } - - $this->mapper= new \OC\Files\Mapper($this->datadir); - } - public function __destruct() { - if (defined('PHPUNIT_RUN')) { - $this->mapper->removePath($this->datadir, true, true); - } - } - public function getId(){ - return 'local::'.$this->datadir; - } - public function mkdir($path) { - return @mkdir($this->buildPath($path)); - } - public function rmdir($path) { - try { - $it = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->buildPath($path)), - \RecursiveIteratorIterator::CHILD_FIRST - ); - foreach ($it as $file) { - /** - * @var \SplFileInfo $file - */ - if (in_array($file->getBasename(), array('.', '..'))) { - continue; - } elseif ($file->isDir()) { - rmdir($file->getPathname()); - } elseif ($file->isFile() || $file->isLink()) { - unlink($file->getPathname()); - } - } - if ($result = @rmdir($this->buildPath($path))) { - $this->cleanMapper($path); - } - return $result; - } catch (\UnexpectedValueException $e) { - return false; - } - } - public function opendir($path) { - $files = array('.', '..'); - $physicalPath= $this->buildPath($path); - - $logicalPath = $this->mapper->physicalToLogic($physicalPath); - $dh = opendir($physicalPath); - if(is_resource($dh)) { - while (($file = readdir($dh)) !== false) { - if ($file === '.' or $file === '..') { - continue; - } - - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); - - $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); - $file = $this->stripLeading($file); - $files[]= $file; - } - } - - \OC\Files\Stream\Dir::register('local-win32'.$path, $files); - return opendir('fakedir://local-win32'.$path); - } - public function is_dir($path) { - if(substr($path, -1)=='/') { - $path=substr($path, 0, -1); - } - return is_dir($this->buildPath($path)); - } - public function is_file($path) { - return is_file($this->buildPath($path)); - } - public function stat($path) { - $fullPath = $this->buildPath($path); - $statResult = stat($fullPath); - - if ($statResult['size'] < 0) { - $size = self::getFileSizeFromOS($fullPath); - $statResult['size'] = $size; - $statResult[7] = $size; - } - return $statResult; - } - public function filetype($path) { - $filetype=filetype($this->buildPath($path)); - if($filetype=='link') { - $filetype=filetype(realpath($this->buildPath($path))); - } - return $filetype; - } - public function filesize($path) { - if($this->is_dir($path)) { - return 0; - }else{ - $fullPath = $this->buildPath($path); - $fileSize = filesize($fullPath); - if ($fileSize < 0) { - return self::getFileSizeFromOS($fullPath); - } - - return $fileSize; - } - } - public function isReadable($path) { - return is_readable($this->buildPath($path)); - } - public function isUpdatable($path) { - return is_writable($this->buildPath($path)); - } - public function file_exists($path) { - return file_exists($this->buildPath($path)); - } - public function filemtime($path) { - return filemtime($this->buildPath($path)); - } - public function touch($path, $mtime=null) { - // sets the modification time of the file to the given value. - // If mtime is nil the current time is set. - // note that the access time of the file always changes to the current time. - if(!is_null($mtime)) { - $result=touch( $this->buildPath($path), $mtime ); - }else{ - $result=touch( $this->buildPath($path)); - } - if( $result ) { - clearstatcache( true, $this->buildPath($path) ); - } - - return $result; - } - public function file_get_contents($path) { - return file_get_contents($this->buildPath($path)); - } - public function file_put_contents($path, $data) { - return file_put_contents($this->buildPath($path), $data); - } - public function unlink($path) { - return $this->delTree($path); - } - public function rename($path1, $path2) { - if (!$this->isUpdatable($path1)) { - \OC_Log::write('core', 'unable to rename, file is not writable : '.$path1, \OC_Log::ERROR); - return false; - } - if(! $this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : '.$path1, \OC_Log::ERROR); - return false; - } - - $physicPath1 = $this->buildPath($path1); - $physicPath2 = $this->buildPath($path2); - if($return=rename($physicPath1, $physicPath2)) { - // mapper needs to create copies or all children - $this->copyMapping($path1, $path2); - $this->cleanMapper($physicPath1, false, true); - } - return $return; - } - public function copy($path1, $path2) { - if($this->is_dir($path2)) { - if(!$this->file_exists($path2)) { - $this->mkdir($path2); - } - $source=substr($path1, strrpos($path1, '/')+1); - $path2.=$source; - } - if($return=copy($this->buildPath($path1), $this->buildPath($path2))) { - // mapper needs to create copies or all children - $this->copyMapping($path1, $path2); - } - return $return; - } - public function fopen($path, $mode) { - if($return=fopen($this->buildPath($path), $mode)) { - switch($mode) { - case 'r': - break; - case 'r+': - case 'w+': - case 'x+': - case 'a+': - break; - case 'w': - case 'x': - case 'a': - break; - } - } - return $return; - } - - public function getMimeType($path) { - if($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->buildPath($path)); - }else{ - return false; - } - } - - private function delTree($dir, $isLogicPath=true) { - $dirRelative=$dir; - if ($isLogicPath) { - $dir=$this->buildPath($dir); - } - if (!file_exists($dir)) { - return true; - } - if (!is_dir($dir) || is_link($dir)) { - if($return=unlink($dir)) { - $this->cleanMapper($dir, false); - return $return; - } - } - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') { - continue; - } - if(is_file($dir.'/'.$item)) { - if(unlink($dir.'/'.$item)) { - $this->cleanMapper($dir.'/'.$item, false); - } - }elseif(is_dir($dir.'/'.$item)) { - if (!$this->delTree($dir. "/" . $item, false)) { - return false; - }; - } - } - if($return=rmdir($dir)) { - $this->cleanMapper($dir, false); - } - return $return; - } - - private static function getFileSizeFromOS($fullPath) { - $name = strtolower(php_uname('s')); - // Windows OS: we use COM to access the filesystem - if (strpos($name, 'win') !== false) { - if (class_exists('COM')) { - $fsobj = new \COM("Scripting.FileSystemObject"); - $f = $fsobj->GetFile($fullPath); - return $f->Size; - } - } else if (strpos($name, 'bsd') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); - } - } else if (strpos($name, 'linux') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); - } - } else { - \OC_Log::write('core', - 'Unable to determine file size of "'.$fullPath.'". Unknown OS: '.$name, - \OC_Log::ERROR); - } - - return 0; - } - - public function hash($path, $type, $raw=false) { - return hash_file($type, $this->buildPath($path), $raw); - } - - public function free_space($path) { - return @disk_free_space($this->buildPath($path)); - } - - public function search($query) { - return $this->searchInDir($query); - } - public function getLocalFile($path) { - return $this->buildPath($path); - } - public function getLocalFolder($path) { - return $this->buildPath($path); - } - - protected function searchInDir($query, $dir='') { - $files=array(); - $physicalDir = $this->buildPath($dir); - foreach (scandir($physicalDir) as $item) { - if ($item == '.' || $item == '..') - continue; - $physicalItem = $this->mapper->physicalToLogic($physicalDir.'/'.$item); - $item = substr($physicalItem, strlen($physicalDir)+1); - - if(strstr(strtolower($item), strtolower($query)) !== false) { - $files[]=$dir.'/'.$item; - } - if(is_dir($physicalItem)) { - $files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item)); - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->filemtime($path)>$time; - } - - private function buildPath($path, $create=true) { - $path = $this->stripLeading($path); - $fullPath = $this->datadir.$path; - return $this->mapper->logicToPhysical($fullPath, $create); - } - - private function cleanMapper($path, $isLogicPath=true, $recursive=true) { - $fullPath = $path; - if ($isLogicPath) { - $fullPath = $this->datadir.$path; - } - $this->mapper->removePath($fullPath, $isLogicPath, $recursive); - } - - private function copyMapping($path1, $path2) { - $path1 = $this->stripLeading($path1); - $path2 = $this->stripLeading($path2); - - $fullPath1 = $this->datadir.$path1; - $fullPath2 = $this->datadir.$path2; - - $this->mapper->copy($fullPath1, $fullPath2); - } - - private function stripLeading($path) { - if(strpos($path, '/') === 0) { - $path = substr($path, 1); - } - if(strpos($path, '\\') === 0) { - $path = substr($path, 1); - } - if ($path === false) { - return ''; - } - - return $path; - } -} diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php deleted file mode 100644 index b673bb9a32d..00000000000 --- a/lib/files/storage/storage.php +++ /dev/null @@ -1,343 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -/** - * Provide a common interface to all different storage options - * - * All paths passed to the storage are relative to the storage and should NOT have a leading slash. - */ -interface Storage extends \OCP\Files\Storage { - /** - * $parameters is a free form array with the configuration options needed to construct the storage - * - * @param array $parameters - */ - public function __construct($parameters); - - /** - * Get the identifier for the storage, - * the returned id should be the same for every storage object that is created with the same parameters - * and two storage objects with the same id should refer to two storages that display the same files. - * - * @return string - */ - public function getId(); - - /** - * see http://php.net/manual/en/function.mkdir.php - * - * @param string $path - * @return bool - */ - public function mkdir($path); - - /** - * see http://php.net/manual/en/function.rmdir.php - * - * @param string $path - * @return bool - */ - public function rmdir($path); - - /** - * see http://php.net/manual/en/function.opendir.php - * - * @param string $path - * @return resource - */ - public function opendir($path); - - /** - * see http://php.net/manual/en/function.is_dir.php - * - * @param string $path - * @return bool - */ - public function is_dir($path); - - /** - * see http://php.net/manual/en/function.is_file.php - * - * @param string $path - * @return bool - */ - public function is_file($path); - - /** - * see http://php.net/manual/en/function.stat.php - * only the following keys are required in the result: size and mtime - * - * @param string $path - * @return array - */ - public function stat($path); - - /** - * see http://php.net/manual/en/function.filetype.php - * - * @param string $path - * @return bool - */ - public function filetype($path); - - /** - * see http://php.net/manual/en/function.filesize.php - * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int - */ - public function filesize($path); - - /** - * check if a file can be created in $path - * - * @param string $path - * @return bool - */ - public function isCreatable($path); - - /** - * check if a file can be read - * - * @param string $path - * @return bool - */ - public function isReadable($path); - - /** - * check if a file can be written to - * - * @param string $path - * @return bool - */ - public function isUpdatable($path); - - /** - * check if a file can be deleted - * - * @param string $path - * @return bool - */ - public function isDeletable($path); - - /** - * check if a file can be shared - * - * @param string $path - * @return bool - */ - public function isSharable($path); - - /** - * get the full permissions of a path. - * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php - * - * @param string $path - * @return int - */ - public function getPermissions($path); - - /** - * see http://php.net/manual/en/function.file_exists.php - * - * @param string $path - * @return bool - */ - public function file_exists($path); - - /** - * see http://php.net/manual/en/function.filemtime.php - * - * @param string $path - * @return int - */ - public function filemtime($path); - - /** - * see http://php.net/manual/en/function.file_get_contents.php - * - * @param string $path - * @return string - */ - public function file_get_contents($path); - - /** - * see http://php.net/manual/en/function.file_put_contents.php - * - * @param string $path - * @param string $data - * @return bool - */ - public function file_put_contents($path, $data); - - /** - * see http://php.net/manual/en/function.unlink.php - * - * @param string $path - * @return bool - */ - public function unlink($path); - - /** - * see http://php.net/manual/en/function.rename.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function rename($path1, $path2); - - /** - * see http://php.net/manual/en/function.copy.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function copy($path1, $path2); - - /** - * see http://php.net/manual/en/function.fopen.php - * - * @param string $path - * @param string $mode - * @return resource - */ - public function fopen($path, $mode); - - /** - * get the mimetype for a file or folder - * The mimetype for a folder is required to be "httpd/unix-directory" - * - * @param string $path - * @return string - */ - public function getMimeType($path); - - /** - * see http://php.net/manual/en/function.hash.php - * - * @param string $type - * @param string $path - * @param bool $raw - * @return string - */ - public function hash($type, $path, $raw = false); - - /** - * see http://php.net/manual/en/function.free_space.php - * - * @param string $path - * @return int - */ - public function free_space($path); - - /** - * search for occurrences of $query in file names - * - * @param string $query - * @return array - */ - public function search($query); - - /** - * see http://php.net/manual/en/function.touch.php - * If the backend does not support the operation, false should be returned - * - * @param string $path - * @param int $mtime - * @return bool - */ - public function touch($path, $mtime = null); - - /** - * get the path to a local version of the file. - * The local version of the file can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFile($path); - - /** - * get the path to a local version of the folder. - * The local version of the folder can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFolder($path); - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - * - * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. - * returning true for other changes in the folder is optional - */ - public function hasUpdated($path, $time); - - /** - * get a cache instance for the storage - * - * @param string $path - * @return \OC\Files\Cache\Cache - */ - public function getCache($path = ''); - - /** - * get a scanner instance for the storage - * - * @param string $path - * @return \OC\Files\Cache\Scanner - */ - public function getScanner($path = ''); - - - /** - * get the user id of the owner of a file or folder - * - * @param string $path - * @return string - */ - public function getOwner($path); - - /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = ''); - - /** - * get a watcher instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Watcher - */ - public function getWatcher($path = ''); - - /** - * @return \OC\Files\Cache\Storage - */ - public function getStorageCache(); - - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path); -} diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php deleted file mode 100644 index d84dbda2e39..00000000000 --- a/lib/files/storage/temporary.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Copyright (c) 2012 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\Storage; - -/** - * local storage backend in temporary folder for testing purpose - */ -class Temporary extends Local{ - public function __construct($arguments) { - parent::__construct(array('datadir' => \OC_Helper::tmpFolder())); - } - - public function cleanUp() { - \OC_Helper::rmdirr($this->datadir); - } - - public function __destruct() { - parent::__destruct(); - $this->cleanUp(); - } -} diff --git a/lib/files/storage/wrapper/quota.php b/lib/files/storage/wrapper/quota.php deleted file mode 100644 index e2da8cf2e05..00000000000 --- a/lib/files/storage/wrapper/quota.php +++ /dev/null @@ -1,104 +0,0 @@ -<?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\Storage\Wrapper; - -class Quota extends Wrapper { - - /** - * @var int $quota - */ - protected $quota; - - /** - * @param array $parameters - */ - public function __construct($parameters) { - $this->storage = $parameters['storage']; - $this->quota = $parameters['quota']; - } - - protected function getSize($path) { - $cache = $this->getCache(); - $data = $cache->get($path); - if (is_array($data) and isset($data['size'])) { - return $data['size']; - } else { - return \OC\Files\SPACE_NOT_COMPUTED; - } - } - - /** - * Get free space as limited by the quota - * - * @param string $path - * @return int - */ - public function free_space($path) { - if ($this->quota < 0) { - return $this->storage->free_space($path); - } else { - $used = $this->getSize(''); - if ($used < 0) { - return \OC\Files\SPACE_NOT_COMPUTED; - } else { - $free = $this->storage->free_space($path); - return min($free, (max($this->quota - $used, 0))); - } - } - } - - /** - * see http://php.net/manual/en/function.file_put_contents.php - * - * @param string $path - * @param string $data - * @return bool - */ - public function file_put_contents($path, $data) { - $free = $this->free_space(''); - if ($free < 0 or strlen($data) < $free) { - return $this->storage->file_put_contents($path, $data); - } else { - return false; - } - } - - /** - * see http://php.net/manual/en/function.copy.php - * - * @param string $source - * @param string $target - * @return bool - */ - public function copy($source, $target) { - $free = $this->free_space(''); - if ($free < 0 or $this->getSize($source) < $free) { - return $this->storage->copy($source, $target); - } else { - return false; - } - } - - /** - * see http://php.net/manual/en/function.fopen.php - * - * @param string $path - * @param string $mode - * @return resource - */ - public function fopen($path, $mode) { - $source = $this->storage->fopen($path, $mode); - $free = $this->free_space(''); - if ($free >= 0) { - return \OC\Files\Stream\Quota::wrap($source, $free); - } else { - return $source; - } - } -} diff --git a/lib/files/storage/wrapper/wrapper.php b/lib/files/storage/wrapper/wrapper.php deleted file mode 100644 index 0336c27efa1..00000000000 --- a/lib/files/storage/wrapper/wrapper.php +++ /dev/null @@ -1,427 +0,0 @@ -<?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\Storage\Wrapper; - -class Wrapper implements \OC\Files\Storage\Storage { - /** - * @var \OC\Files\Storage\Storage $storage - */ - protected $storage; - - /** - * @param array $parameters - */ - public function __construct($parameters) { - $this->storage = $parameters['storage']; - } - - /** - * @return \OC\Files\Storage\Storage - */ - public function getWrapperStorage() { - return $this->storage; - } - - /** - * Get the identifier for the storage, - * the returned id should be the same for every storage object that is created with the same parameters - * and two storage objects with the same id should refer to two storages that display the same files. - * - * @return string - */ - public function getId() { - return $this->storage->getId(); - } - - /** - * see http://php.net/manual/en/function.mkdir.php - * - * @param string $path - * @return bool - */ - public function mkdir($path) { - return $this->storage->mkdir($path); - } - - /** - * see http://php.net/manual/en/function.rmdir.php - * - * @param string $path - * @return bool - */ - public function rmdir($path) { - return $this->storage->rmdir($path); - } - - /** - * see http://php.net/manual/en/function.opendir.php - * - * @param string $path - * @return resource - */ - public function opendir($path) { - return $this->storage->opendir($path); - } - - /** - * see http://php.net/manual/en/function.is_dir.php - * - * @param string $path - * @return bool - */ - public function is_dir($path) { - return $this->storage->is_dir($path); - } - - /** - * see http://php.net/manual/en/function.is_file.php - * - * @param string $path - * @return bool - */ - public function is_file($path) { - return $this->storage->is_file($path); - } - - /** - * see http://php.net/manual/en/function.stat.php - * only the following keys are required in the result: size and mtime - * - * @param string $path - * @return array - */ - public function stat($path) { - return $this->storage->stat($path); - } - - /** - * see http://php.net/manual/en/function.filetype.php - * - * @param string $path - * @return bool - */ - public function filetype($path) { - return $this->storage->filetype($path); - } - - /** - * see http://php.net/manual/en/function.filesize.php - * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int - */ - public function filesize($path) { - return $this->storage->filesize($path); - } - - /** - * check if a file can be created in $path - * - * @param string $path - * @return bool - */ - public function isCreatable($path) { - return $this->storage->isCreatable($path); - } - - /** - * check if a file can be read - * - * @param string $path - * @return bool - */ - public function isReadable($path) { - return $this->storage->isReadable($path); - } - - /** - * check if a file can be written to - * - * @param string $path - * @return bool - */ - public function isUpdatable($path) { - return $this->storage->isUpdatable($path); - } - - /** - * check if a file can be deleted - * - * @param string $path - * @return bool - */ - public function isDeletable($path) { - return $this->storage->isDeletable($path); - } - - /** - * check if a file can be shared - * - * @param string $path - * @return bool - */ - public function isSharable($path) { - return $this->storage->isSharable($path); - } - - /** - * get the full permissions of a path. - * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php - * - * @param string $path - * @return int - */ - public function getPermissions($path) { - return $this->storage->getPermissions($path); - } - - /** - * see http://php.net/manual/en/function.file_exists.php - * - * @param string $path - * @return bool - */ - public function file_exists($path) { - return $this->storage->file_exists($path); - } - - /** - * see http://php.net/manual/en/function.filemtime.php - * - * @param string $path - * @return int - */ - public function filemtime($path) { - return $this->storage->filemtime($path); - } - - /** - * see http://php.net/manual/en/function.file_get_contents.php - * - * @param string $path - * @return string - */ - public function file_get_contents($path) { - return $this->storage->file_get_contents($path); - } - - /** - * see http://php.net/manual/en/function.file_put_contents.php - * - * @param string $path - * @param string $data - * @return bool - */ - public function file_put_contents($path, $data) { - return $this->storage->file_put_contents($path, $data); - } - - /** - * see http://php.net/manual/en/function.unlink.php - * - * @param string $path - * @return bool - */ - public function unlink($path) { - return $this->storage->unlink($path); - } - - /** - * see http://php.net/manual/en/function.rename.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function rename($path1, $path2) { - return $this->storage->rename($path1, $path2); - } - - /** - * see http://php.net/manual/en/function.copy.php - * - * @param string $path1 - * @param string $path2 - * @return bool - */ - public function copy($path1, $path2) { - return $this->storage->copy($path1, $path2); - } - - /** - * see http://php.net/manual/en/function.fopen.php - * - * @param string $path - * @param string $mode - * @return resource - */ - public function fopen($path, $mode) { - return $this->storage->fopen($path, $mode); - } - - /** - * get the mimetype for a file or folder - * The mimetype for a folder is required to be "httpd/unix-directory" - * - * @param string $path - * @return string - */ - public function getMimeType($path) { - return $this->storage->getMimeType($path); - } - - /** - * see http://php.net/manual/en/function.hash.php - * - * @param string $type - * @param string $path - * @param bool $raw - * @return string - */ - public function hash($type, $path, $raw = false) { - return $this->storage->hash($type, $path, $raw); - } - - /** - * see http://php.net/manual/en/function.free_space.php - * - * @param string $path - * @return int - */ - public function free_space($path) { - return $this->storage->free_space($path); - } - - /** - * search for occurrences of $query in file names - * - * @param string $query - * @return array - */ - public function search($query) { - return $this->storage->search($query); - } - - /** - * see http://php.net/manual/en/function.touch.php - * If the backend does not support the operation, false should be returned - * - * @param string $path - * @param int $mtime - * @return bool - */ - public function touch($path, $mtime = null) { - return $this->storage->touch($path, $mtime); - } - - /** - * get the path to a local version of the file. - * The local version of the file can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFile($path) { - return $this->storage->getLocalFile($path); - } - - /** - * get the path to a local version of the folder. - * The local version of the folder can be temporary and doesn't have to be persistent across requests - * - * @param string $path - * @return string - */ - public function getLocalFolder($path) { - return $this->storage->getLocalFolder($path); - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - * - * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. - * returning true for other changes in the folder is optional - */ - public function hasUpdated($path, $time) { - return $this->storage->hasUpdated($path, $time); - } - - /** - * get a cache instance for the storage - * - * @param string $path - * @return \OC\Files\Cache\Cache - */ - public function getCache($path = '') { - return $this->storage->getCache($path); - } - - /** - * get a scanner instance for the storage - * - * @param string $path - * @return \OC\Files\Cache\Scanner - */ - public function getScanner($path = '') { - return $this->storage->getScanner($path); - } - - - /** - * get the user id of the owner of a file or folder - * - * @param string $path - * @return string - */ - public function getOwner($path) { - return $this->storage->getOwner($path); - } - - /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = '') { - return $this->storage->getPermissionsCache($path); - } - - /** - * get a watcher instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Watcher - */ - public function getWatcher($path = '') { - return $this->storage->getWatcher($path); - } - - /** - * @return \OC\Files\Cache\Storage - */ - public function getStorageCache() { - return $this->storage->getStorageCache(); - } - - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path) { - return $this->storage->getETag($path); - } -} diff --git a/lib/files/stream/close.php b/lib/files/stream/close.php deleted file mode 100644 index 80de3497c36..00000000000 --- a/lib/files/stream/close.php +++ /dev/null @@ -1,100 +0,0 @@ -<?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\Stream; - -/** - * stream wrapper that provides a callback on stream close - */ -class Close { - private static $callBacks = array(); - private $path = ''; - private $source; - private static $open = array(); - - public function stream_open($path, $mode, $options, &$opened_path) { - $path = substr($path, strlen('close://')); - $this->path = $path; - $this->source = fopen($path, $mode); - if (is_resource($this->source)) { - $this->meta = stream_get_meta_data($this->source); - } - self::$open[] = $path; - return is_resource($this->source); - } - - public function stream_seek($offset, $whence = SEEK_SET) { - fseek($this->source, $offset, $whence); - } - - public function stream_tell() { - return ftell($this->source); - } - - public function stream_read($count) { - return fread($this->source, $count); - } - - public function stream_write($data) { - return fwrite($this->source, $data); - } - - public function stream_set_option($option, $arg1, $arg2) { - switch ($option) { - case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->source, $arg1); - break; - case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->source, $arg1, $arg2); - break; - case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->source, $arg1, $arg2); - } - } - - public function stream_stat() { - return fstat($this->source); - } - - public function stream_lock($mode) { - flock($this->source, $mode); - } - - public function stream_flush() { - return fflush($this->source); - } - - public function stream_eof() { - return feof($this->source); - } - - public function url_stat($path) { - $path = substr($path, strlen('close://')); - if (file_exists($path)) { - return stat($path); - } else { - return false; - } - } - - public function stream_close() { - fclose($this->source); - if (isset(self::$callBacks[$this->path])) { - call_user_func(self::$callBacks[$this->path], $this->path); - } - } - - public function unlink($path) { - $path = substr($path, strlen('close://')); - return unlink($path); - } - - public static function registerCallback($path, $callback) { - self::$callBacks[$path] = $callback; - } -} diff --git a/lib/files/stream/dir.php b/lib/files/stream/dir.php deleted file mode 100644 index 6ca884fc994..00000000000 --- a/lib/files/stream/dir.php +++ /dev/null @@ -1,47 +0,0 @@ -<?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\Stream; - -class Dir { - private static $dirs = array(); - private $name; - private $index; - - public function dir_opendir($path, $options) { - $this->name = substr($path, strlen('fakedir://')); - $this->index = 0; - if (!isset(self::$dirs[$this->name])) { - self::$dirs[$this->name] = array(); - } - return true; - } - - public function dir_readdir() { - if ($this->index >= count(self::$dirs[$this->name])) { - return false; - } - $filename = self::$dirs[$this->name][$this->index]; - $this->index++; - return $filename; - } - - public function dir_closedir() { - $this->name = ''; - return true; - } - - public function dir_rewinddir() { - $this->index = 0; - return true; - } - - public static function register($path, $content) { - self::$dirs[$path] = $content; - } -} diff --git a/lib/files/stream/oc.php b/lib/files/stream/oc.php deleted file mode 100644 index 88e7e062df9..00000000000 --- a/lib/files/stream/oc.php +++ /dev/null @@ -1,129 +0,0 @@ -<?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\Stream; - -/** - * a stream wrappers for ownCloud's virtual filesystem - */ -class OC { - /** - * @var \OC\Files\View - */ - static private $rootView; - - private $path; - private $dirSource; - private $fileSource; - private $meta; - - private function setup(){ - if (!self::$rootView) { - self::$rootView = new \OC\Files\View(''); - } - } - - public function stream_open($path, $mode, $options, &$opened_path) { - $this->setup(); - $path = substr($path, strlen('oc://')); - $this->path = $path; - $this->fileSource = self::$rootView->fopen($path, $mode); - if (is_resource($this->fileSource)) { - $this->meta = stream_get_meta_data($this->fileSource); - } - return is_resource($this->fileSource); - } - - public function stream_seek($offset, $whence = SEEK_SET) { - fseek($this->fileSource, $offset, $whence); - } - - public function stream_tell() { - return ftell($this->fileSource); - } - - public function stream_read($count) { - return fread($this->fileSource, $count); - } - - public function stream_write($data) { - return fwrite($this->fileSource, $data); - } - - public function stream_set_option($option, $arg1, $arg2) { - switch ($option) { - case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->fileSource, $arg1); - break; - case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->fileSource, $arg1, $arg2); - break; - case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->fileSource, $arg1, $arg2); - } - } - - public function stream_stat() { - return fstat($this->fileSource); - } - - public function stream_lock($mode) { - flock($this->fileSource, $mode); - } - - public function stream_flush() { - return fflush($this->fileSource); - } - - public function stream_eof() { - return feof($this->fileSource); - } - - public function url_stat($path) { - $this->setup(); - $path = substr($path, strlen('oc://')); - if (self::$rootView->file_exists($path)) { - return self::$rootView->stat($path); - } else { - return false; - } - } - - public function stream_close() { - fclose($this->fileSource); - } - - public function unlink($path) { - $this->setup(); - $path = substr($path, strlen('oc://')); - return self::$rootView->unlink($path); - } - - public function dir_opendir($path, $options) { - $this->setup(); - $path = substr($path, strlen('oc://')); - $this->path = $path; - $this->dirSource = self::$rootView->opendir($path); - if (is_resource($this->dirSource)) { - $this->meta = stream_get_meta_data($this->dirSource); - } - return is_resource($this->dirSource); - } - - public function dir_readdir() { - return readdir($this->dirSource); - } - - public function dir_closedir() { - closedir($this->dirSource); - } - - public function dir_rewinddir() { - rewinddir($this->dirSource); - } -} diff --git a/lib/files/stream/quota.php b/lib/files/stream/quota.php deleted file mode 100644 index 53d8a03d30f..00000000000 --- a/lib/files/stream/quota.php +++ /dev/null @@ -1,128 +0,0 @@ -<?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\Stream; - -/** - * stream wrapper limits the amount of data that can be written to a stream - * - * usage: void \OC\Files\Stream\Quota::register($id, $stream, $limit) - * or: resource \OC\Files\Stream\Quota::wrap($stream, $limit) - */ -class Quota { - private static $streams = array(); - - /** - * @var resource $source - */ - private $source; - - /** - * @var int $limit - */ - private $limit; - - /** - * @param string $id - * @param resource $stream - * @param int $limit - */ - public static function register($id, $stream, $limit) { - self::$streams[$id] = array($stream, $limit); - } - - /** - * remove all registered streams - */ - public static function clear() { - self::$streams = array(); - } - - /** - * @param resource $stream - * @param int $limit - * @return resource - */ - static public function wrap($stream, $limit) { - $id = uniqid(); - self::register($id, $stream, $limit); - $meta = stream_get_meta_data($stream); - return fopen('quota://' . $id, $meta['mode']); - } - - public function stream_open($path, $mode, $options, &$opened_path) { - $id = substr($path, strlen('quota://')); - if (isset(self::$streams[$id])) { - list($this->source, $this->limit) = self::$streams[$id]; - return true; - } else { - return false; - } - } - - public function stream_seek($offset, $whence = SEEK_SET) { - if ($whence === SEEK_SET) { - $this->limit += $this->stream_tell() - $offset; - } else { - $this->limit -= $offset; - } - fseek($this->source, $offset, $whence); - } - - public function stream_tell() { - return ftell($this->source); - } - - public function stream_read($count) { - $this->limit -= $count; - return fread($this->source, $count); - } - - public function stream_write($data) { - $size = strlen($data); - if ($size > $this->limit) { - $data = substr($data, 0, $this->limit); - $size = $this->limit; - } - $this->limit -= $size; - return fwrite($this->source, $data); - } - - public function stream_set_option($option, $arg1, $arg2) { - switch ($option) { - case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->source, $arg1); - break; - case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->source, $arg1, $arg2); - break; - case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->source, $arg1, $arg2); - } - } - - public function stream_stat() { - return fstat($this->source); - } - - public function stream_lock($mode) { - flock($this->source, $mode); - } - - public function stream_flush() { - return fflush($this->source); - } - - public function stream_eof() { - return feof($this->source); - } - - public function stream_close() { - fclose($this->source); - } -} diff --git a/lib/files/stream/staticstream.php b/lib/files/stream/staticstream.php deleted file mode 100644 index 45b1a7a81f8..00000000000 --- a/lib/files/stream/staticstream.php +++ /dev/null @@ -1,156 +0,0 @@ -<?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\Stream; - -class StaticStream { - const MODE_FILE = 0100000; - - public $context; - protected static $data = array(); - - protected $path = ''; - protected $pointer = 0; - protected $writable = false; - - public function stream_close() { - } - - public function stream_eof() { - return $this->pointer >= strlen(self::$data[$this->path]); - } - - public function stream_flush() { - } - - public static function clear() { - self::$data = array(); - } - - public function stream_open($path, $mode, $options, &$opened_path) { - switch ($mode[0]) { - case 'r': - if (!isset(self::$data[$path])) return false; - $this->path = $path; - $this->writable = isset($mode[1]) && $mode[1] == '+'; - break; - case 'w': - self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - break; - case 'a': - if (!isset(self::$data[$path])) self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - $this->pointer = strlen(self::$data[$path]); - break; - case 'x': - if (isset(self::$data[$path])) return false; - $this->path = $path; - $this->writable = true; - break; - case 'c': - if (!isset(self::$data[$path])) self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - break; - default: - return false; - } - $opened_path = $this->path; - return true; - } - - public function stream_read($count) { - $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count); - $data = substr(self::$data[$this->path], $this->pointer, $bytes); - $this->pointer += $bytes; - return $data; - } - - public function stream_seek($offset, $whence = SEEK_SET) { - $len = strlen(self::$data[$this->path]); - switch ($whence) { - case SEEK_SET: - if ($offset <= $len) { - $this->pointer = $offset; - return true; - } - break; - case SEEK_CUR: - if ($this->pointer + $offset <= $len) { - $this->pointer += $offset; - return true; - } - break; - case SEEK_END: - if ($len + $offset <= $len) { - $this->pointer = $len + $offset; - return true; - } - break; - } - return false; - } - - public function stream_stat() { - return $this->url_stat($this->path); - } - - public function stream_tell() { - return $this->pointer; - } - - public function stream_write($data) { - if (!$this->writable) return 0; - $size = strlen($data); - if ($this->stream_eof()) { - self::$data[$this->path] .= $data; - } else { - self::$data[$this->path] = substr_replace( - self::$data[$this->path], - $data, - $this->pointer - ); - } - $this->pointer += $size; - return $size; - } - - public function unlink($path) { - if (isset(self::$data[$path])) { - unset(self::$data[$path]); - } - return true; - } - - public function url_stat($path) { - if (isset(self::$data[$path])) { - $size = strlen(self::$data[$path]); - $time = time(); - $data = array( - 'dev' => 0, - 'ino' => 0, - 'mode' => self::MODE_FILE | 0777, - 'nlink' => 1, - 'uid' => 0, - 'gid' => 0, - 'rdev' => '', - 'size' => $size, - 'atime' => $time, - 'mtime' => $time, - 'ctime' => $time, - 'blksize' => -1, - 'blocks' => -1, - ); - return array_values($data) + $data; - } - return false; - } -} diff --git a/lib/files/type/detection.php b/lib/files/type/detection.php deleted file mode 100644 index 242a81cb5a4..00000000000 --- a/lib/files/type/detection.php +++ /dev/null @@ -1,121 +0,0 @@ -<?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\Type; - -/** - * Class Detection - * - * Mimetype detection - * - * @package OC\Files\Type - */ -class Detection { - protected $mimetypes = array(); - - /** - * add an extension -> mimetype mapping - * - * @param string $extension - * @param string $mimetype - */ - public function registerType($extension, $mimetype) { - $this->mimetypes[$extension] = $mimetype; - } - - /** - * add an array of extension -> mimetype mappings - * - * @param array $types - */ - public function registerTypeArray($types) { - $this->mimetypes = array_merge($this->mimetypes, $types); - } - - /** - * detect mimetype only based on filename, content of file is not used - * - * @param string $path - * @return string - */ - public function detectPath($path) { - if (strpos($path, '.')) { - //try to guess the type by the file extension - $extension = strtolower(strrchr(basename($path), ".")); - $extension = substr($extension, 1); //remove leading . - return (isset($this->mimetypes[$extension])) ? $this->mimetypes[$extension] : 'application/octet-stream'; - } else { - return 'application/octet-stream'; - } - } - - /** - * detect mimetype based on both filename and content - * - * @param string $path - * @return string - */ - public function detect($path) { - $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://'); - - if (@is_dir($path)) { - // directories are easy - return "httpd/unix-directory"; - } - - $mimeType = $this->detectPath($path); - - if ($mimeType === 'application/octet-stream' and function_exists('finfo_open') - and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME) - ) { - $info = @strtolower(finfo_file($finfo, $path)); - if ($info) { - $mimeType = substr($info, 0, strpos($info, ';')); - } - finfo_close($finfo); - } - if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) { - // use mime magic extension if available - $mimeType = mime_content_type($path); - } - if (!$isWrapped and $mimeType === 'application/octet-stream' && \OC_Helper::canExecute("file")) { - // it looks like we have a 'file' command, - // lets see if it does have mime support - $path = escapeshellarg($path); - $fp = popen("file -b --mime-type $path 2>/dev/null", "r"); - $reply = fgets($fp); - pclose($fp); - - //trim the newline - $mimeType = trim($reply); - - } - return $mimeType; - } - - /** - * detect mimetype based on the content of a string - * - * @param string $data - * @return string - */ - public function detectString($data) { - if (function_exists('finfo_open') and function_exists('finfo_file')) { - $finfo = finfo_open(FILEINFO_MIME); - return finfo_buffer($finfo, $data); - } else { - $tmpFile = \OC_Helper::tmpFile(); - $fh = fopen($tmpFile, 'wb'); - fwrite($fh, $data, 8024); - fclose($fh); - $mime = $this->detect($tmpFile); - unset($tmpFile); - return $mime; - } - } -} diff --git a/lib/files/type/templatemanager.php b/lib/files/type/templatemanager.php deleted file mode 100644 index cd1536d2732..00000000000 --- a/lib/files/type/templatemanager.php +++ /dev/null @@ -1,46 +0,0 @@ -<?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\Type; - -class TemplateManager { - protected $templates = array(); - - public function registerTemplate($mimetype, $path) { - $this->templates[$mimetype] = $path; - } - - /** - * get the path of the template for a mimetype - * - * @param string $mimetype - * @return string | null - */ - public function getTemplatePath($mimetype) { - if (isset($this->templates[$mimetype])) { - return $this->templates[$mimetype]; - } else { - return null; - } - } - - /** - * get the template content for a mimetype - * - * @param string $mimetype - * @return string - */ - public function getTemplate($mimetype) { - $path = $this->getTemplatePath($mimetype); - if ($path) { - return file_get_contents($path); - } else { - return ''; - } - } -} diff --git a/lib/files/utils/scanner.php b/lib/files/utils/scanner.php deleted file mode 100644 index 2cad7dd77bd..00000000000 --- a/lib/files/utils/scanner.php +++ /dev/null @@ -1,96 +0,0 @@ -<?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\Utils; - -use OC\Files\Filesystem; -use OC\Hooks\PublicEmitter; - -/** - * Class Scanner - * - * Hooks available in scope \OC\Utils\Scanner - * - scanFile(string $absolutePath) - * - scanFolder(string $absolutePath) - * - * @package OC\Files\Utils - */ -class Scanner extends PublicEmitter { - /** - * @var string $user - */ - private $user; - - /** - * @param string $user - */ - public function __construct($user) { - $this->user = $user; - } - - /** - * get all storages for $dir - * - * @param string $dir - * @return \OC\Files\Mount\Mount[] - */ - protected function getMounts($dir) { - //TODO: move to the node based fileapi once that's done - \OC_Util::tearDownFS(); - \OC_Util::setupFS($this->user); - $absolutePath = Filesystem::getView()->getAbsolutePath($dir); - - $mountManager = Filesystem::getMountManager(); - $mounts = $mountManager->findIn($absolutePath); - $mounts[] = $mountManager->find($absolutePath); - $mounts = array_reverse($mounts); //start with the mount of $dir - - return $mounts; - } - - /** - * attach listeners to the scanner - * - * @param \OC\Files\Mount\Mount $mount - */ - protected function attachListener($mount) { - $scanner = $mount->getStorage()->getScanner(); - $emitter = $this; - $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function ($path) use ($mount, $emitter) { - $emitter->emit('\OC\Files\Utils\Scanner', 'scanFile', array($mount->getMountPoint() . $path)); - }); - $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount, $emitter) { - $emitter->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path)); - }); - } - - public function backgroundScan($dir) { - $mounts = $this->getMounts($dir); - foreach ($mounts as $mount) { - if (is_null($mount->getStorage())) { - continue; - } - $scanner = $mount->getStorage()->getScanner(); - $this->attachListener($mount); - $scanner->backgroundScan(); - } - } - - public function scan($dir) { - $mounts = $this->getMounts($dir); - foreach ($mounts as $mount) { - if (is_null($mount->getStorage())) { - continue; - } - $scanner = $mount->getStorage()->getScanner(); - $this->attachListener($mount); - $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG); - } - } -} - diff --git a/lib/files/view.php b/lib/files/view.php deleted file mode 100644 index aa08a5f7cc9..00000000000 --- a/lib/files/view.php +++ /dev/null @@ -1,1078 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -/** - * Class to provide access to ownCloud filesystem via a "view", and methods for - * working with files within that view (e.g. read, write, delete, etc.). Each - * view is restricted to a set of directories via a virtual root. The default view - * uses the currently logged in user's data directory as root (parts of - * OC_Filesystem are merely a wrapper for OC_FilesystemView). - * - * Apps that need to access files outside of the user data folders (to modify files - * belonging to a user other than the one currently logged in, for example) should - * use this class directly rather than using OC_Filesystem, or making use of PHP's - * built-in file manipulation functions. This will ensure all hooks and proxies - * are triggered correctly. - * - * Filesystem functions are not called directly; they are passed to the correct - * \OC\Files\Storage\Storage object - */ - -namespace OC\Files; - -class View { - private $fakeRoot = ''; - private $internal_path_cache = array(); - private $storage_cache = array(); - - public function __construct($root = '') { - $this->fakeRoot = $root; - } - - public function getAbsolutePath($path = '/') { - if (!$path) { - $path = '/'; - } - if ($path[0] !== '/') { - $path = '/' . $path; - } - return $this->fakeRoot . $path; - } - - /** - * change the root to a fake root - * - * @param string $fakeRoot - * @return bool - */ - public function chroot($fakeRoot) { - if (!$fakeRoot == '') { - if ($fakeRoot[0] !== '/') { - $fakeRoot = '/' . $fakeRoot; - } - } - $this->fakeRoot = $fakeRoot; - } - - /** - * get the fake root - * - * @return string - */ - public function getRoot() { - return $this->fakeRoot; - } - - /** - * get path relative to the root of the view - * - * @param string $path - * @return string - */ - public function getRelativePath($path) { - if ($this->fakeRoot == '') { - return $path; - } - if (strpos($path, $this->fakeRoot) !== 0) { - return null; - } else { - $path = substr($path, strlen($this->fakeRoot)); - if (strlen($path) === 0) { - return '/'; - } else { - return $path; - } - } - } - - /** - * get the mountpoint of the storage object for a path - * ( note: because a storage is not always mounted inside the fakeroot, the - * returned mountpoint is relative to the absolute root of the filesystem - * and doesn't take the chroot into account ) - * - * @param string $path - * @return string - */ - public function getMountPoint($path) { - return Filesystem::getMountPoint($this->getAbsolutePath($path)); - } - - /** - * resolve a path to a storage and internal path - * - * @param string $path - * @return array consisting of the storage and the internal path - */ - public function resolvePath($path) { - return Filesystem::resolvePath($this->getAbsolutePath($path)); - } - - /** - * return the path to a local version of the file - * we need this because we can't know if a file is stored local or not from - * outside the filestorage and for some purposes a local file is needed - * - * @param string $path - * @return string - */ - public function getLocalFile($path) { - $parent = substr($path, 0, strrpos($path, '/')); - $path = $this->getAbsolutePath($path); - list($storage, $internalPath) = Filesystem::resolvePath($path); - if (Filesystem::isValidPath($parent) and $storage) { - return $storage->getLocalFile($internalPath); - } else { - return null; - } - } - - /** - * @param string $path - * @return string - */ - public function getLocalFolder($path) { - $parent = substr($path, 0, strrpos($path, '/')); - $path = $this->getAbsolutePath($path); - list($storage, $internalPath) = Filesystem::resolvePath($path); - if (Filesystem::isValidPath($parent) and $storage) { - return $storage->getLocalFolder($internalPath); - } else { - return null; - } - } - - /** - * the following functions operate with arguments and return values identical - * to those of their PHP built-in equivalents. Mostly they are merely wrappers - * for \OC\Files\Storage\Storage via basicOperation(). - */ - public function mkdir($path) { - return $this->basicOperation('mkdir', $path, array('create', 'write')); - } - - public function rmdir($path) { - return $this->basicOperation('rmdir', $path, array('delete')); - } - - public function opendir($path) { - return $this->basicOperation('opendir', $path, array('read')); - } - - public function readdir($handle) { - $fsLocal = new Storage\Local(array('datadir' => '/')); - return $fsLocal->readdir($handle); - } - - public function is_dir($path) { - if ($path == '/') { - return true; - } - return $this->basicOperation('is_dir', $path); - } - - public function is_file($path) { - if ($path == '/') { - return false; - } - return $this->basicOperation('is_file', $path); - } - - public function stat($path) { - return $this->basicOperation('stat', $path); - } - - public function filetype($path) { - return $this->basicOperation('filetype', $path); - } - - public function filesize($path) { - return $this->basicOperation('filesize', $path); - } - - public function readfile($path) { - @ob_end_clean(); - $handle = $this->fopen($path, 'rb'); - if ($handle) { - $chunkSize = 8192; // 8 kB chunks - while (!feof($handle)) { - echo fread($handle, $chunkSize); - flush(); - } - $size = $this->filesize($path); - return $size; - } - return false; - } - - public function isCreatable($path) { - return $this->basicOperation('isCreatable', $path); - } - - public function isReadable($path) { - return $this->basicOperation('isReadable', $path); - } - - public function isUpdatable($path) { - return $this->basicOperation('isUpdatable', $path); - } - - public function isDeletable($path) { - return $this->basicOperation('isDeletable', $path); - } - - public function isSharable($path) { - return $this->basicOperation('isSharable', $path); - } - - public function file_exists($path) { - if ($path == '/') { - return true; - } - return $this->basicOperation('file_exists', $path); - } - - public function filemtime($path) { - return $this->basicOperation('filemtime', $path); - } - - public function touch($path, $mtime = null) { - if (!is_null($mtime) and !is_numeric($mtime)) { - $mtime = strtotime($mtime); - } - - $hooks = array('touch'); - - if (!$this->file_exists($path)) { - $hooks[] = 'create'; - $hooks[] = 'write'; - } - $result = $this->basicOperation('touch', $path, $hooks, $mtime); - if (!$result) { //if native touch fails, we emulate it by changing the mtime in the cache - $this->putFileInfo($path, array('mtime' => $mtime)); - } - return true; - } - - public function file_get_contents($path) { - return $this->basicOperation('file_get_contents', $path, array('read')); - } - - public function file_put_contents($path, $data) { - if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); - if (\OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) - and Filesystem::isValidPath($path) - and !Filesystem::isFileBlacklisted($path) - ) { - $path = $this->getRelativePath($absolutePath); - $exists = $this->file_exists($path); - $run = true; - if ($this->shouldEmitHooks($path)) { - if (!$exists) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_create, - array( - Filesystem::signal_param_path => $this->getHookPath($path), - Filesystem::signal_param_run => &$run - ) - ); - } - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_write, - array( - Filesystem::signal_param_path => $this->getHookPath($path), - Filesystem::signal_param_run => &$run - ) - ); - } - if (!$run) { - return false; - } - $target = $this->fopen($path, 'w'); - if ($target) { - list ($count, $result) = \OC_Helper::streamCopy($data, $target); - fclose($target); - fclose($data); - if ($this->shouldEmitHooks($path) && $result !== false) { - if (!$exists) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_create, - array(Filesystem::signal_param_path => $this->getHookPath($path)) - ); - } - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_write, - array(Filesystem::signal_param_path => $this->getHookPath($path)) - ); - } - \OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); - return $result; - } else { - return false; - } - } else { - return false; - } - } else { - return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); - } - } - - public function unlink($path) { - return $this->basicOperation('unlink', $path, array('delete')); - } - - public function deleteAll($directory, $empty = false) { - return $this->rmdir($directory); - } - - public function rename($path1, $path2) { - $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; - $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; - $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); - if ( - \OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) - and Filesystem::isValidPath($path2) - and Filesystem::isValidPath($path1) - and !Filesystem::isFileBlacklisted($path2) - ) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if ($path1 == null or $path2 == null) { - return false; - } - $run = true; - if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) { - // if it was a rename from a part file to a regular file it was a write and not a rename operation - \OC_Hook::emit( - Filesystem::CLASSNAME, Filesystem::signal_write, - array( - Filesystem::signal_param_path => $this->getHookPath($path2), - Filesystem::signal_param_run => &$run - ) - ); - } elseif ($this->shouldEmitHooks()) { - \OC_Hook::emit( - Filesystem::CLASSNAME, Filesystem::signal_rename, - array( - Filesystem::signal_param_oldpath => $this->getHookPath($path1), - Filesystem::signal_param_newpath => $this->getHookPath($path2), - Filesystem::signal_param_run => &$run - ) - ); - } - if ($run) { - $mp1 = $this->getMountPoint($path1 . $postFix1); - $mp2 = $this->getMountPoint($path2 . $postFix2); - if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($storage) { - $result = $storage->rename($internalPath1, $internalPath2); - \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2); - } else { - $result = false; - } - } else { - if ($this->is_dir($path1)) { - $result = $this->copy($path1, $path2); - if ($result === true) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - $result = $storage1->deleteAll($internalPath1); - } - } else { - $source = $this->fopen($path1 . $postFix1, 'r'); - $target = $this->fopen($path2 . $postFix2, 'w'); - list($count, $result) = \OC_Helper::streamCopy($source, $target); - - // close open handle - especially $source is necessary because unlink below will - // throw an exception on windows because the file is locked - fclose($source); - fclose($target); - - if ($result !== false) { - list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - $storage1->unlink($internalPath1); - } - } - } - if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { - // if it was a rename from a part file to a regular file it was a write and not a rename operation - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_write, - array( - Filesystem::signal_param_path => $this->getHookPath($path2), - ) - ); - } elseif ($this->shouldEmitHooks() && $result !== false) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_rename, - array( - Filesystem::signal_param_oldpath => $this->getHookPath($path1), - Filesystem::signal_param_newpath => $this->getHookPath($path2) - ) - ); - } - return $result; - } else { - return false; - } - } else { - return false; - } - } - - public function copy($path1, $path2) { - $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; - $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; - $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); - if ( - \OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) - and Filesystem::isValidPath($path2) - and Filesystem::isValidPath($path1) - and !Filesystem::isFileBlacklisted($path2) - ) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if ($path1 == null or $path2 == null) { - return false; - } - $run = true; - $exists = $this->file_exists($path2); - if ($this->shouldEmitHooks()) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_copy, - array( - Filesystem::signal_param_oldpath => $this->getHookPath($path1), - Filesystem::signal_param_newpath => $this->getHookPath($path2), - Filesystem::signal_param_run => &$run - ) - ); - if ($run and !$exists) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_create, - array( - Filesystem::signal_param_path => $this->getHookPath($path2), - Filesystem::signal_param_run => &$run - ) - ); - } - if ($run) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_write, - array( - Filesystem::signal_param_path => $this->getHookPath($path2), - Filesystem::signal_param_run => &$run - ) - ); - } - } - if ($run) { - $mp1 = $this->getMountPoint($path1 . $postFix1); - $mp2 = $this->getMountPoint($path2 . $postFix2); - if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($storage) { - $result = $storage->copy($internalPath1, $internalPath2); - } else { - $result = false; - } - } else { - if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) { - $result = $this->mkdir($path2); - if (is_resource($dh)) { - while (($file = readdir($dh)) !== false) { - if (!Filesystem::isIgnoredDir($file)) { - $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file); - } - } - } - } else { - $source = $this->fopen($path1 . $postFix1, 'r'); - $target = $this->fopen($path2 . $postFix2, 'w'); - list($count, $result) = \OC_Helper::streamCopy($source, $target); - } - } - if ($this->shouldEmitHooks() && $result !== false) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_copy, - array( - Filesystem::signal_param_oldpath => $this->getHookPath($path1), - Filesystem::signal_param_newpath => $this->getHookPath($path2) - ) - ); - if (!$exists) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_create, - array(Filesystem::signal_param_path => $this->getHookPath($path2)) - ); - } - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_post_write, - array(Filesystem::signal_param_path => $this->getHookPath($path2)) - ); - } - return $result; - } else { - return false; - } - } else { - return false; - } - } - - public function fopen($path, $mode) { - $hooks = array(); - switch ($mode) { - case 'r': - case 'rb': - $hooks[] = 'read'; - break; - case 'r+': - case 'rb+': - case 'w+': - case 'wb+': - case 'x+': - case 'xb+': - case 'a+': - case 'ab+': - $hooks[] = 'read'; - $hooks[] = 'write'; - break; - case 'w': - case 'wb': - case 'x': - case 'xb': - case 'a': - case 'ab': - $hooks[] = 'write'; - break; - default: - \OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, \OC_Log::ERROR); - } - - return $this->basicOperation('fopen', $path, $hooks, $mode); - } - - public function toTmpFile($path) { - if (Filesystem::isValidPath($path)) { - $source = $this->fopen($path, 'r'); - if ($source) { - $extension = pathinfo($path, PATHINFO_EXTENSION); - $tmpFile = \OC_Helper::tmpFile($extension); - file_put_contents($tmpFile, $source); - return $tmpFile; - } else { - return false; - } - } else { - return false; - } - } - - public function fromTmpFile($tmpFile, $path) { - if (Filesystem::isValidPath($path)) { - if (!$tmpFile) { - debug_print_backtrace(); - } - $source = fopen($tmpFile, 'r'); - if ($source) { - $this->file_put_contents($path, $source); - unlink($tmpFile); - return true; - } else { - return false; - } - } else { - return false; - } - } - - public function getMimeType($path) { - return $this->basicOperation('getMimeType', $path); - } - - public function hash($type, $path, $raw = false) { - $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); - if (\OC_FileProxy::runPreProxies('hash', $absolutePath) && Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - if ($path == null) { - return false; - } - if ($this->shouldEmitHooks($path)) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - Filesystem::signal_read, - array(Filesystem::signal_param_path => $this->getHookPath($path)) - ); - } - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); - if ($storage) { - $result = $storage->hash($type, $internalPath, $raw); - $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); - return $result; - } - } - return null; - } - - public function free_space($path = '/') { - return $this->basicOperation('free_space', $path); - } - - /** - * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage - * @param string $operation - * @param string $path - * @param array $hooks (optional) - * @param mixed $extraParam (optional) - * @return mixed - * - * This method takes requests for basic filesystem functions (e.g. reading & writing - * files), processes hooks and proxies, sanitises paths, and finally passes them on to - * \OC\Files\Storage\Storage for delegation to a storage backend for execution - */ - private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) { - $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); - if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) - and Filesystem::isValidPath($path) - and !Filesystem::isFileBlacklisted($path) - ) { - $path = $this->getRelativePath($absolutePath); - if ($path == null) { - return false; - } - - $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); - if ($run and $storage) { - if (!is_null($extraParam)) { - $result = $storage->$operation($internalPath, $extraParam); - } else { - $result = $storage->$operation($internalPath); - } - $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if ($this->shouldEmitHooks($path) && $result !== false) { - if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open - $this->runHooks($hooks, $path, true); - } - } - return $result; - } - } - return null; - } - - /** - * get the path relative to the default root for hook usage - * - * @param string $path - * @return string - */ - private function getHookPath($path) { - if (!Filesystem::getView()) { - return $path; - } - return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path)); - } - - private function shouldEmitHooks($path = '') { - if ($path && Cache\Scanner::isPartialFile($path)) { - return false; - } - if (!Filesystem::$loaded) { - return false; - } - $defaultRoot = Filesystem::getRoot(); - return (strlen($this->fakeRoot) >= strlen($defaultRoot)) && (substr($this->fakeRoot, 0, strlen($defaultRoot)) === $defaultRoot); - } - - private function runHooks($hooks, $path, $post = false) { - $path = $this->getHookPath($path); - $prefix = ($post) ? 'post_' : ''; - $run = true; - if ($this->shouldEmitHooks($path)) { - foreach ($hooks as $hook) { - if ($hook != 'read') { - \OC_Hook::emit( - Filesystem::CLASSNAME, - $prefix . $hook, - array( - Filesystem::signal_param_run => &$run, - Filesystem::signal_param_path => $path - ) - ); - } elseif (!$post) { - \OC_Hook::emit( - Filesystem::CLASSNAME, - $prefix . $hook, - array( - Filesystem::signal_param_path => $path - ) - ); - } - } - } - return $run; - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->basicOperation('hasUpdated', $path, array(), $time); - } - - /** - * get the filesystem info - * - * @param string $path - * @return array - * - * returns an associative array with the following keys: - * - size - * - mtime - * - mimetype - * - encrypted - * - versioned - */ - public function getFileInfo($path) { - $data = array(); - if (!Filesystem::isValidPath($path)) { - return $data; - } - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = Filesystem::resolvePath($path); - if ($storage) { - $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); - $user = \OC_User::getUser(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner($internalPath); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = $storage->getWatcher($internalPath); - $watcher->checkUpdate($internalPath); - } - - $data = $cache->get($internalPath); - - if ($data and $data['fileid']) { - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = Filesystem::getStorage($mountPoint); - if ($subStorage) { - $subCache = $subStorage->getCache(''); - $rootEntry = $subCache->get(''); - $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; - } - } - } - - $permissions = $permissionsCache->get($data['fileid'], $user); - if ($permissions === -1) { - $permissions = $storage->getPermissions($internalPath); - $permissionsCache->set($data['fileid'], $user, $permissions); - } - $data['permissions'] = $permissions; - } - } - - $data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data); - - return $data; - } - - /** - * get the content of a directory - * - * @param string $directory path under datadirectory - * @param string $mimetype_filter limit returned content to this mimetype or mimepart - * @return array - */ - public function getDirectoryContent($directory, $mimetype_filter = '') { - $result = array(); - if (!Filesystem::isValidPath($directory)) { - return $result; - } - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = Filesystem::resolvePath($path); - if ($storage) { - $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); - $user = \OC_User::getUser(); - - if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { - $scanner = $storage->getScanner($internalPath); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = $storage->getWatcher($internalPath); - $watcher->checkUpdate($internalPath); - } - - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - $permissions = $permissionsCache->getDirectoryPermissions($cache->getId($internalPath), $user); - - $ids = array(); - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - - if (!isset($permissions[$file['fileid']])) { - $permissions[$file['fileid']] = $storage->getPermissions($file['path']); - $permissionsCache->set($file['fileid'], $user, $permissions[$file['fileid']]); - } - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } - - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($path); - $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = Filesystem::getStorage($mountPoint); - if ($subStorage) { - $subCache = $subStorage->getCache(''); - - if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { - $subScanner = $subStorage->getScanner(''); - $subScanner->scanFile(''); - } - - $rootEntry = $subCache->get(''); - if ($rootEntry) { - $relativePath = trim(substr($mountPoint, $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) { - $entry['size'] += $rootEntry['size']; - } - } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $subPermissionsCache = $subStorage->getPermissionsCache(''); - $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); - if ($permissions === -1) { - $permissions = $subStorage->getPermissions($rootEntry['path']); - $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); - } - $rootEntry['permissions'] = $permissions; - - //remove any existing entry with the same name - foreach ($files as $i => $file) { - if ($file['name'] === $rootEntry['name']) { - unset($files[$i]); - break; - } - } - $files[] = $rootEntry; - } - } - } - } - - if ($mimetype_filter) { - foreach ($files as $file) { - if (strpos($mimetype_filter, '/')) { - if ($file['mimetype'] === $mimetype_filter) { - $result[] = $file; - } - } else { - if ($file['mimepart'] === $mimetype_filter) { - $result[] = $file; - } - } - } - } else { - $result = $files; - } - } - return $result; - } - - /** - * change file metadata - * - * @param string $path - * @param array $data - * @return int - * - * returns the fileid of the updated file - */ - public function putFileInfo($path, $data) { - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = Filesystem::resolvePath($path); - if ($storage) { - $cache = $storage->getCache($path); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner($internalPath); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } - - return $cache->put($internalPath, $data); - } else { - return -1; - } - } - - /** - * search for files with the name matching $query - * - * @param string $query - * @return array - */ - public function search($query) { - return $this->searchCommon('%' . $query . '%', 'search'); - } - - /** - * search for files by mimetype - * - * @param string $mimetype - * @return array - */ - public function searchByMime($mimetype) { - return $this->searchCommon($mimetype, 'searchByMime'); - } - - /** - * @param string $query - * @param string $method - * @return array - */ - private function searchCommon($query, $method) { - $files = array(); - $rootLength = strlen($this->fakeRoot); - - $mountPoint = Filesystem::getMountPoint($this->fakeRoot); - $storage = Filesystem::getStorage($mountPoint); - if ($storage) { - $cache = $storage->getCache(''); - - $results = $cache->$method($query); - foreach ($results as $result) { - if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') { - $result['path'] = substr($mountPoint . $result['path'], $rootLength); - $files[] = $result; - } - } - - $mountPoints = Filesystem::getMountPoints($this->fakeRoot); - foreach ($mountPoints as $mountPoint) { - $storage = Filesystem::getStorage($mountPoint); - if ($storage) { - $cache = $storage->getCache(''); - - $relativeMountPoint = substr($mountPoint, $rootLength); - $results = $cache->$method($query); - if ($results) { - foreach ($results as $result) { - $result['path'] = $relativeMountPoint . $result['path']; - $files[] = $result; - } - } - } - } - } - return $files; - } - - /** - * Get the owner for a file or folder - * - * @param string $path - * @return string - */ - public function getOwner($path) { - return $this->basicOperation('getOwner', $path); - } - - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path) { - /** - * @var Storage\Storage $storage - * @var string $internalPath - */ - list($storage, $internalPath) = $this->resolvePath($path); - if ($storage) { - return $storage->getETag($internalPath); - } else { - return null; - } - } - - /** - * Get the path of a file by id, relative to the view - * - * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file - * - * @param int $id - * @return string - */ - public function getPath($id) { - list($storage, $internalPath) = Cache\Cache::getById($id); - $mounts = Filesystem::getMountByStorageId($storage); - foreach ($mounts as $mount) { - /** - * @var \OC\Files\Mount $mount - */ - $fullPath = $mount->getMountPoint() . $internalPath; - if (!is_null($path = $this->getRelativePath($fullPath))) { - return $path; - } - } - return null; - } -} |