diff options
Diffstat (limited to 'lib/files/storage')
-rw-r--r-- | lib/files/storage/common.php | 34 | ||||
-rw-r--r-- | lib/files/storage/local.php | 432 | ||||
-rw-r--r-- | lib/files/storage/mappedlocal.php | 9 | ||||
-rw-r--r-- | lib/files/storage/storage.php | 283 |
4 files changed, 536 insertions, 222 deletions
diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 8aa227ec0b7..e87fe3b5239 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -21,6 +21,11 @@ namespace OC\Files\Storage; */ abstract class Common implements \OC\Files\Storage\Storage { + private $cache; + private $scanner; + private $permissioncache; + private $watcher; + private $storageCache; public function __construct($parameters) { } @@ -269,19 +274,38 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function getCache($path = '') { - return new \OC\Files\Cache\Cache($this); + if (!isset($this->cache)) { + $this->cache = new \OC\Files\Cache\Cache($this); + } + return $this->cache; } public function getScanner($path = '') { - return new \OC\Files\Cache\Scanner($this); + if (!isset($this->scanner)) { + $this->scanner = new \OC\Files\Cache\Scanner($this); + } + return $this->scanner; } public function getPermissionsCache($path = '') { - return new \OC\Files\Cache\Permissions($this); + if (!isset($this->permissioncache)) { + $this->permissioncache = new \OC\Files\Cache\Permissions($this); + } + return $this->permissioncache; } public function getWatcher($path = '') { - return new \OC\Files\Cache\Watcher($this); + 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; } /** @@ -345,7 +369,7 @@ abstract class Common implements \OC\Files\Storage\Storage { * get the free space in the storage * * @param $path - * return int + * @return int */ public function free_space($path) { return \OC\Files\FREE_SPACE_UNKNOWN; diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index da6597c8057..d684905bf9a 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -14,245 +14,277 @@ if (\OC_Util::runningOnWindows()) { } } 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.='/'; + /** + * 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) { - return @rmdir($this->datadir.$path); - } - public function opendir($path) { - return opendir($this->datadir.$path); - } - public function is_dir($path) { - if(substr($path, -1)=='/') { - $path=substr($path, 0, -1); + + public function __destruct() { } - 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; + public function getId() { + return 'local::' . $this->datadir; } - return $statResult; - } - public function filetype($path) { - $filetype=filetype($this->datadir.$path); - if($filetype=='link') { - $filetype=filetype(realpath($this->datadir.$path)); + + public function mkdir($path) { + return @mkdir($this->datadir . $path); } - return $filetype; - } - public function filesize($path) { - if($this->is_dir($path)) { - return 0; - }else{ + + public function rmdir($path) { + return @rmdir($this->datadir . $path); + } + + 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; - $fileSize = filesize($fullPath); - if ($fileSize < 0) { - return self::getFileSizeFromOS($fullPath); + $statResult = stat($fullPath); + + if ($statResult['size'] < 0) { + $size = self::getFileSizeFromOS($fullPath); + $statResult['size'] = $size; + $statResult[7] = $size; } + return $statResult; + } - return $fileSize; + public function filetype($path) { + $filetype = filetype($this->datadir . $path); + if ($filetype == 'link') { + $filetype = filetype(realpath($this->datadir . $path)); + } + return $filetype; } - } - 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(!is_null($mtime)) { - $result=touch( $this->datadir.$path, $mtime ); - }else{ - $result=touch( $this->datadir.$path); + + 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; + } } - if( $result ) { - clearstatcache( true, $this->datadir.$path ); + + public function isReadable($path) { + return is_readable($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; + public function isUpdatable($path) { + return is_writable($this->datadir . $path); } - if(! $this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : '.$path1, \OC_Log::ERROR); - return false; + + public function file_exists($path) { + return file_exists($this->datadir . $path); } - if($return=rename($this->datadir.$path1, $this->datadir.$path2)) { + public function filemtime($path) { + return filemtime($this->datadir . $path); } - return $return; - } - public function copy($path1, $path2) { - if($this->is_dir($path2)) { - if(!$this->file_exists($path2)) { - $this->mkdir($path2); + + 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); } - $source=substr($path1, strrpos($path1, '/')+1); - $path2.=$source; + if ($result) { + clearstatcache(true, $this->datadir . $path); + } + + return $result; } - 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; + + 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; } - return $return; - } - public function getMimeType($path) { - if($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->datadir . $path); - }else{ - return false; + 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); } - } - 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)) { + 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; } - }elseif(is_dir($dir.'/'.$item)) { - if (!$this->delTree($dirRelative. "/" . $item)) { - return false; - }; } + return $return; } - if($return=rmdir($dir)) { + + public function getMimeType($path) { + if ($this->isReadable($path)) { + return \OC_Helper::getMimeType($this->datadir . $path); + } else { + return 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; + 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; + }; + } } - } else if (strpos($name, 'bsd') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); + if ($return = rmdir($dir)) { } - } else if (strpos($name, 'linux') !== false) { - if (\OC_Helper::is_function_enabled('exec')) { - return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); + 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); } - } else { - \OC_Log::write('core', - 'Unable to determine file size of "'.$fullPath.'". Unknown OS: '.$name, - \OC_Log::ERROR); + + return 0; } - return 0; - } + public function hash($path, $type, $raw = false) { + return hash_file($type, $this->datadir . $path, $raw); + } - 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\FREE_SPACE_UNKNOWN; + } + return $space; + } - public function free_space($path) { - return @disk_free_space($this->datadir.$path); - } + public function search($query) { + return $this->searchInDir($query); + } - public function search($query) { - return $this->searchInDir($query); - } - public function getLocalFile($path) { - return $this->datadir.$path; - } - public function getLocalFolder($path) { - return $this->datadir.$path; - } + public function getLocalFile($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)); + 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; } - 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; + /** + * 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 index 434c10bcbf7..ba3fcdc5c9e 100644 --- a/lib/files/storage/mappedlocal.php +++ b/lib/files/storage/mappedlocal.php @@ -50,7 +50,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ continue; } - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.DIRECTORY_SEPARATOR.$file); + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); $file = $this->stripLeading($file); @@ -130,7 +130,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ public function file_get_contents($path) { return file_get_contents($this->buildPath($path)); } - public function file_put_contents($path, $data) {//trigger_error("$path = ".var_export($path, 1)); + public function file_put_contents($path, $data) { return file_put_contents($this->buildPath($path), $data); } public function unlink($path) { @@ -280,7 +280,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ foreach (scandir($physicalDir) as $item) { if ($item == '.' || $item == '..') continue; - $physicalItem = $this->mapper->physicalToLogic($physicalDir.DIRECTORY_SEPARATOR.$item); + $physicalItem = $this->mapper->physicalToLogic($physicalDir.'/'.$item); $item = substr($physicalItem, strlen($physicalDir)+1); if(strstr(strtolower($item), strtolower($query)) !== false) { @@ -331,6 +331,9 @@ class MappedLocal extends \OC\Files\Storage\Common{ if(strpos($path, '/') === 0) { $path = substr($path, 1); } + if(strpos($path, '\\') === 0) { + $path = substr($path, 1); + } if ($path === false) { return ''; } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 2cc835236ba..c96caebf4af 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -10,73 +10,328 @@ 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{ +interface 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); - public function file_put_contents($path,$data); + + /** + * 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); - public function rename($path1,$path2); - public function copy($path1,$path2); - public function fopen($path,$mode); + + /** + * 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); - public function hash($type,$path,$raw = false); + + /** + * 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); - public function touch($path, $mtime=null); - public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote - public function getLocalFolder($path);// get a path to a local version of the folder, whether the original file is local or remote + + /** + * 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); + public function hasUpdated($path, $time); /** + * get a cache instance for the storage + * * @param string $path * @return \OC\Files\Cache\Cache */ - public function getCache($path=''); + public function getCache($path = ''); + /** + * get a scanner instance for the storage + * * @param string $path * @return \OC\Files\Cache\Scanner */ - public function getScanner($path=''); + 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=''); + public function getPermissionsCache($path = ''); /** + * get a watcher instance for the cache + * * @param string $path * @return \OC\Files\Cache\Watcher */ - public function getWatcher($path=''); + public function getWatcher($path = ''); + + /** + * @return \OC\Files\Cache\Storage + */ + public function getStorageCache(); /** * get the ETag for a file or folder |