From bd834220959bf7edcc4cce4bfe6c77e0a4649b8b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Sep 2012 18:30:48 +0200 Subject: put filestorages in a namespace --- lib/files/storage/common.php | 270 +++++++++++++++++++++++++++++++++++++++ lib/files/storage/commontest.php | 77 +++++++++++ lib/files/storage/local.php | 208 ++++++++++++++++++++++++++++++ lib/files/storage/storage.php | 54 ++++++++ lib/files/storage/temporary.php | 26 ++++ 5 files changed, 635 insertions(+) create mode 100644 lib/files/storage/common.php create mode 100644 lib/files/storage/commontest.php create mode 100644 lib/files/storage/local.php create mode 100644 lib/files/storage/storage.php create mode 100644 lib/files/storage/temporary.php (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php new file mode 100644 index 00000000000..0a60ff757eb --- /dev/null +++ b/lib/files/storage/common.php @@ -0,0 +1,270 @@ + + * 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 extends \OC\Files\Storage\Storage { + + public function __construct($parameters) {} +// abstract public function mkdir($path); +// abstract public function rmdir($path); +// abstract public function opendir($path); + public function is_dir($path) { + return $this->filetype($path)=='dir'; + } + public function is_file($path) { + return $this->filetype($path)=='file'; + } +// abstract public function stat($path); +// abstract public function filetype($path); + public function filesize($path) { + if($this->is_dir($path)) { + return 0;//by definition + }else{ + $stat = $this->stat($path); + return $stat['size']; + } + } + public function isCreatable($path) { + return $this->isUpdatable($path); + } +// abstract public function isReadable($path); +// abstract public function isUpdatable($path); + public function isDeletable($path) { + return $this->isUpdatable($path); + } + public function isSharable($path) { + return $this->isReadable($path); + } +// abstract public function file_exists($path); + public function filectime($path) { + $stat = $this->stat($path); + return $stat['ctime']; + } + public function filemtime($path) { + $stat = $this->stat($path); + return $stat['mtime']; + } + public function fileatime($path) { + $stat = $this->stat($path); + return $stat['atime']; + } + 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); + } +// abstract public function unlink($path); + 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'); + $count=\OC_Helper::streamCopy($source,$target); + return $count>0; + } +// abstract public function fopen($path,$mode); + + /** + * @brief Deletes all files and folders recursively within a directory + * @param $directory The directory whose contents will be deleted + * @param $empty Flag indicating whether directory will be emptied + * @returns true/false + * + * @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 ) { + + // strip leading slash + if( substr( $directory, 0, 1 ) == "/" ) { + + $directory = substr( $directory, 1 ); + + } + + // strip trailing slash + if( substr( $directory, -1) == "/" ) { + + $directory = substr( $directory, 0, -1 ); + + } + + if ( !$this->file_exists( \OCP\USER::getUser() . '/' . $directory ) || !$this->is_dir( \OCP\USER::getUser() . '/' . $directory ) ) { + + return false; + + } elseif( !$this->is_readable( \OCP\USER::getUser() . '/' . $directory ) ) { + + return false; + + } else { + + $directoryHandle = $this->opendir( \OCP\USER::getUser() . '/' . $directory ); + + while ( $contents = readdir( $directoryHandle ) ) { + + if ( $contents != '.' && $contents != '..') { + + $path = $directory . "/" . $contents; + + if ( $this->is_dir( $path ) ) { + + deleteAll( $path ); + + } else { + + $this->unlink( \OCP\USER::getUser() .'/' . $path ); // TODO: make unlink use same system path as is_dir + + } + } + + } + + //$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV + + 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(); + $hash=hash($type,$tmpFile,$raw); + unlink($tmpFile); + return $hash; + } +// abstract public function free_space($path); + 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 usefull 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) { + if($dh=$this->opendir($path)) { + while($file=readdir($dh)) { + 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); + } + } + } + } + } +// abstract public function touch($path, $mtime=null); + + protected function searchInDir($query,$dir='') { + $files=array(); + $dh=$this->opendir($dir); + if($dh) { + while($item=readdir($dh)) { + 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 int $time + * @return bool + */ + public function hasUpdated($path,$time) { + return $this->filemtime($path)>$time; + } +} diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php new file mode 100644 index 00000000000..773bfffcb49 --- /dev/null +++ b/lib/files/storage/commontest.php @@ -0,0 +1,77 @@ +. +* +*/ + +/** + * 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 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); + } +} \ No newline at end of file diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php new file mode 100644 index 00000000000..e47441499a1 --- /dev/null +++ b/lib/files/storage/local.php @@ -0,0 +1,208 @@ + + * 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 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 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); + } + return is_dir($this->datadir.$path); + } + public function is_file($path) { + return is_file($this->datadir.$path); + } + public function stat($path) { + return stat($this->datadir.$path); + } + 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{ + return filesize($this->datadir.$path); + } + } + 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 filectime($path) { + return filectime($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); + } + 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) { + 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; + } + + public function hash($path,$type,$raw=false) { + return hash_file($type,$this->datadir.$path,$raw); + } + + public function free_space($path) { + return disk_free_space($this->datadir.$path); + } + + 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 int $time + * @return bool + */ + public function hasUpdated($path,$time) { + return $this->filemtime($path)>$time; + } +} diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php new file mode 100644 index 00000000000..a2f6cb7ec34 --- /dev/null +++ b/lib/files/storage/storage.php @@ -0,0 +1,54 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * Provde a common interface to all different storage options + */ +abstract class Storage{ + abstract public function __construct($parameters); + abstract public function mkdir($path); + abstract public function rmdir($path); + abstract public function opendir($path); + abstract public function is_dir($path); + abstract public function is_file($path); + abstract public function stat($path); + abstract public function filetype($path); + abstract public function filesize($path); + abstract public function isCreatable($path); + abstract public function isReadable($path); + abstract public function isUpdatable($path); + abstract public function isDeletable($path); + abstract public function isSharable($path); + abstract public function file_exists($path); + abstract public function filectime($path); + abstract public function filemtime($path); + abstract public function file_get_contents($path); + abstract public function file_put_contents($path,$data); + abstract public function unlink($path); + abstract public function rename($path1,$path2); + abstract public function copy($path1,$path2); + abstract public function fopen($path,$mode); + abstract public function getMimeType($path); + abstract public function hash($type,$path,$raw = false); + abstract public function free_space($path); + abstract public function search($query); + abstract public function touch($path, $mtime=null); + abstract public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote + abstract public function getLocalFolder($path);// get a path to a local version of the folder, whether the original file is local or remote + /** + * check if a file or folder has been updated since $time + * @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 + */ + abstract public function hasUpdated($path,$time); +} diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php new file mode 100644 index 00000000000..0e69c9112ac --- /dev/null +++ b/lib/files/storage/temporary.php @@ -0,0 +1,26 @@ + + * 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 backnd in temporary folder for testing purpores + */ +class Temporary extends OC\Files\Storage\Local{ + public function __construct($arguments) { + $this->datadir=\OC_Helper::tmpFolder(); + } + + public function cleanUp() { + \OC_Helper::rmdirr($this->datadir); + } + + public function __destruct() { + $this->cleanUp(); + } +} -- cgit v1.2.3 From e8d3a4768541980fcc391117e5a173875b2f75e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 22:50:10 +0200 Subject: add getId to storage backends --- lib/files/storage/common.php | 1 + lib/files/storage/commontest.php | 3 +++ lib/files/storage/local.php | 3 +++ lib/files/storage/storage.php | 1 + 4 files changed, 8 insertions(+) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 0a60ff757eb..1f8b6204802 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,6 +23,7 @@ namespace OC\Files\Storage; abstract class Common extends \OC\Files\Storage\Storage { public function __construct($parameters) {} +// abstract public function getId(); // abstract public function mkdir($path); // abstract public function rmdir($path); // abstract public function opendir($path); diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php index 773bfffcb49..2b42cfe1156 100644 --- a/lib/files/storage/commontest.php +++ b/lib/files/storage/commontest.php @@ -38,6 +38,9 @@ class CommonTest extends \OC\Files\Storage\Common{ $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); } diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index e47441499a1..78e4877a005 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -19,6 +19,9 @@ class Local extends \OC\Files\Storage\Common{ $this->datadir.='/'; } } + public function getId(){ + return 'local::'.$this->datadir; + } public function mkdir($path) { return @mkdir($this->datadir.$path); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index a2f6cb7ec34..bd4cc4743b6 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -13,6 +13,7 @@ namespace OC\Files\Storage; */ abstract class Storage{ abstract public function __construct($parameters); + abstract public function getId(); abstract public function mkdir($path); abstract public function rmdir($path); abstract public function opendir($path); -- cgit v1.2.3 From c94fe38d3900acff474c909aaa730d7ab51f914d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 23:25:57 +0200 Subject: add getPermissions to storage backends to get all permission flags in one go --- lib/files/storage/common.php | 19 +++++++++++++++++++ lib/files/storage/storage.php | 1 + 2 files changed, 20 insertions(+) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 1f8b6204802..b2b4ea8eee4 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -54,6 +54,25 @@ abstract class Common extends \OC\Files\Storage\Storage { public function isSharable($path) { return $this->isReadable($path); } + public function getPermissions($path){ + $permissions = 0; + if($this->isCreatable($path)){ + $permissions |= OCP\Share::PERMISSION_CREATE; + } + if($this->isReadable($path)){ + $permissions |= OCP\Share::PERMISSION_READ; + } + if($this->isUpdatable($path)){ + $permissions |= OCP\Share::PERMISSION_UPDATE; + } + if($this->isDeletable($path)){ + $permissions |= OCP\Share::PERMISSION_DELETE; + } + if($this->isSharable($path)){ + $permissions |= OCP\Share::PERMISSION_SHARE; + } + return $permissions; + } // abstract public function file_exists($path); public function filectime($path) { $stat = $this->stat($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bd4cc4743b6..f149c61830c 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -27,6 +27,7 @@ abstract class Storage{ abstract public function isUpdatable($path); abstract public function isDeletable($path); abstract public function isSharable($path); + abstract public function getPermissions($path); abstract public function file_exists($path); abstract public function filectime($path); abstract public function filemtime($path); -- cgit v1.2.3 From 954596c251cb3132878d8d5eafcc37c47b3f520e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 16 Sep 2012 16:52:32 +0200 Subject: rework filecache to work directly on storage backends wip --- lib/files/cache/cache.php | 189 ++++++++++++++++++++++++++++++++++++++++++++ lib/files/cache/scanner.php | 78 ++++++++++++++++++ lib/files/file.php | 61 ++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 lib/files/cache/cache.php create mode 100644 lib/files/cache/scanner.php create mode 100644 lib/files/file.php (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php new file mode 100644 index 00000000000..8fc575948dc --- /dev/null +++ b/lib/files/cache/cache.php @@ -0,0 +1,189 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Cache { + /** + * @var array partial data for the cache + */ + private static $partial = array(); + + /** + * get the stored metadata of a file or folder + * + * @param \OC\Files\File or int $file + * @return array + */ + static public function get($file) { + if ($file instanceof \OC\Files\File) { + $where = 'WHERE `storage` = ? AND `path_hash` = ?'; + $params = array($file->getStorageId(), $file->getInternalPath()); + } else { //file id + $where = 'WHERE `fileid` = ?'; + $params = array($file); + } + $query = \OC_DB::prepare( + 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` ' . $where); + $result=$query->execute($params); + return $result->fetchRow(); + } + + /** + * store meta data for a file or folder + * + * @param \OC\Files\File $file + * @param array $data + * + * @return int file id + */ + static public function put(\OC\Files\File $file, array $data) { + if ($id = self::getId($file) > -1) { + self::update($id, $data); + return $id; + } else { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { //add any saved partial data + $data = array_merge($data, self::$partial[$key]); + unset(self::$partial[$key]); + } + + $requiredFields = array('size', 'mtime', 'mimetype'); + foreach ($requiredFields as $field) { + if (!isset($data[$field])) { //data not complete save as partial and return + self::$partial[$key] = $data; + return -1; + } + } + + $data['path'] = $file->getInternalPath(); + $data['parent'] = self::getParentId($file); + $data['name'] = basename($file->getInternalPath()); + + list($queryParts, $params) = self::buildParts($data); + $queryParts[] = '`storage`'; + $params[] = $file->getStorageId(); + $valuesPlaceholder = array_fill(0, count($queryParts), '?'); + + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query->execute($params); + + return \OC_DB::insertid('*PREFIX*filecache'); + } + } + + /** + * update the metadata in the cache + * + * @param int $id + * @param array $data + */ + static public function update($id, array $data) { + list($queryParts, $params) = self::buildParts($data); + $params[] = $id; + + $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE fileid = ?'); + $query->execute($params); + } + + /** + * extract query parts and params array from data array + * + * @param array $data + * @return array + */ + private static function buildParts(array $data) { + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + + $params = array(); + $queryParts = array(); + foreach ($data as $name => $value) { + if (array_search($name, $fields) !== false) { + $params[] = $value; + $queryParts[] = '`' . $name . '`'; + if ($name === 'path') { + $params[] = md5($value); + $queryParts[] = '`path_hash`'; + } elseif ($name === 'mimetype') { + $params[] = substr($value, 0, strpos($value, '/')); + $queryParts[] = '`mimepart`'; + } + } + } + return array($queryParts, $params); + } + + /** + * get the file id for a file + * + * @param \OC\Files\File $file + * @return int + */ + static public function getId(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + + $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($storageId, $pathHash)); + + if ($row = $result->fetchRow()) { + return $row['id']; + } else { + return -1; + } + } + + /** + * get the id of the parent folder of a file + * + * @param \OC\Files\File $file + * return int + */ + static public function getParentId(\OC\Files\File $file) { + $path = $file->getInternalPath(); + if ($path === '/' or $path === '') { + return -1; + } else { + return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + } + } + + /** + * check if a file is available in the cache + * + * @param \OC\Files\File $file + * @return bool + */ + static public function inCache(\OC\Files\File $file) { + return self::getId($file) != -1; + } + + /** + * remove a file or folder from the cache + * + * @param \OC\Files\File $file + */ + public function remove(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query->execute(array($storageId, $pathHash)); + } + + /** + * remove all entries for files that are stored on $storage form the cache + * + * @param \OC\Files\Storage\Storage $storage + */ + public function removeStorage(\OC\Files\Storage\Storage $storage) { + $storageId = $storage->getId(); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); + $query->execute(array($storageId)); + } +} diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php new file mode 100644 index 00000000000..8f2c5bda5ca --- /dev/null +++ b/lib/files/cache/scanner.php @@ -0,0 +1,78 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Scanner { + const SCAN_RECURSIVE = true; + const SCAN_SHALLOW = false; + + /** + * get all the metadata of a file or folder + * * + * @param \OC\Files\File $file + * @return array with metadata of the file + */ + public static function getData(\OC\Files\File $file) { + $data = array(); + $storage = $file->getStorage(); + $path = $file->getInternalPath(); + if (!$storage->isReadable($path)) return null; //cant read, nothing we can do + clearstatcache(); + $data['mimetype'] = $storage->getMimeType($path); + $data['mtime'] = $storage->filemtime($path); + if ($data['mimetype'] == 'httpd/unix-directory') { + $data['size'] = -1; //unknown + $data['permissions'] = $storage->getPermissions($path . '/'); + } else { + $data['size'] = $storage->filesize($path); + $data['permissions'] = $storage->getPermissions($path); + } + return $data; + } + + /** + * scan a single file and store it in the cache + * + * @param \OC\Files\File $file + * @return array with metadata of the scanned file + */ + public static function scanFile(\OC\Files\File $file) { + $data = self::getData($file); + Cache::put($file, $data); + return $data; + } + + /** + * scan all the files in a folder and store them in the cache + * + * @param \OC\Files\File $folder + * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @return int the size of the scanned folder or -1 if the size is unknown at this stage + */ + public static function scan(\OC\Files\File $folder, $recursive) { + $size = 0; + $storage = $folder->getStorage(); + $path = $folder->getInternalPath(); + if ($dh = $storage->opendir($path)) { + while ($file = readdir($dh)) { + if ($file !== '.' and $file !== '..') { + $child = new \OC\Files\File($storage, $path . '/' . $file); + $data = self::scanFile($child); + if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { + $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + } + if ($data['size'] >= 0 and $size >= 0) { + $size += $data['size']; + } + } + } + } + return $size; + } +} diff --git a/lib/files/file.php b/lib/files/file.php new file mode 100644 index 00000000000..b6432e63458 --- /dev/null +++ b/lib/files/file.php @@ -0,0 +1,61 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files; + +/** + * representation of the location a file or folder is stored + */ + +class File{ + /** + * @var Storage\Storage $storage + */ + private $storage; + /** + * @var string internalPath + */ + private $internalPath; + + public function __construct(Storage\Storage $storage, $internalPath){ + $this->storage = $storage; + $this->internalPath = $internalPath; + } + + public static function resolve($fullPath){ + $storage = null; + $internalPath = ''; + list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + return new File($storage, $internalPath); + } + + /** + * get the internal path of the file inside the filestorage + * @return string + */ + public function getInternalPath(){ + return $this->internalPath; + } + + /** + * get the storage the file is stored in + * @return \OC\Files\Storage\Storage + */ + public function getStorage(){ + return $this->storage; + } + + /** + * get the id of the storage the file is stored in + * @return string + */ + public function getStorageId(){ + return $this->storage->getId(); + } + +} -- cgit v1.2.3 From 153cd802a9bbc0f5a5f67fe428af7ca78185011f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:40:04 +0200 Subject: add partial file data to the result of Cache::get --- lib/files/cache/cache.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 8fc575948dc..9d90ab041f6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -31,7 +31,13 @@ class Cache { $query = \OC_DB::prepare( 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); - $result=$query->execute($params); + $result = $query->execute($params); + + //merge partial data + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $result=array_merge($result, self::$partial[$key]); + } return $result->fetchRow(); } -- cgit v1.2.3 From 46896be0d482f5dcec85ec32b232dd8a205f3e41 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:03:17 +0200 Subject: fix namespace error in temporary storage backend --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index 0e69c9112ac..ffc55e27507 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -11,7 +11,7 @@ namespace OC\Files\Storage; /** * local storage backnd in temporary folder for testing purpores */ -class Temporary extends OC\Files\Storage\Local{ +class Temporary extends Local{ public function __construct($arguments) { $this->datadir=\OC_Helper::tmpFolder(); } -- cgit v1.2.3 From 97b0eabc850f64949282b471288c93d7148c72ff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:43:48 +0200 Subject: fix several problems in the new filecache in order to complete the tests --- lib/files/cache/cache.php | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d90ab041f6..5d4cb9dd2b6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -23,22 +23,25 @@ class Cache { static public function get($file) { if ($file instanceof \OC\Files\File) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), $file->getInternalPath()); + $params = array($file->getStorageId(), md5($file->getInternalPath())); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); + $data = $result->fetchRow(); //merge partial data - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $result=array_merge($result, self::$partial[$key]); + if (!$data and $file instanceof \OC\Files\File) { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $data = self::$partial[$key]; + } } - return $result->fetchRow(); + return $data; } /** @@ -50,13 +53,13 @@ class Cache { * @return int file id */ static public function put(\OC\Files\File $file, array $data) { - if ($id = self::getId($file) > -1) { + if (($id = self::getId($file)) > -1) { self::update($id, $data); return $id; } else { $key = $file->getStorageId() . '::' . $file->getInternalPath(); if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge($data, self::$partial[$key]); + $data = array_merge(self::$partial[$key], $data); unset(self::$partial[$key]); } @@ -77,7 +80,7 @@ class Cache { $params[] = $file->getStorageId(); $valuesPlaceholder = array_fill(0, count($queryParts), '?'); - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); return \OC_DB::insertid('*PREFIX*filecache'); @@ -135,11 +138,11 @@ class Cache { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); - $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($storageId, $pathHash)); if ($row = $result->fetchRow()) { - return $row['id']; + return $row['fileid']; } else { return -1; } @@ -175,7 +178,7 @@ class Cache { * * @param \OC\Files\File $file */ - public function remove(\OC\Files\File $file) { + static public function remove(\OC\Files\File $file) { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); @@ -187,7 +190,7 @@ class Cache { * * @param \OC\Files\Storage\Storage $storage */ - public function removeStorage(\OC\Files\Storage\Storage $storage) { + static public function removeStorage(\OC\Files\Storage\Storage $storage) { $storageId = $storage->getId(); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $query->execute(array($storageId)); -- cgit v1.2.3 From 6fafd5d4e9d23cd98738a3b00ce0053d6b6e3dff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:48:39 +0200 Subject: this should be done elsewhere if needed --- lib/files/cache/cache.php | 2 +- lib/files/cache/scanner.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5d4cb9dd2b6..0c1d6788ec6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -152,7 +152,7 @@ class Cache { * get the id of the parent folder of a file * * @param \OC\Files\File $file - * return int + * @return int */ static public function getParentId(\OC\Files\File $file) { $path = $file->getInternalPath(); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 8f2c5bda5ca..e8e9c71c4e5 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -23,7 +23,6 @@ class Scanner { $storage = $file->getStorage(); $path = $file->getInternalPath(); if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - clearstatcache(); $data['mimetype'] = $storage->getMimeType($path); $data['mtime'] = $storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { -- cgit v1.2.3 From dcf995fff3ecc2780d3187744397461d1a14c041 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 23 Sep 2012 15:25:03 +0200 Subject: add Cache::getFolderContent --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 0c1d6788ec6..f8808ad0b4d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,6 +44,25 @@ class Cache { return $data; } + /** + * get the metadata of all files stored in $folder + * + * @param \OC\Files\File $folder + * @return array + */ + static public function getFolderContents($folder) { + $fileId = self::getId($folder); + if ($fileId > -1) { + $query = \OC_DB::prepare( + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` WHERE parent = ?'); + $result = $query->execute(array($fileId)); + return $result->fetchAll(); + } else { + return array(); + } + } + /** * store meta data for a file or folder * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 168489a7213..9f35cd889ac 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -78,6 +78,29 @@ class Cache extends \UnitTestCase { $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); } + public function testFolder() { + $file1 = $this->createPath('folder'); + $file2 = $this->createPath('folder/bar'); + $file3 = $this->createPath('folder/foo'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + FileCache::put($file1, $data1); + FileCache::put($file2, $fileData['bar']); + FileCache::put($file3, $fileData['foo']); + + $content = FileCache::getFolderContents($file1); + $this->assertEqual(count($content), 2); + foreach ($content as $cachedData) { + $data = $fileData[$cachedData['name']]; + foreach ($data as $name => $value) { + $this->assertEqual($value, $cachedData[$name]); + } + } + } + public function tearDown() { FileCache::removeStorage($this->storage); } -- cgit v1.2.3 From 522d7df860fb47d3cc56e315850dda2797569ac5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 26 Sep 2012 17:52:02 +0200 Subject: convert Cache to a non-static class that handles the cache for a single storage backend --- lib/files/cache/cache.php | 121 ++++++++++++++++++++++------------------ lib/files/cache/scanner.php | 1 + tests/lib/files/cache/cache.php | 82 ++++++++++++++------------- 3 files changed, 110 insertions(+), 94 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index f8808ad0b4d..167cc5d13f9 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,21 +9,36 @@ namespace OC\Files\Cache; class Cache { + /** + * @var \OC\Files\Storage\Storage + */ + private $storage; + /** * @var array partial data for the cache */ - private static $partial = array(); + private $partial = array(); + + private $storageId; + + /** + * @param \OC\Files\Storage\Storage $storage + */ + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->storageId = $storage->getId(); + } /** * get the stored metadata of a file or folder * - * @param \OC\Files\File or int $file + * @param string/int $file * @return array */ - static public function get($file) { - if ($file instanceof \OC\Files\File) { + public function get($file) { + if (is_string($file)) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), md5($file->getInternalPath())); + $params = array($this->storageId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -35,23 +50,28 @@ class Cache { $data = $result->fetchRow(); //merge partial data - if (!$data and $file instanceof \OC\Files\File) { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $data = self::$partial[$key]; + 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']; } + return $data; } /** * get the metadata of all files stored in $folder * - * @param \OC\Files\File $folder + * @param string $folder * @return array */ - static public function getFolderContents($folder) { - $fileId = self::getId($folder); + public function getFolderContents($folder) { + $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` @@ -66,43 +86,42 @@ class Cache { /** * store meta data for a file or folder * - * @param \OC\Files\File $file + * @param string $file * @param array $data * * @return int file id */ - static public function put(\OC\Files\File $file, array $data) { - if (($id = self::getId($file)) > -1) { - self::update($id, $data); + public function put($file, array $data) { + if (($id = $this->getId($file)) > -1) { + $this->update($id, $data); return $id; } else { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge(self::$partial[$key], $data); - unset(self::$partial[$key]); + 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 - self::$partial[$key] = $data; + $this->partial[$file] = $data; return -1; } } - $data['path'] = $file->getInternalPath(); - $data['parent'] = self::getParentId($file); - $data['name'] = basename($file->getInternalPath()); + $data['path'] = $file; + $data['parent'] = $this->getParentId($file); + $data['name'] = basename($file); - list($queryParts, $params) = self::buildParts($data); + list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $file->getStorageId(); + $params[] = $this->storageId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return \OC_DB::insertid('*PREFIX*filecache'); + return (int) \OC_DB::insertid('*PREFIX*filecache'); } } @@ -112,8 +131,8 @@ class Cache { * @param int $id * @param array $data */ - static public function update($id, array $data) { - list($queryParts, $params) = self::buildParts($data); + public function update($id, array $data) { + list($queryParts, $params) = $this->buildParts($data); $params[] = $id; $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE fileid = ?'); @@ -126,7 +145,7 @@ class Cache { * @param array $data * @return array */ - private static function buildParts(array $data) { + static function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); $params = array(); @@ -150,15 +169,14 @@ class Cache { /** * get the file id for a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getId(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + public function getId($file) { + $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($storageId, $pathHash)); + $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -170,48 +188,43 @@ class Cache { /** * get the id of the parent folder of a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getParentId(\OC\Files\File $file) { - $path = $file->getInternalPath(); - if ($path === '/' or $path === '') { + public function getParentId($file) { + if ($file === '/' or $file === '') { return -1; } else { - return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + return $this->getId(dirname($file)); } } /** * check if a file is available in the cache * - * @param \OC\Files\File $file + * @param string $file * @return bool */ - static public function inCache(\OC\Files\File $file) { - return self::getId($file) != -1; + public function inCache($file) { + return $this->getId($file) != -1; } /** * remove a file or folder from the cache * - * @param \OC\Files\File $file + * @param string $file */ - static public function remove(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + public function remove($file) { + $pathHash = md5($file); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($storageId, $pathHash)); + $query->execute(array($this->storageId, $pathHash)); } /** - * remove all entries for files that are stored on $storage form the cache - * - * @param \OC\Files\Storage\Storage $storage + * remove all entries for files that are stored on the storage from the cache */ - static public function removeStorage(\OC\Files\Storage\Storage $storage) { - $storageId = $storage->getId(); + public function clear() { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); - $query->execute(array($storageId)); + $query->execute(array($this->storageId)); } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8e9c71c4e5..17fc0fb2e8e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -15,6 +15,7 @@ class Scanner { /** * get all the metadata of a file or folder * * + * * @param \OC\Files\File $file * @return array with metadata of the file */ diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9f35cd889ac..24dd38fa736 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -16,82 +16,83 @@ class Cache extends \UnitTestCase { */ private $storage; - private function createPath($path) { - return new \OC\Files\File($this->storage, $path); - } + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; public function testSimple() { - $file1 = $this->createPath('foo'); - $file2 = $this->createPath('foo/bar'); + $file1 = 'foo'; + $file2 = 'foo/bar'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); - $this->assertFalse(FileCache::inCache($file1)); - $this->assertEqual(FileCache::get($file1), null); + $this->assertFalse($this->cache->inCache($file1)); + $this->assertEqual($this->cache->get($file1), null); - $id1 = FileCache::put($file1, $data1); - $this->assertTrue(FileCache::inCache($file1)); - $cacheData1 = FileCache::get($file1); + $id1 = $this->cache->put($file1, $data1); + $this->assertTrue($this->cache->inCache($file1)); + $cacheData1 = $this->cache->get($file1); foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } $this->assertEqual($cacheData1['fileid'], $id1); - $this->assertEqual($id1, FileCache::getId($file1)); + $this->assertEqual($id1, $this->cache->getId($file1)); - $this->assertFalse(FileCache::inCache($file2)); - $id2 = FileCache::put($file2, $data2); - $this->assertTrue(FileCache::inCache($file2)); - $cacheData2 = FileCache::get($file2); + $this->assertFalse($this->cache->inCache($file2)); + $id2 = $this->cache->put($file2, $data2); + $this->assertTrue($this->cache->inCache($file2)); + $cacheData2 = $this->cache->get($file2); foreach ($data2 as $key => $value) { $this->assertEqual($value, $cacheData2[$key]); } $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); $this->assertEqual($cacheData2['fileid'], $id2); - $this->assertEqual($id2, FileCache::getId($file2)); - $this->assertEqual($id1, FileCache::getParentId($file2)); + $this->assertEqual($id2, $this->cache->getId($file2)); + $this->assertEqual($id1, $this->cache->getParentId($file2)); $newSize = 1050; - $newId2 = FileCache::put($file2, array('size' => $newSize)); - $cacheData2 = FileCache::get($file2); + $newId2 = $this->cache->put($file2, array('size' => $newSize)); + $cacheData2 = $this->cache->get($file2); $this->assertEqual($newId2, $id2); $this->assertEqual($cacheData2['size'], $newSize); - $this->assertEqual($cacheData1, FileCache::get($file1)); + $this->assertEqual($cacheData1, $this->cache->get($file1)); - FileCache::remove($file2); - $this->assertFalse(FileCache::inCache($file2)); - $this->assertEqual(FileCache::get($file2), null); - $this->assertTrue(FileCache::inCache($file1)); + $this->cache->remove($file2); + $this->assertFalse($this->cache->inCache($file2)); + $this->assertEqual($this->cache->get($file2), null); + $this->assertTrue($this->cache->inCache($file1)); - $this->assertEqual($cacheData1, FileCache::get($id1)); + $this->assertEqual($cacheData1, $this->cache->get($id1)); } public function testPartial() { - $file1 = $this->createPath('foo'); + $file1 = 'foo'; - FileCache::put($file1, array('size' => 10)); - $this->assertEqual(array('size' => 10), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 10)); + $this->assertEqual(array('size' => 10), $this->cache->get($file1)); - FileCache::put($file1, array('mtime' => 15)); - $this->assertEqual(array('size' => 10, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('mtime' => 15)); + $this->assertEqual(array('size' => 10, 'mtime' => 15), $this->cache->get($file1)); - FileCache::put($file1, array('size' => 12)); - $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 12)); + $this->assertEqual(array('size' => 12, 'mtime' => 15), $this->cache->get($file1)); } public function testFolder() { - $file1 = $this->createPath('folder'); - $file2 = $this->createPath('folder/bar'); - $file3 = $this->createPath('folder/foo'); + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); - FileCache::put($file1, $data1); - FileCache::put($file2, $fileData['bar']); - FileCache::put($file3, $fileData['foo']); + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['bar']); + $this->cache->put($file3, $fileData['foo']); - $content = FileCache::getFolderContents($file1); + $content = $this->cache->getFolderContents($file1); $this->assertEqual(count($content), 2); foreach ($content as $cachedData) { $data = $fileData[$cachedData['name']]; @@ -102,10 +103,11 @@ class Cache extends \UnitTestCase { } public function tearDown() { - FileCache::removeStorage($this->storage); + $this->cache->clear(); } public function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->cache = new \OC\Files\Cache\Cache($this->storage); } } -- cgit v1.2.3 From 92555eff711ff391f3af5ef6fb6f6414bfe012cf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:34:45 +0200 Subject: add encrypted column to the new filecache --- lib/files/cache/cache.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 167cc5d13f9..9d8275e5e03 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,7 +44,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -59,6 +59,7 @@ class Cache { $data['fileid'] = (int)$data['fileid']; $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; + $data['encrypted'] = (bool)$data['encrypted']; } return $data; @@ -74,7 +75,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ?'); $result = $query->execute(array($fileId)); return $result->fetchAll(); @@ -112,6 +113,7 @@ class Cache { $data['path'] = $file; $data['parent'] = $this->getParentId($file); $data['name'] = basename($file); + $data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0; list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; @@ -121,7 +123,7 @@ class Cache { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return (int) \OC_DB::insertid('*PREFIX*filecache'); + return (int)\OC_DB::insertid('*PREFIX*filecache'); } } @@ -146,7 +148,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); -- cgit v1.2.3 From 636c75ce061492751d0fb001e0bf7219df379f09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:23:33 +0200 Subject: better parent path bahaviour for the filecache --- lib/files/cache/cache.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d8275e5e03..79673771e5e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -194,10 +194,14 @@ class Cache { * @return int */ public function getParentId($file) { - if ($file === '/' or $file === '') { + if ($file === '') { return -1; } else { - return $this->getId(dirname($file)); + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + return $this->getId($parent); } } -- cgit v1.2.3 From 96d7cd59978cc416bc0d9c5ac487af23692ef1d8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:10 +0200 Subject: correct namespace usage in common filestorage backend --- lib/files/storage/common.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index b2b4ea8eee4..3886a041829 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common extends \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\Share::PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= OCP\Share::PERMISSION_READ; + $permissions |= \OCP\Share::PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\Share::PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\Share::PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\Share::PERMISSION_SHARE; } return $permissions; } -- cgit v1.2.3 From e415e90c6d8a2e8bb129be7c63a7077c56ab3da8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:49 +0200 Subject: make filestorage scanner non-static and add a simple test case --- lib/files/cache/scanner.php | 64 +++++++++++++++++++++++++-------------- tests/lib/files/cache/cache.php | 1 + tests/lib/files/cache/scanner.php | 47 ++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 tests/lib/files/cache/scanner.php (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 17fc0fb2e8e..721d0d825ec 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -9,29 +9,42 @@ namespace OC\Files\Cache; class Scanner { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->cache = new Cache($storage); + } + /** * get all the metadata of a file or folder * * * - * @param \OC\Files\File $file + * @param string $path * @return array with metadata of the file */ - public static function getData(\OC\Files\File $file) { + public function getData($path) { $data = array(); - $storage = $file->getStorage(); - $path = $file->getInternalPath(); - if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - $data['mimetype'] = $storage->getMimeType($path); - $data['mtime'] = $storage->filemtime($path); + 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 - $data['permissions'] = $storage->getPermissions($path . '/'); + $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { - $data['size'] = $storage->filesize($path); - $data['permissions'] = $storage->getPermissions($path); + $data['size'] = $this->storage->filesize($path); + $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -39,33 +52,40 @@ class Scanner { /** * scan a single file and store it in the cache * - * @param \OC\Files\File $file + * @param string $file * @return array with metadata of the scanned file */ - public static function scanFile(\OC\Files\File $file) { - $data = self::getData($file); - Cache::put($file, $data); + public function scanFile($file) { + $data = $this->getData($file); + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } + } + $this->cache->put($file, $data); return $data; } /** * scan all the files in a folder and store them in the cache * - * @param \OC\Files\File $folder + * @param string $path * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public static function scan(\OC\Files\File $folder, $recursive) { + public function scan($path, $recursive) { $size = 0; - $storage = $folder->getStorage(); - $path = $folder->getInternalPath(); - if ($dh = $storage->opendir($path)) { + if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = new \OC\Files\File($storage, $path . '/' . $file); - $data = self::scanFile($child); + $child = $path . '/' . $file; + $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); } if ($data['size'] >= 0 and $size >= 0) { $size += $data['size']; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 48cdc1c8c8c..8cedadbf19a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -34,6 +34,7 @@ class Cache extends \UnitTestCase { foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } + $this->assertEqual($cacheData1['mimepart'], 'foo'); $this->assertEqual($cacheData1['fileid'], $id1); $this->assertEqual($id1, $this->cache->getId($file1)); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php new file mode 100644 index 00000000000..3d1c1546ab0 --- /dev/null +++ b/tests/lib/files/cache/scanner.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Scanner extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + function testFile() { + $data = "dummy file data\n"; + $this->storage->file_put_contents('foo.txt', $data); + $this->scanner->scanFile('foo.txt'); + + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'text/plain'); + } + + function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->scanner = new \OC\Files\Cache\Scanner($this->storage); + $this->cache = new \OC\Files\Cache\Cache($this->storage); + } + + function tearDown() { +// $this->cache->clear(); + } +} -- cgit v1.2.3 From 85be00be6595a3af168f6df963ffdeac8c3c6d5e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:40:09 +0200 Subject: add some more test cases for the scanner --- lib/files/cache/scanner.php | 6 ++++-- tests/lib/files/cache/scanner.php | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 721d0d825ec..7d449204e81 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -77,12 +77,14 @@ class Scanner { * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public function scan($path, $recursive) { + public function scan($path, $recursive = self::SCAN_RECURSIVE) { + $this->scanFile($path); + $size = 0; if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = $path . '/' . $file; + $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 3d1c1546ab0..7ee28dfc3fd 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -33,6 +33,27 @@ class Scanner extends \UnitTestCase { $cachedData = $this->cache->get('foo.txt'); $this->assertEqual($cachedData['size'], strlen($data)); $this->assertEqual($cachedData['mimetype'], 'text/plain'); + $this->assertNotEqual($cachedData['parent'], -1); //parent folders should be scanned automatically + + $data = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.png', $data); + $this->scanner->scanFile('foo.png'); + + $this->assertEqual($this->cache->inCache('foo.png'), true); + $cachedData = $this->cache->get('foo.png'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'image/png'); + } + + function testFolder() { + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + + $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); } function setUp() { @@ -42,6 +63,6 @@ class Scanner extends \UnitTestCase { } function tearDown() { -// $this->cache->clear(); + $this->cache->clear(); } } -- cgit v1.2.3 From b9b9fd9dbaae47b3a15aed9694c18b95404550b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 13:07:19 +0200 Subject: more tests and fixes for the filesystem scanner --- lib/files/cache/scanner.php | 15 ++++++++++++--- tests/lib/files/cache/scanner.php | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7d449204e81..e8f54c34be7 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -86,15 +86,24 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } } - if ($data['size'] >= 0 and $size >= 0) { + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { $size += $data['size']; } } } } + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } return $size; } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 7ee28dfc3fd..41286e69d3e 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -45,15 +45,52 @@ class Scanner extends \UnitTestCase { $this->assertEqual($cachedData['mimetype'], 'image/png'); } - function testFolder() { + private function fillTestFolders() { $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); $this->storage->file_put_contents('foo.txt', $textData); $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + } + + function testFolder() { + $this->fillTestFolders(); $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache(''), true); $this->assertEqual($this->cache->inCache('foo.txt'), true); $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), true); + + $cachedDataText = $this->cache->get('foo.txt'); + $cachedDataText2 = $this->cache->get('foo.txt'); + $cachedDataImage = $this->cache->get('foo.png'); + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataImage['parent'], $cachedDataText['parent']); + $this->assertEqual($cachedDataFolder['fileid'], $cachedDataImage['parent']); + $this->assertEqual($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); + $this->assertEqual($cachedDataFolder2['size'], $cachedDataText2['size']); + } + + function testShallow() { + $this->fillTestFolders(); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertEqual($this->cache->inCache(''), true); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), false); + + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataFolder['size'], -1); + $this->assertEqual($cachedDataFolder2['size'], -1); } function setUp() { -- cgit v1.2.3 From 13515effc99bfad7e776d00476e897fa396a8c6c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 8 Oct 2012 14:58:21 +0200 Subject: add Cache::getStatus --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 10 ++++++++++ 2 files changed, 39 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 79673771e5e..5ef49246ea5 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,6 +9,11 @@ namespace OC\Files\Cache; 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 \OC\Files\Storage\Storage */ @@ -233,4 +238,28 @@ class Cache { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $query->execute(array($this->storageId)); } + + /** + * @param string $file + * + * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE + */ + public function getStatus($file) { + $pathHash = md5($file); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($this->storageId, $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; + } + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 8cedadbf19a..177cf1c045d 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -101,6 +101,16 @@ class Cache extends \UnitTestCase { } } + function testStatus() { + $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1)); + $this->assertEquals(\OC\Files\Cache\Cache::PARTIAL, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1, 'mtime' => 20, 'mimetype' => 'foo/file')); + $this->assertEquals(\OC\Files\Cache\Cache::SHALLOW, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => 10)); + $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 9df60d27bd9dad6a37a0d763b808a5b1c5ade5c5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 11:54:44 +0200 Subject: move some code around --- lib/files/filesystem.php | 629 ++++++++++++++++++++++++++++++++++++++++++++ lib/files/view.php | 658 +++++++++++++++++++++++++++++++++++++++++++++++ lib/filesystem.php | 562 ---------------------------------------- lib/filesystemview.php | 633 --------------------------------------------- 4 files changed, 1287 insertions(+), 1195 deletions(-) create mode 100644 lib/files/filesystem.php create mode 100644 lib/files/view.php delete mode 100644 lib/filesystemview.php (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php new file mode 100644 index 00000000000..d0a96b59a0e --- /dev/null +++ b/lib/files/filesystem.php @@ -0,0 +1,629 @@ + + * 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 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 emited 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 emited in that order) + * post_rename(oldpath,newpath) + * + * the &run parameter can be set to false to prevent the operation from occuring + */ + +namespace OC\Files; + +class Filesystem { + static private $storages = array(); + static private $mounts = array(); + public static $loaded = false; + /** + * @var \OC\Files\Storage\Storage $defaultInstance + */ + static private $defaultInstance; + + + /** + * classname which used for hooks handling + * used as signalclass in OC_Hooks::emit() + */ + const CLASSNAME = 'OC_Filesystem'; + + /** + * signalname emited before file renaming + * + * @param oldpath + * @param newpath + */ + const signal_rename = 'rename'; + + /** + * signal emited after file renaming + * + * @param oldpath + * @param newpath + */ + const signal_post_rename = 'post_rename'; + + /** + * signal emited before file/dir creation + * + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_create = 'create'; + + /** + * signal emited after file/dir creation + * + * @param path + * @param 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 oldpath + * @param newpath + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_copy = 'copy'; + + /** + * signal emits after file/dir copy + * + * @param oldpath + * @param newpath + */ + const signal_post_copy = 'post_copy'; + + /** + * signal emits before file/dir save + * + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_write = 'write'; + + /** + * signal emits after file/dir save + * + * @param path + */ + const signal_post_write = 'post_write'; + + /** + * signal emits when reading file/dir + * + * @param path + */ + const signal_read = 'read'; + + /** + * signal emits when removing file/dir + * + * @param 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'; + + /** + * 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) { + OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); + if (!$path) { + $path = '/'; + } + if ($path[0] !== '/') { + $path = '/' . $path; + } + $path = str_replace('//', '/', $path); + $foundMountPoint = ''; + $mountPoints = array_keys(OC_Filesystem::$mounts); + foreach ($mountPoints as $mountpoint) { + if ($mountpoint == $path) { + return $mountpoint; + } + if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { + $foundMountPoint = $mountpoint; + } + } + return $foundMountPoint; + } + + /** + * get the part of the path relative to the mountpoint of the storage it's stored in + * + * @param string path + * @return bool + */ + static public function getInternalPath($path) { + $mountPoint = self::getMountPoint($path); + $internalPath = substr($path, strlen($mountPoint)); + return $internalPath; + } + + /** + * get the storage object for a path + * + * @param string path + * @return \OC\Files\Storage\Storage + */ + static public function getStorage($path) { + $mountpoint = self::getMountPoint($path); + if ($mountpoint) { + if (!isset(OC_Filesystem::$storages[$mountpoint])) { + $mount = OC_Filesystem::$mounts[$mountpoint]; + OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + } + return OC_Filesystem::$storages[$mountpoint]; + } + } + + /** + * 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) { + $mountpoint = self::getMountPoint($path); + if ($mountpoint) { + if (!isset(OC_Filesystem::$storages[$mountpoint])) { + $mount = OC_Filesystem::$mounts[$mountpoint]; + OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + } + $storage = OC_Filesystem::$storages[$mountpoint]; + $internalPath = substr($path, strlen($mountpoint)); + return array($storage, $internalPath); + } + } + + static public function init($root) { + if (self::$defaultInstance) { + return false; + } + self::$defaultInstance = new OC_FilesystemView($root); + +//load custom mount config + if (is_file(OC::$SERVERROOT . '/config/mount.php')) { + $mountConfig = include(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(OC_User::getUser(), $group)) { + foreach ($mounts as $mountPoint => $options) { + $mountPoint = self::setUserVars($mountPoint); + foreach ($options as &$option) { + $option = self::setUserVars($option); + } + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } + } + + if (isset($mountConfig['user'])) { + foreach ($mountConfig['user'] as $user => $mounts) { + if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) { + foreach ($mounts as $mountPoint => $options) { + $mountPoint = self::setUserVars($mountPoint); + foreach ($options as &$option) { + $option = self::setUserVars($option); + } + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } + } + } + + self::$loaded = true; + } + + /** + * fill in the correct values for $user, and $password placeholders + * + * @param string intput + * @return string + */ + private static function setUserVars($input) { + return str_replace('$user', OC_User::getUser(), $input); + } + + /** + * get the default filesystem view + * + * @return OC_FilesystemView + */ + static public function getView() { + return self::$defaultInstance; + } + + /** + * tear down the filesystem, removing all storage providers + */ + static public function tearDown() { + self::$storages = array(); + } + + /** + * create a new storage of a specific type + * + * @param string type + * @param array arguments + * @return \OC\Files\Storage\Storage + */ + static private function createStorage($class, $arguments) { + if (class_exists($class)) { + try { + return new $class($arguments); + } catch (Exception $exception) { + OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); + return false; + } + } else { + OC_Log::write('core', 'storage backend ' . $class . ' not found', OC_Log::ERROR); + return false; + } + } + + /** + * change the root to a fake root + * + * @param string fakeRoot + * @return bool + */ + static public function chroot($fakeRoot) { + return self::$defaultInstance->chroot($fakeRoot); + } + + /** + * @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() { + self::$mounts = array(); + self::$storages = array(); + } + + /** + * mount an \OC\Files\Storage\Storage in our virtual filesystem + * + * @param \OC\Files\Storage\Storage storage + * @param string mountpoint + */ + static public function mount($class, $arguments, $mountpoint) { + if ($mountpoint[0] != '/') { + $mountpoint = '/' . $mountpoint; + } + if (substr($mountpoint, -1) !== '/') { + $mountpoint = $mountpoint . '/'; + } + self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); + } + + /** + * 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) { + 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) { + $blacklist = array('.htaccess'); + if (isset($data['path'])) { + $path = $data['path']; + } else if (isset($data['newpath'])) { + $path = $data['newpath']; + } + if (isset($path)) { + $filename = strtolower(basename($path)); + if (in_array($filename, $blacklist)) { + $data['run'] = 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); + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + static public function is_readable($path) { + return self::$defaultInstance->is_readable($path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + static public function is_writable($path) { + return self::$defaultInstance->is_writable($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 filectime($path) { + return self::$defaultInstance->filectime($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 OC_FileCache::search($query); + } + + /** + * check if a file or folder has been updated since $time + * + * @param int $time + * @return bool + */ + static public function hasUpdated($path, $time) { + return self::$defaultInstance->hasUpdated($path, $time); + } + + static public function removeETagHook($params, $root = false) { + if (isset($params['path'])) { + $path = $params['path']; + } else { + $path = $params['oldpath']; + } + + if ($root) { // reduce path to the required part of it (no 'username/files') + $fakeRootView = new OC_FilesystemView($root); + $count = 1; + $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); + } + + $path = self::normalizePath($path); + OC_Connector_Sabre_Node::removeETagPropertyForPath($path); + } + + /** + * normalize a 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 trainling slash + if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { + $path = substr($path, 0, -1); + } +//remove duplicate slashes + while (strpos($path, '//') !== false) { + $path = str_replace('//', '/', $path); + } +//normalize unicode if possible + if (class_exists('Normalizer')) { + $path = Normalizer::normalize($path); + } + return $path; + } +} + +OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); +OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); +OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); + +OC_Util::setupFS(); diff --git a/lib/files/view.php b/lib/files/view.php new file mode 100644 index 00000000000..8c3f288f445 --- /dev/null +++ b/lib/files/view.php @@ -0,0 +1,658 @@ + + * 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 toor + * + * @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 the part of the path relative to the mountpoint of the storage it's stored in + * + * @param string path + * @return bool + */ + public function getInternalPath($path) { + if (!isset($this->internal_path_cache[$path])) { + $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); + } + return $this->internal_path_cache[$path]; + } + + /** + * 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 storage object for a path + * + * @param string path + * @return \OC\Files\Storage\Storage + */ + public function getStorage($path) { + if (!isset($this->storage_cache[$path])) { + $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); + } + return $this->storage_cache[$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 OC_Filesystem::getMountPoint($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, '/')); + if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + return $storage->getLocalFile($this->getInternalPath($path)); + } + } + + /** + * @param string path + * @return string + */ + public function getLocalFolder($path) { + $parent = substr($path, 0, strrpos($path, '/')); + if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + return $storage->getLocalFolder($this->getInternalPath($path)); + } + } + + /** + * 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 \OC\Files\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 MB chunks + while (!feof($handle)) { + echo fread($handle, $chunkSize); + flush(); + } + $size = $this->filesize($path); + return $size; + } + return false; + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + public function is_readable($path) { + return $this->basicOperation('isReadable', $path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + public function is_writable($path) { + return $this->basicOperation('isUpdatable', $path); + } + + 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 filectime($path) { + return $this->basicOperation('filectime', $path); + } + + public function filemtime($path) { + return $this->basicOperation('filemtime', $path); + } + + public function touch($path, $mtime = null) { + return $this->basicOperation('touch', $path, array('write'), $mtime); + } + + 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); + if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + $exists = $this->file_exists($path); + $run = true; + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if (!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + if (!$run) { + return false; + } + $target = $this->fopen($path, 'w'); + if ($target) { + $count = OC_Helper::streamCopy($data, $target); + fclose($target); + fclose($data); + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if (!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_create, + array(OC_Filesystem::signal_param_path => $path) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array(OC_Filesystem::signal_param_path => $path) + ); + } + OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); + return $count > 0; + } 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->basicOperation('deleteAll', $directory, array('delete'), $empty); + } + + public function rename($path1, $path2) { + $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; + $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; + $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + + if ($path1 == null or $path2 == null) { + return false; + } + $run = true; + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + if ($run) { + $mp1 = $this->getMountPoint($path1 . $postFix1); + $mp2 = $this->getMountPoint($path2 . $postFix2); + if ($mp1 == $mp2) { + if ($storage = $this->getStorage($path1)) { + $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } + } else { + $source = $this->fopen($path1 . $postFix1, 'r'); + $target = $this->fopen($path2 . $postFix2, 'w'); + $count = OC_Helper::streamCopy($source, $target); + $storage1 = $this->getStorage($path1); + $storage1->unlink($this->getInternalPath($path1 . $postFix1)); + $result = $count > 0; + } + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_rename, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2 + ) + ); + } + return $result; + } + } + } + + public function copy($path1, $path2) { + $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; + $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; + $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + + if ($path1 == null or $path2 == null) { + return false; + } + $run = true; + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_copy, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + $exists = $this->file_exists($path2); + if ($run and !$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + if ($run) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + } + if ($run) { + $mp1 = $this->getMountPoint($path1 . $postFix1); + $mp2 = $this->getMountPoint($path2 . $postFix2); + if ($mp1 == $mp2) { + if ($storage = $this->getStorage($path1 . $postFix1)) { + $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } + } else { + $source = $this->fopen($path1 . $postFix1, 'r'); + $target = $this->fopen($path2 . $postFix2, 'w'); + $result = OC_Helper::streamCopy($source, $target); + } + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_copy, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2 + ) + ); + if (!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_create, + array(OC_Filesystem::signal_param_path => $path2) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array(OC_Filesystem::signal_param_path => $path2) + ); + } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions + OC_FileCache_Update::update($path2, $this->fakeRoot); + OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); + } + return $result; + } + } + } + + 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 (OC_Filesystem::isValidPath($path)) { + $source = $this->fopen($path, 'r'); + if ($source) { + $extension = ''; + $extOffset = strpos($path, '.'); + if ($extOffset !== false) { + $extension = substr($path, strrpos($path, '.')); + } + $tmpFile = OC_Helper::tmpFile($extension); + file_put_contents($tmpFile, $source); + return $tmpFile; + } + } + } + + public function fromTmpFile($tmpFile, $path) { + if (OC_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 { + } + } 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); + if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + if ($path == null) { + return false; + } + if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_read, + array(OC_Filesystem::signal_param_path => $path) + ); + } + if ($storage = $this->getStorage($path . $postFix)) { + $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $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 (optional) hooks + * @param mixed (optional) $extraParam + * @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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); + if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + if ($path == null) { + return false; + } + $internalPath = $this->getInternalPath($path . $postFix); + $run = $this->runHooks($hooks, $path); + if ($run and $storage = $this->getStorage($path . $postFix)) { + if (!is_null($extraParam)) { + $result = $storage->$operation($internalPath, $extraParam); + } else { + $result = $storage->$operation($internalPath); + } + $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); + if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open + $this->runHooks($hooks, $path, true); + } + } + return $result; + } + } + return null; + } + + private function runHooks($hooks, $path, $post = false) { + $prefix = ($post) ? 'post_' : ''; + $run = true; + if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + foreach ($hooks as $hook) { + if ($hook != 'read') { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix . $hook, + array( + OC_Filesystem::signal_param_run => &$run, + OC_Filesystem::signal_param_path => $path + ) + ); + } elseif (!$post) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix . $hook, + array( + OC_Filesystem::signal_param_path => $path + ) + ); + } + } + } + return $run; + } + + /** + * check if a file or folder has been updated since $time + * + * @param int $time + * @return bool + */ + public function hasUpdated($path, $time) { + return $this->basicOperation('hasUpdated', $path, array(), $time); + } +} diff --git a/lib/filesystem.php b/lib/filesystem.php index b73b52d4203..b1200f95bfa 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -22,566 +22,4 @@ */ -/** - * Class for abstraction of filesystem functions - * This class won't call any filesystem functions for itself but 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 emited 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 emited in that order) - * post_rename(oldpath,newpath) - * - * the &run parameter can be set to false to prevent the operation from occuring - */ - -class OC_Filesystem{ - static private $storages=array(); - static private $mounts=array(); - public static $loaded=false; - /** - * @var \OC\Files\Storage\Storage $defaultInstance - */ - static private $defaultInstance; - - - /** - * classname which used for hooks handling - * used as signalclass in OC_Hooks::emit() - */ - const CLASSNAME = 'OC_Filesystem'; - - /** - * signalname emited before file renaming - * @param oldpath - * @param newpath - */ - const signal_rename = 'rename'; - - /** - * signal emited after file renaming - * @param oldpath - * @param newpath - */ - const signal_post_rename = 'post_rename'; - - /** - * signal emited before file/dir creation - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_create = 'create'; - - /** - * signal emited after file/dir creation - * @param path - * @param 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 oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_copy = 'copy'; - - /** - * signal emits after file/dir copy - * @param oldpath - * @param newpath - */ - const signal_post_copy = 'post_copy'; - - /** - * signal emits before file/dir save - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_write = 'write'; - - /** - * signal emits after file/dir save - * @param path - */ - const signal_post_write = 'post_write'; - - /** - * signal emits when reading file/dir - * @param path - */ - const signal_read = 'read'; - - /** - * signal emits when removing file/dir - * @param 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'; - - /** - * 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) { - OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path)); - if(!$path) { - $path='/'; - } - if($path[0]!=='/') { - $path='/'.$path; - } - $path=str_replace('//', '/',$path); - $foundMountPoint=''; - $mountPoints=array_keys(OC_Filesystem::$mounts); - foreach($mountPoints as $mountpoint) { - if($mountpoint==$path) { - return $mountpoint; - } - if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)) { - $foundMountPoint=$mountpoint; - } - } - return $foundMountPoint; - } - - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * @param string path - * @return bool - */ - static public function getInternalPath($path) { - $mountPoint=self::getMountPoint($path); - $internalPath=substr($path,strlen($mountPoint)); - return $internalPath; - } - /** - * get the storage object for a path - * @param string path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - $mountpoint=self::getMountPoint($path); - if($mountpoint) { - if(!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount=OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']); - } - return OC_Filesystem::$storages[$mountpoint]; - } - } - - /** - * 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){ - $mountpoint=self::getMountPoint($path); - if($mountpoint) { - if(!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount=OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']); - } - $storage = OC_Filesystem::$storages[$mountpoint]; - $internalPath=substr($path,strlen($mountpoint)); - return array($storage, $internalPath); - } - } - - static public function init($root) { - if(self::$defaultInstance) { - return false; - } - self::$defaultInstance=new OC_FilesystemView($root); - - //load custom mount config - if(is_file(OC::$SERVERROOT.'/config/mount.php')) { - $mountConfig=include(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(OC_User::getUser(),$group)) { - foreach($mounts as $mountPoint=>$options) { - $mountPoint=self::setUserVars($mountPoint); - foreach($options as &$option) { - $option=self::setUserVars($option); - } - self::mount($options['class'],$options['options'],$mountPoint); - } - } - } - } - - if(isset($mountConfig['user'])) { - foreach($mountConfig['user'] as $user=>$mounts) { - if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())) { - foreach($mounts as $mountPoint=>$options) { - $mountPoint=self::setUserVars($mountPoint); - foreach($options as &$option) { - $option=self::setUserVars($option); - } - self::mount($options['class'],$options['options'],$mountPoint); - } - } - } - } - } - - self::$loaded=true; - } - - /** - * fill in the correct values for $user, and $password placeholders - * @param string intput - * @return string - */ - private static function setUserVars($input) { - return str_replace('$user',OC_User::getUser(),$input); - } - - /** - * get the default filesystem view - * @return OC_FilesystemView - */ - static public function getView() { - return self::$defaultInstance; - } - - /** - * tear down the filesystem, removing all storage providers - */ - static public function tearDown() { - self::$storages=array(); - } - - /** - * create a new storage of a specific type - * @param string type - * @param array arguments - * @return \OC\Files\Storage\Storage - */ - static private function createStorage($class,$arguments) { - if(class_exists($class)) { - try { - return new $class($arguments); - } catch (Exception $exception) { - OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); - return false; - } - }else{ - OC_Log::write('core','storage backend '.$class.' not found',OC_Log::ERROR); - return false; - } - } - - /** - * change the root to a fake root - * @param string fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return self::$defaultInstance->chroot($fakeRoot); - } - - /** - * @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() { - self::$mounts=array(); - self::$storages=array(); - } - - /** - * mount an \OC\Files\Storage\Storage in our virtual filesystem - * @param \OC\Files\Storage\Storage storage - * @param string mountpoint - */ - static public function mount($class,$arguments,$mountpoint) { - if($mountpoint[0]!='/') { - $mountpoint='/'.$mountpoint; - } - if(substr($mountpoint,-1)!=='/') { - $mountpoint=$mountpoint.'/'; - } - self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments); - } - - /** - * 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) { - 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) { - $blacklist = array('.htaccess'); - if (isset($data['path'])) { - $path = $data['path']; - } else if (isset($data['newpath'])) { - $path = $data['newpath']; - } - if (isset($path)) { - $filename = strtolower(basename($path)); - if (in_array($filename, $blacklist)) { - $data['run'] = 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); - } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return self::$defaultInstance->is_readable($path); - } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return self::$defaultInstance->is_writable($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 filectime($path) { - return self::$defaultInstance->filectime($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 OC_FileCache::search($query); - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - static public function hasUpdated($path,$time) { - return self::$defaultInstance->hasUpdated($path,$time); - } - - static public function removeETagHook($params, $root = false) { - if (isset($params['path'])) { - $path=$params['path']; - } else { - $path=$params['oldpath']; - } - - if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); - $count = 1; - $path=str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); - } - - $path = self::normalizePath($path); - OC_Connector_Sabre_Node::removeETagPropertyForPath($path); - } - - /** - * normalize a 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 trainling slash - if($stripTrailingSlash and strlen($path)>1 and substr($path,-1,1)==='/') { - $path=substr($path,0,-1); - } - //remove duplicate slashes - while(strpos($path,'//')!==false) { - $path=str_replace('//','/',$path); - } - //normalize unicode if possible - if(class_exists('Normalizer')) { - $path=Normalizer::normalize($path); - } - return $path; - } -} -OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook'); -OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook'); -OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); -OC_Util::setupFS(); diff --git a/lib/filesystemview.php b/lib/filesystemview.php deleted file mode 100644 index 071fc781f12..00000000000 --- a/lib/filesystemview.php +++ /dev/null @@ -1,633 +0,0 @@ -. - */ - - -/** - * 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 - */ - -class OC_FilesystemView { - 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 toor - * @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 the part of the path relative to the mountpoint of the storage it's stored in - * @param string path - * @return bool - */ - public function getInternalPath($path) { - if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); - } - return $this->internal_path_cache[$path]; - } - - /** - * 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 storage object for a path - * @param string path - * @return \OC\Files\Storage\Storage - */ - public function getStorage($path) { - if (!isset($this->storage_cache[$path])) { - $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); - } - return $this->storage_cache[$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 OC_Filesystem::getMountPoint($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,'/')); - if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) { - return $storage->getLocalFile($this->getInternalPath($path)); - } - } - /** - * @param string path - * @return string - */ - public function getLocalFolder($path) { - $parent=substr($path, 0, strrpos($path,'/')); - if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) { - return $storage->getLocalFolder($this->getInternalPath($path)); - } - } - - /** - * 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 \OC\Files\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 MB chunks - while (!feof($handle)) { - echo fread($handle, $chunkSize); - flush(); - } - $size=$this->filesize($path); - return $size; - } - return false; - } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - public function is_readable($path) { - return $this->basicOperation('isReadable',$path); - } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - public function is_writable($path) { - return $this->basicOperation('isUpdatable',$path); - } - 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 filectime($path) { - return $this->basicOperation('filectime', $path); - } - public function filemtime($path) { - return $this->basicOperation('filemtime', $path); - } - public function touch($path, $mtime=null) { - return $this->basicOperation('touch', $path, array('write'), $mtime); - } - 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - $exists = $this->file_exists($path); - $run = true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - if(!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, - array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, - array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - if(!$run) { - return false; - } - $target=$this->fopen($path, 'w'); - if($target) { - $count=OC_Helper::streamCopy($data, $target); - fclose($target); - fclose($data); - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - if(!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array( OC_Filesystem::signal_param_path => $path) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path) - ); - } - OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); - return $count > 0; - }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->basicOperation( 'deleteAll', $directory, array('delete'), $empty ); - } - public function rename($path1, $path2) { - $postFix1=(substr($path1,-1,1)==='/')?'/':''; - $postFix2=(substr($path2,-1,1)==='/')?'/':''; - $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if($path1 == null or $path2 == null) { - return false; - } - $run=true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - if($run) { - $mp1 = $this->getMountPoint($path1.$postFix1); - $mp2 = $this->getMountPoint($path2.$postFix2); - if($mp1 == $mp2) { - if($storage = $this->getStorage($path1)) { - $result = $storage->rename($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); - } - } else { - $source = $this->fopen($path1.$postFix1, 'r'); - $target = $this->fopen($path2.$postFix2, 'w'); - $count = OC_Helper::streamCopy($source, $target); - $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1.$postFix1)); - $result = $count>0; - } - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_rename, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 - ) - ); - } - return $result; - } - } - } - public function copy($path1, $path2) { - $postFix1=(substr($path1,-1,1)==='/')?'/':''; - $postFix2=(substr($path2,-1,1)==='/')?'/':''; - $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if($path1 == null or $path2 == null) { - return false; - } - $run=true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_copy, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath=>$path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - $exists=$this->file_exists($path2); - if($run and !$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, - array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - if($run) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, - array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - } - if($run) { - $mp1=$this->getMountPoint($path1.$postFix1); - $mp2=$this->getMountPoint($path2.$postFix2); - if($mp1 == $mp2) { - if($storage = $this->getStorage($path1.$postFix1)) { - $result=$storage->copy($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); - } - } else { - $source = $this->fopen($path1.$postFix1, 'r'); - $target = $this->fopen($path2.$postFix2, 'w'); - $result = OC_Helper::streamCopy($source, $target); - } - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_copy, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath=>$path2 - ) - ); - if(!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path2) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path2) - ); - } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions - OC_FileCache_Update::update($path2, $this->fakeRoot); - OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); - } - return $result; - } - } - } - 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(OC_Filesystem::isValidPath($path)) { - $source = $this->fopen($path, 'r'); - if($source) { - $extension=''; - $extOffset=strpos($path, '.'); - if($extOffset !== false) { - $extension=substr($path, strrpos($path,'.')); - } - $tmpFile = OC_Helper::tmpFile($extension); - file_put_contents($tmpFile, $source); - return $tmpFile; - } - } - } - public function fromTmpFile($tmpFile, $path) { - if(OC_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 { - } - } 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - if ($path == null) { - return false; - } - if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_read, - array( OC_Filesystem::signal_param_path => $path) - ); - } - if ($storage = $this->getStorage($path.$postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path.$postFix), $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 (optional) hooks - * @param mixed (optional) $extraParam - * @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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - if($path == null) { - return false; - } - $internalPath = $this->getInternalPath($path.$postFix); - $run=$this->runHooks($hooks,$path); - if($run and $storage = $this->getStorage($path.$postFix)) { - if(!is_null($extraParam)) { - $result = $storage->$operation($internalPath, $extraParam); - } else { - $result = $storage->$operation($internalPath); - } - $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { - if($operation!='fopen') {//no post hooks for fopen, the file stream is still open - $this->runHooks($hooks,$path,true); - } - } - return $result; - } - } - return null; - } - - private function runHooks($hooks,$path,$post=false) { - $prefix=($post)?'post_':''; - $run=true; - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { - foreach($hooks as $hook) { - if($hook!='read') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $prefix.$hook, - array( - OC_Filesystem::signal_param_run => &$run, - OC_Filesystem::signal_param_path => $path - ) - ); - } elseif(!$post) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $prefix.$hook, - array( - OC_Filesystem::signal_param_path => $path - ) - ); - } - } - } - return $run; - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->basicOperation('hasUpdated', $path, array(), $time); - } -} -- cgit v1.2.3 From 07c53841899262fdd34304302ffaaf2704800c38 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:25:46 +0200 Subject: fix namespaces in filesystem and filesystemview --- lib/app.php | 6 +- lib/files/filesystem.php | 153 +++++++++++++++------------- lib/files/view.php | 260 ++++++++++++++++++++++++++--------------------- 3 files changed, 225 insertions(+), 194 deletions(-) (limited to 'lib/files') diff --git a/lib/app.php b/lib/app.php index 395230156f6..4d7353e99dc 100755 --- a/lib/app.php +++ b/lib/app.php @@ -714,16 +714,16 @@ class OC_App{ /** * @param string $appid - * @return OC_FilesystemView + * @return \OC\Files\View */ public static function getStorage($appid) { if(OC_App::isEnabled($appid)) {//sanity check if(OC_User::isLoggedIn()) { - $view = new OC_FilesystemView('/'.OC_User::getUser()); + $view = new \OC\Files\View('/'.OC_User::getUser()); if(!$view->file_exists($appid)) { $view->mkdir($appid); } - return new OC_FilesystemView('/'.OC_User::getUser().'/'.$appid); + return new \OC\Files\View('/'.OC_User::getUser().'/'.$appid); }else{ OC_Log::write('core', 'Can\'t get app storage, app, user not logged in', OC_Log::ERROR); return false; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d0a96b59a0e..f23f3a79e98 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -15,16 +15,16 @@ * read(path) * write(path, &run) * post_write(path) - * create(path, &run) (when a file is created, both create and write will be emited in that order) + * 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 emited in that order) + * 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) * - * the &run parameter can be set to false to prevent the operation from occuring + * the &run parameter can be set to false to prevent the operation from occurring */ namespace OC\Files; @@ -34,7 +34,7 @@ class Filesystem { static private $mounts = array(); public static $loaded = false; /** - * @var \OC\Files\Storage\Storage $defaultInstance + * @var \OC\Files\View $defaultInstance */ static private $defaultInstance; @@ -46,80 +46,80 @@ class Filesystem { const CLASSNAME = 'OC_Filesystem'; /** - * signalname emited before file renaming + * signalname emitted before file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_rename = 'rename'; /** - * signal emited after file renaming + * signal emitted after file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_post_rename = 'post_rename'; /** - * signal emited before file/dir creation + * signal emitted before file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @param string $path + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_create = 'create'; /** - * signal emited after file/dir creation + * signal emitted after file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @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 oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event + * @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 oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_post_copy = 'post_copy'; /** * signal emits before file/dir save * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @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 path + * @param string $path */ const signal_post_write = 'post_write'; /** * signal emits when reading file/dir * - * @param path + * @param string $path */ const signal_read = 'read'; /** * signal emits when removing file/dir * - * @param path + * @param string $path */ const signal_delete = 'delete'; @@ -139,11 +139,11 @@ class Filesystem { * 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 + * @param string $path * @return string */ static public function getMountPoint($path) { - OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); if (!$path) { $path = '/'; } @@ -152,7 +152,7 @@ class Filesystem { } $path = str_replace('//', '/', $path); $foundMountPoint = ''; - $mountPoints = array_keys(OC_Filesystem::$mounts); + $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { if ($mountpoint == $path) { return $mountpoint; @@ -167,7 +167,7 @@ class Filesystem { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @param string $path * @return bool */ static public function getInternalPath($path) { @@ -179,17 +179,19 @@ class Filesystem { /** * get the storage object for a path * - * @param string path + * @param string $path * @return \OC\Files\Storage\Storage */ static public function getStorage($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount = OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - return OC_Filesystem::$storages[$mountpoint]; + return self::$storages[$mountpoint]; + }else{ + return null; } } @@ -202,13 +204,15 @@ class Filesystem { static public function resolvePath($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount = OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - $storage = OC_Filesystem::$storages[$mountpoint]; + $storage = self::$storages[$mountpoint]; $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); + }else{ + return array(null, null); } } @@ -216,11 +220,11 @@ class Filesystem { if (self::$defaultInstance) { return false; } - self::$defaultInstance = new OC_FilesystemView($root); + self::$defaultInstance = new View($root); -//load custom mount config - if (is_file(OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = include(OC::$SERVERROOT . '/config/mount.php'); + //load custom mount config + if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -229,7 +233,7 @@ class Filesystem { if (isset($mountConfig['group'])) { foreach ($mountConfig['group'] as $group => $mounts) { - if (OC_Group::inGroup(OC_User::getUser(), $group)) { + if (\OC_Group::inGroup(\OC_User::getUser(), $group)) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -243,7 +247,7 @@ class Filesystem { if (isset($mountConfig['user'])) { foreach ($mountConfig['user'] as $user => $mounts) { - if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) { + if ($user === 'all' or strtolower($user) === strtolower(\OC_User::getUser())) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -257,22 +261,24 @@ class Filesystem { } self::$loaded = true; + + return true; } /** * fill in the correct values for $user, and $password placeholders * - * @param string intput + * @param string $input * @return string */ private static function setUserVars($input) { - return str_replace('$user', OC_User::getUser(), $input); + return str_replace('$user', \OC_User::getUser(), $input); } /** * get the default filesystem view * - * @return OC_FilesystemView + * @return View */ static public function getView() { return self::$defaultInstance; @@ -288,20 +294,20 @@ class Filesystem { /** * create a new storage of a specific type * - * @param string type - * @param array arguments + * @param string $type + * @param array $arguments * @return \OC\Files\Storage\Storage */ static private function createStorage($class, $arguments) { if (class_exists($class)) { try { return new $class($arguments); - } catch (Exception $exception) { - OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); + } catch (\Exception $exception) { + \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); return false; } } else { - OC_Log::write('core', 'storage backend ' . $class . ' not found', OC_Log::ERROR); + \OC_Log::write('core', 'storage backend ' . $class . ' not found', \OC_Log::ERROR); return false; } } @@ -309,7 +315,7 @@ class Filesystem { /** * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ static public function chroot($fakeRoot) { @@ -337,8 +343,9 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage storage - * @param string mountpoint + * @param \OC\Files\Storage\Storage $storage + * @param array $arguments + * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { if ($mountpoint[0] != '/') { @@ -354,7 +361,7 @@ class Filesystem { * 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 + * @param string $path * @return string */ static public function getLocalFile($path) { @@ -362,7 +369,7 @@ class Filesystem { } /** - * @param string path + * @param string $path * @return string */ static public function getLocalFolder($path) { @@ -372,11 +379,11 @@ class Filesystem { /** * return path to file which reflects one visible in browser * - * @param string path + * @param string $path * @return string */ static public function getLocalPath($path) { - $datadir = OC_User::getHome(OC_User::getUser()) . '/files'; + $datadir = \OC_User::getHome(\OC_User::getUser()) . '/files'; $newpath = $path; if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { $newpath = substr($path, strlen($datadir)); @@ -387,7 +394,7 @@ class Filesystem { /** * check if the requested path is valid * - * @param string path + * @param string $path * @return bool */ static public function isValidPath($path) { @@ -468,7 +475,7 @@ class Filesystem { * @deprecated Replaced by isReadable() as part of CRUDS */ static public function is_readable($path) { - return self::$defaultInstance->is_readable($path); + return self::$defaultInstance->isReadable($path); } /** @@ -559,7 +566,7 @@ class Filesystem { } static public function search($query) { - return OC_FileCache::search($query); + return Cache\Cache::search($query); } /** @@ -580,19 +587,19 @@ class Filesystem { } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); - OC_Connector_Sabre_Node::removeETagPropertyForPath($path); + \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); } /** * normalize a path * - * @param string path + * @param string $path * @param bool $stripTrailingSlash * @return string */ @@ -606,7 +613,7 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trainling slash +//remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } @@ -616,14 +623,14 @@ class Filesystem { } //normalize unicode if possible if (class_exists('Normalizer')) { - $path = Normalizer::normalize($path); + $path = \Normalizer::normalize($path); } return $path; } } -OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); -OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); -OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); -OC_Util::setupFS(); +\OC_Util::setupFS(); diff --git a/lib/files/view.php b/lib/files/view.php index 8c3f288f445..230455479cf 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -45,9 +45,9 @@ class View { } /** - * change the root to a fake toor + * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ public function chroot($fakeRoot) { @@ -71,12 +71,12 @@ class View { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @param string $path * @return bool */ public function getInternalPath($path) { if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); + $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); } return $this->internal_path_cache[$path]; } @@ -84,7 +84,7 @@ class View { /** * get path relative to the root of the view * - * @param string path + * @param string $path * @return string */ public function getRelativePath($path) { @@ -106,12 +106,12 @@ class View { /** * get the storage object for a path * - * @param string path + * @param string $path * @return \OC\Files\Storage\Storage */ public function getStorage($path) { if (!isset($this->storage_cache[$path])) { - $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); + $this->storage_cache[$path] = Filesystem::getStorage($this->getAbsolutePath($path)); } return $this->storage_cache[$path]; } @@ -120,35 +120,39 @@ class View { * 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 + * @param string $path * @return string */ public function getMountPoint($path) { - return OC_Filesystem::getMountPoint($this->getAbsolutePath($path)); + return Filesystem::getMountPoint($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 + * @param string $path * @return string */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFile($this->getInternalPath($path)); + } else { + return null; } } /** - * @param string path + * @param string $path * @return string */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFolder($this->getInternalPath($path)); + } else { + return null; } } @@ -274,28 +278,28 @@ class View { 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + if (\OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); $exists = $this->file_exists($path); $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } @@ -304,28 +308,30 @@ class View { } $target = $this->fopen($path, 'w'); if ($target) { - $count = OC_Helper::streamCopy($data, $target); + $count = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_Filesystem::signal_param_path => $path) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + array(Filesystem::signal_param_path => $path) ); } - OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); + \OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); return $count > 0; } else { return false; } + } else { + return false; } } else { return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); @@ -343,9 +349,9 @@ class View { public function rename($path1, $path2) { $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; - $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if (OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (\OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); @@ -353,13 +359,13 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, Filesystem::signal_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -369,36 +375,42 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1)) { $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $count = OC_Helper::streamCopy($source, $target); + $count = \OC_Helper::streamCopy($source, $target); $storage1 = $this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1 . $postFix1)); $result = $count > 0; } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if (OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (\OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); @@ -406,34 +418,34 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_copy, + $exists = $this->file_exists($path2); + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); - $exists = $this->file_exists($path2); if ($run and !$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } if ($run) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -444,39 +456,45 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1 . $postFix1)) { $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $result = OC_Helper::streamCopy($source, $target); + $result = \OC_Helper::streamCopy($source, $target); } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_copy, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2 ) ); if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path2) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + array(Filesystem::signal_param_path => $path2) ); } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions - OC_FileCache_Update::update($path2, $this->fakeRoot); - OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); +// OC_FileCache_Update::update($path2, $this->fakeRoot); + Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; + } else { + return false; } + } else { + return false; } } @@ -507,14 +525,14 @@ class View { $hooks[] = 'write'; break; default: - OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, OC_Log::ERROR); + \OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, \OC_Log::ERROR); } return $this->basicOperation('fopen', $path, $hooks, $mode); } public function toTmpFile($path) { - if (OC_Filesystem::isValidPath($path)) { + if (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); if ($source) { $extension = ''; @@ -522,15 +540,19 @@ class View { if ($extOffset !== false) { $extension = substr($path, strrpos($path, '.')); } - $tmpFile = OC_Helper::tmpFile($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 (OC_Filesystem::isValidPath($path)) { + if (Filesystem::isValidPath($path)) { if (!$tmpFile) { debug_print_backtrace(); } @@ -540,6 +562,7 @@ class View { unlink($tmpFile); return true; } else { + return false; } } else { return false; @@ -552,22 +575,22 @@ class View { public function hash($type, $path, $raw = false) { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $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 (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_read, - array(OC_Filesystem::signal_param_path => $path) + if (Filesystem::$loaded && $this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_read, + array(Filesystem::signal_param_path => $path) ); } if ($storage = $this->getStorage($path . $postFix)) { $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); - $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); + $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } } @@ -581,9 +604,9 @@ class View { /** * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation - * @param string #path - * @param array (optional) hooks - * @param mixed (optional) $extraParam + * @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 @@ -592,8 +615,8 @@ class View { */ private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if ($path == null) { return false; @@ -606,8 +629,8 @@ class View { } else { $result = $storage->$operation($internalPath); } - $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open $this->runHooks($hooks, $path, true); } @@ -621,23 +644,23 @@ class View { private function runHooks($hooks, $path, $post = false) { $prefix = ($post) ? 'post_' : ''; $run = true; - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { foreach ($hooks as $hook) { if ($hook != 'read') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_run => &$run, - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_run => &$run, + Filesystem::signal_param_path => $path ) ); } elseif (!$post) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_path => $path ) ); } @@ -649,6 +672,7 @@ class View { /** * check if a file or folder has been updated since $time * + * @param string $path * @param int $time * @return bool */ -- cgit v1.2.3 From aaa1b733642c41821a53bc6d04fab246bfe7f1e6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 13:18:36 +0200 Subject: don't use depricated OC_Filesystem --- apps/files/ajax/autocomplete.php | 6 +-- apps/files/ajax/newfile.php | 6 +-- apps/files/ajax/upload.php | 4 +- apps/files/appinfo/filesync.php | 4 +- apps/files/download.php | 8 +-- apps/files/index.php | 14 +++--- apps/files_encryption/lib/crypt.php | 6 +-- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 6 +-- apps/files_encryption/tests/proxy.php | 30 +++++------ apps/files_external/ajax/addRootCertificate.php | 12 ++--- apps/files_external/lib/config.php | 12 ++--- apps/files_sharing/lib/sharedstorage.php | 66 ++++++++++++------------- apps/files_sharing/public.php | 8 +-- apps/files_versions/lib/hooks.php | 4 +- apps/files_versions/lib/versions.php | 16 +++--- lib/connector/sabre/directory.php | 10 ++-- lib/connector/sabre/file.php | 10 ++-- lib/connector/sabre/node.php | 8 +-- lib/filechunking.php | 38 +++++++------- lib/fileproxy/quota.php | 2 +- lib/files.php | 54 ++++++++++---------- lib/files/file.php | 2 +- lib/helper.php | 2 +- lib/image.php | 2 +- lib/ocs.php | 4 +- lib/public/files.php | 2 +- lib/public/share.php | 6 +-- lib/util.php | 10 ++-- settings/personal.php | 2 +- tests/lib/cache/file.php | 4 +- tests/lib/filesystem.php | 56 +++++++++++---------- 32 files changed, 209 insertions(+), 207 deletions(-) (limited to 'lib/files') diff --git a/apps/files/ajax/autocomplete.php b/apps/files/ajax/autocomplete.php index fae38368a85..d0dab9c2bd7 100644 --- a/apps/files/ajax/autocomplete.php +++ b/apps/files/ajax/autocomplete.php @@ -33,8 +33,8 @@ $query=strtolower($query); $files=array(); -if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { - $dh = OC_Filesystem::opendir($base); +if(\OC\Files\Filesystem::file_exists($base) and \OC\Files\Filesystem::is_dir($base)) { + $dh = \OC\Files\Filesystem::opendir($base); if($dh) { if(substr($base, -1, 1)!='/') { $base=$base.'/'; @@ -43,7 +43,7 @@ if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { if ($file != "." && $file != "..") { if(substr(strtolower($file), 0, $queryLen)==$query) { $item=$base.$file; - if((!$dirOnly or OC_Filesystem::is_dir($item))) { + if((!$dirOnly or \OC\Files\Filesystem::is_dir($item))) { $files[]=(object)array('id'=>$item,'label'=>$item,'name'=>$item); } } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 77d866979c3..4d73970b68d 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -63,12 +63,12 @@ if($source) { $ctx = stream_context_create(null, array('notification' =>'progress')); $sourceStream=fopen($source, 'rb', false, $ctx); $target=$dir.'/'.$filename; - $result=OC_Filesystem::file_put_contents($target, $sourceStream); + $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); if($result) { $meta = OC_FileCache::get($target); $mime=$meta['mimetype']; $id = OC_FileCache::getId($target); - $eventSource->send('success', array('mime'=>$mime, 'size'=>OC_Filesystem::filesize($target), 'id' => $id)); + $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); } else { $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); } @@ -76,7 +76,7 @@ if($source) { exit(); } else { if($content) { - if(OC_Filesystem::file_put_contents($dir.'/'.$filename, $content)) { + if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { $meta = OC_FileCache::get($dir.'/'.$filename); $id = OC_FileCache::getId($dir.'/'.$filename); OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index a4dcd80a2e2..8bf7f10e18b 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -38,7 +38,7 @@ $totalSize=0; foreach($files['size'] as $size) { $totalSize+=$size; } -if($totalSize>OC_Filesystem::free_space('/')) { +if($totalSize>\OC\Files\Filesystem::free_space('/')) { OCP\JSON::error(array("data" => array( "message" => "Not enough space available" ))); exit(); } @@ -48,7 +48,7 @@ if(strpos($dir, '..') === false) { $fileCount=count($files['name']); for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); - if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { + if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { $meta = OC_FileCache::get($target); $id = OC_FileCache::getId($target); $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); diff --git a/apps/files/appinfo/filesync.php b/apps/files/appinfo/filesync.php index c1fe444cec7..e755771de64 100644 --- a/apps/files/appinfo/filesync.php +++ b/apps/files/appinfo/filesync.php @@ -43,7 +43,7 @@ if ($type != 'oc_chunked') { die; } -if (!OC_Filesystem::is_file($file)) { +if (!\OC\Files\Filesystem::is_file($file)) { OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND); die; } @@ -51,7 +51,7 @@ if (!OC_Filesystem::is_file($file)) { switch($_SERVER['REQUEST_METHOD']) { case 'PUT': $input = fopen("php://input", "r"); - $org_file = OC_Filesystem::fopen($file, 'rb'); + $org_file = \OC\Files\Filesystem::fopen($file, 'rb'); $info = array( 'name' => basename($file), ); diff --git a/apps/files/download.php b/apps/files/download.php index ff6aefbbe0f..b00a50a0452 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -29,7 +29,7 @@ OCP\User::checkLoggedIn(); $filename = $_GET["file"]; -if(!OC_Filesystem::file_exists($filename)) { +if(!\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OCP\Template( '', '404', 'guest' ); $tmpl->assign('file',$filename); @@ -37,12 +37,12 @@ if(!OC_Filesystem::file_exists($filename)) { exit; } -$ftype=OC_Filesystem::getMimeType( $filename ); +$ftype=\OC\Files\Filesystem::getMimeType( $filename ); header('Content-Type:'.$ftype); header('Content-Disposition: attachment; filename="'.basename($filename).'"'); OCP\Response::disableCaching(); -header('Content-Length: '.OC_Filesystem::filesize($filename)); +header('Content-Length: '.\OC\Files\Filesystem::filesize($filename)); @ob_end_clean(); -OC_Filesystem::readfile( $filename ); +\OC\Files\Filesystem::readfile( $filename ); diff --git a/apps/files/index.php b/apps/files/index.php index 493087d26f1..b02aaf81c0f 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -38,7 +38,7 @@ OCP\App::setActiveNavigationEntry( 'files_index' ); // Load the files $dir = isset( $_GET['dir'] ) ? stripslashes($_GET['dir']) : ''; // Redirect if directory does not exist -if(!OC_Filesystem::is_dir($dir.'/')) { +if(!\OC\Files\Filesystem::is_dir($dir.'/')) { header('Location: '.$_SERVER['SCRIPT_NAME'].''); exit(); } @@ -85,26 +85,26 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace=OC_Filesystem::free_space('/'); +$freeSpace=\OC\Files\Filesystem::free_space('/'); $freeSpace=max($freeSpace,0); $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $permissions = OCP\Share::PERMISSION_READ; -if (OC_Filesystem::isUpdatable($dir.'/')) { +if (\OC\Files\Filesystem::isUpdatable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_UPDATE; } -if (OC_Filesystem::isDeletable($dir.'/')) { +if (\OC\Files\Filesystem::isDeletable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_DELETE; } -if (OC_Filesystem::isSharable($dir.'/')) { +if (\OC\Files\Filesystem::isSharable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_SHARE; } $tmpl = new OCP\Template( 'files', 'index', 'user' ); $tmpl->assign( 'fileList', $list->fetchPage(), false ); $tmpl->assign( 'breadcrumb', $breadcrumbNav->fetchPage(), false ); -$tmpl->assign( 'dir', OC_Filesystem::normalizePath($dir)); -$tmpl->assign( 'isCreatable', OC_Filesystem::isCreatable($dir.'/')); +$tmpl->assign( 'dir', \OC\Files\Filesystem::normalizePath($dir)); +$tmpl->assign( 'isCreatable', \OC\Files\Filesystem::isCreatable($dir.'/')); $tmpl->assign('permissions', $permissions); $tmpl->assign( 'files', $files ); $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize); diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 38d8edf28c3..6bee8accf71 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -44,7 +44,7 @@ class OC_Crypt { } public static function init($login,$password) { - $view=new OC_FilesystemView('/'); + $view=new \OC\Files\View('/'); if(!$view->file_exists('/'.$login)) { $view->mkdir('/'.$login); } @@ -90,7 +90,7 @@ class OC_Crypt { // Write the file $proxyEnabled=OC_FileProxy::$enabled; OC_FileProxy::$enabled=false; - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); $view->file_put_contents('/encryption.key',$enckey); OC_FileProxy::$enabled=$proxyEnabled; } @@ -98,7 +98,7 @@ class OC_Crypt { public static function changekeypasscode($oldPassword, $newPassword) { if(OCP\User::isLoggedIn()) { $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); // read old key $key=$view->file_get_contents('/encryption.key'); diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index 721a1b955df..89a071327ad 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -38,7 +38,7 @@ class OC_CryptStream{ public function stream_open($path, $mode, $options, &$opened_path) { if(!self::$rootView) { - self::$rootView=new OC_FilesystemView(''); + self::$rootView=new \OC\Files\View(''); } $path=str_replace('crypt://','',$path); if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])) { diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index f61cd1e3773..27abe3bb19e 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -90,13 +90,13 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ fclose($result); $result=fopen('crypt://'.$path,$meta['mode']); }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb') { - if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0) { + if(\OC\Files\Filesystem::file_exists($path) and \OC\Files\Filesystem::filesize($path)>0) { //first encrypt the target file so we don't end up with a half encrypted file OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing',OCP\Util::DEBUG); - $tmp=fopen('php://temp'); + $tmp=fopen('php://temp', 'w+'); OCP\Files::streamCopy($result,$tmp); fclose($result); - OC_Filesystem::file_put_contents($path,$tmp); + \OC\Files\Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index d600bbc4071..c04e0e5c4fc 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -29,13 +29,13 @@ class Test_CryptProxy extends UnitTestCase { OC_FileProxy::register(new OC_FileProxy_Encryption()); //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); - OC_Filesystem::init('/'.$user.'/files'); + \OC\Files\Filesystem::init('/'.$user.'/files'); //set up the users home folder in the temp storage - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); } @@ -51,13 +51,13 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -68,8 +68,8 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - $rootView=new OC_FilesystemView(''); - $view=new OC_FilesystemView('/'.OC_User::getUser()); + $rootView=new \OC\Files\View(''); + $view=new \OC\Files\View('/'.OC_User::getUser()); $userDir='/'.OC_User::getUser().'/files'; $rootView->file_put_contents($userDir.'/file',$original); @@ -90,13 +90,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/binary'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -104,13 +104,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/zeros'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); } diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php index e0a0239c954..6fef9aac1ed 100644 --- a/apps/files_external/ajax/addRootCertificate.php +++ b/apps/files_external/ajax/addRootCertificate.php @@ -3,23 +3,23 @@ OCP\JSON::checkAppEnabled('files_external'); if ( !($filename = $_FILES['rootcert_import']['name']) ) { - header("Location: settings/personal.php"); + header("Location: settings/personal.php"); exit; } -$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); -$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); +$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); +$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); fclose($fh); $filename = $_FILES['rootcert_import']['name']; - -$view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_external/uploads'); + +$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files_external/uploads'); if (!$view->file_exists('')) $view->mkdir(''); $isValid = openssl_pkey_get_public($data); //maybe it was just the wrong file format, try to convert it... if ($isValid == false) { - $data = chunk_split(base64_encode($data), 64, "\n"); + $data = chunk_split(base64_encode($data), 64, "\n"); $data = "-----BEGIN CERTIFICATE-----\n".$data."-----END CERTIFICATE-----\n"; $isValid = openssl_pkey_get_public($data); } diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index cb32fed2032..7be23360199 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -109,10 +109,10 @@ class OC_Mount_Config { return $personal; } - /** - * Add directory for mount point to the filesystem - * @param OC_Fileview instance $view - * @param string path to mount point + /** + * Add directory for mount point to the filesystem + * @param OC_Fileview instance $view + * @param string path to mount point */ private static function addMountPointDirectory($view, $path) { $dir = ''; @@ -142,11 +142,11 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } - $view = new OC_FilesystemView('/'.OCP\User::getUser().'/files'); + $view = new \OC\Files\View('/'.OCP\User::getUser().'/files'); self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { - $view = new OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); switch ($mountType) { case 'user': if ($applicable == "all") { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 876e719956f..e17c4b6e043 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -80,7 +80,7 @@ class Shared extends \OC\Files\Storage\Common { $file = $this->getFile($target); if (isset($file['path'])) { $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - \OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); + \\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -105,7 +105,7 @@ class Shared extends \OC\Files\Storage\Common { * @return Source file path with mount point stripped out */ private function getInternalPath($path) { - $mountPoint = \OC_Filesystem::getMountPoint($path); + $mountPoint = \OC\Files\Filesystem::getMountPoint($path); $internalPath = substr($path, strlen($mountPoint)); return $internalPath; } @@ -114,7 +114,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } return false; @@ -122,7 +122,7 @@ class Shared extends \OC\Files\Storage\Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->rmdir($this->getInternalPath($source)); } return false; @@ -130,11 +130,11 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { - $files = OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); + $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->opendir($this->getInternalPath($source)); } return false; @@ -144,7 +144,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } return false; @@ -152,7 +152,7 @@ class Shared extends \OC\Files\Storage\Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } return false; @@ -165,7 +165,7 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } return false; @@ -175,7 +175,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); } return false; @@ -185,7 +185,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); } return false; @@ -195,7 +195,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_CREATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_CREATE); } public function isReadable($path) { @@ -206,28 +206,28 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_UPDATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_UPDATE); } public function isDeletable($path) { if ($path == '') { return true; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_DELETE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_DELETE); } public function isSharable($path) { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_SHARE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_SHARE); } public function file_exists($path) { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); } return false; @@ -248,7 +248,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); } } @@ -269,7 +269,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); } } @@ -282,8 +282,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_get_contents($this->getInternalPath($source)); } } @@ -298,8 +298,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); $result = $storage->file_put_contents($this->getInternalPath($source), $data); return $result; } @@ -310,7 +310,7 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->unlink($this->getInternalPath($source)); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -319,7 +319,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $itemType = 'file'; } - return OCP\Share::unshareFromSelf($itemType, $path); + return \OCP\Share::unshareFromSelf($itemType, $path); } } return false; @@ -334,7 +334,7 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } else { @@ -349,7 +349,7 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } @@ -394,8 +394,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, 'mode' => $mode, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->fopen($this->getInternalPath($source), $mode); } return false; @@ -406,7 +406,7 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); } return false; @@ -415,21 +415,21 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source), $mtime); } return false; @@ -437,7 +437,7 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { $user_dir = $options['user_dir']; - \OC_Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 34340102a9e..c5f4b39d704 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -73,7 +73,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { if (isset($_GET['path'])) { $path .= $_GET['path']; $dir .= $_GET['path']; - if (!OC_Filesystem::file_exists($path)) { + if (!\OC\Files\Filesystem::file_exists($path)) { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -101,7 +101,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('owner', $uidOwner); // Show file list - if (OC_Filesystem::is_dir($path)) { + if (\OC\Files\Filesystem::is_dir($path)) { OCP\Util::addStyle('files', 'files'); OCP\Util::addScript('files', 'files'); OCP\Util::addScript('files', 'filelist'); @@ -157,7 +157,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', basename($dir)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); if (isset($_GET['path'])) { $getPath = $_GET['path']; @@ -170,7 +170,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', dirname($path)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); if ($type == 'file') { $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.$_GET['file'].'&download'); } else { diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php index 9ec0b01a7f9..7cb3170df23 100644 --- a/apps/files_versions/lib/hooks.php +++ b/apps/files_versions/lib/hooks.php @@ -21,9 +21,9 @@ class Hooks { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - $versions = new Storage( new \OC_FilesystemView('') ); + $versions = new Storage( new \OC\Files\View('') ); - $path = $params[\OC_Filesystem::signal_param_path]; + $path = $params[\OC\Files\Filesystem::signal_param_path]; if($path<>'') $versions->store( $path ); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 7d12e58f941..7f7837a7425 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -58,8 +58,8 @@ class Storage { public function store($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $files_view = new \OC_FilesystemView('/'.$uid.'/files'); - $users_view = new \OC_FilesystemView('/'.$uid); + $files_view = new \OC\Files\View('/'.$uid.'/files'); + $users_view = new \OC\Files\View('/'.$uid); //check if source file already exist as version to avoid recursions. // todo does this check work? @@ -94,7 +94,7 @@ class Storage { // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $matches=glob($versionsFolderName.'/'.$filename.'.v*'); sort($matches); @@ -127,7 +127,7 @@ class Storage { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $users_view = new \OC_FilesystemView('/'.$uid); + $users_view = new \OC\Files\View('/'.$uid); // rollback if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) { @@ -150,7 +150,7 @@ class Storage { public static function isversioned($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); @@ -178,7 +178,7 @@ class Storage { if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $versions = array(); @@ -190,7 +190,7 @@ class Storage { $i = 0; - $files_view = new \OC_FilesystemView('/'.$uid.'/files'); + $files_view = new \OC\Files\View('/'.$uid.'/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { @@ -245,7 +245,7 @@ class Storage { public static function expire($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 413efef73b7..4fff3ba51b8 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -62,7 +62,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } } else { $newPath = $this->path . '/' . $name; - OC_Filesystem::file_put_contents($newPath, $data); + \OC\Files\Filesystem::file_put_contents($newPath, $data); return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } @@ -78,7 +78,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa public function createDirectory($name) { $newPath = $this->path . '/' . $name; - OC_Filesystem::mkdir($newPath); + \OC\Files\Filesystem::mkdir($newPath); } @@ -154,7 +154,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa public function childExists($name) { $path = $this->path . '/' . $name; - return OC_Filesystem::file_exists($path); + return \OC\Files\Filesystem::file_exists($path); } @@ -167,7 +167,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa if ($this->path != "/Shared") { foreach($this->getChildren() as $child) $child->delete(); - OC_Filesystem::rmdir($this->path); + \OC\Files\Filesystem::rmdir($this->path); } } @@ -181,7 +181,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $rootInfo=OC_FileCache_Cached::get(''); return array( $rootInfo['size'], - OC_Filesystem::free_space() + \OC\Files\Filesystem::free_space() ); } diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 5bd38240d44..1770b491280 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -45,7 +45,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function put($data) { - OC_Filesystem::file_put_contents($this->path,$data); + \OC\Files\Filesystem::file_put_contents($this->path,$data); return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); } @@ -57,7 +57,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - return OC_Filesystem::fopen($this->path,'rb'); + return \OC\Files\Filesystem::fopen($this->path,'rb'); } @@ -68,7 +68,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function delete() { - OC_Filesystem::unlink($this->path); + \OC\Files\Filesystem::unlink($this->path); } @@ -107,7 +107,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @return string|null Returns null if the ETag can not effectively be determined */ static protected function createETag($path) { - return OC_Filesystem::hash('md5', $path); + return \OC\Files\Filesystem::hash('md5', $path); } /** @@ -122,7 +122,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D return $this->fileinfo_cache['mimetype']; } - return OC_Filesystem::getMimeType($this->path); + return \OC\Files\Filesystem::getMimeType($this->path); } } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 72de9723774..e7e83507ea2 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -80,7 +80,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr $newPath = $parentPath . '/' . $newName; $oldPath = $this->path; - OC_Filesystem::rename($this->path,$newPath); + \OC\Files\Filesystem::rename($this->path,$newPath); $this->path = $newPath; @@ -99,9 +99,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ protected function getFileinfoCache() { if (!isset($this->fileinfo_cache)) { - if ($fileinfo_cache = OC_FileCache::get($this->path)) { + if ($fileinfo_cache = \OC\Files\Filesystem::get($this->path)) { } else { - $fileinfo_cache = OC_Filesystem::stat($this->path); + $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } $this->fileinfo_cache = $fileinfo_cache; @@ -130,7 +130,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * Even if the modification time is set to a custom value the access time is set to now. */ public function touch($mtime) { - OC_Filesystem::touch($this->path, $mtime); + \OC\Files\Filesystem::touch($this->path, $mtime); } /** diff --git a/lib/filechunking.php b/lib/filechunking.php index 5ab33c77ad7..e616e3b12d8 100644 --- a/lib/filechunking.php +++ b/lib/filechunking.php @@ -94,49 +94,49 @@ class OC_FileChunking { } public function file_assemble($path) { - $absolutePath = OC_Filesystem::normalizePath(OC_Filesystem::getView()->getAbsolutePath($path)); + $absolutePath = \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getView()->getAbsolutePath($path)); $data = ''; // use file_put_contents as method because that best matches what this function does - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { - $path = OC_Filesystem::getView()->getRelativePath($absolutePath); - $exists = OC_Filesystem::file_exists($path); + if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && \OC\Files\Filesystem::isValidPath($path)) { + $path = \OC\Files\Filesystem::getView()->getRelativePath($absolutePath); + $exists = \OC\Files\Filesystem::file_exists($path); $run = true; if(!$exists) { OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + \OC\Files\Filesystem::signal_param_path => $path, + \OC\Files\Filesystem::signal_param_run => &$run ) ); } OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + \OC\Files\Filesystem::signal_param_path => $path, + \OC\Files\Filesystem::signal_param_run => &$run ) ); if(!$run) { return false; } - $target = OC_Filesystem::fopen($path, 'w'); + $target = \OC\Files\Filesystem::fopen($path, 'w'); if($target) { $count = $this->assemble($target); fclose($target); if(!$exists) { OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array( OC_Filesystem::signal_param_path => $path) + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_post_create, + array( \OC\Files\Filesystem::signal_param_path => $path) ); } OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path) + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_post_write, + array( \OC\Files\Filesystem::signal_param_path => $path) ); OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); return $count > 0; diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 5a0dbdb6fe2..bc5ef9c8df4 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -88,7 +88,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ public function preCopy($path1,$path2) { if(!self::$rootView){ - self::$rootView = new OC_FilesystemView(''); + self::$rootView = new \OC\Files\View(''); } return (self::$rootView->filesize($path1)<$this->getFreeSpace() or $this->getFreeSpace()==0); } diff --git a/lib/files.php b/lib/files.php index 2b2b8b42dc4..29322cf2d06 100644 --- a/lib/files.php +++ b/lib/files.php @@ -46,10 +46,10 @@ class OC_Files { if ($path == '/Shared') { list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); }else{ - $info['size'] = OC_Filesystem::filesize($path); - $info['mtime'] = OC_Filesystem::filemtime($path); - $info['ctime'] = OC_Filesystem::filectime($path); - $info['mimetype'] = OC_Filesystem::getMimeType($path); + $info['size'] = \OC\Files\Filesystem::filesize($path); + $info['mtime'] = \OC\Files\Filesystem::filemtime($path); + $info['ctime'] = \OC\Files\Filesystem::filectime($path); + $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); $info['encrypted'] = false; $info['versioned'] = false; } @@ -64,7 +64,7 @@ class OC_Files { * @param dir $directory path under datadirectory */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=OC_Filesystem::normalizePath($directory); + $directory=\OC\Files\Filesystem::normalizePath($directory); if($directory=='/') { $directory=''; } @@ -151,17 +151,17 @@ class OC_Files { } foreach($files as $file) { $file=$dir.'/'.$file; - if(OC_Filesystem::is_file($file)) { - $tmpFile=OC_Filesystem::toTmpFile($file); + if(\OC\Files\Filesystem::is_file($file)) { + $tmpFile=OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); self::$tmpFiles[]=$tmpFile; $zip->addFile($tmpFile,basename($file)); - }elseif(OC_Filesystem::is_dir($file)) { + }elseif(\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file,$zip); } } $zip->close(); set_time_limit($executionTime); - }elseif(OC_Filesystem::is_dir($dir.'/'.$files)) { + }elseif(\OC\Files\Filesystem::is_dir($dir.'/'.$files)) { self::validateZipDownload($dir,$files); $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); @@ -179,7 +179,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or OC_Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::is_readable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); @@ -188,9 +188,9 @@ class OC_Files { header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); }else{ - header('Content-Type: '.OC_Filesystem::getMimeType($filename)); + header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); } - }elseif($zip or !OC_Filesystem::file_exists($filename)) { + }elseif($zip or !\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OC_Template( '', '404', 'guest' ); $tmpl->assign('file',$filename); @@ -201,7 +201,7 @@ class OC_Files { } if($only_header) { if(!$zip) - header("Content-Length: ".OC_Filesystem::filesize($filename)); + header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); return ; } if($zip) { @@ -215,7 +215,7 @@ class OC_Files { } unlink($filename); }else{ - OC_Filesystem::readfile($filename); + \OC\Files\Filesystem::readfile($filename); } foreach(self::$tmpFiles as $tmpFile) { if(file_exists($tmpFile) and is_file($tmpFile)) { @@ -232,11 +232,11 @@ class OC_Files { foreach($files as $file) { $filename=$file['name']; $file=$dir.'/'.$filename; - if(OC_Filesystem::is_file($file)) { - $tmpFile=OC_Filesystem::toTmpFile($file); + if(\OC\Files\Filesystem::is_file($file)) { + $tmpFile=\OC\Files\Filesystem::toTmpFile($file); OC_Files::$tmpFiles[]=$tmpFile; $zip->addFile($tmpFile,$internalDir.$filename); - }elseif(OC_Filesystem::is_dir($file)) { + }elseif(\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file,$zip,$internalDir); } } @@ -253,7 +253,7 @@ class OC_Files { if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { $targetFile=self::normalizePath($targetDir.'/'.$target); $sourceFile=self::normalizePath($sourceDir.'/'.$source); - return OC_Filesystem::rename($sourceFile,$targetFile); + return \OC\Files\Filesystem::rename($sourceFile,$targetFile); } else { return false; } @@ -271,7 +271,7 @@ class OC_Files { if(OC_User::isLoggedIn()) { $targetFile=$targetDir.'/'.$target; $sourceFile=$sourceDir.'/'.$source; - return OC_Filesystem::copy($sourceFile,$targetFile); + return \OC\Files\Filesystem::copy($sourceFile,$targetFile); } } @@ -286,9 +286,9 @@ class OC_Files { if(OC_User::isLoggedIn()) { $file=$dir.'/'.$name; if($type=='dir') { - return OC_Filesystem::mkdir($file); + return \OC\Files\Filesystem::mkdir($file); }elseif($type=='file') { - $fileHandle=OC_Filesystem::fopen($file, 'w'); + $fileHandle=\OC\Files\Filesystem::fopen($file, 'w'); if($fileHandle) { fclose($fileHandle); return true; @@ -308,7 +308,7 @@ class OC_Files { public static function delete($dir,$file) { if(OC_User::isLoggedIn() && ($dir!= '' || $file != 'Shared')) { $file=$dir.'/'.$file; - return OC_Filesystem::unlink($file); + return \OC\Files\Filesystem::unlink($file); } } @@ -339,10 +339,10 @@ class OC_Files { $totalsize = 0; if(is_array($files)) { foreach($files as $file) { - $totalsize += OC_Filesystem::filesize($dir.'/'.$file); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$file); } }else{ - $totalsize += OC_Filesystem::filesize($dir.'/'.$files); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$files); } if($totalsize > $zipLimit) { $l = OC_L10N::get('lib'); @@ -368,7 +368,7 @@ class OC_Files { * @return string guessed mime type */ static function getMimeType($path) { - return OC_Filesystem::getMimeType($path); + return \OC\Files\Filesystem::getMimeType($path); } /** @@ -378,7 +378,7 @@ class OC_Files { * @return array */ static function getTree($path) { - return OC_Filesystem::getTree($path); + return \OC\Files\Filesystem::getTree($path); } /** @@ -402,7 +402,7 @@ class OC_Files { $httpCode=$info['http_code']; curl_close($ch); if($httpCode==200 or $httpCode==0) { - OC_Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); + \OC\Files\Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); return true; }else{ return false; diff --git a/lib/files/file.php b/lib/files/file.php index b6432e63458..0d33cea7ee7 100644 --- a/lib/files/file.php +++ b/lib/files/file.php @@ -30,7 +30,7 @@ class File{ public static function resolve($fullPath){ $storage = null; $internalPath = ''; - list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); return new File($storage, $internalPath); } diff --git a/lib/helper.php b/lib/helper.php index 908a61b5a2d..48e16cebd00 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -560,7 +560,7 @@ class OC_Helper { $newpath = $path . '/' . $filename; $counter = 2; - while (OC_Filesystem::file_exists($newpath)) { + while (\OC\Files\Filesystem::file_exists($newpath)) { $newname = $name . ' (' . $counter . ')' . $ext; $newpath = $path . '/' . $newname; $counter++; diff --git a/lib/image.php b/lib/image.php index 861353e039d..94fe3ce827a 100644 --- a/lib/image.php +++ b/lib/image.php @@ -470,7 +470,7 @@ class OC_Image { default: // this is mostly file created from encrypted file - $this->resource = imagecreatefromstring(\OC_Filesystem::file_get_contents(\OC_Filesystem::getLocalPath($imagepath))); + $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagepath))); $itype = IMAGETYPE_PNG; OC_Log::write('core','OC_Image->loadFromFile, Default', OC_Log::DEBUG); break; diff --git a/lib/ocs.php b/lib/ocs.php index 7350c3c8821..645380ddba8 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -589,11 +589,11 @@ class OC_OCS { if(OC_User::userExists($user)) { // calculate the disc space $user_dir = '/'.$user.'/files'; - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::init($user_dir); $rootInfo=OC_FileCache::get(''); $sharedInfo=OC_FileCache::get('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; - $free=OC_Filesystem::free_space(); + $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/lib/public/files.php b/lib/public/files.php index 90889c59ad8..2d6775e01f1 100644 --- a/lib/public/files.php +++ b/lib/public/files.php @@ -98,7 +98,7 @@ class Files { /** * @param string appid * @param $app app - * @return OC_FilesystemView + * @return \OC\Files\View */ public static function getStorage( $app ) { return \OC_App::getStorage( $app ); diff --git a/lib/public/share.php b/lib/public/share.php index 1db3a0b2c1d..7c4ede5e882 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -515,7 +515,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -602,7 +602,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } @@ -751,7 +751,7 @@ class Share { } else { $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { diff --git a/lib/util.php b/lib/util.php index 557f731522e..5cf76574574 100755 --- a/lib/util.php +++ b/lib/util.php @@ -34,7 +34,7 @@ class OC_Util { $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage if(!self::$rootMounted) { - OC_Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); self::$rootMounted=true; } @@ -46,8 +46,8 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); + \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); OC_FileProxy::register($quotaProxy); // Load personal mount config @@ -55,7 +55,7 @@ class OC_Util { $mountConfig = include($user_root.'/mount.php'); if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - OC_Filesystem::mount($options['class'], $options['options'], $mountPoint); + \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); } } } @@ -64,7 +64,7 @@ class OC_Util { } public static function tearDownFS() { - OC_Filesystem::tearDown(); + \OC\Files\Filesystem::tearDown(); self::$fsSetup=false; } diff --git a/settings/personal.php b/settings/personal.php index 9297f5d91cc..54002d87c59 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -25,7 +25,7 @@ if (!isset($sharedInfo['size'])) { } $used=$rootInfo['size']-$sharedSize; if($used<0) $used=0; -$free=OC_Filesystem::free_space(); +$free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 3e8fd8c1bb1..5dcd3268804 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -38,8 +38,8 @@ class Test_Cache_File extends Test_Cache { } //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index b402b86af1f..af3620f5707 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -20,6 +20,8 @@ * */ +use \OC\Files\Filesystem as Filesystem; + class Test_Filesystem extends UnitTestCase { /** * @var array tmpDirs @@ -42,64 +44,64 @@ class Test_Filesystem extends UnitTestCase { } public function setUp() { - OC_Filesystem::clearMounts(); + Filesystem::clearMounts(); } public function testMount() { - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',OC_Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('',Filesystem::getInternalPath('/')); + $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some')); + $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); } public function testNormalize() { - $this->assertEqual('/path', OC_Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', OC_Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', OC_Filesystem::normalizePath('path')); - $this->assertEqual('/path', OC_Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo////bar')); + $this->assertEqual('/path', Filesystem::normalizePath('/path/')); + $this->assertEqual('/path/', Filesystem::normalizePath('/path/', false)); + $this->assertEqual('/path', Filesystem::normalizePath('path')); + $this->assertEqual('/path', Filesystem::normalizePath('\path')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo//bar/')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo////bar')); if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", OC_Filesystem::normalizePath("/foo/baru\xCC\x88")); + $this->assertEqual("/foo/bar\xC3\xBC", Filesystem::normalizePath("/foo/baru\xCC\x88")); } } public function testHooks() { - if(OC_Filesystem::getView()){ + if(Filesystem::getView()){ $user = OC_User::getUser(); }else{ $user=uniqid(); - OC_Filesystem::init('/'.$user.'/files'); + Filesystem::init('/'.$user.'/files'); } OC_Hook::clear('OC_Filesystem'); OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); - OC_Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); + Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); - OC_Filesystem::file_put_contents('/foo', 'foo'); - OC_Filesystem::mkdir('/bar'); - OC_Filesystem::file_put_contents('/bar//foo', 'foo'); + Filesystem::file_put_contents('/foo', 'foo'); + Filesystem::mkdir('/bar'); + Filesystem::file_put_contents('/bar//foo', 'foo'); $tmpFile = OC_Helper::tmpFile(); file_put_contents($tmpFile, 'foo'); $fh = fopen($tmpFile, 'r'); - OC_Filesystem::file_put_contents('/bar//foo', $fh); + Filesystem::file_put_contents('/bar//foo', $fh); } public function dummyHook($arguments) { $path = $arguments['path']; - $this->assertEqual($path, OC_Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + $this->assertEqual($path, Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } } -- cgit v1.2.3 From 5c6e9518edde10e0c23d0d734d2cc6d161fc15c0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 17:46:29 +0200 Subject: drop Filesystem::getInternalPath and Filesystem::getStorage in favor of Filesystem::resolvePath --- apps/files_sharing/lib/sharedstorage.php | 86 ++++++++++++++++---------------- lib/files/filesystem.php | 31 ------------ lib/files/view.php | 61 ++++++++-------------- lib/filesystem.php | 22 -------- tests/lib/filesystem.php | 9 ++-- 5 files changed, 71 insertions(+), 138 deletions(-) (limited to 'lib/files') diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e17c4b6e043..e12027a4f2b 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -114,16 +114,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->mkdir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->mkdir($internalPath); } return false; } public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->rmdir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->rmdir($internalPath); } return false; } @@ -134,8 +134,8 @@ class Shared extends \OC\Files\Storage\Common { \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->opendir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->opendir($internalPath); } return false; } @@ -144,16 +144,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->is_dir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->is_dir($internalPath); } return false; } public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->is_file($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->is_file($internalPath); } return false; } @@ -165,8 +165,8 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->stat($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->stat($internalPath); } return false; } @@ -175,8 +175,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filetype($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filetype($internalPath); } return false; } @@ -185,8 +185,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filesize($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filesize($internalPath); } return false; } @@ -227,8 +227,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->file_exists($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->file_exists($internalPath); } return false; } @@ -248,8 +248,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filectime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filectime($internalPath); } } } @@ -269,8 +269,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filemtime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filemtime($internalPath); } } } @@ -283,8 +283,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->file_get_contents($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->file_get_contents($internalPath); } } @@ -299,8 +299,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - $result = $storage->file_put_contents($this->getInternalPath($source), $data); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + $result = $storage->file_put_contents($internalPath, $data); return $result; } return false; @@ -310,8 +310,8 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->unlink($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->unlink($internalPath); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder if ($this->is_dir($path)) { @@ -334,8 +334,9 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC\Files\Filesystem::getStorage($oldSource); - return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); + list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + return $storage->rename($oldInternalPath, $newInternalPath); } } else { // Move the file if DELETE and CREATE permissions are granted @@ -349,8 +350,9 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC\Files\Filesystem::getStorage($oldSource); - return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); + list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + return $storage->rename($oldInternalPath, $newInternalPath); } } } @@ -395,8 +397,8 @@ class Shared extends \OC\Files\Storage\Common { 'mode' => $mode, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->fopen($this->getInternalPath($source), $mode); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->fopen($internalPath, $mode); } return false; } @@ -406,8 +408,8 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->getMimeType($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->getMimeType($internalPath); } return false; } @@ -415,22 +417,22 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->free_space($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->free_space($internalPath); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->getLocalFile($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->getLocalFile($internalPath); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->touch($this->getInternalPath($source), $mtime); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->touch($internalPath, $mtime); } return false; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index f23f3a79e98..841f30c7679 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,37 +164,6 @@ class Filesystem { return $foundMountPoint; } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @param string $path - * @return bool - */ - static public function getInternalPath($path) { - $mountPoint = self::getMountPoint($path); - $internalPath = substr($path, strlen($mountPoint)); - return $internalPath; - } - - /** - * get the storage object for a path - * - * @param string $path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - $mountpoint = self::getMountPoint($path); - if ($mountpoint) { - if (!isset(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); - } - return self::$storages[$mountpoint]; - }else{ - return null; - } - } - /** * resolve a path to a storage and internal path * diff --git a/lib/files/view.php b/lib/files/view.php index 230455479cf..bffeb434f28 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -68,19 +68,6 @@ class View { return $this->fakeRoot; } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @param string $path - * @return bool - */ - public function getInternalPath($path) { - if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); - } - return $this->internal_path_cache[$path]; - } - /** * get path relative to the root of the view * @@ -103,19 +90,6 @@ class View { } } - /** - * get the storage object for a path - * - * @param string $path - * @return \OC\Files\Storage\Storage - */ - public function getStorage($path) { - if (!isset($this->storage_cache[$path])) { - $this->storage_cache[$path] = Filesystem::getStorage($this->getAbsolutePath($path)); - } - return $this->storage_cache[$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 @@ -136,8 +110,9 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFile($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFile($internalPath); } else { return null; } @@ -149,8 +124,9 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFolder($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFolder($internalPath); } else { return null; } @@ -373,8 +349,10 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - if ($storage = $this->getStorage($path1)) { - $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->rename($internalPath1, $internalPath2); } else { $result = false; } @@ -382,8 +360,8 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1 . $postFix1)); + list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + $storage1->unlink($internalPath1); $result = $count > 0; } if ($this->fakeRoot == Filesystem::getRoot()) { @@ -454,8 +432,10 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - if ($storage = $this->getStorage($path1 . $postFix1)) { - $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->copy($internalPath1, $internalPath2); } else { $result = false; } @@ -588,8 +568,9 @@ class View { array(Filesystem::signal_param_path => $path) ); } - if ($storage = $this->getStorage($path . $postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($storage) { + $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } @@ -621,9 +602,9 @@ class View { if ($path == null) { return false; } - $internalPath = $this->getInternalPath($path . $postFix); $run = $this->runHooks($hooks, $path); - if ($run and $storage = $this->getStorage($path . $postFix)) { + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 4189fe36c2b..587eb50d9e0 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -44,28 +44,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::getMountPoint($path); } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return bool - */ - static public function getInternalPath($path) { - return \OC\Files\Filesystem::getInternalPath($path); - } - - /** - * get the storage object for a path - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - return \OC\Files\Filesystem::getStorage($path); - } - /** * resolve a path to a storage and internal path * diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index af3620f5707..6e7b4fb781f 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -51,15 +51,18 @@ class Test_Filesystem extends UnitTestCase { Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); + $this->assertEqual('',$internalPath); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('some/folder',$internalPath); Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); $this->assertEqual('/',Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('folder',$internalPath); } public function testNormalize() { -- cgit v1.2.3 From cfa036eaa916c1adf38fb161a16c50cd050c0a3b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 20 Oct 2012 23:54:37 +0200 Subject: drop filectime from the filesystem api's --- apps/files_external/lib/amazons3.php | 2 -- apps/files_external/lib/dropbox.php | 1 - apps/files_external/lib/google.php | 2 -- apps/files_external/lib/swift.php | 2 -- apps/files_external/lib/webdav.php | 1 - apps/files_sharing/lib/sharedstorage.php | 22 ---------------------- lib/files.php | 3 +-- lib/files/filesystem.php | 4 ---- lib/files/storage/common.php | 4 ---- lib/files/storage/local.php | 3 --- lib/files/storage/storage.php | 1 - lib/files/view.php | 4 ---- lib/filesystem.php | 7 ------- 13 files changed, 1 insertion(+), 55 deletions(-) (limited to 'lib/files') diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 832127d3e79..c3fa4651f64 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -115,12 +115,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { $stat['size'] = $this->s3->get_bucket_filesize($this->bucket); $stat['atime'] = time(); $stat['mtime'] = $stat['atime']; - $stat['ctime'] = $stat['atime']; } else if ($object = $this->getObject($path)) { $stat['size'] = $object['Size']; $stat['atime'] = time(); $stat['mtime'] = strtotime($object['LastModified']); - $stat['ctime'] = $stat['mtime']; } if (isset($stat)) { return $stat; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 0f7593162e4..0e82f80668f 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -119,7 +119,6 @@ class Dropbox extends \OC\Files\Storage\Common { $stat['size'] = $metaData['bytes']; $stat['atime'] = time(); $stat['mtime'] = (isset($metaData['modified'])) ? strtotime($metaData['modified']) : time(); - $stat['ctime'] = $stat['mtime']; return $stat; } return false; diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 141fc619e35..7ee5b97f8be 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -257,14 +257,12 @@ class Google extends \OC\Files\Storage\Common { $stat['size'] = $this->free_space($path); $stat['atime'] = time(); $stat['mtime'] = time(); - $stat['ctime'] = time(); } else if ($entry = $this->getResource($path)) { // NOTE: Native resources don't have a file size $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; // if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) // $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue); $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue); - $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue); } if (isset($stat)) { return $stat; diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 4b3f38166dc..c3578b0c23e 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -500,7 +500,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>-1, 'size'=>$container->bytes_used, - 'ctime'=>-1 ); } @@ -518,7 +517,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>$mtime, 'size'=>$obj->content_length, - 'ctime'=>-1, ); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 73231b6ad81..c9785f3eb11 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -256,7 +256,6 @@ class DAV extends \OC\Files\Storage\Common{ return array( 'mtime'=>strtotime($response['{DAV:}getlastmodified']), 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, - 'ctime'=>-1, ); }catch(\Exception $e) { return array(); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e12027a4f2b..521dfb69f2a 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -162,7 +162,6 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { $stat['size'] = $this->filesize($path); $stat['mtime'] = $this->filemtime($path); - $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); @@ -233,27 +232,6 @@ class Shared extends \OC\Files\Storage\Common { return false; } - public function filectime($path) { - if ($path == '' || $path == '/') { - $ctime = 0; - if ($dh = $this->opendir($path)) { - while (($filename = readdir($dh)) !== false) { - $tempctime = $this->filectime($filename); - if ($tempctime < $ctime) { - $ctime = $tempctime; - } - } - } - return $ctime; - } else { - $source = $this->getSourcePath($path); - if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); - return $storage->filectime($internalPath); - } - } - } - public function filemtime($path) { if ($path == '' || $path == '/') { $mtime = 0; diff --git a/lib/files.php b/lib/files.php index 29322cf2d06..28c8d0b449f 100644 --- a/lib/files.php +++ b/lib/files.php @@ -30,13 +30,12 @@ class OC_Files { /** * get the filesystem info - * @param string path + * @param string $path * @return array * * returns an associative array with the following keys: * - size * - mtime - * - ctime * - mimetype * - encrypted * - versioned diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index e4c269257c2..94e8a562564 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -478,10 +478,6 @@ class Filesystem { return self::$defaultInstance->file_exists($path); } - static public function filectime($path) { - return self::$defaultInstance->filectime($path); - } - static public function filemtime($path) { return self::$defaultInstance->filemtime($path); } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3886a041829..17405845554 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -74,10 +74,6 @@ abstract class Common extends \OC\Files\Storage\Storage { return $permissions; } // abstract public function file_exists($path); - public function filectime($path) { - $stat = $this->stat($path); - return $stat['ctime']; - } public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index 66ae5542e36..ccd69e3971c 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -66,9 +66,6 @@ class Local extends \OC\Files\Storage\Common{ public function file_exists($path) { return file_exists($this->datadir.$path); } - public function filectime($path) { - return filectime($this->datadir.$path); - } public function filemtime($path) { return filemtime($this->datadir.$path); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index f149c61830c..941bc3b0779 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -29,7 +29,6 @@ abstract class Storage{ abstract public function isSharable($path); abstract public function getPermissions($path); abstract public function file_exists($path); - abstract public function filectime($path); abstract public function filemtime($path); abstract public function file_get_contents($path); abstract public function file_put_contents($path,$data); diff --git a/lib/files/view.php b/lib/files/view.php index bffeb434f28..58e3ee6f051 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -236,10 +236,6 @@ class View { return $this->basicOperation('file_exists', $path); } - public function filectime($path) { - return $this->basicOperation('filectime', $path); - } - public function filemtime($path) { return $this->basicOperation('filemtime', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 587eb50d9e0..9ce75aaf8ce 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -306,13 +306,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::file_exists($path); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filectime($path) { - return \OC\Files\Filesystem::filectime($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ -- cgit v1.2.3 From 1901ac8b17c99eef3ccd99edf877fd0a86737d17 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:13:16 +0200 Subject: drop depricated is_readable and is_writable --- lib/files.php | 2 +- lib/files/filesystem.php | 14 -------------- lib/files/view.php | 14 -------------- lib/filesystem.php | 7 ------- 4 files changed, 1 insertion(+), 36 deletions(-) (limited to 'lib/files') diff --git a/lib/files.php b/lib/files.php index 28c8d0b449f..ba111bee967 100644 --- a/lib/files.php +++ b/lib/files.php @@ -178,7 +178,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or \OC\Files\Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::isReadable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 94e8a562564..0dae774febe 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -440,20 +440,6 @@ class Filesystem { return self::$defaultInstance->readfile($path); } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return self::$defaultInstance->isReadable($path); - } - - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return self::$defaultInstance->is_writable($path); - } - static public function isCreatable($path) { return self::$defaultInstance->isCreatable($path); } diff --git a/lib/files/view.php b/lib/files/view.php index 58e3ee6f051..a59ad8105d6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -195,20 +195,6 @@ class View { return false; } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - public function is_readable($path) { - return $this->basicOperation('isReadable', $path); - } - - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - public function is_writable($path) { - return $this->basicOperation('isUpdatable', $path); - } - public function isCreatable($path) { return $this->basicOperation('isCreatable', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 9ce75aaf8ce..ea0a289c8d2 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -257,13 +257,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::isReadable($path); } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return \OC\Files\Filesystem::is_writable($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ -- cgit v1.2.3 From 3ff0772a05c70592360c7b11b280cc4cf45a385e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:31:32 +0200 Subject: add getCache and getScanner to storage api in order to allow storage backends to overwride caching behaviour --- lib/files/storage/common.php | 50 ++++++++----------------------- lib/files/storage/storage.php | 70 ++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 72 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 17405845554..de02c0d5d81 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -20,7 +20,7 @@ namespace OC\Files\Storage; * in classes which extend it, e.g. $this->stat() . */ -abstract class Common extends \OC\Files\Storage\Storage { +abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} // abstract public function getId(); @@ -123,64 +123,30 @@ abstract class Common extends \OC\Files\Storage\Storage { * deleted together with its contents. To avoid this set $empty to true */ public function deleteAll( $directory, $empty = false ) { - - // strip leading slash - if( substr( $directory, 0, 1 ) == "/" ) { - - $directory = substr( $directory, 1 ); - - } - - // strip trailing slash - if( substr( $directory, -1) == "/" ) { - - $directory = substr( $directory, 0, -1 ); - - } + $directory = trim($directory,'/'); if ( !$this->file_exists( \OCP\USER::getUser() . '/' . $directory ) || !$this->is_dir( \OCP\USER::getUser() . '/' . $directory ) ) { - return false; - } elseif( !$this->is_readable( \OCP\USER::getUser() . '/' . $directory ) ) { - return false; - } else { - $directoryHandle = $this->opendir( \OCP\USER::getUser() . '/' . $directory ); - while ( $contents = readdir( $directoryHandle ) ) { - if ( $contents != '.' && $contents != '..') { - $path = $directory . "/" . $contents; - if ( $this->is_dir( $path ) ) { - deleteAll( $path ); - } else { - $this->unlink( \OCP\USER::getUser() .'/' . $path ); // TODO: make unlink use same system path as is_dir - } } - } - //$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV - if ( $empty == false ) { - if ( !$this->rmdir( $directory ) ) { - - return false; - + return false; } - } - return true; } @@ -209,7 +175,7 @@ abstract class Common extends \OC\Files\Storage\Storage { return $mime; } public function hash($type,$path,$raw = false) { - $tmpFile=$this->getLocalFile(); + $tmpFile=$this->getLocalFile($path); $hash=hash($type,$tmpFile,$raw); unlink($tmpFile); return $hash; @@ -283,4 +249,12 @@ abstract class Common extends \OC\Files\Storage\Storage { public function hasUpdated($path,$time) { return $this->filemtime($path)>$time; } + + public function getCache(){ + return new \OC\Files\Cache\Cache($this); + } + + public function getScanner(){ + return new \OC\Files\Cache\Scanner($this); + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 941bc3b0779..b1ec0bdb500 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -9,40 +9,40 @@ namespace OC\Files\Storage; /** - * Provde a common interface to all different storage options + * Provide a common interface to all different storage options */ -abstract class Storage{ - abstract public function __construct($parameters); - abstract public function getId(); - abstract public function mkdir($path); - abstract public function rmdir($path); - abstract public function opendir($path); - abstract public function is_dir($path); - abstract public function is_file($path); - abstract public function stat($path); - abstract public function filetype($path); - abstract public function filesize($path); - abstract public function isCreatable($path); - abstract public function isReadable($path); - abstract public function isUpdatable($path); - abstract public function isDeletable($path); - abstract public function isSharable($path); - abstract public function getPermissions($path); - abstract public function file_exists($path); - abstract public function filemtime($path); - abstract public function file_get_contents($path); - abstract public function file_put_contents($path,$data); - abstract public function unlink($path); - abstract public function rename($path1,$path2); - abstract public function copy($path1,$path2); - abstract public function fopen($path,$mode); - abstract public function getMimeType($path); - abstract public function hash($type,$path,$raw = false); - abstract public function free_space($path); - abstract public function search($query); - abstract public function touch($path, $mtime=null); - abstract public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote - abstract public function getLocalFolder($path);// get a path to a local version of the folder, whether the original file is local or remote +interface Storage{ + public function __construct($parameters); + public function getId(); + public function mkdir($path); + public function rmdir($path); + public function opendir($path); + public function is_dir($path); + public function is_file($path); + public function stat($path); + public function filetype($path); + public function filesize($path); + public function isCreatable($path); + public function isReadable($path); + public function isUpdatable($path); + public function isDeletable($path); + public function isSharable($path); + public function getPermissions($path); + public function file_exists($path); + public function filemtime($path); + public function file_get_contents($path); + public function file_put_contents($path,$data); + public function unlink($path); + public function rename($path1,$path2); + public function copy($path1,$path2); + public function fopen($path,$mode); + public function getMimeType($path); + public function hash($type,$path,$raw = false); + public function free_space($path); + 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 /** * check if a file or folder has been updated since $time * @param int $time @@ -51,5 +51,7 @@ abstract class Storage{ * 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 */ - abstract public function hasUpdated($path,$time); + public function hasUpdated($path,$time); + public function getCache(); + public function getScanner(); } -- cgit v1.2.3 From 01594b8610ce4f08e28010994d9cbecda4c52e35 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:54:34 +0200 Subject: remove chroot from filesystem api --- lib/files/filesystem.php | 10 ---------- lib/filesystem.php | 11 ----------- 2 files changed, 21 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 0dae774febe..05dd698ab4b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,16 +281,6 @@ class Filesystem { } } - /** - * change the root to a fake root - * - * @param string $fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return self::$defaultInstance->chroot($fakeRoot); - } - /** * @brief get the relative path of the root data directory for the current user * @return string diff --git a/lib/filesystem.php b/lib/filesystem.php index ea0a289c8d2..20b5ab27909 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -81,17 +81,6 @@ class OC_Filesystem { \OC\Files\Filesystem::tearDown(); } - /** - * change the root to a fake root - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return \OC\Files\Filesystem::chroot($fakeRoot); - } - /** * @brief get the relative path of the root data directory for the current user * @return string -- cgit v1.2.3 From 2522c25af726a8487ac13855e8a035b990cd69a4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 02:12:58 +0200 Subject: use OC_Files::getFileInfo and OC_Files::getDirectoryContent as high level api for the filecache most apps would want to use this api instead of using the cache directly --- lib/files.php | 108 +++++++++++++++++++++--------------------- lib/files/filesystem.php | 73 +++++++++++++++++++++------- lib/files/storage/storage.php | 7 +++ tests/lib/files.php | 87 ++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 71 deletions(-) create mode 100644 tests/lib/files.php (limited to 'lib/files') diff --git a/lib/files.php b/lib/files.php index ba111bee967..8d402c0001d 100644 --- a/lib/files.php +++ b/lib/files.php @@ -41,69 +41,67 @@ class OC_Files { * - versioned */ public static function getFileInfo($path) { - if (($path == '/Shared' || substr($path, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { - if ($path == '/Shared') { - list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); - }else{ - $info['size'] = \OC\Files\Filesystem::filesize($path); - $info['mtime'] = \OC\Files\Filesystem::filemtime($path); - $info['ctime'] = \OC\Files\Filesystem::filectime($path); - $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); - $info['encrypted'] = false; - $info['versioned'] = false; + $path=\OC\Files\Filesystem::normalizePath($path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $data = $cache->get($internalPath); + + if($data['mimetype'] === 'httpd/unix-directory'){ + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; } - } else { - $info = OC_FileCache::get($path); } - return $info; + + return $data; } /** * get the content of a directory - * @param dir $directory path under datadirectory + * @param string $directory path under datadirectory + * @return array */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=\OC\Files\Filesystem::normalizePath($directory); - if($directory=='/') { - $directory=''; - } - $files = array(); - if (($directory == '/Shared' || substr($directory, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { - if ($directory == '/Shared') { - $files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); - } else { - $pos = strpos($directory, '/', 8); - // Get shared folder name - if ($pos !== false) { - $itemTarget = substr($directory, 7, $pos - 7); - } else { - $itemTarget = substr($directory, 7); - } - $files = OCP\Share::getItemSharedWith('folder', $itemTarget, OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); - } - } else { - $files = OC_FileCache::getFolderContent($directory, false, $mimetype_filter); - foreach ($files as &$file) { - $file['directory'] = $directory; - $file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; - $permissions = OCP\Share::PERMISSION_READ; - // NOTE: Remove check when new encryption is merged - if (!$file['encrypted']) { - $permissions |= OCP\Share::PERMISSION_SHARE; - } - if ($file['type'] == 'dir' && $file['writable']) { - $permissions |= OCP\Share::PERMISSION_CREATE; - } - if ($file['writable']) { - $permissions |= OCP\Share::PERMISSION_UPDATE | OCP\Share::PERMISSION_DELETE; + $path=\OC\Files\Filesystem::normalizePath($directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $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']; + } } - $file['permissions'] = $permissions; - } - if ($directory == '' && OC_App::isEnabled('files_sharing')) { - // Add 'Shared' folder - $files = array_merge($files, OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT)); + }else{ //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $files[] = $rootEntry; } } + usort($files, "fileCmp");//TODO: remove this once ajax is merged return $files; } @@ -145,7 +143,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } foreach($files as $file) { @@ -166,7 +164,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } $file=$dir.'/'.$files; @@ -446,7 +444,7 @@ class OC_Files { $setting = 'php_value '.$key.' '.$size; $hasReplaced = 0; $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); - if($content !== NULL) { + if($content !== null) { $htaccess = $content; } if($hasReplaced == 0) { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 05dd698ab4b..b7f8483fbf9 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,6 +164,43 @@ class Filesystem { return $foundMountPoint; } + /** + * get a list of all mount points in a directory + * + * @param string $path + * @return string[] + */ + static public function getMountPoints($path) { + $path = self::normalizePath($path); + if (strlen($path) > 1) { + $path .= '/'; + } + $pathLength = strlen($path); + + $mountPoints = array_keys(self::$mounts); + $result = array(); + foreach ($mountPoints as $mountPoint) { + if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { + $result[] = $mountPoint; + } + } + return $result; + } + + /** + * get the storage mounted at $mountPoint + * + * @param string $mountPoint + * @return \OC\Files\Storage\Storage + */ + public static function getStorage($mountPoint) { + if (!isset(self::$storages[$mountPoint])) { + $mount = self::$mounts[$mountPoint]; + self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); + } + return self::$storages[$mountPoint]; + } + /** * resolve a path to a storage and internal path * @@ -173,14 +210,14 @@ class Filesystem { static public function resolvePath($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); + $storage = self::getStorage($mountpoint); + if ($mountpoint === $path) { + $internalPath = ''; + } else { + $internalPath = substr($path, strlen($mountpoint)); } - $storage = self::$storages[$mountpoint]; - $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); - }else{ + } else { return array(null, null); } } @@ -302,18 +339,22 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $class * @param array $arguments * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - if ($mountpoint[0] != '/') { - $mountpoint = '/' . $mountpoint; + $mountpoint = self::normalizePath($mountpoint); + if (strlen($mountpoint) > 1) { + $mountpoint .= '/'; } - if (substr($mountpoint, -1) !== '/') { - $mountpoint = $mountpoint . '/'; + + if ($class instanceof \OC\Files\Storage\Storage) { + self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); + self::$storages[$mountpoint] = $class; + } else { + self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } - self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } /** @@ -522,15 +563,15 @@ class Filesystem { static public function removeETagHook($params, $root = false) { if (isset($params['path'])) { - $path=$params['path']; + $path = $params['path']; } else { - $path=$params['oldpath']; + $path = $params['oldpath']; } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b1ec0bdb500..853e8ba5198 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -52,6 +52,13 @@ interface Storage{ * returning true for other changes in the folder is optional */ public function hasUpdated($path,$time); + + /** + * @return \OC\Files\Cache\Cache + */ public function getCache(); + /** + * @return \OC\Files\Cache\Scanner + */ public function getScanner(); } diff --git a/tests/lib/files.php b/tests/lib/files.php new file mode 100644 index 00000000000..9cb52768458 --- /dev/null +++ b/tests/lib/files.php @@ -0,0 +1,87 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +use \OC\Files\Filesystem as Filesystem; + +class Test_Files extends PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $cache->clear(); + } + } + + public function testCacheAPI() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $cachedData = OC_Files::getFileInfo('/foo.txt'); + $this->assertEquals($textSize, $cachedData['size']); + $this->assertEquals('text/plain', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/'); + $this->assertEquals($storageSize * 3, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/folder'); + $this->assertEquals($storageSize + $textSize, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $folderData = OC_Files::getDirectoryContent('/'); + /** + * expected entries: + * folder + * foo.png + * foo.txt + * substorage + */ + $this->assertEquals(4, count($folderData)); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('substorage', $folderData[3]['name']); + + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($storageSize, $folderData[3]['size']); + } + + /** + * @return OC\Files\Storage\Storage + */ + private function getTestStorage() { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + + $scanner = $storage->getScanner(); + $scanner->scan(''); + $this->storages[] = $storage; + return $storage; + } +} -- cgit v1.2.3 From 56c7ee799cb13f7a4db60663f60b76cdf223614b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 23 Oct 2012 16:34:58 +0200 Subject: use strtotime on non-nummeric times in oc_filesystem::touch --- lib/files/view.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index a59ad8105d6..18d9193035e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -227,6 +227,9 @@ class View { } public function touch($path, $mtime = null) { + if (!is_null($mtime) and !is_numeric($mtime)) { + $mtime = strtotime($mtime); + } return $this->basicOperation('touch', $path, array('write'), $mtime); } @@ -331,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -342,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -414,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -550,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -585,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); -- cgit v1.2.3 From 39adadd3e3e50dcf3bf577a22870aaec52f63052 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:30:25 +0200 Subject: move the cache api from OC_Files to filesystem(view) --- lib/files.php | 92 ------------------------------------- lib/files/cache/cache.php | 5 ++ lib/files/filesystem.php | 27 +++++++++++ lib/files/view.php | 92 +++++++++++++++++++++++++++++++++++++ tests/lib/files.php | 108 -------------------------------------------- tests/lib/files/view.php | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+), 200 deletions(-) delete mode 100644 tests/lib/files.php create mode 100644 tests/lib/files/view.php (limited to 'lib/files') diff --git a/lib/files.php b/lib/files.php index 7ab7c89201a..422e7f4ffe7 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,98 +28,6 @@ class OC_Files { static $tmpFiles = array(); - /** - * 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) { - $path = \OC\Files\Filesystem::normalizePath($path); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $data = $cache->get($internalPath); - - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; - } - } - - return $data; - } - - /** - * get the content of a directory - * - * @param string $directory path under datadirectory - * @return array - */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($directory); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); - $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $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; - $files[] = $rootEntry; - } - } - - usort($files, "fileCmp"); //TODO: remove this once ajax is merged - return $files; - } - public static function searchByMime($mimetype_filter) { $files = array(); $dirs_to_check = array(''); diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5ef49246ea5..9b55666f959 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -8,6 +8,11 @@ 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 diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b7f8483fbf9..d735cf8626a 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -609,6 +609,33 @@ class Filesystem { } 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); + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public static function getDirectoryContent($directory, $mimetype_filter = '') { + return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); + } } \OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); diff --git a/lib/files/view.php b/lib/files/view.php index 18d9193035e..aaca1618acb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -645,4 +645,96 @@ class View { 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) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $data = $cache->get($internalPath); + + if ($data['mimetype'] === 'httpd/unix-directory') { + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } + } + + return $data; + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public function getDirectoryContent($directory, $mimetype_filter = '') { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $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; + $files[] = $rootEntry; + } + } + + usort($files, "fileCmp"); //TODO: remove this once ajax is merged + return $files; + } } diff --git a/tests/lib/files.php b/tests/lib/files.php deleted file mode 100644 index d978ac3fd13..00000000000 --- a/tests/lib/files.php +++ /dev/null @@ -1,108 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. */ - -use \OC\Files\Filesystem as Filesystem; - -class Test_Files extends PHPUnit_Framework_TestCase { - /** - * @var \OC\Files\Storage\Storage[] $storages; - */ - private $storages = array(); - - public function setUp() { - Filesystem::clearMounts(); - } - - public function tearDown() { - foreach ($this->storages as $storage) { - $cache = $storage->getCache(); - $cache->clear(); - } - } - - public function testCacheAPI() { - $storage1 = $this->getTestStorage(); - $storage2 = $this->getTestStorage(); - $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); - $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $storageSize = $textSize * 2 + $imageSize; - - $cachedData = OC_Files::getFileInfo('/foo.txt'); - $this->assertEquals($textSize, $cachedData['size']); - $this->assertEquals('text/plain', $cachedData['mimetype']); - - $cachedData = OC_Files::getFileInfo('/'); - $this->assertEquals($storageSize * 3, $cachedData['size']); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - - $cachedData = OC_Files::getFileInfo('/folder'); - $this->assertEquals($storageSize + $textSize, $cachedData['size']); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - - $folderData = OC_Files::getDirectoryContent('/'); - /** - * expected entries: - * folder - * foo.png - * foo.txt - * substorage - */ - $this->assertEquals(4, count($folderData)); - $this->assertEquals('folder', $folderData[0]['name']); - $this->assertEquals('foo.png', $folderData[1]['name']); - $this->assertEquals('foo.txt', $folderData[2]['name']); - $this->assertEquals('substorage', $folderData[3]['name']); - - $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); - $this->assertEquals($imageSize, $folderData[1]['size']); - $this->assertEquals($textSize, $folderData[2]['size']); - $this->assertEquals($storageSize, $folderData[3]['size']); - } - - public function testAutoScan() { - $storage1 = $this->getTestStorage(false); - $storage2 = $this->getTestStorage(false); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $storageSize = $textSize * 2 + $imageSize; - - $cachedData = \OC_Files::getFileInfo('/'); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - $this->assertEquals(-1, $cachedData['size']); - - $folderData = \OC_Files::getDirectoryContent('/substorage/folder'); - $this->assertEquals('text/plain', $folderData[0]['mimetype']); - $this->assertEquals($textSize, $folderData[0]['size']); - } - - /** - * @param bool $scan - * @return OC\Files\Storage\Storage - */ - private function getTestStorage($scan = true) { - $storage = new \OC\Files\Storage\Temporary(array()); - $textData = "dummy file data\n"; - $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); - $storage->mkdir('folder'); - $storage->file_put_contents('foo.txt', $textData); - $storage->file_put_contents('foo.png', $imgData); - $storage->file_put_contents('folder/bar.txt', $textData); - - if ($scan) { - $scanner = $storage->getScanner(); - $scanner->scan(''); - } - $this->storages[] = $storage; - return $storage; - } -} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php new file mode 100644 index 00000000000..6e7608f596b --- /dev/null +++ b/tests/lib/files/view.php @@ -0,0 +1,113 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +namespace Test\Files; + +use \OC\Files\Filesystem as Filesystem; + +class View extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $cache->clear(); + } + } + + public function testCacheAPI() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertEquals($textSize, $cachedData['size']); + $this->assertEquals('text/plain', $cachedData['mimetype']); + + $cachedData = $rootView->getFileInfo('/'); + $this->assertEquals($storageSize * 3, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $cachedData = $rootView->getFileInfo('/folder'); + $this->assertEquals($storageSize + $textSize, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $folderData = $rootView->getDirectoryContent('/'); + /** + * expected entries: + * folder + * foo.png + * foo.txt + * substorage + */ + $this->assertEquals(4, count($folderData)); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('substorage', $folderData[3]['name']); + + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($storageSize, $folderData[3]['size']); + } + + public function testAutoScan() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(false); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/'); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + $this->assertEquals(-1, $cachedData['size']); + + $folderData = $rootView->getDirectoryContent('/substorage/folder'); + $this->assertEquals('text/plain', $folderData[0]['mimetype']); + $this->assertEquals($textSize, $folderData[0]['size']); + } + + /** + * @param bool $scan + * @return \OC\Files\Storage\Storage + */ + private function getTestStorage($scan = true) { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } + $this->storages[] = $storage; + return $storage; + } +} -- cgit v1.2.3 From e63e246c4894aa7f72feb550d98747890838af0b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:37:49 +0200 Subject: fix problem with normalizePath when there was a double leading slash --- lib/files/filesystem.php | 8 ++++---- tests/lib/files/view.php | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d735cf8626a..2b51131b20b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -595,14 +595,14 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trailing slash - if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { - $path = substr($path, 0, -1); - } //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 if (class_exists('Normalizer')) { $path = \Normalizer::normalize($path); diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6e7608f596b..adbed5a18b6 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -69,6 +69,9 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($imageSize, $folderData[1]['size']); $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + + $folderView = new \OC\Files\View('/folder'); + $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); } public function testAutoScan() { -- cgit v1.2.3 From 7ef0ffe8ad8f95b023f95f80e7b91c2a3ee50c67 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:43:23 +0200 Subject: add View->putFileInfo to the filecache api --- lib/files/view.php | 30 ++++++++++++++++++++++++++++-- tests/lib/files/view.php | 7 +++++++ 2 files changed, 35 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index aaca1618acb..094a7d92a4d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -663,7 +663,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -700,7 +700,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -737,4 +737,30 @@ class View { usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } + + /** + * change file metadata + * + * @param string $path + * @param array $data + * @return int + * + * returns the fileid of the updated file + */ + public function putFileInfo($path, $data) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + return $cache->put($internalPath, $data); + } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index adbed5a18b6..051ae251627 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -72,6 +72,13 @@ class View extends \PHPUnit_Framework_TestCase { $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertFalse($cachedData['encrypted']); + $id = $rootView->putFileInfo('/foo.txt', array('encrypted' => true)); + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertTrue($cachedData['encrypted']); + $this->assertEquals($cachedData['fileid'], $id); } public function testAutoScan() { -- cgit v1.2.3 From 8bce661e4ddedb611d5873c578203dfda631ce7e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 13:23:15 +0200 Subject: add search to the filecache api --- lib/files/cache/cache.php | 21 ++++++++++- lib/files/filesystem.php | 2 +- lib/files/view.php | 84 ++++++++++++++++++++++++++++++----------- tests/lib/files/cache/cache.php | 20 ++++++++++ tests/lib/files/view.php | 45 +++++++++++++++++++++- 5 files changed, 146 insertions(+), 26 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9b55666f959..7e0c5cb21f9 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -251,7 +251,7 @@ class Cache { */ public function getStatus($file) { $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { @@ -267,4 +267,23 @@ class Cache { } } } + + /** + * search for files matching $pattern + * + * @param string $pattern + * @return array of file data + */ + public function search($pattern) { + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' + ); + $result = $query->execute(array($pattern, $this->storageId)); + $files = array(); + while ($row = $result->fetchRow()) { + $files[] = $row; + } + return $files; + } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 2b51131b20b..4031c0c5b80 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -548,7 +548,7 @@ class Filesystem { } static public function search($query) { - return Cache\Cache::search($query); + return self::$defaultInstance->search($query); } /** diff --git a/lib/files/view.php b/lib/files/view.php index 094a7d92a4d..ee95cce0c1d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -150,7 +150,7 @@ class View { } public function readdir($handle) { - $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/')); + $fsLocal = new Storage\Local(array('datadir' => '/')); return $fsLocal->readdir($handle); } @@ -334,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -553,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -588,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -660,26 +660,26 @@ class View { * - versioned */ public function getFileInfo($path) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $data = $cache->get($internalPath); if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -697,26 +697,26 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($directory); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -748,19 +748,57 @@ class View { * returns the fileid of the updated file */ public function putFileInfo($path, $data) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } return $cache->put($internalPath, $data); } + + /** + * search for files with the name matching $query + * + * @param string $query + * @return array + */ + public function search($query) { + $files = array(); + $rootLength = strlen($this->fakeRoot); + + $mountPoint = Filesystem::getMountPoint($this->fakeRoot); + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { + $result['path'] = substr($mountPoint . $result['path'], $rootLength); + $files[] = $result; + } + } + + $mountPoints = Filesystem::getMountPoints($this->fakeRoot); + foreach ($mountPoints as $mountPoint) { + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $relativeMountPoint = substr($mountPoint, $rootLength); + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } + + return $files; + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 177cf1c045d..839e06e93fc 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -111,6 +111,26 @@ class Cache extends \UnitTestCase { $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); } + function testSearch() { + $file1 = 'folder'; + $file2 = 'folder/foobar'; + $file3 = 'folder/foo'; + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['foobar']); + $this->cache->put($file3, $fileData['foo']); + + $this->assertEquals(2, count($this->cache->search('%foo%'))); + $this->assertEquals(1, count($this->cache->search('foo'))); + $this->assertEquals(1, count($this->cache->search('%folder%'))); + $this->assertEquals(1, count($this->cache->search('folder%'))); + $this->assertEquals(3, count($this->cache->search('%'))); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 051ae251627..fc872ea5e27 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -87,7 +87,6 @@ class View extends \PHPUnit_Framework_TestCase { Filesystem::mount($storage1, array(), '/'); Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $rootView = new \OC\Files\View(''); @@ -100,6 +99,50 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($textSize, $folderData[0]['size']); } + function testSearch() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $results = $rootView->search('foo'); + $this->assertEquals(6, count($results)); + $paths = array(); + foreach ($results as $result) { + $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $paths[] = $result['path']; + } + $this->assertContains('/foo.txt', $paths); + $this->assertContains('/foo.png', $paths); + $this->assertContains('/substorage/foo.txt', $paths); + $this->assertContains('/substorage/foo.png', $paths); + $this->assertContains('/folder/anotherstorage/foo.txt', $paths); + $this->assertContains('/folder/anotherstorage/foo.png', $paths); + + $folderView = new \OC\Files\View('/folder'); + $results = $folderView->search('bar'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/folder/bar.txt', $paths); + $this->assertContains('/bar.txt', $paths); + + $results = $folderView->search('foo'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/foo.txt', $paths); + $this->assertContains('/anotherstorage/foo.png', $paths); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From c22a723785f80671548b89c543e9163c2fff9264 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 19:07:29 +0200 Subject: add file permissions cache --- db_structure.xml | 47 +++++++++++++++++++ lib/files/cache/permissions.php | 85 +++++++++++++++++++++++++++++++++++ lib/util.php | 2 +- tests/lib/files/cache/permissions.php | 47 +++++++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 lib/files/cache/permissions.php create mode 100644 tests/lib/files/cache/permissions.php (limited to 'lib/files') diff --git a/db_structure.xml b/db_structure.xml index e0b9dc11e94..e420a9f0e44 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -175,6 +175,53 @@ + + + *dbprefix*permissions + + + + + fileid + integer + 0 + true + 4 + + + + user + text + + true + 64 + + + + permissions + integer + 0 + true + 4 + + + + id_user_index + true + + fileid + ascending + + + user + ascending + + + + + +
+ *dbprefix*group_user diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php new file mode 100644 index 00000000000..e3fa63c464a --- /dev/null +++ b/lib/files/cache/permissions.php @@ -0,0 +1,85 @@ + + * 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 { + /** + * get the permissions for a single file + * + * @param int $fileId + * @param string $user + * @return int (-1 if file no permissions set) + */ + static public function get($fileId, $user) { + $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'); + $result = $query->execute(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 + */ + static public function set($fileId, $user, $permissions) { + if (self::get($fileId, $user) !== -1) { + $query = \OC_DB::prepare('UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'); + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'); + } + $query->execute(array($permissions, $user, $fileId)); + } + + /** + * get the permissions of multiply files + * + * @param int[] $fileIds + * @param string $user + * @return int[] + */ + static public function getMultiple($fileIds, $user) { + $params = $fileIds; + $params[] = $user; + $inPart = implode(', ', array_fill(0, count($fileIds), '?')); + + $query = \OC_DB::prepare('SELECT `fileid`, `permissions` FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + $result = $query->execute($params); + $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 + */ + static public function remove($fileId, $user) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + $query->execute(array($fileId, $user)); + } + + static public function removeMultiple($fileIds, $user) { + $params = $fileIds; + $params[] = $user; + $inPart = implode(', ', array_fill(0, count($fileIds), '?')); + + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + $query->execute($params); + } +} diff --git a/lib/util.php b/lib/util.php index 137766d0129..a2e0422c97f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -86,7 +86,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,00); + return array(4,91,01); } /** diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php new file mode 100644 index 00000000000..4d47929a3ee --- /dev/null +++ b/tests/lib/files/cache/permissions.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Permissions extends \PHPUnit_Framework_TestCase { + function testSimple() { + $ids = range(1, 10); + $user = uniqid(); + + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::set(1, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + + \OC\Files\Cache\Permissions::set(1, $user, 2); + $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + + \OC\Files\Cache\Permissions::set(2, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + \OC\Files\Cache\Permissions::remove(1, $user); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::remove(1, $user . '2'); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + $expected = array(); + foreach ($ids as $id) { + \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $expected[$id] = 10 + $id; + } + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + unset($expected[9]); + unset($expected[10]); + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + } +} -- cgit v1.2.3 From 6db81afab9d68ccd50c1e164622252e47ae76c2f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:05:02 +0200 Subject: move some stuff to the new api --- apps/files/ajax/list.php | 2 +- apps/files/ajax/newfile.php | 12 ++++++------ apps/files/ajax/newfolder.php | 3 ++- apps/files/ajax/rawlist.php | 2 +- apps/files/ajax/upload.php | 2 +- apps/files/index.php | 2 +- apps/files/settings.php | 2 +- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 10 +++++----- apps/files_sharing/appinfo/update.php | 3 ++- lib/connector/sabre/directory.php | 6 +++--- lib/connector/sabre/node.php | 4 ++-- lib/fileproxy/quota.php | 12 ++++-------- lib/files.php | 2 +- lib/files/filesystem.php | 13 +++++++++++++ lib/files/view.php | 1 - lib/ocs.php | 4 ++-- lib/public/share.php | 15 +++++++++------ lib/search/provider/file.php | 2 +- settings/personal.php | 4 ++-- 20 files changed, 58 insertions(+), 45 deletions(-) (limited to 'lib/files') diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 568fe754c02..92091f42135 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -32,7 +32,7 @@ if($doBreadcrumb) { // make filelist $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i["date"] = OCP\Util::formatDate($i["mtime"] ); $files[] = $i; } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 5f3f3d88f27..38714f34a63 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -65,9 +65,9 @@ if($source) { $target=$dir.'/'.$filename; $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); if($result) { - $meta = OC_FileCache::get($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $mime=$meta['mimetype']; - $id = OC_FileCache::getId($target); + $id = $meta['fileid']; $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); } else { $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); @@ -77,14 +77,14 @@ if($source) { } else { if($content) { if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } }elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index c36c2084551..e26e1238bc6 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -25,7 +25,8 @@ if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($foldername))) { } else { $path = '/'.$foldername; } - $id = OC_FileCache::getId($path); + $meta = \OC\Files\Filesystem::getFileInfo($path); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('id'=>$id))); exit(); } diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index e0aa0bdac52..1cd2944483c 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -15,7 +15,7 @@ $mimetype = isset($_GET['mimetype']) ? $_GET['mimetype'] : ''; // make filelist $files = array(); -foreach( OC_Files::getdirectorycontent( $dir, $mimetype ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $i ) { $i["date"] = OCP\Util::formatDate($i["mtime"] ); $i['mimetype_icon'] = $i['type'] == 'dir' ? \mimetype_icon('dir'): \mimetype_icon($i['mimetype']); $files[] = $i; diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index b6b8c7f7b46..2a784d61691 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -49,7 +49,7 @@ if(strpos($dir, '..') === false) { for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { - $meta = \OC_Files::getFileInfo($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $id = $meta['fileid']; $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); } diff --git a/apps/files/index.php b/apps/files/index.php index 192cd2696f2..4676ebc6021 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -44,7 +44,7 @@ if(!\OC\Files\Filesystem::is_dir($dir.'/')) { } $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i['date'] = OCP\Util::formatDate($i['mtime'] ); if($i['type']=='file') { $fileinfo=pathinfo($i['name']); diff --git a/apps/files/settings.php b/apps/files/settings.php index 52ec9fd0fe3..30463210f71 100644 --- a/apps/files/settings.php +++ b/apps/files/settings.php @@ -36,7 +36,7 @@ OCP\Util::addscript( "files", "files" ); $dir = isset( $_GET['dir'] ) ? $_GET['dir'] : ''; $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i["date"] = date( $CONFIG_DATEFORMAT, $i["mtime"] ); $files[] = $i; } diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index e98013e1f42..c4298382646 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -167,7 +167,7 @@ class OC_CryptStream{ public function stream_close() { $this->flush(); if($this->meta['mode']!='r' and $this->meta['mode']!='rb') { - OC_FileCache::put($this->path, array('encrypted'=>true,'size'=>$this->size),''); + \OC\Files\Filesystem::putFileInfo($this->path, array('encrypted'=>true,'size'=>$this->size),''); } return fclose($this->source); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7b7bafe73eb..49fb30ac291 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -59,7 +59,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ * @return bool */ private static function isEncrypted($path) { - $metadata=OC_FileCache_Cached::get($path,''); + $metadata=\OC\Files\Filesystem::getFileInfo($path,''); return isset($metadata['encrypted']) and (bool)$metadata['encrypted']; } @@ -68,14 +68,14 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ if (!is_resource($data)) {//stream put contents should have been converter to fopen $size=strlen($data); $data=OC_Crypt::blockEncrypt($data); - OC_FileCache::put($path, array('encrypted'=>true,'size'=>$size),''); + \OC\Files\Filesystem::putFileInfo($path, array('encrypted'=>true,'size'=>$size),''); } } } public function postFile_get_contents($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data=OC_Crypt::blockDecrypt($data,'',$cached['size']); } return $data; @@ -113,7 +113,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postStat($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data['size']=$cached['size']; } return $data; @@ -121,7 +121,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postFileSize($path,$size) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); return $cached['size']; }else{ return $size; diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index e75c538b150..51048bd178c 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -10,6 +10,7 @@ if (version_compare($installedVersion, '0.3', '<')) { OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); while ($row = $result->fetchRow()) { + $meta = \OC\Files\Filesystem::getId($path, ''); $itemSource = OC_FileCache::getId($row['source'], ''); if ($itemSource != -1) { $file = OC_FileCache::get($row['source'], ''); @@ -70,4 +71,4 @@ if (version_compare($installedVersion, '0.3.3', '<')) { foreach ($users as $user) { OC_FileCache::delete('Shared', '/'.$user.'/files/'); } -} \ No newline at end of file +} diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 3df85b2bbbe..d4f58527d21 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -93,7 +93,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $path = $this->path . '/' . $name; if (is_null($info)) { - $info = OC_Files::getFileInfo($path); + $info = \OC\Files\Filesystem::getFileInfo($path); } if (!$info) { @@ -117,7 +117,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function getChildren() { - $folder_content = OC_Files::getDirectoryContent($this->path); + $folder_content = \OC\Files\Filesystem::getDirectoryContent($this->path); $paths = array(); foreach($folder_content as $info) { $paths[] = $this->path.'/'.$info['name']; @@ -178,7 +178,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return array */ public function getQuotaInfo() { - $rootInfo=OC_FileCache_Cached::get(''); + $rootInfo=\OC\Files\Filesystem::getFileInfo(''); return array( $rootInfo['size'], \OC\Files\Filesystem::free_space() diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index e7e83507ea2..2095c956e5f 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -95,11 +95,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * Make sure the fileinfo cache is filled. Uses OC_FileCache or a direct stat + * Make sure the fileinfo cache is filled. Uses the file cache or a direct stat */ protected function getFileinfoCache() { if (!isset($this->fileinfo_cache)) { - if ($fileinfo_cache = \OC\Files\Filesystem::get($this->path)) { + if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) { } else { $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index d120f309998..cd9a2f4a192 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -57,7 +57,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ * @return int */ private function getFreeSpace($path) { - $storage=OC_Filesystem::getStorage($path); + list($storage,)=\OC\Files\Filesystem::resolvePath($path); $owner=$storage->getOwner($path); $totalSpace=$this->getQuota($owner); @@ -65,13 +65,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ return 0; } - $rootInfo=OC_FileCache::get('', "/".$owner."/files"); - // TODO Remove after merge of share_api - if (OC_FileCache::inCache('/Shared', "/".$owner."/files")) { - $sharedInfo=OC_FileCache::get('/Shared', "/".$owner."/files"); - } else { - $sharedInfo = null; - } + $view = new \OC\Files\View("/".$owner."/files"); + + $rootInfo=$view->getFileInfo('/'); $usedSpace=isset($rootInfo['size'])?$rootInfo['size']:0; $usedSpace=isset($sharedInfo['size'])?$usedSpace-$sharedInfo['size']:$usedSpace; return $totalSpace-$usedSpace; diff --git a/lib/files.php b/lib/files.php index 422e7f4ffe7..6a063f216d5 100644 --- a/lib/files.php +++ b/lib/files.php @@ -146,7 +146,7 @@ class OC_Files { $dirname = basename($dir); $zip->addEmptyDir($internalDir . $dirname); $internalDir .= $dirname .= '/'; - $files = OC_Files::getdirectorycontent($dir); + $files = \OC\Files\Filesystem::getDirectoryContent($dir); foreach ($files as $file) { $filename = $file['name']; $file = $dir . '/' . $filename; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4031c0c5b80..b3c92f38558 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -627,6 +627,19 @@ class Filesystem { 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 * diff --git a/lib/files/view.php b/lib/files/view.php index ee95cce0c1d..e9b583f8ae6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -451,7 +451,6 @@ class View { array(Filesystem::signal_param_path => $path2) ); } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions -// OC_FileCache_Update::update($path2, $this->fakeRoot); Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; diff --git a/lib/ocs.php b/lib/ocs.php index 645380ddba8..c6bcd2c06e1 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -590,8 +590,8 @@ class OC_OCS { // calculate the disc space $user_dir = '/'.$user.'/files'; \OC\Files\Filesystem::init($user_dir); - $rootInfo=OC_FileCache::get(''); - $sharedInfo=OC_FileCache::get('/Shared'); + $rootInfo=\OC\Files\Filesystem::getFileInfo(''); + $sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; diff --git a/lib/public/share.php b/lib/public/share.php index 7a9a087d1bd..dd6c841c99d 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -285,10 +285,10 @@ class Share { // If the item is a folder, scan through the folder looking for equivalent item types if ($itemType == 'folder') { $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); - if ($parentFolder && $files = \OC_Files::getDirectoryContent($itemSource)) { + if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { for ($i = 0; $i < count($files); $i++) { $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC_Files::getDirectoryContent($name, '/')) { + if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/')) { // Continue scanning into child folders array_push($files, $children); } else { @@ -768,9 +768,10 @@ class Share { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { - $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); + $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); + $childItem['file_source'] = $meta['fileid']; } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { @@ -881,7 +882,8 @@ class Share { if ($itemType == 'file' || $itemType == 'folder') { $fileSource = $itemSource; } else { - $fileSource = \OC_FileCache::getId($filePath); + $meta = \OC\Files\Filesystem::getFileInfo($filePath); + $fileSource = $meta['fileid']; } if ($fileSource == -1) { $message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache'; @@ -1063,7 +1065,8 @@ class Share { } if ($item['uid_owner'] == $uidOwner) { if ($itemType == 'file' || $itemType == 'folder') { - if ($item['file_source'] == \OC_FileCache::getId($itemSource)) { + $meta = \OC\Files\Filesystem::getFileInfo($itemSource); + if ($item['file_source'] == $meta['fileid']) { return $target; } } else if ($item['item_source'] == $itemSource) { diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php index 0d4b332b792..456e12b5ec2 100644 --- a/lib/search/provider/file.php +++ b/lib/search/provider/file.php @@ -2,7 +2,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{ function search($query) { - $files=OC_FileCache::search($query, true); + $files=\OC\Files\Filesystem::search($query, true); $results=array(); $l=OC_L10N::get('lib'); foreach($files as $fileData) { diff --git a/settings/personal.php b/settings/personal.php index c73a3dd3701..5a267ec2844 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -16,8 +16,8 @@ OC_Util::addStyle( '3rdparty', 'chosen' ); OC_App::setActiveNavigationEntry( 'personal' ); // calculate the disc space -$rootInfo=OC_FileCache::get(''); -$sharedInfo=OC_FileCache::get('/Shared'); +$rootInfo=\OC\Files\Filesystem::getFileInfo(''); +$sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']; if($used<0) $used=0; $free=\OC\Files\Filesystem::free_space(); -- cgit v1.2.3 From 7d6da68d532fe1b1299f3a724e70b8ec3960ec8d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:25:52 +0200 Subject: prove some compatibility with the old cache api --- lib/files/view.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index e9b583f8ae6..04b7dca8afc 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -712,7 +712,7 @@ class View { $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($path); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); @@ -733,6 +733,10 @@ class View { } } + foreach($files as $i => $file){ + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + } + usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } -- cgit v1.2.3 From 695405dfeb4da3733df1b1be239a97100f2ce66f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:01:20 +0200 Subject: add permissions data to the results of the cache api --- lib/files/cache/cache.php | 15 +++++++++++++++ lib/files/cache/scanner.php | 3 ++- lib/files/view.php | 12 +++++++++++- tests/lib/files/cache/scanner.php | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7e0c5cb21f9..5efc7d67c4a 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -286,4 +286,19 @@ class Cache { } return $files; } + + /** + * get all file ids on the files on the storage + * + * @return int[] + */ + public function getAll() { + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); + $result = $query->execute(array($this->storageId)); + $ids = array(); + while ($row = $result->fetchRow()) { + $ids[] = $row['fileid']; + } + return $ids; + } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8f54c34be7..0adde1d354d 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -66,7 +66,8 @@ class Scanner { $this->scanFile($parent); } } - $this->cache->put($file, $data); + $id = $this->cache->put($file, $data); + Permissions::set($id, \OC_User::getUser(), $data['permissions']); return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 04b7dca8afc..82455d582eb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -686,6 +686,8 @@ class View { } } + $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + return $data; } @@ -733,8 +735,16 @@ class View { } } - foreach($files as $i => $file){ + $ids = array(); + + foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + + $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; } usort($files, "fileCmp"); //TODO: remove this once ajax is merged diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index e3f47047f54..34fefc784d4 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -106,6 +106,8 @@ class Scanner extends \UnitTestCase { } function tearDown() { + $ids = $this->cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } -- cgit v1.2.3 From fcc92a9f43e75ecdb15adb0e948d45eac119306f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:34:25 +0200 Subject: add searchByMime to new cache api --- lib/files/cache/cache.php | 21 +++++++++++++++++++++ lib/files/filesystem.php | 4 ++++ lib/files/view.php | 25 ++++++++++++++++++++++--- tests/lib/files/cache/cache.php | 3 +++ tests/lib/files/view.php | 3 +++ 5 files changed, 53 insertions(+), 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5efc7d67c4a..6604525477b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -287,6 +287,27 @@ class Cache { return $files; } + /** + * search for files by mimetype + * + * @param string $part1 + * @param string $part2 + * @return array + */ + public function searchByMime($mimetype) { + if (strpos($mimetype, '/')) { + $where = '`mimetype` = ?'; + } else { + $where = '`mimepart` = ?'; + } + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' + ); + $result = $query->execute(array($mimetype, $this->storageId)); + return $result->fetchAll(); + } + /** * get all file ids on the files on the storage * diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b3c92f38558..96660a8ce30 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -551,6 +551,10 @@ class Filesystem { 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 * diff --git a/lib/files/view.php b/lib/files/view.php index 82455d582eb..0a5a6436c27 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -747,7 +747,7 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); //TODO: remove this once ajax is merged + usort($files, "fileCmp"); return $files; } @@ -784,6 +784,25 @@ class View { * @return array */ public function search($query) { + return $this->searchCommon('%' . $query . '%', 'search'); + } + + /** + * search for files by mimetype + * + * @param string $query + * @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); @@ -791,7 +810,7 @@ class View { $storage = Filesystem::getStorage($mountPoint); $cache = $storage->getCache(); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { $result['path'] = substr($mountPoint . $result['path'], $rootLength); @@ -805,7 +824,7 @@ class View { $cache = $storage->getCache(); $relativeMountPoint = substr($mountPoint, $rootLength); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { $result['path'] = $relativeMountPoint . $result['path']; $files[] = $result; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 839e06e93fc..5a8d79b902c 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -129,6 +129,9 @@ class Cache extends \UnitTestCase { $this->assertEquals(1, count($this->cache->search('%folder%'))); $this->assertEquals(1, count($this->cache->search('folder%'))); $this->assertEquals(3, count($this->cache->search('%'))); + + $this->assertEquals(3, count($this->cache->searchByMime('foo'))); + $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } public function tearDown() { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 980c5298fb4..5144fb1caad 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -139,6 +139,9 @@ class View extends \PHPUnit_Framework_TestCase { } $this->assertContains('/anotherstorage/foo.txt', $paths); $this->assertContains('/anotherstorage/foo.png', $paths); + + $this->assertEquals(6, count($rootView->searchByMime('text'))); + $this->assertEquals(3, count($folderView->searchByMime('text'))); } /** -- cgit v1.2.3 From 5bfff6c56e8d4d911c7a5265bb5462c7122ca495 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:17:35 +0200 Subject: use absolute paths when resolving mount points --- lib/files.php | 10 ---------- lib/files/cache/permissions.php | 3 +++ lib/files/view.php | 35 ++++++++++++++++++++++++++--------- lib/public/share.php | 4 ++-- 4 files changed, 31 insertions(+), 21 deletions(-) (limited to 'lib/files') diff --git a/lib/files.php b/lib/files.php index 28df2255809..e6b324f062b 100644 --- a/lib/files.php +++ b/lib/files.php @@ -249,13 +249,3 @@ class OC_Files { return false; } } - -function fileCmp($a, $b) { - if ($a['type'] == 'dir' and $b['type'] != 'dir') { - return -1; - } elseif ($a['type'] != 'dir' and $b['type'] == 'dir') { - return 1; - } else { - return strnatcasecmp($a['name'], $b['name']); - } -} diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index e3fa63c464a..dd7233abc70 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -50,6 +50,9 @@ class Permissions { * @return int[] */ static public function getMultiple($fileIds, $user) { + if (count($fileIds) === 0) { + return array(); + } $params = $fileIds; $params[] = $user; $inPart = implode(', ', array_fill(0, count($fileIds), '?')); diff --git a/lib/files/view.php b/lib/files/view.php index 0a5a6436c27..0f9a5feb5dd 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,6 +110,7 @@ class View { */ 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); @@ -124,6 +125,7 @@ class View { */ 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); @@ -334,8 +336,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +347,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +419,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -552,7 +554,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -587,7 +589,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -747,8 +749,23 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); - return $files; + 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; } /** diff --git a/lib/public/share.php b/lib/public/share.php index 060f67c9e91..707d5abe440 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -534,7 +534,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -621,7 +621,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } -- cgit v1.2.3 From 56e9ce44c3ac18d6183a8959c690c6e3269bc79e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 17:02:05 +0200 Subject: add a way to recalucale the size of a folder in the cache --- lib/files/cache/cache.php | 25 +++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 11 +++++++++++ 2 files changed, 36 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6604525477b..734890329ae 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -308,6 +308,31 @@ class Cache { return $result->fetchAll(); } + /** + * get the size of a folder and set it in the cache + * + * @param string $path + * @return int + */ + public function calculateFolderSize($path) { + $id = $this->getId($path); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); + $result = $query->execute(array($id, $this->storageId)); + $totalSize = 0; + while ($row = $result->fetchRow()) { + $size = (int)$row['size']; + if ($size === -1) { + $totalSize = -1; + break; + } else { + $totalSize += $size; + } + } + + $this->update($id, array('size' => $totalSize)); + return $totalSize; + } + /** * get all file ids on the files on the storage * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 5a8d79b902c..57a154d295c 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -99,6 +99,17 @@ class Cache extends \UnitTestCase { $this->assertEqual($value, $cachedData[$name]); } } + + $file4 = 'folder/unkownSize'; + $fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(-1, $this->cache->calculateFolderSize($file1)); + + $fileData['unkownSize'] = array('size' => 5, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); } function testStatus() { -- cgit v1.2.3 From 79d0ac21ccc65d12b6643ab525d45977644873e8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 18:05:40 +0200 Subject: delete child entries when a folder gets removed from cache --- lib/files/cache/cache.php | 12 +++++++++--- lib/files/cache/scanner.php | 16 ++++++++++++++++ tests/lib/files/cache/cache.php | 6 +++++- tests/lib/files/cache/scanner.php | 9 +++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 734890329ae..cba48e4dbea 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -231,9 +231,15 @@ class Cache { * @param string $file */ public function remove($file) { - $pathHash = md5($file); - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($this->storageId, $pathHash)); + $entry = $this->get($file); + if ($entry['mimetype'] === 'httpd/unix-directory') { + $children = $this->getFolderContents($file); + foreach($children as $child){ + $this->remove($child['path']); + } + } + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + $query->execute(array($entry['fileid'])); } /** diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354d..7062888d74a 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,4 +107,20 @@ class Scanner { } return $size; } + + /** + * update the folder size and the size of all parent folders + * + * @param $path + */ + public function correctFolderSize($path) { + $this->cache->calculateFolderSize($path); + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.') { + $parent = ''; + } + $this->correctFolderSize($parent); + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 57a154d295c..4f22e9bd1d9 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -82,7 +82,7 @@ class Cache extends \UnitTestCase { $file1 = 'folder'; $file2 = 'folder/bar'; $file3 = 'folder/foo'; - $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); @@ -110,6 +110,10 @@ class Cache extends \UnitTestCase { $this->cache->put($file4, $fileData['unkownSize']); $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); + + $this->cache->remove('folder'); + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/bar')); } function testStatus() { diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34fefc784d4..34d38c42736 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -89,14 +89,19 @@ class Scanner extends \UnitTestCase { $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertEqual($cachedDataFolder['size'], -1); - $this->assertEqual($cachedDataFolder2['size'], -1); + $this->assertEqual(-1, $cachedDataFolder['size']); + $this->assertEqual(-1, $cachedDataFolder2['size']); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertNotEqual($cachedDataFolder2['size'], -1); + + $this->scanner->correctFolderSize('folder'); + + $cachedDataFolder = $this->cache->get(''); + $this->assertNotEqual($cachedDataFolder['size'], -1); } function setUp() { -- cgit v1.2.3 From fba7be1194fd31da2cb71c56d0cd8e6ab1c1ff49 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:26:31 +0100 Subject: add filesystem watcher to detect updates --- lib/files/cache/cache.php | 8 +++- lib/files/cache/watcher.php | 70 +++++++++++++++++++++++++++++++ tests/lib/files/cache/watcher.php | 86 +++++++++++++++++++++++++++++++++++++++ tests/lib/files/view.php | 2 + 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 lib/files/cache/watcher.php create mode 100644 tests/lib/files/cache/watcher.php (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index cba48e4dbea..138a5e6e63e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -234,7 +234,7 @@ class Cache { $entry = $this->get($file); if ($entry['mimetype'] === 'httpd/unix-directory') { $children = $this->getFolderContents($file); - foreach($children as $child){ + foreach ($children as $child) { $this->remove($child['path']); } } @@ -325,7 +325,9 @@ class Cache { $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); $result = $query->execute(array($id, $this->storageId)); $totalSize = 0; + $hasChilds = 0; while ($row = $result->fetchRow()) { + $hasChilds = true; $size = (int)$row['size']; if ($size === -1) { $totalSize = -1; @@ -335,7 +337,9 @@ class Cache { } } - $this->update($id, array('size' => $totalSize)); + if ($hasChilds) { + $this->update($id, array('size' => $totalSize)); + } return $totalSize; } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php new file mode 100644 index 00000000000..f04ca9b4656 --- /dev/null +++ b/lib/files/cache/watcher.php @@ -0,0 +1,70 @@ + + * 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['mtime'])) { + if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->scanner->scan($path, Scanner::SCAN_SHALLOW); + $this->cleanFolder($path); + } else { + $this->scanner->scanFile($path); + } + $this->scanner->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/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php new file mode 100644 index 00000000000..a7076d9b0b5 --- /dev/null +++ b/tests/lib/files/cache/watcher.php @@ -0,0 +1,86 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Watcher extends \PHPUnit_Framework_TestCase { + + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + \OC\Files\Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $cache->clear(); + } + } + + function testWatcher() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertTrue($cache->inCache('folder/bar2.txt')); + + $this->assertFalse($cache->inCache('bar.test')); + $storage->file_put_contents('bar.test', 'foo'); + $updater->checkUpdate(''); + $this->assertTrue($cache->inCache('bar.test')); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(3, $cachedData['size']); + + $cache->put('bar.test', array('mtime' => 10)); + $storage->file_put_contents('bar.test', 'test data'); + + $updater->checkUpdate('bar.test'); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(9, $cachedData['size']); + + $cache->put('folder', array('mtime' => 10)); + + $storage->unlink('folder/bar2.txt'); + $updater->checkUpdate('folder'); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertFalse($cache->inCache('folder/bar2.txt')); + } + + /** + * @param bool $scan + * @return \OC\Files\Storage\Storage + */ + private function getTestStorage($scan = true) { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + $storage->file_put_contents('folder/bar2.txt', $textData); + + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } + $this->storages[] = $storage; + return $storage; + } +} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 5144fb1caad..8ff03963e40 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -20,6 +20,8 @@ class View extends \PHPUnit_Framework_TestCase { public function tearDown() { foreach ($this->storages as $storage) { $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } -- cgit v1.2.3 From b07672821bcdc1ce31e169d691cf9a94ad5fad21 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:43:45 +0100 Subject: check for changes when using the cache api --- lib/files/view.php | 6 ++++++ tests/lib/files/view.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 0f9a5feb5dd..c5e470b438e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -672,6 +672,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $data = $cache->get($internalPath); @@ -711,6 +714,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 8ff03963e40..fa562cb15cd 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -146,6 +146,23 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, count($folderView->searchByMime('text'))); } + function testWatcher() { + $storage1 = $this->getTestStorage(); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(16, $cachedData['size']); + + $rootView->putFileInfo('foo.txt', array('mtime' => 10)); + $storage1->file_put_contents('foo.txt', 'foo'); + clearstatcache(); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From 8a6bb7965d96b1c4297da8f5dbc9644fec7aeb0f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 2 Nov 2012 22:25:33 +0100 Subject: add Cache::move --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++-- tests/lib/files/cache/cache.php | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 138a5e6e63e..9d13b56104d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -242,6 +242,32 @@ class Cache { $query->execute(array($entry['fileid'])); } + /** + * Move a file or folder in the cache + * + * @param string $source + * @param string $target + */ + public function move($source, $target) { + $sourceId = $this->getId($source); + $newParentId = $this->getParentId($target); + + //find all child entries + $query = \OC_DB::prepare('SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `path` LIKE ?'); + $result = $query->execute(array($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); + $query->execute(array($targetPath, md5($targetPath), $child['fileid'])); + } + + $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `parent` =? WHERE `fileid` = ?'); + $query->execute(array($target, md5($target), $newParentId, $sourceId)); + } + /** * remove all entries for files that are stored on the storage from the cache */ @@ -296,8 +322,7 @@ class Cache { /** * search for files by mimetype * - * @param string $part1 - * @param string $part2 + * @param string $mimetype * @return array */ public function searchByMime($mimetype) { diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 4f22e9bd1d9..9c469aa9374 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -149,6 +149,32 @@ class Cache extends \UnitTestCase { $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } + function testMove() { + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; + $file4 = 'folder/foo/1'; + $file5 = 'folder/foo/2'; + $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $this->cache->put($file4, $data); + $this->cache->put($file5, $data); + + $this->cache->move('folder/foo', 'folder/foobar'); + + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/foo/1')); + $this->assertFalse($this->cache->inCache('folder/foo/2')); + + $this->assertTrue($this->cache->inCache('folder/bar')); + $this->assertTrue($this->cache->inCache('folder/foobar')); + $this->assertTrue($this->cache->inCache('folder/foobar/1')); + $this->assertTrue($this->cache->inCache('folder/foobar/2')); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 72c38686449a8887d8441377a11f0bfc910bc31f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:42:26 +0100 Subject: add resolvePath to filesystem view api --- lib/files/view.php | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 709e374d863..e3f9b762f7a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -101,6 +101,16 @@ class View { 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 -- cgit v1.2.3 From 706bb3ccd654f76c0a6c5b7874fcc1e288b13f54 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:47:00 +0100 Subject: move ETag generation to storage backends --- lib/connector/sabre/node.php | 16 +--------------- lib/files/filesystem.php | 10 ++++++++++ lib/files/storage/common.php | 16 ++++++++++++++++ lib/files/storage/storage.php | 8 ++++++++ lib/files/view.php | 15 +++++++++++++++ 5 files changed, 50 insertions(+), 15 deletions(-) (limited to 'lib/files') diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ebc9e539625..d0ab0c24988 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -210,27 +210,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return $props; } - /** - * Creates a ETag for this path. - * @param string $path Path of the file - * @return string|null Returns null if the ETag can not effectively be determined - */ - static protected function createETag($path) { - if(self::$ETagFunction) { - $hash = call_user_func(self::$ETagFunction, $path); - return $hash; - }else{ - return uniqid('', true); - } - } - /** * Returns the ETag surrounded by double-quotes for this path. * @param string $path Path of the file * @return string|null Returns null if the ETag can not effectively be determined */ static public function getETagPropertyForPath($path) { - $tag = self::createETag($path); + $tag = \OC\Files\Filesystem::getETag($path); if (empty($tag)) { return null; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 76a188e4120..ed2814211f4 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -654,6 +654,16 @@ class Filesystem { public static function getDirectoryContent($directory, $mimetype_filter = '') { return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + static public function getETag($path){ + return self::$defaultInstance->getETag($path); + } } \OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e22264d0da9..f471752d1ff 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -267,4 +267,20 @@ abstract class Common implements \OC\Files\Storage\Storage { 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('', true); + } + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 1f5c9356294..bb1ba16984d 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -63,4 +63,12 @@ interface Storage{ public function getScanner(); public function getOwner($path); + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path); } diff --git a/lib/files/view.php b/lib/files/view.php index e3f9b762f7a..a54c3ee3564 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -866,4 +866,19 @@ class View { return $files; } + + /** + * 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); + return $storage->getETag($internalPath); + } } -- cgit v1.2.3 From e7bed5ddabea5a3841d4a08082badaec025ed242 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:59:08 +0100 Subject: allow creating Cache objects with only the storage id instead of the whole storage object --- lib/files/cache/cache.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d13b56104d..dba026a611e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -19,24 +19,25 @@ class Cache { const SHALLOW = 2; //folder in cache, but not all child files are completely scanned const COMPLETE = 3; - /** - * @var \OC\Files\Storage\Storage - */ - private $storage; - /** * @var array partial data for the cache */ private $partial = array(); + /** + * @var string + */ private $storageId; /** - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $storage */ - public function __construct(\OC\Files\Storage\Storage $storage) { - $this->storage = $storage; - $this->storageId = $storage->getId(); + public function __construct($storage) { + if($storage instanceof \OC\Files\Storage\Storage){ + $this->storageId = $storage->getId(); + }else{ + $this->storageId = $storage; + } } /** -- cgit v1.2.3 From 3f644fe70c8451ab1ab877c4dd97f34366548b70 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:07:30 +0100 Subject: fix calculateFolderSize for non existing files --- lib/files/cache/cache.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index dba026a611e..83d3585bb5f 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -348,6 +348,9 @@ class Cache { */ public function calculateFolderSize($path) { $id = $this->getId($path); + if($id === -1){ + return 0; + } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); $result = $query->execute(array($id, $this->storageId)); $totalSize = 0; -- cgit v1.2.3 From 15b8a3f98757f220db190c1e9489d5888b2b1015 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:10:54 +0100 Subject: move correctFolderSize from Scanner to Cache --- lib/files/cache/cache.php | 16 ++++++++++++++++ lib/files/cache/scanner.php | 16 ---------------- lib/files/cache/watcher.php | 2 +- tests/lib/files/cache/scanner.php | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 83d3585bb5f..7c6bba4fadb 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -340,6 +340,22 @@ class Cache { return $result->fetchAll(); } + /** + * 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 === '.') { + $parent = ''; + } + $this->correctFolderSize($parent); + } + } + /** * get the size of a folder and set it in the cache * diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7062888d74a..0adde1d354d 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,20 +107,4 @@ class Scanner { } return $size; } - - /** - * update the folder size and the size of all parent folders - * - * @param $path - */ - public function correctFolderSize($path) { - $this->cache->calculateFolderSize($path); - if ($path !== '') { - $parent = dirname($path); - if ($parent === '.') { - $parent = ''; - } - $this->correctFolderSize($parent); - } - } } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index f04ca9b4656..d6039d9945c 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -50,7 +50,7 @@ class Watcher { } else { $this->scanner->scanFile($path); } - $this->scanner->correctFolderSize($path); + $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34d38c42736..f784a82dada 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -98,7 +98,7 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder2['size'], -1); - $this->scanner->correctFolderSize('folder'); + $this->cache->correctFolderSize('folder'); $cachedDataFolder = $this->cache->get(''); $this->assertNotEqual($cachedDataFolder['size'], -1); -- cgit v1.2.3 From 5a173b901f90dba3465847cde4477be9994a1341 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 20:47:40 +0100 Subject: fix Scanner->scan setting the filesize to 0 for files --- lib/files/cache/scanner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354d..eb947a2d53e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -101,9 +101,9 @@ class Scanner { } } } - } - if ($size !== -1) { - $this->cache->put($path, array('size' => $size)); + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } } return $size; } -- cgit v1.2.3 From fedff3eafe73a3eafbc1bc7af364297e8135d086 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:12:40 +0100 Subject: add cache updater --- lib/files/cache/updater.php | 71 +++++++++++++++++++++++ tests/lib/files/cache/updater.php | 116 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 lib/files/cache/updater.php create mode 100644 tests/lib/files/cache/updater.php (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php new file mode 100644 index 00000000000..fb9783023e8 --- /dev/null +++ b/lib/files/cache/updater.php @@ -0,0 +1,71 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * listen to filesystem hooks and change the cache accordingly + */ +class Updater { + + /** + * 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) { + $view = \OC\Files\Filesystem::getView(); + return $view->resolvePath($path); + } + + static public function writeUpdate($path) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($path); + $cache = new Cache($storage); + $scanner = new Scanner($storage); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } + + static public function deleteUpdate($path) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($path); + $cache = new Cache($storage); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } + + /** + * @param array $params + */ + static public function writeHook($params) { + self::writeUpdate($params['path']); + } + + /** + * @param array $params + */ + static public function renameHook($params) { + self::deleteUpdate($params['oldpath']); + self::writeUpdate($params['newpath']); + } + + /** + * @param array $params + */ + static public function deleteHook($params) { + self::deleteUpdate($params['path']); + } +} diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php new file mode 100644 index 00000000000..8059418dc16 --- /dev/null +++ b/tests/lib/files/cache/updater.php @@ -0,0 +1,116 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +use \OC\Files\Filesystem as Filesystem; + +class Updater extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + private static $user; + + public function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + $this->storage->file_put_contents('folder/bar2.txt', $textData); + + $this->scanner = $this->storage->getScanner(); + $this->scanner->scan(''); + $this->cache = $this->storage->getCache(); + + if (!self::$user) { + if (!\OC\Files\Filesystem::getView()) { + self::$user = uniqid(); + \OC\Files\Filesystem::init('/' . self::$user . '/files'); + } else { + self::$user = \OC_User::getUser(); + } + } + + Filesystem::clearMounts(); + Filesystem::mount($this->storage, array(), '/' . self::$user . '/files'); + + \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); + \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); + \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); + + } + + public function tearDown() { + $this->cache->clear(); + Filesystem::tearDown(); + } + + public function testWrite() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + Filesystem::file_put_contents('foo.txt', 'asd'); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::file_put_contents('bar.txt', 'asd'); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('bar.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + } + + public function testDelete() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + Filesystem::unlink('foo.txt', 'asd'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + } + + public function testRename() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::rename('foo.txt', 'bar.txt'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + } +} -- cgit v1.2.3 From cbcd9ba84ada830d91a6f1d7bee0ac59762835ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 00:57:30 +0100 Subject: allow storage backends to implement custom permission management --- lib/files/cache/permissions.php | 36 +++++++++++++++++++--------- lib/files/storage/common.php | 14 +++++++---- lib/files/storage/storage.php | 5 ++++ lib/files/view.php | 6 +++-- tests/lib/files/cache/permissions.php | 45 +++++++++++++++++++++-------------- tests/lib/files/cache/scanner.php | 3 ++- tests/lib/files/cache/watcher.php | 3 ++- tests/lib/files/view.php | 3 ++- 8 files changed, 76 insertions(+), 39 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index dd7233abc70..d0968337f02 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -9,6 +9,22 @@ 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 * @@ -16,7 +32,7 @@ class Permissions { * @param string $user * @return int (-1 if file no permissions set) */ - static public function get($fileId, $user) { + public function get($fileId, $user) { $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'); $result = $query->execute(array($user, $fileId)); if ($row = $result->fetchRow()) { @@ -33,7 +49,7 @@ class Permissions { * @param string $user * @param int $permissions */ - static public function set($fileId, $user, $permissions) { + public function set($fileId, $user, $permissions) { if (self::get($fileId, $user) !== -1) { $query = \OC_DB::prepare('UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'); } else { @@ -49,7 +65,7 @@ class Permissions { * @param string $user * @return int[] */ - static public function getMultiple($fileIds, $user) { + public function getMultiple($fileIds, $user) { if (count($fileIds) === 0) { return array(); } @@ -72,17 +88,15 @@ class Permissions { * @param int $fileId * @param string $user */ - static public function remove($fileId, $user) { + public function remove($fileId, $user) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); $query->execute(array($fileId, $user)); } - static public function removeMultiple($fileIds, $user) { - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); - $query->execute($params); + public function removeMultiple($fileIds, $user) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + foreach($fileIds as $fileId){ + $query->execute(array($fileId, $user)); + } } } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index f471752d1ff..cf6fe64a4f2 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= \OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= \OCP\Share::PERMISSION_READ; + $permissions |= \OCP\PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= \OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= \OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= \OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\PERMISSION_SHARE; } return $permissions; } @@ -259,6 +259,10 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Scanner($this); } + public function getPermissionsCache(){ + return new \OC\Files\Cache\Permissions($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bb1ba16984d..73dcb8fe36b 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -64,6 +64,11 @@ interface Storage{ public function getOwner($path); + /** + * @return \OC\Files\Cache\Permissions + */ + public function getPermissionsCache(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index a54c3ee3564..e516a4fed6a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -701,7 +701,8 @@ class View { } } - $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); return $data; } @@ -759,8 +760,9 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } + $permissionsCache = $storage->getPermissionsCache(); - $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { $files[$i]['permissions'] = $permissions[$file['fileid']]; } diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php index 4d47929a3ee..56dbbc4518e 100644 --- a/tests/lib/files/cache/permissions.php +++ b/tests/lib/files/cache/permissions.php @@ -9,39 +9,48 @@ namespace Test\Files\Cache; class Permissions extends \PHPUnit_Framework_TestCase { + /*** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + + function setUp(){ + $this->permissionsCache=new \OC\Files\Cache\Permissions('dummy'); + } + function testSimple() { $ids = range(1, 10); $user = uniqid(); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::set(1, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->set(1, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(1, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(2, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user . '2')); - \OC\Files\Cache\Permissions::set(1, $user, 2); - $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + $this->permissionsCache->set(1, $user, 2); + $this->assertEquals(2, $this->permissionsCache->get(1, $user)); - \OC\Files\Cache\Permissions::set(2, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->set(2, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); - \OC\Files\Cache\Permissions::remove(1, $user); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::remove(1, $user . '2'); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->remove(1, $user); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->remove(1, $user . '2'); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); $expected = array(); foreach ($ids as $id) { - \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $this->permissionsCache->set($id, $user, 10 + $id); $expected[$id] = 10 + $id; } - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + $this->permissionsCache->removeMultiple(array(10, 9), $user); unset($expected[9]); unset($expected[10]); - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + $this->permissionsCache->removeMultiple($ids, $user); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index f784a82dada..c53da92727c 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -112,7 +112,8 @@ class Scanner extends \UnitTestCase { function tearDown() { $ids = $this->cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $this->storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index a7076d9b0b5..0125dd843b9 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -23,7 +23,8 @@ class Watcher extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index fa562cb15cd..a173094b1cc 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -21,7 +21,8 @@ class View extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } -- cgit v1.2.3 From 40fae0acbf2e84782c273a82eb10a2ed9fdf8162 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 18 Nov 2012 14:10:28 +0100 Subject: fix outdated permissions cache use in scanner --- lib/files/cache/scanner.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index eb947a2d53e..404029ee2ef 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -19,12 +19,18 @@ class Scanner { */ private $cache; + /** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; - $this->cache = new Cache($storage); + $this->cache = $storage->getCache(); + $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -67,7 +73,7 @@ class Scanner { } } $id = $this->cache->put($file, $data); - Permissions::set($id, \OC_User::getUser(), $data['permissions']); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } -- cgit v1.2.3 From b76d1afe193fae3bf94aed9a95e270b452e62eb8 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 22 Nov 2012 00:44:48 -0500 Subject: Create public function initMountPoints() for initializing a specified user's mount points --- lib/files/filesystem.php | 53 +++++++++++++++++++++++++++++++++--------------- lib/util.php | 16 --------------- 2 files changed, 37 insertions(+), 32 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index ed2814211f4..cee3cd883b3 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -229,35 +229,50 @@ class Filesystem { self::$defaultInstance = new View($root); //load custom mount config - if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + self::initMountPoints(); + + self::$loaded = true; + + return true; + } + + /** + * Initialize system and personal mount points for a user + * + * @param string $user + */ + public static function initMountPoints($user = '') { + if ($user == '') { + $user = \OC_User::getUser(); + } + // Load system mount points + if (is_file(\OC::$SERVERROOT.'/config/mount.php')) { $mountConfig = include '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(\OC_User::getUser(), $group)) { + if (\OC_Group::inGroup($user, $group)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } } } } - if (isset($mountConfig['user'])) { - foreach ($mountConfig['user'] as $user => $mounts) { - if ($user === 'all' or strtolower($user) === strtolower(\OC_User::getUser())) { + foreach ($mountConfig['user'] as $mountUser => $mounts) { + if ($user === 'all' or strtolower($mountUser) === strtolower($user)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } @@ -265,10 +280,16 @@ class Filesystem { } } } - - self::$loaded = true; - - return true; + // Load personal mount points + $root = OC_User::getHome($user); + if (is_file($root.'/mount.php')) { + $mountConfig = include $root.'/mount.php'; + if (isset($mountConfig['user'][$user])) { + foreach ($mountConfig['user'][$user] as $mountPoint => $options) { + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } } /** @@ -277,8 +298,8 @@ class Filesystem { * @param string $input * @return string */ - private static function setUserVars($input) { - return str_replace('$user', \OC_User::getUser(), $input); + private static function setUserVars($user, $input) { + return str_replace('$user', $user, $input); } /** diff --git a/lib/util.php b/lib/util.php index c79afe19572..25fdcef1aea 100755 --- a/lib/util.php +++ b/lib/util.php @@ -58,8 +58,6 @@ class OC_Util { $fileOperationProxy = new OC_FileProxy_FileOperations(); OC_FileProxy::register($quotaProxy); OC_FileProxy::register($fileOperationProxy); - // Load personal mount config - self::loadUserMountPoints($user); OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); } @@ -71,20 +69,6 @@ class OC_Util { self::$fsSetup=false; } - public static function loadUserMountPoints($user) { - $user_dir = '/'.$user.'/files'; - $user_root = OC_User::getHome($user); - $userdirectory = $user_root . '/files'; - if (is_file($user_root.'/mount.php')) { - $mountConfig = include $user_root.'/mount.php'; - if (isset($mountConfig['user'][$user])) { - foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); - } - } - } - } - /** * get the current installed version of ownCloud * @return array -- cgit v1.2.3 From 208c6fd966dd5f9f387cdd1b4f030a2723144347 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 22 Nov 2012 10:21:48 +0100 Subject: fixing namespace --- lib/files/filesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index cee3cd883b3..9e8ce3ec184 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,7 +281,7 @@ class Filesystem { } } // Load personal mount points - $root = OC_User::getHome($user); + $root = \OC_User::getHome($user); if (is_file($root.'/mount.php')) { $mountConfig = include $root.'/mount.php'; if (isset($mountConfig['user'][$user])) { -- cgit v1.2.3 From e6cf082fe07e4e33c883bd5f9aaa0cc72b082741 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 22:44:43 +0100 Subject: emit a hooks during the filesystem scan --- lib/files/cache/scanner.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 404029ee2ef..e650a220f56 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -14,6 +14,11 @@ class Scanner { */ private $storage; + /** + * @var string $storageId + */ + private $storageId; + /** * @var \OC\Files\Cache\Cache $cache */ @@ -29,6 +34,7 @@ class Scanner { public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; + $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); $this->permissionsCache = $storage->getPermissionsCache(); } @@ -62,6 +68,7 @@ class Scanner { * @return array with metadata of the scanned file */ public function scanFile($file) { + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($file !== '') { $parent = dirname($file); @@ -85,6 +92,7 @@ class Scanner { * @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) { + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); $this->scanFile($path); $size = 0; -- cgit v1.2.3 From 186c9e77e89dcd057a311ed08df9e1bb9e13ea8f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:02:43 +0100 Subject: add Cache->getIncomplete for use in background scanning --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7c6bba4fadb..b52c0f40677 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -402,4 +402,23 @@ class Cache { } 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 LIMIT 1'); + $query->execute(array($this->storageId)); + if($row = $query->fetchRow()){ + return $row['path']; + }else{ + return false; + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9c469aa9374..e9105cd5abd 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -175,6 +175,23 @@ class Cache extends \UnitTestCase { $this->assertTrue($this->cache->inCache('folder/foobar/2')); } + function testGetIncomplete() { + $file1 = 'folder1'; + $file2 = 'folder2'; + $file3 = 'folder3'; + $file4 = 'folder4'; + $data = array('size' => 10, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $data['size'] = -1; + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $data['size'] = 12; + $this->cache->put($file4, $data); + + $this->assertEquals($file3, $this->cache->getIncomplete()); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 8687e0d346e7dad6890982c1a7b08befd8998aeb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:18:58 +0100 Subject: add Scanner->backgroundScan --- lib/files/cache/scanner.php | 10 ++++++++++ tests/lib/files/cache/scanner.php | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e650a220f56..3c83b6528a7 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -121,4 +121,14 @@ class Scanner { } return $size; } + + /** + * walk over any folders that are not fully scanned yet and scan them + */ + public function backgroundScan() { + while ($path = $this->cache->getIncomplete()) { + $this->scan($path); + $this->cache->correctFolderSize($path); + } + } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index c53da92727c..6d26150d82b 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -104,6 +104,28 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder['size'], -1); } + function testBackgroundScan(){ + $this->fillTestFolders(); + $this->storage->mkdir('folder2'); + $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertFalse($this->cache->inCache('folder/bar.txt')); + $this->assertFalse($this->cache->inCache('folder/2bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(-1, $cachedData['size']); + + $this->scanner->backgroundScan(); + + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + + $cachedData = $this->cache->get(''); + $this->assertnotEquals(-1, $cachedData['size']); + + $this->assertFalse($this->cache->getIncomplete()); + } + function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); $this->scanner = new \OC\Files\Cache\Scanner($this->storage); -- cgit v1.2.3 From 810563ae8aa5884a101cc64226c4f8c3c897132e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 Nov 2012 12:44:31 +0100 Subject: don't redefine inherited functions as abstract --- lib/files/storage/common.php | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index cf6fe64a4f2..9978cea5712 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,18 +23,12 @@ namespace OC\Files\Storage; abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} - abstract public function getId(); - abstract public function mkdir($path); - abstract public function rmdir($path); - abstract public function opendir($path); public function is_dir($path) { return $this->filetype($path)=='dir'; } public function is_file($path) { return $this->filetype($path)=='file'; } - abstract public function stat($path); - abstract public function filetype($path); public function filesize($path) { if($this->is_dir($path)) { return 0;//by definition @@ -46,8 +40,6 @@ abstract class Common implements \OC\Files\Storage\Storage { public function isCreatable($path) { return $this->isUpdatable($path); } - abstract public function isReadable($path); - abstract public function isUpdatable($path); public function isDeletable($path) { return $this->isUpdatable($path); } @@ -73,7 +65,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } return $permissions; } - abstract public function file_exists($path); public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; @@ -97,7 +88,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $handle = $this->fopen($path, "w"); return fwrite($handle, $data); } - abstract public function unlink($path); public function rename($path1,$path2) { if($this->copy($path1,$path2)) { return $this->unlink($path1); @@ -111,7 +101,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $count=\OC_Helper::streamCopy($source,$target); return $count>0; } - abstract public function fopen($path,$mode); /** * @brief Deletes all files and folders recursively within a directory @@ -180,7 +169,6 @@ abstract class Common implements \OC\Files\Storage\Storage { unlink($tmpFile); return $hash; } - abstract public function free_space($path); public function search($query) { return $this->searchInDir($query); } @@ -222,7 +210,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } } } - abstract public function touch($path, $mtime=null); protected function searchInDir($query,$dir='') { $files=array(); -- cgit v1.2.3 From ad706229f5dbc6382ade61493e9f100a2dc07293 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 00:17:18 +0100 Subject: explicitly sort files when using getFolderContents --- lib/files/cache/cache.php | 14 +++++++------- tests/lib/files/view.php | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index b52c0f40677..6b93673097b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -33,9 +33,9 @@ class Cache { * @param \OC\Files\Storage\Storage|string $storage */ public function __construct($storage) { - if($storage instanceof \OC\Files\Storage\Storage){ + if ($storage instanceof \OC\Files\Storage\Storage) { $this->storageId = $storage->getId(); - }else{ + } else { $this->storageId = $storage; } } @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ?'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { @@ -364,7 +364,7 @@ class Cache { */ public function calculateFolderSize($path) { $id = $this->getId($path); - if($id === -1){ + if ($id === -1) { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); @@ -412,12 +412,12 @@ class Cache { * * @return string|bool the path of the folder or false when no folder matched */ - public function getIncomplete(){ + public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); $query->execute(array($this->storageId)); - if($row = $query->fetchRow()){ + if ($row = $query->fetchRow()) { return $row['path']; - }else{ + } else { return false; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index a173094b1cc..ecfc803dc23 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,20 +55,20 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: - * folder * foo.png * foo.txt + * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('folder', $folderData[0]['name']); - $this->assertEquals('foo.png', $folderData[1]['name']); - $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); - $this->assertEquals($imageSize, $folderData[1]['size']); - $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($imageSize, $folderData[0]['size']); + $this->assertEquals($textSize, $folderData[1]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderView = new \OC\Files\View('/folder'); -- cgit v1.2.3 From c47bf9bbcefb0640c24ab0aa6ee79f4c52222b45 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 16:42:54 -0500 Subject: Add checks for storage object --- apps/files/ajax/scan.php | 15 ++-- lib/files/view.php | 207 +++++++++++++++++++++++++---------------------- 2 files changed, 120 insertions(+), 102 deletions(-) (limited to 'lib/files') diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 53ae4f5ff04..391b98608bd 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -20,13 +20,14 @@ $mountPoints = array_reverse($mountPoints); //start with the mount point of $dir foreach ($mountPoints as $mountPoint) { $storage = \OC\Files\Filesystem::getStorage($mountPoint); - error_log('scanning mp '.$mountPoint); - ScanListener::$mountPoints[$storage->getId()] = $mountPoint; - $scanner = $storage->getScanner(); - if ($force) { - $scanner->scan(''); - } else { - $scanner->backgroundScan(); + if ($storage) { + ScanListener::$mountPoints[$storage->getId()] = $mountPoint; + $scanner = $storage->getScanner(); + if ($force) { + $scanner->scan(''); + } else { + $scanner->backgroundScan(); + } } } diff --git a/lib/files/view.php b/lib/files/view.php index e516a4fed6a..468808566a7 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -671,39 +671,41 @@ class View { * - versioned */ public function getFileInfo($path) { + $data = array(); $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); + } - $data = $cache->get($internalPath); + $data = $cache->get($internalPath); - 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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); + 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); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); - $data['size'] += $rootEntry['size']; + $data['size'] += $rootEntry['size']; + } } - } - - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + } return $data; } @@ -714,75 +716,79 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { + $result = array(); $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $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']; + //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(); + $rootEntry = $subCache->get(''); + + $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; + $files[] = $rootEntry; } } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $files[] = $rootEntry; } - } - $ids = array(); + $ids = array(); - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache(); + foreach ($files as $i => $file) { + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + $permissionsCache = $storage->getPermissionsCache(); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; + } - 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; + 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; } - } else { - $result = $files; } - return $result; } @@ -802,14 +808,18 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } - return $cache->put($internalPath, $data); + return $cache->put($internalPath, $data); + } else { + return -1; + } } /** @@ -843,29 +853,32 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); - $cache = $storage->getCache(); - - $results = $cache->$method($query); - foreach ($results as $result) { - if (substr($mountPoint . $result['path'], 0, $rootLength) === $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); foreach ($results as $result) { - $result['path'] = $relativeMountPoint . $result['path']; - $files[] = $result; + if (substr($mountPoint . $result['path'], 0, $rootLength) === $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); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } + } + } return $files; } @@ -881,6 +894,10 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = $this->resolvePath($path); - return $storage->getETag($internalPath); + if ($storage) { + return $storage->getETag($internalPath); + } else { + return null; + } } } -- cgit v1.2.3 From d3e37fa157faa59598e92a9aa02c6bbf818b60e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 16:23:52 +0100 Subject: remove fileatime from common storage backend --- lib/fileproxy.php | 2 +- lib/files/storage/common.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'lib/files') diff --git a/lib/fileproxy.php b/lib/fileproxy.php index 2f81bde64a1..52ec79b4bdb 100644 --- a/lib/fileproxy.php +++ b/lib/fileproxy.php @@ -36,7 +36,7 @@ * The return value of the post-proxy will be used as the new result of the operation * The operations that have a post-proxy are: * file_get_contents, is_file, is_dir, file_exists, stat, is_readable, - * is_writable, fileatime, filemtime, filectime, file_get_contents, + * is_writable, filemtime, filectime, file_get_contents, * getMimeType, hash, fopen, free_space and search */ diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 9978cea5712..c891d0c3ad0 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -69,10 +69,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $stat = $this->stat($path); return $stat['mtime']; } - public function fileatime($path) { - $stat = $this->stat($path); - return $stat['atime']; - } public function file_get_contents($path) { $handle = $this->fopen($path, "r"); if(!$handle) { -- cgit v1.2.3 From 709aacfa0fef29692bff231f09625db5ba0bef6f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 24 Nov 2012 23:41:39 +0100 Subject: change behaviour of Filesystem::getMountPoint when a mountpoint is passed as path without trailing slash --- lib/files/filesystem.php | 8 +------- tests/lib/files/filesystem.php | 2 +- tests/lib/files/view.php | 12 ++++++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 9e8ce3ec184..4e3eb1989b7 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -144,13 +144,7 @@ class Filesystem { */ static public function getMountPoint($path) { \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); - if (!$path) { - $path = '/'; - } - if ($path[0] !== '/') { - $path = '/' . $path; - } - $path = str_replace('//', '/', $path); + $path = self::normalizePath($path) . '/'; $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 363426511bd..5837093fdd6 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -60,7 +60,7 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/folder')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/')); - $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some')); list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); $this->assertEquals('folder',$internalPath); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ecfc803dc23..6f8d29c25b2 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -71,6 +71,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + $folderData = $rootView->getDirectoryContent('/substorage'); + /** + * expected entries: + * foo.png + * foo.txt + * folder + */ + $this->assertEquals(3, count($folderData)); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); + $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); -- cgit v1.2.3 From cc5d8e56098189f49fbd68c598c11be2b8354846 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 20:29:57 -0500 Subject: Check if data variable in scanner isn't null before using it --- lib/files/cache/scanner.php | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 3c83b6528a7..9ee509bb132 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -70,17 +70,19 @@ class Scanner { public function scanFile($file) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); - if ($file !== '') { - $parent = dirname($file); - if ($parent === '.') { - $parent = ''; - } - if (!$this->cache->inCache($parent)) { - $this->scanFile($parent); + if ($data) { + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } } + $id = $this->cache->put($file, $data); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } - $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } @@ -101,17 +103,19 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($data['mimetype'] === 'httpd/unix-directory') { - if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); - } else { - $data['size'] = -1; + if ($data) { + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } + } + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { + $size += $data['size']; } - } - if ($data['size'] === -1) { - $size = -1; - } elseif ($size !== -1) { - $size += $data['size']; } } } -- cgit v1.2.3 From 0cfef83ed98951f852b07ce61dc10ee2e8266445 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:08:35 +0100 Subject: sort output of getFolderContent by name --- lib/files/cache/cache.php | 2 +- tests/lib/files/view.php | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6b93673097b..bc52f21d910 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6f8d29c25b2..ed08dcc1148 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,33 +55,33 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: + * folder * foo.png * foo.txt - * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($imageSize, $folderData[0]['size']); - $this->assertEquals($textSize, $folderData[1]['size']); - $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderData = $rootView->getDirectoryContent('/substorage'); /** * expected entries: + * folder * foo.png * foo.txt - * folder */ $this->assertEquals(3, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); -- cgit v1.2.3 From a609992a75d1dad15398f55e22ad2244c78650dc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:30:57 +0100 Subject: better check if we are passing a fileid to Cache::get --- lib/files/cache/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index bc52f21d910..5aeb6f25af0 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -47,7 +47,7 @@ class Cache { * @return array */ public function get($file) { - if (is_string($file)) { + if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; $params = array($this->storageId, md5($file)); } else { //file id -- cgit v1.2.3 From dbbb357f62c1ba86bdff0fbe63e4cea9bc2977fc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 30 Nov 2012 01:41:30 +0100 Subject: add upgrade path from old cache to preserve file id's --- apps/files/appinfo/app.php | 14 +++++++++++-- apps/files/appinfo/version | 2 +- lib/files/cache/upgrade.php | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 lib/files/cache/upgrade.php (limited to 'lib/files') diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index b431ddfec02..fb64a80ec0d 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -1,8 +1,18 @@ "files_index", "order" => 0, "href" => OCP\Util::linkTo( "files", "index.php" ), "icon" => OCP\Util::imagePath( "core", "places/home.svg" ), "name" => $l->t("Files") )); +OCP\App::addNavigationEntry(array("id" => "files_index", "order" => 0, "href" => OCP\Util::linkTo("files", "index.php"), "icon" => OCP\Util::imagePath("core", "places/home.svg"), "name" => $l->t("Files"))); OC_Search::registerProvider('OC_Search_Provider_File'); + +if (OC_User::isLoggedIn()) { + // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually + $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); + if ($cacheVersion < 5) { + \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); + \OC\Files\Cache\Upgrade::upgrade(); + OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); + } +} diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version index 0664a8fd291..2bf1ca5f549 100644 --- a/apps/files/appinfo/version +++ b/apps/files/appinfo/version @@ -1 +1 @@ -1.1.6 +1.1.7 diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php new file mode 100644 index 00000000000..5be04b42070 --- /dev/null +++ b/lib/files/cache/upgrade.php @@ -0,0 +1,50 @@ + + * 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 { + static $permissionsCaches = array(); + + static function upgrade() { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + $oldEntriesResult = $oldEntriesQuery->execute(); + + while ($row = $oldEntriesResult->fetchRow()) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath; + */ + $pathHash = md5($internalPath); + $storageId = $storage->getId(); + $parentId = ($internalPath === '') ? -1 : $row['parent']; + + $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); + + $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; + $permissionsCache = self::getPermissionsCache($storage); + $permissionsCache->set($row['id'], $row['user'], $permissions); + } + } + + /** + * @param \OC\Files\Storage\Storage $storage + * @return Permissions + */ + static function getPermissionsCache($storage) { + $storageId = $storage->getId(); + if (!isset(self::$permissionsCaches[$storageId])) { + self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + } + return self::$permissionsCaches[$storageId]; + } +} -- cgit v1.2.3 From 702444b2422326388e494091e815fd3d9b03cc87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 1 Dec 2012 00:59:49 +0100 Subject: fail gracefully when no old filecache is present during upgrade --- lib/files/cache/upgrade.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 5be04b42070..899f6f7ac83 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -16,7 +16,14 @@ class Upgrade { VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - $oldEntriesResult = $oldEntriesQuery->execute(); + try{ + $oldEntriesResult = $oldEntriesQuery->execute(); + }catch(\Exception $e){ + return; + } + if(!$oldEntriesResult){ + return; + } while ($row = $oldEntriesResult->fetchRow()) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); -- cgit v1.2.3 From 01eb5d2790638ab836adc95a9726b6a1003562b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 2 Dec 2012 03:43:51 +0100 Subject: fix some edge cases while scanning the root of a storage --- lib/files/cache/scanner.php | 4 ++-- lib/files/filesystem.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 9ee509bb132..4c0ec9617f9 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -71,7 +71,7 @@ class Scanner { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { - if ($file !== '') { + if ($file) { $parent = dirname($file); if ($parent === '.') { $parent = ''; @@ -101,7 +101,7 @@ class Scanner { if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = ($path !== '') ? $path . '/' . $file : $file; + $child = ($path) ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4e3eb1989b7..724c83b3618 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -143,8 +143,8 @@ class Filesystem { * @return string */ static public function getMountPoint($path) { - \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $path = self::normalizePath($path) . '/'; + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { @@ -205,7 +205,7 @@ class Filesystem { $mountpoint = self::getMountPoint($path); if ($mountpoint) { $storage = self::getStorage($mountpoint); - if ($mountpoint === $path) { + if ($mountpoint === $path or $mountpoint . '/' === $path) { $internalPath = ''; } else { $internalPath = substr($path, strlen($mountpoint)); -- cgit v1.2.3 From 317cd4c70a3042c4e16424cafb4a8b34c8cd8c3c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 6 Dec 2012 17:49:35 +0100 Subject: catch error if old filecache table is not present during upgrade --- lib/files/cache/upgrade.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 899f6f7ac83..ebac387de96 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -15,13 +15,17 @@ class Upgrade { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - try{ + try { + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + } catch (\Exception $e) { + return; + } + try { $oldEntriesResult = $oldEntriesQuery->execute(); - }catch(\Exception $e){ + } catch (\Exception $e) { return; } - if(!$oldEntriesResult){ + if (!$oldEntriesResult) { return; } -- cgit v1.2.3 From 8635699db932959ac147193473b014406b0e9e09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:06:21 +0100 Subject: fix cache behaviour for non existing files --- lib/files/view.php | 28 +++++++++++++++------------- tests/lib/files/cache/cache.php | 5 +++++ tests/lib/files/view.php | 3 +++ 3 files changed, 23 insertions(+), 13 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 468808566a7..994dbcc85cf 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -691,20 +691,22 @@ class View { $data = $cache->get($internalPath); - 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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if ($data) { + 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); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } } - } - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + } } return $data; } @@ -888,7 +890,7 @@ class View { * @param string $path * @return string */ - public function getETag($path){ + public function getETag($path) { /** * @var Storage\Storage $storage * @var string $internalPath diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index e9105cd5abd..a2b131ac0ac 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -192,6 +192,11 @@ class Cache extends \UnitTestCase { $this->assertEquals($file3, $this->cache->getIncomplete()); } + function testNonExisting() { + $this->assertFalse($this->cache->get('foo.txt')); + $this->assertEquals(array(), $this->cache->getFolderContents('foo')); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ed08dcc1148..1b8f6dc1e8c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -92,6 +92,9 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertTrue($cachedData['encrypted']); $this->assertEquals($cachedData['fileid'], $id); + + $this->assertFalse($rootView->getFileInfo('/non/existing')); + $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } public function testAutoScan() { -- cgit v1.2.3 From 438d3c21f651240e416b6e50ad49f72dd079a9ae Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:24:53 +0100 Subject: actually connect the filesystem hooks to the cache updater --- lib/files/filesystem.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 724c83b3618..c5b56ba9f01 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -685,4 +685,8 @@ class Filesystem { \OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); +\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); +\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); + \OC_Util::setupFS(); -- cgit v1.2.3 From bc52f121626bb1bb1f67bc1f876d0420d153b3d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 02:29:34 +0100 Subject: dont insert and entry in the filecache during upgrade if the id already exists in the filecache most likely the result from an incompelte upgrade --- lib/files/cache/upgrade.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index ebac387de96..9219deebef5 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -29,7 +29,13 @@ class Upgrade { return; } + $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + while ($row = $oldEntriesResult->fetchRow()) { + if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + continue; + } + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); /** * @var \OC\Files\Storage\Storage $storage -- cgit v1.2.3 From 4be039e6cbc0a826b07fc2af1a6c6d94888a9187 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:10:56 +0100 Subject: Filecache Watcher: use scan or scanFile based on the current item, not the cached item --- lib/files/cache/watcher.php | 6 ++++-- tests/lib/files/cache/watcher.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index d6039d9945c..31059ec7f56 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -44,12 +44,14 @@ class Watcher { public function checkUpdate($path) { $cachedEntry = $this->cache->get($path); if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) { - if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + if ($this->storage->is_dir($path)) { $this->scanner->scan($path, Scanner::SCAN_SHALLOW); - $this->cleanFolder($path); } else { $this->scanner->scanFile($path); } + if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->cleanFolder($path); + } $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 0125dd843b9..07c8ac3640c 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -63,6 +63,40 @@ class Watcher extends \PHPUnit_Framework_TestCase { $this->assertFalse($cache->inCache('folder/bar2.txt')); } + public function testFileToFolder() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate(''); + + $entry= $cache->get('foo.txt'); + $this->assertEquals(-1, $entry['size']); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertFalse($cache->inCache('folder')); + $this->assertFalse($cache->inCache('folder/bar.txt')); + + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('foo.txt', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate('foo.txt'); + + $entry= $cache->get('foo.txt'); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertTrue($cache->inCache('foo.txt/bar.txt')); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From cf3665057c0c195bb3a0e2d9f8f8746f5d2f5787 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:20:50 +0100 Subject: make sure folders that are not fully scanned are at least shallow scanned when we open them the fact that they are in the cache does not mean they are scanned --- lib/files/view.php | 2 +- tests/lib/files/view.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 994dbcc85cf..6d917bb585e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -728,7 +728,7 @@ class View { if ($storage) { $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { + if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 1b8f6dc1e8c..712166ab32c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -97,6 +97,19 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testCacheIncompleteFolder() { + $storage1 = $this->getTestStorage(false); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + $rootView = new \OC\Files\View(''); + + $entries = $rootView->getDirectoryContent('/'); + $this->assertEquals(3, count($entries)); + + // /folder will already be in the cache but not scanned + $entries = $rootView->getDirectoryContent('/folder'); + $this->assertEquals(1, count($entries)); + } + public function testAutoScan() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(false); -- cgit v1.2.3 From 8951769cae5f1acc9b709ac676fffe26513d14f6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 15 Dec 2012 17:16:26 -0500 Subject: Check sub storage isn't null or false --- lib/files/view.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 6d917bb585e..592c484a21c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -697,10 +697,11 @@ class View { $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if ($subStorage) { + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + $data['size'] += $rootEntry['size']; + } } } -- cgit v1.2.3 From b12abb2c94072ab5b84d0477ecb7ce9789bdda0d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 23:28:07 +0100 Subject: use numeric ids for storages in the filecache --- db_structure.xml | 40 ++++++++++++++++++++++++++++++++++++++-- lib/files/cache/cache.php | 44 ++++++++++++++++++++++++++++++++++---------- lib/files/cache/upgrade.php | 21 +++++++++++++++++++-- lib/util.php | 2 +- 4 files changed, 92 insertions(+), 15 deletions(-) (limited to 'lib/files') diff --git a/db_structure.xml b/db_structure.xml index 2856ee4ff94..aa0916264c9 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -58,6 +58,42 @@
+ + + *dbprefix*storages + + + + + id + text + + true + 64 + + + + numeric_id + integer + 0 + true + 1 + 4 + + + + storages_id_index + true + + id + ascending + + + + + +
+ *dbprefix*filecache @@ -75,10 +111,10 @@ storage - text + integer true - 64 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5aeb6f25af0..3ebae9baa5d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -29,6 +29,13 @@ class Cache { */ private $storageId; + /** + * numeric storage id + * + * @var int $numericId + */ + private $numericId; + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -38,6 +45,20 @@ class Cache { } else { $this->storageId = $storage; } + + $query = \OC_DB::prepare('SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'); + $result = $query->execute(array($this->storageId)); + if ($row = $result->fetchRow()) { + $this->numericId = $row['numeric_id']; + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*storages`(`id`) VALUES(?)'); + $query->execute(array($this->storageId)); + $this->numericId = \OC_DB::insertid('*PREFIX*filecache'); + } + } + + public function getNumericStorageId() { + return $this->numericId; } /** @@ -49,7 +70,7 @@ class Cache { public function get($file) { if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($this->storageId, md5($file)); + $params = array($this->numericId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -128,7 +149,7 @@ class Cache { list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $this->storageId; + $params[] = $this->numericId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); @@ -189,7 +210,7 @@ class Cache { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -273,7 +294,10 @@ class Cache { * remove all entries for files that are stored on the storage from the cache */ public function clear() { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage = ?'); + $query->execute(array($this->numericId)); + + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*storages` WHERE id = ?'); $query->execute(array($this->storageId)); } @@ -285,7 +309,7 @@ class Cache { public function getStatus($file) { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { return self::SHALLOW; @@ -312,7 +336,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' ); - $result = $query->execute(array($pattern, $this->storageId)); + $result = $query->execute(array($pattern, $this->numericId)); $files = array(); while ($row = $result->fetchRow()) { $files[] = $row; @@ -336,7 +360,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); - $result = $query->execute(array($mimetype, $this->storageId)); + $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } @@ -368,7 +392,7 @@ class Cache { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); - $result = $query->execute(array($id, $this->storageId)); + $result = $query->execute(array($id, $this->numericId)); $totalSize = 0; $hasChilds = 0; while ($row = $result->fetchRow()) { @@ -395,7 +419,7 @@ class Cache { */ public function getAll() { $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); - $result = $query->execute(array($this->storageId)); + $result = $query->execute(array($this->numericId)); $ids = array(); while ($row = $result->fetchRow()) { $ids[] = $row['fileid']; @@ -414,7 +438,7 @@ class Cache { */ public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); - $query->execute(array($this->storageId)); + $query->execute(array($this->numericId)); if ($row = $query->fetchRow()) { return $row['path']; } else { diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 9219deebef5..77db4c2339e 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -11,6 +11,8 @@ namespace OC\Files\Cache; class Upgrade { static $permissionsCaches = array(); + static $numericIds = array(); + static function upgrade() { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); @@ -32,7 +34,7 @@ class Upgrade { $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); while ($row = $oldEntriesResult->fetchRow()) { - if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { continue; } @@ -42,7 +44,7 @@ class Upgrade { * @var string $internalPath; */ $pathHash = md5($internalPath); - $storageId = $storage->getId(); + $storageId = self::getNumericId($storage); $parentId = ($internalPath === '') ? -1 : $row['parent']; $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); @@ -64,4 +66,19 @@ class Upgrade { } return self::$permissionsCaches[$storageId]; } + + /** + * get the numeric storage id + * + * @param \OC\Files\Storage\Storage $storage + * @return int + */ + static function getNumericId($storage) { + $storageId = $storage->getId(); + if (!isset(self::$numericIds[$storageId])) { + $cache = new Cache($storage); + self::$numericIds[$storageId] = $cache->getNumericStorageId(); + } + return self::$numericIds[$storageId]; + } } diff --git a/lib/util.php b/lib/util.php index 0f6ead24190..4411b327310 100755 --- a/lib/util.php +++ b/lib/util.php @@ -75,7 +75,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,02); + return array(4,91,04); } /** -- cgit v1.2.3 From b4515d874e5259647886d148db902f9753bbeb81 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 26 Dec 2012 15:36:50 -0500 Subject: Only folders have Create permission --- lib/files/storage/common.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index c891d0c3ad0..3cf960d05df 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -38,7 +38,10 @@ abstract class Common implements \OC\Files\Storage\Storage { } } public function isCreatable($path) { - return $this->isUpdatable($path); + if ($this->is_dir($path) && $this->isUpdatable($path)) { + return true; + } + return false; } public function isDeletable($path) { return $this->isUpdatable($path); -- cgit v1.2.3 From 8bdfb040565eafb33bc27305463eb08374f14e32 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 28 Dec 2012 15:06:12 -0500 Subject: Fix shared folders --- apps/files_sharing/lib/cache.php | 17 ++++++++++++++--- lib/files/filesystem.php | 1 + lib/util.php | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 196e767cf6e..d2ac8ccaaad 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -30,6 +30,10 @@ class Shared_Cache extends Cache { private $files = array(); + public function __construct($storage) { + + } + /** * @brief Get the source cache of a shared file or folder * @param string Shared target file path @@ -41,8 +45,12 @@ class Shared_Cache extends Cache { $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; \OC\Files\Filesystem::initMountPoints($source['uid_owner']); list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']); - $this->files[$target] = $internalPath; - return $storage->getCache(); + if ($storage) { + $this->files[$target] = $internalPath; + $cache = $storage->getCache(); + $this->numericId = $cache->getNumericStorageId(); + return $cache; + } } return false; } @@ -83,8 +91,11 @@ class Shared_Cache extends Cache { if ($folder == '') { return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); } else { - return $this->getSourceCache($folder)->getFolderContents('/'.$this->files[$folder]); + if ($cache = $this->getSourceCache($folder)) { + return $cache->getFolderContents($this->files[$folder]); + } } + return false; } /** diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index c5b56ba9f01..8183b8ff99c 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -276,6 +276,7 @@ class Filesystem { } // Load personal mount points $root = \OC_User::getHome($user); + self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); if (is_file($root.'/mount.php')) { $mountConfig = include $root.'/mount.php'; if (isset($mountConfig['user'][$user])) { diff --git a/lib/util.php b/lib/util.php index 4ebc2564d1c..c5a495234d0 100755 --- a/lib/util.php +++ b/lib/util.php @@ -51,7 +51,6 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); -- cgit v1.2.3 From 2c23e143d33e231e62dccb450bf1f1b0f3938ccd Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 16:32:55 -0500 Subject: Store etags in the file cache --- db_structure.xml | 8 ++++++++ lib/files/cache/cache.php | 10 +++++----- lib/files/cache/scanner.php | 1 + lib/util.php | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) (limited to 'lib/files') diff --git a/db_structure.xml b/db_structure.xml index aa0916264c9..7c67ca78f4e 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -189,6 +189,14 @@ 4 + + etag + text + + true + 250 + + storage_path_hash true diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5d..d105f865ebd 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -76,7 +76,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -107,7 +107,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); @@ -180,7 +180,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag'); $params = array(); $queryParts = array(); @@ -333,7 +333,7 @@ class Cache { */ public function search($pattern) { $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' ); $result = $query->execute(array($pattern, $this->numericId)); @@ -357,7 +357,7 @@ class Cache { $where = '`mimepart` = ?'; } $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); $result = $query->execute(array($mimetype, $this->numericId)); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f9..e7bfb1898e1 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -58,6 +58,7 @@ class Scanner { $data['size'] = $this->storage->filesize($path); $data['permissions'] = $this->storage->getPermissions($path); } + $data['etag'] = $this->storage->getETag($path); return $data; } diff --git a/lib/util.php b/lib/util.php index c5a495234d0..df26a825d1c 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** -- cgit v1.2.3 From 83064aca51db7d8382282743ade2ab9da2a6e1b0 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:23:31 -0500 Subject: Remove old etag code --- lib/connector/sabre/node.php | 24 ------------------------ lib/files/filesystem.php | 21 --------------------- lib/files/view.php | 2 -- lib/filesystem.php | 7 ------- 4 files changed, 54 deletions(-) (limited to 'lib/files') diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index d4023dfad78..dd8ae152ff5 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -218,28 +218,4 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return null; } - /** - * @brief Remove the ETag from the cache. - * @param string $path Path of the file - */ - static public function removeETagPropertyForPath($path) { - // remove tags from this and parent paths - $paths = array(); - while ($path != '/' && $path != '.' && $path != '' && $path != '\\') { - $paths[] = $path; - $path = dirname($path); - } - if (empty($paths)) { - return; - } - $paths[] = $path; - $path_placeholders = join(',', array_fill(0, count($paths), '?')); - $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`' - .' WHERE `userid` = ?' - .' AND `propertyname` = ?' - .' AND `propertypath` IN ('.$path_placeholders.')' - ); - $vals = array( OC_User::getUser(), self::GETETAG_PROPERTYNAME ); - $query->execute(array_merge( $vals, $paths )); - } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99c..d62b5186cbe 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -582,23 +582,6 @@ class Filesystem { return self::$defaultInstance->hasUpdated($path, $time); } - static public function removeETagHook($params, $root = false) { - if (isset($params['path'])) { - $path = $params['path']; - } else { - $path = $params['oldpath']; - } - - if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new View($root); - $count = 1; - $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); - } - - $path = self::normalizePath($path); - \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); - } - /** * normalize a path * @@ -682,10 +665,6 @@ class Filesystem { } } -\OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); -\OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); -\OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); - \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21c..77146895e64 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -462,8 +462,6 @@ class View { Filesystem::signal_post_write, array(Filesystem::signal_param_path => $path2) ); - } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions - Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 20b5ab27909..57cca902303 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -398,13 +398,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::hasUpdated($path, $time); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function removeETagHook($params, $root = false) { - \OC\Files\Filesystem::removeETagHook($params, $root); - } - /** * normalize a path * -- cgit v1.2.3 From 77f12c526bf0010219e363844b588ffae27f1251 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:54:51 -0500 Subject: Update etags in parent folders --- lib/files/cache/updater.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e8..d57e4a1abe6 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -34,6 +34,7 @@ class Updater { $scanner = new Scanner($storage); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); } static public function deleteUpdate($path) { @@ -45,6 +46,29 @@ class Updater { $cache = new Cache($storage); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); + } + + static public function eTagUpdate($path) { + if ($path !== '') { + $parent = dirname($path); + if ($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('etag' => $storage->getETag($internalPath))); + self::updateFolderETags($parent); + } + } + } } /** -- cgit v1.2.3 From 3ee3323b8766992a0b60bb76b909e49fc1ea76d2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 20:27:38 -0500 Subject: Fix retrieving of cache and scanner in Updater class --- lib/files/cache/updater.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e8..c8c96a97eea 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -30,10 +30,12 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $scanner = new Scanner($storage); - $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } } static public function deleteUpdate($path) { @@ -42,9 +44,11 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $cache->remove($internalPath); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } } /** -- cgit v1.2.3 From 96e08a1d962b42782d03721009970cbab352eec2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 21:23:17 -0500 Subject: Fix function name --- lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index d57e4a1abe6..7fc9bd382fe 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -65,7 +65,7 @@ class Updater { $id = $cache->getId($internalPath); if ($id !== -1) { $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::updateFolderETags($parent); + self::eTagUpdate($parent); } } } -- cgit v1.2.3 From d0a50fae8317e4b4871027ee4b2940ab5443961f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 31 Dec 2012 18:16:44 -0500 Subject: Fix eTagUpdate and add tests --- lib/files/cache/updater.php | 2 +- tests/lib/files/cache/updater.php | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 26041590091..cfc1ec731e2 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -54,7 +54,7 @@ class Updater { } static public function eTagUpdate($path) { - if ($path !== '') { + if ($path !== '' && $path !== '/') { $parent = dirname($path); if ($parent === '.') { $parent = ''; diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index d19966c1910..cad3d9d46fc 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -70,14 +70,18 @@ class Updater extends \PHPUnit_Framework_TestCase { public function testWrite() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); + $fooCachedData = $this->cache->get('foo.txt'); Filesystem::file_put_contents('foo.txt', 'asd'); $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::file_put_contents('bar.txt', 'asd'); @@ -86,38 +90,50 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, $cachedData['size']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testDelete() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); Filesystem::unlink('foo.txt', 'asd'); $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); $this->assertTrue($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::rmdir('bar_folder'); $this->assertFalse($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testRename() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); + $fooCachedData = $this->cache->get('foo.txt'); $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } } -- cgit v1.2.3 From b41189de4420ea8a48adaaf7bb59f9227124b70a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:04:29 +0100 Subject: Cache: allow storage backends to overwrite Watcher --- lib/files/storage/common.php | 7 +++++++ lib/files/storage/storage.php | 5 +++++ lib/files/view.php | 4 ++-- tests/lib/files/cache/watcher.php | 14 +++++++------- 4 files changed, 21 insertions(+), 9 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3cf960d05df..ab167f28646 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -249,6 +249,13 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Permissions($this); } + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(){ + return new \OC\Files\Cache\Watcher($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 73dcb8fe36b..b603381dc90 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -69,6 +69,11 @@ interface Storage{ */ public function getPermissionsCache(); + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21c..d3f93d39f5a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -685,7 +685,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } @@ -733,7 +733,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 07c8ac3640c..e8a1689cab0 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -32,7 +32,7 @@ class Watcher extends \PHPUnit_Framework_TestCase { function testWatcher() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); @@ -66,16 +66,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { public function testFileToFolder() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate(''); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals(-1, $entry['size']); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertFalse($cache->inCache('folder')); @@ -83,16 +83,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate('foo.txt'); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertTrue($cache->inCache('foo.txt/bar.txt')); } -- cgit v1.2.3 From 04f83e3b539c6a20ce819bbe4f66c1996e7169f7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:11:39 +0100 Subject: Cache: optional path argument for getCache/Scanner/etc --- lib/files/storage/common.php | 11 ++++------- lib/files/storage/storage.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index ab167f28646..e859d447f39 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -237,22 +237,19 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->filemtime($path)>$time; } - public function getCache(){ + public function getCache($path=''){ return new \OC\Files\Cache\Cache($this); } - public function getScanner(){ + public function getScanner($path=''){ return new \OC\Files\Cache\Scanner($this); } - public function getPermissionsCache(){ + public function getPermissionsCache($path=''){ return new \OC\Files\Cache\Permissions($this); } - /** - * @return \OC\Files\Cache\Watcher - */ - public function getWatcher(){ + public function getWatcher($path=''){ return new \OC\Files\Cache\Watcher($this); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b603381dc90..2cc835236ba 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -54,25 +54,29 @@ interface Storage{ public function hasUpdated($path,$time); /** + * @param string $path * @return \OC\Files\Cache\Cache */ - public function getCache(); + public function getCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Scanner */ - public function getScanner(); + public function getScanner($path=''); public function getOwner($path); /** + * @param string $path * @return \OC\Files\Cache\Permissions */ - public function getPermissionsCache(); + public function getPermissionsCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Watcher */ - public function getWatcher(); + public function getWatcher($path=''); /** * get the ETag for a file or folder -- cgit v1.2.3 From a164fd160fb0d3da548dfe01ec27df67d76b0b59 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:19:53 +0100 Subject: Cache: provide path hints to getCache/etc where available --- lib/files/cache/updater.php | 6 +++--- lib/files/view.php | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index c8c96a97eea..c14adba3e55 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -31,8 +31,8 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); - $scanner = $storage->getScanner(); + $cache = $storage->getCache($internalPath); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); } @@ -45,7 +45,7 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); } diff --git a/lib/files/view.php b/lib/files/view.php index d3f93d39f5a..8558b03fe1e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -679,13 +679,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -698,14 +698,14 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += $rootEntry['size']; } } } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); } } @@ -727,13 +727,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -745,7 +745,7 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $relativePath = trim(substr($mountPoint, $dirLength), '/'); @@ -769,7 +769,7 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { @@ -812,10 +812,10 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($path); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } @@ -857,7 +857,7 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $results = $cache->$method($query); foreach ($results as $result) { @@ -871,7 +871,7 @@ class View { foreach ($mountPoints as $mountPoint) { $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $relativeMountPoint = substr($mountPoint, $rootLength); $results = $cache->$method($query); -- cgit v1.2.3 From a068ddff64bb6071de204b948129c4ca23c16d26 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 2 Jan 2013 14:40:06 -0500 Subject: Use the sub storage's permission cache for retrieving the correct permission --- lib/files/view.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 8558b03fe1e..9ba3eea3cf9 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -739,6 +739,18 @@ class View { $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter + $ids = array(); + foreach ($files as $i => $file) { + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + + $permissionsCache = $storage->getPermissionsCache($internalPath); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $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); @@ -758,24 +770,14 @@ class View { } } 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(''); + $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); $files[] = $rootEntry; } } } - $ids = array(); - - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } - if ($mimetype_filter) { foreach ($files as $file) { if (strpos($mimetype_filter, '/')) { -- cgit v1.2.3 From 38876fc98a11a917e68780357d7f4b5a146ba89a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:07:04 -0500 Subject: Update old storage classes names to the new namespace during mounting --- apps/files_external/lib/config.php | 12 ++++++++++++ lib/files/filesystem.php | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 323e4060a43..d7286c52c02 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -120,6 +120,10 @@ class OC_Mount_Config { if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) { foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) { foreach ($mounts as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); // Merge the mount point into the current mount points @@ -139,6 +143,10 @@ class OC_Mount_Config { if (isset($mountPoints[self::MOUNT_TYPE_USER])) { foreach ($mountPoints[self::MOUNT_TYPE_USER] as $user => $mounts) { foreach ($mounts as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); // Merge the mount point into the current mount points @@ -169,6 +177,10 @@ class OC_Mount_Config { $personal = array(); if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) { foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/uid/files/' from mount point $personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99c..b9fd6a03762 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,7 +364,10 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; -- cgit v1.2.3 From 1137723b2a46c37d61e7f501694c73562b21ef74 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:13:45 -0500 Subject: Remove unnecessary length parameter from last commit --- apps/files_external/lib/config.php | 6 +++--- lib/files/filesystem.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index d7286c52c02..3bb512493d8 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -122,7 +122,7 @@ class OC_Mount_Config { foreach ($mounts as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -145,7 +145,7 @@ class OC_Mount_Config { foreach ($mounts as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -179,7 +179,7 @@ class OC_Mount_Config { foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/uid/files/' from mount point $personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b9fd6a03762..d9487bde806 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -366,7 +366,7 @@ class Filesystem { } // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + $class = '\OC\Files\Storage\\'.substr($class, 15); } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); -- cgit v1.2.3 From 457dc270f5147863c00b55355542298ba4d41762 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 00:36:39 +0100 Subject: Fix messed up mounts --- lib/files/filesystem.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d9487bde806..b3ba62c3a49 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,14 +364,14 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - // Update old classes to new namespace - if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); - } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; } else { + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15); + } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } } -- cgit v1.2.3 From 439578288facbae3144f131aca85a7235f622053 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:03:11 +0100 Subject: Cache: split permission cache scanning and cache scanning --- lib/files/cache/scanner.php | 9 --------- lib/files/view.php | 30 ++++++++++++++++++++++-------- tests/lib/files/view.php | 1 + 3 files changed, 23 insertions(+), 17 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f9..526d4a2aab5 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -24,11 +24,6 @@ class Scanner { */ private $cache; - /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - private $permissionsCache; - const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; @@ -36,7 +31,6 @@ class Scanner { $this->storage = $storage; $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -53,10 +47,8 @@ class Scanner { $data['mtime'] = $this->storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { $data['size'] = -1; //unknown - $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { $data['size'] = $this->storage->filesize($path); - $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -81,7 +73,6 @@ class Scanner { } } $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 9ba3eea3cf9..124345f3c6f 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -680,6 +680,8 @@ class View { 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); @@ -705,8 +707,12 @@ class View { } } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissions = $permissionsCache->get($data['fileid'], $user); + if ($permissions === -1) { + $permissions = $storage->getPermissions($internalPath); + $permissionsCache->set($data['fileid'], $user, $permissions); + } + $data['permissions'] = $permissions; } } return $data; @@ -728,6 +734,8 @@ class View { 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); @@ -743,12 +751,13 @@ class View { foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; + $permissions = $permissionsCache->get($file['fileid'], $user); + if ($permissions === -1) { + $permissions = $storage->getPermissions($file['path']); + $permissionsCache->set($file['fileid'], $user, $permissions); + } + $files[$i]['permissions'] = $permissions; } //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders @@ -772,7 +781,12 @@ class View { $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $subPermissionsCache = $subStorage->getPermissionsCache(''); - $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); + $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); + if ($permissions === -1) { + $permissions = $subStorage->getPermissions($rootEntry['path']); + $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); + } + $rootEntry['permissions'] = $subPermissionsCache; $files[] = $rootEntry; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 712166ab32c..4b0abc2201d 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -43,6 +43,7 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); + $this->assertEquals(\OCP\PERMISSION_ALL ^ \OCP\PERMISSION_CREATE, $cachedData['permissions']); $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); -- cgit v1.2.3 From d0377b1951a156e218ca0200340e2bcfb51ac0c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:40:09 +0100 Subject: Cache: normalize mimetypes --- db_structure.xml | 44 +++++++++++++++++++++++++++++++---- lib/files/cache/cache.php | 59 +++++++++++++++++++++++++++++++++++++++++++---- lib/files/view.php | 2 +- lib/util.php | 2 +- 4 files changed, 96 insertions(+), 11 deletions(-) (limited to 'lib/files') diff --git a/db_structure.xml b/db_structure.xml index e47cf3c6292..3022983473b 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -94,6 +94,42 @@
+ + + *dbprefix*mimetypes + + + + + id + integer + 0 + true + 1 + 4 + + + + mimetype + text + + true + 64 + + + + mimetype_id_index + true + + mimetype + ascending + + + + + +
+ *dbprefix*filecache @@ -151,18 +187,18 @@ mimetype - text + integer true - 64 + 4 mimepart - text + integer true - 32 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5d..0001c2752da 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -36,6 +36,9 @@ class Cache { */ private $numericId; + private $mimetypeIds = array(); + private $mimetypes = array(); + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -61,6 +64,41 @@ class Cache { return $this->numericId; } + /** + * normalize mimetypes + * + * @param string $mime + * @return int + */ + public function getMimetypeId($mime) { + if (!isset($this->mimetypeIds[$mime])) { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); + $result = $query->execute(array($mime)); + if ($row = $result->fetchRow()) { + $this->mimetypeIds[$mime] = $row['id']; + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)'); + $query->execute(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])) { + $query = \OC_DB::prepare('SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'); + $result = $query->execute(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 * @@ -92,6 +130,8 @@ class Cache { $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['encrypted'] = (bool)$data['encrypted']; + $data['mimetype'] = $this->getMimetype($data['mimetype']); + $data['mimepart'] = $this->getMimetype($data['mimepart']); } return $data; @@ -110,7 +150,12 @@ class Cache { 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); - return $result->fetchAll(); + $files = $result->fetchAll(); + foreach ($files as &$file) { + $file['mimetype'] = $this->getMimetype($file['mimetype']); + $file['mimepart'] = $this->getMimetype($file['mimepart']); + } + return $files; } else { return array(); } @@ -179,22 +224,23 @@ class Cache { * @param array $data * @return array */ - static function buildParts(array $data) { + function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { if (array_search($name, $fields) !== false) { - $params[] = $value; - $queryParts[] = '`' . $name . '`'; if ($name === 'path') { $params[] = md5($value); $queryParts[] = '`path_hash`'; } elseif ($name === 'mimetype') { - $params[] = substr($value, 0, strpos($value, '/')); + $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); $queryParts[] = '`mimepart`'; + $value = $this->getMimetypeId($value); } + $params[] = $value; + $queryParts[] = '`' . $name . '`'; } } return array($queryParts, $params); @@ -339,6 +385,8 @@ class Cache { $result = $query->execute(array($pattern, $this->numericId)); $files = array(); while ($row = $result->fetchRow()) { + $row['mimetype'] = $this->getMimetype($row['mimetype']); + $row['mimepart'] = $this->getMimetype($row['mimepart']); $files[] = $row; } return $files; @@ -360,6 +408,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); + $mimetype = $this->getMimetypeId($mimetype); $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } diff --git a/lib/files/view.php b/lib/files/view.php index 124345f3c6f..8303a080bd8 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -693,7 +693,7 @@ class View { $data = $cache->get($internalPath); - if ($data) { + if ($data and $data['fileid']) { if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = Filesystem::getMountPoints($path); diff --git a/lib/util.php b/lib/util.php index 805ef6f18b0..93c0d0f26d8 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** -- cgit v1.2.3 From 5174eda23270463f09c82db77f2f61d3496f752f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 15:21:38 -0500 Subject: Fix permissions for mount point --- lib/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 8303a080bd8..94c89603aed 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -786,7 +786,7 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - $rootEntry['permissions'] = $subPermissionsCache; + $rootEntry['permissions'] = $permissions; $files[] = $rootEntry; } } -- cgit v1.2.3 From aa15fcf22f4c32026eca5ff8ae5e5df244f2c53e Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 12:09:55 -0500 Subject: Scan mount points in root before adding a entry --- lib/files/view.php | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 94c89603aed..703cda5123c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -767,27 +767,37 @@ class View { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { $subCache = $subStorage->getCache(''); - $rootEntry = $subCache->get(''); - $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']; + if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + $subScanner = $subStorage->getScanner(''); + $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + } else { + $subWatcher = $subStorage->getWatcher(''); + $subWatcher->checkUpdate(''); + } + + $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; + $files[] = $rootEntry; } - } 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; - $files[] = $rootEntry; } } } -- cgit v1.2.3 From 4835525c469d5ac75104e92c2dfbbb049d62890c Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 22:28:50 -0500 Subject: Switch scan to scanFile for root of mount points --- lib/files/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 703cda5123c..fa031b7478d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -768,9 +768,9 @@ class View { if ($subStorage) { $subCache = $subStorage->getCache(''); - if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); - $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + $subScanner->scanFile(''); } else { $subWatcher = $subStorage->getWatcher(''); $subWatcher->checkUpdate(''); -- cgit v1.2.3 From 8a63bcc1e85499335ade1df459f0c9f467161404 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 20:56:36 -0500 Subject: Don't use more entropy for etags --- lib/files/storage/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e859d447f39..591803f0440 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -274,7 +274,7 @@ abstract class Common implements \OC\Files\Storage\Storage { $hash = call_user_func($ETagFunction, $path); return $hash; }else{ - return uniqid('', true); + return uniqid(); } } } -- cgit v1.2.3 From 94068e5d08cba776e410d925e26037d442b5bc62 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 3 Jan 2013 00:26:13 +0100 Subject: Cache: show upgrade progress --- apps/files/ajax/upgrade.php | 42 +++++++++++ apps/files/appinfo/app.php | 10 --- apps/files/css/files.css | 9 +++ apps/files/index.php | 72 ++++++++++-------- apps/files/js/upgrade.js | 17 +++++ apps/files/templates/upgrade.php | 4 + lib/files/cache/legacy.php | 73 ++++++++++++++++++ lib/files/cache/upgrade.php | 155 ++++++++++++++++++++++++++++----------- 8 files changed, 302 insertions(+), 80 deletions(-) create mode 100644 apps/files/ajax/upgrade.php create mode 100644 apps/files/js/upgrade.js create mode 100644 apps/files/templates/upgrade.php create mode 100644 lib/files/cache/legacy.php (limited to 'lib/files') diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php new file mode 100644 index 00000000000..965c0073b8a --- /dev/null +++ b/apps/files/ajax/upgrade.php @@ -0,0 +1,42 @@ +hasItems()) { + OC_Hook::connect('\OC\Files\Cache\Upgrade', 'migrate_path', $listener, 'upgradePath'); + + $upgrade = new \OC\Files\Cache\Upgrade($legacy); + $count = $legacy->getCount(); + $eventSource->send('total', $count); + $upgrade->upgradePath('/' . $user . '/files'); +} +\OC\Files\Cache\Upgrade::upgradeDone($user); +$eventSource->send('done', true); +$eventSource->close(); + +class UpgradeListener { + /** + * @var OC_EventSource $eventSource + */ + private $eventSource; + + private $count = 0; + private $lastSend = 0; + + public function __construct($eventSource) { + $this->eventSource = $eventSource; + } + + public function upgradePath($path) { + $this->count++; + if ($this->count > ($this->lastSend + 5)) { + $this->lastSend = $this->count; + $this->eventSource->send('count', $this->count); + } + } +} diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index 643d8ed18a2..ab2f3b01a29 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -10,13 +10,3 @@ OCP\App::addNavigationEntry( array( "id" => "files_index", "name" => $l->t("Files") )); OC_Search::registerProvider('OC_Search_Provider_File'); - -if (OC_User::isLoggedIn()) { - // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually - $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); - if ($cacheVersion < 5) { - \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); - \OC\Files\Cache\Upgrade::upgrade(); - OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); - } -} diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 36a1e5c954b..0c130efe472 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -122,3 +122,12 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } #scanning-message{ top:40%; left:40%; position:absolute; display:none; } div.crumb a{ padding:0.9em 0 0.7em 0; } + +#upgrade { + width: 400px; + position: absolute; + top: 200px; + left: 50%; + text-align: center; + margin-left: -200px; +} diff --git a/apps/files/index.php b/apps/files/index.php index 993d8b4dcff..0dce7686962 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -28,7 +28,6 @@ OCP\User::checkLoggedIn(); OCP\Util::addStyle('files', 'files'); OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); -OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'filelist'); OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'keyboardshortcuts'); @@ -37,8 +36,8 @@ OCP\App::setActiveNavigationEntry('files_index'); // Load the files $dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; // Redirect if directory does not exist -if(!\OC\Files\Filesystem::is_dir($dir . '/')) { - header('Location: '.$_SERVER['SCRIPT_NAME'].''); +if (!\OC\Files\Filesystem::is_dir($dir . '/')) { + header('Location: ' . $_SERVER['SCRIPT_NAME'] . ''); exit(); } @@ -53,16 +52,25 @@ function fileCmp($a, $b) { } $files = array(); -foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { - $i['date'] = OCP\Util::formatDate($i['mtime'] ); - if($i['type'] == 'file') { +$user = OC_User::getUser(); +if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we need to upgrade the cache + $content = array(); + $needUpgrade = true; + $freeSpace = 0; +} else { + $content = \OC\Files\Filesystem::getDirectoryContent($dir); + $freeSpace = \OC\Files\Filesystem::free_space($dir); + $needUpgrade = false; +} +foreach ($content as $i) { + $i['date'] = OCP\Util::formatDate($i['mtime']); + if ($i['type'] == 'file') { $fileinfo = pathinfo($i['name']); $i['basename'] = $fileinfo['filename']; if (!empty($fileinfo['extension'])) { - $i['extension']='.' . $fileinfo['extension']; - } - else { - $i['extension']=''; + $i['extension'] = '.' . $fileinfo['extension']; + } else { + $i['extension'] = ''; } } $i['directory'] = $dir; @@ -74,10 +82,10 @@ usort($files, "fileCmp"); // Make breadcrumb $breadcrumb = array(); $pathtohere = ''; -foreach( explode( '/', $dir ) as $i ) { - if( $i != '' ) { +foreach (explode('/', $dir) as $i) { + if ($i != '') { $pathtohere .= '/' . $i; - $breadcrumb[] = array( 'dir' => $pathtohere, 'name' => $i ); + $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); } } @@ -94,29 +102,35 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace = \OC\Files\Filesystem::free_space($dir); -$freeSpace = max($freeSpace,0); +$freeSpace = max($freeSpace, 0); $maxUploadFilesize = min($maxUploadFilesize, $freeSpace); $permissions = OCP\PERMISSION_READ; if (\OC\Files\Filesystem::isUpdatable($dir . '/')) { - $permissions |= OCP\PERMISSION_UPDATE; + $permissions |= OCP\PERMISSION_UPDATE; } if (\OC\Files\Filesystem::isDeletable($dir . '/')) { - $permissions |= OCP\PERMISSION_DELETE; + $permissions |= OCP\PERMISSION_DELETE; } if (\OC\Files\Filesystem::isSharable($dir . '/')) { - $permissions |= OCP\PERMISSION_SHARE; + $permissions |= OCP\PERMISSION_SHARE; } -$tmpl = new OCP\Template( 'files', 'index', 'user' ); -$tmpl->assign( 'fileList', $list->fetchPage(), false ); -$tmpl->assign( 'breadcrumb', $breadcrumbNav->fetchPage(), false ); -$tmpl->assign( 'dir', \OC\Files\Filesystem::normalizePath($dir)); -$tmpl->assign( 'isCreatable', \OC\Files\Filesystem::isCreatable($dir . '/')); -$tmpl->assign('permissions', $permissions); -$tmpl->assign('files', $files); -$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); -$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); -$tmpl->printPage(); +if ($needUpgrade) { + OCP\Util::addscript('files', 'upgrade'); + $tmpl = new OCP\Template('files', 'upgrade', 'user'); + $tmpl->printPage(); +} else { + OCP\Util::addscript('files', 'files'); + $tmpl = new OCP\Template('files', 'index', 'user'); + $tmpl->assign('fileList', $list->fetchPage(), false); + $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); + $tmpl->assign('dir', \OC\Files\Filesystem::normalizePath($dir)); + $tmpl->assign('isCreatable', \OC\Files\Filesystem::isCreatable($dir . '/')); + $tmpl->assign('permissions', $permissions); + $tmpl->assign('files', $files); + $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); + $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); + $tmpl->printPage(); +} diff --git a/apps/files/js/upgrade.js b/apps/files/js/upgrade.js new file mode 100644 index 00000000000..02d57fc9e6c --- /dev/null +++ b/apps/files/js/upgrade.js @@ -0,0 +1,17 @@ +$(document).ready(function () { + var eventSource, total, bar = $('#progressbar'); + console.log('start'); + bar.progressbar({value: 0}); + eventSource = new OC.EventSource(OC.filePath('files', 'ajax', 'upgrade.php')); + eventSource.listen('total', function (count) { + total = count; + console.log(count + ' files needed to be migrated'); + }); + eventSource.listen('count', function (count) { + bar.progressbar({value: (count / total) * 100}); + console.log(count); + }); + eventSource.listen('done', function () { + document.location.reload(); + }); +}); diff --git a/apps/files/templates/upgrade.php b/apps/files/templates/upgrade.php new file mode 100644 index 00000000000..de6cc713028 --- /dev/null +++ b/apps/files/templates/upgrade.php @@ -0,0 +1,4 @@ +
+ t('Upgrading filesystem cache...');?> +
+
diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php new file mode 100644 index 00000000000..ee10a1c1350 --- /dev/null +++ b/lib/files/cache/legacy.php @@ -0,0 +1,73 @@ + + * 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; + + public function __construct($user) { + $this->user = $user; + } + + function getCount() { + $query = \OC_DB::prepare('SELECT COUNT(`id`) AS `count` FROM `*PREFIX*fscache` WHERE `user` = ?'); + $result = $query->execute(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() { + try { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); + } catch (\Exception $e) { + return false; + } + try { + $result = $query->execute(array($this->user)); + } catch (\Exception $e) { + return false; + } + return (bool)$result->fetchRow(); + } + + /** + * @param string|int $path + * @return array + */ + function get($path) { + if (is_numeric($path)) { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `id` = ?'); + } else { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?'); + } + $result = $query->execute(array($path)); + return $result->fetchRow(); + } + + /** + * @param int $id + * @return array + */ + function getChildren($id) { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?'); + $result = $query->execute(array($id)); + return $result->fetchAll(); + } +} diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 77db4c2339e..1032e0a844c 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -9,62 +9,102 @@ namespace OC\Files\Cache; class Upgrade { - static $permissionsCaches = array(); + /** + * @var Legacy $legacy + */ + private $legacy; - static $numericIds = array(); + private $permissionsCaches = array(); - static function upgrade() { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + private $numericIds = array(); - try { - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - } catch (\Exception $e) { - return; - } - try { - $oldEntriesResult = $oldEntriesQuery->execute(); - } catch (\Exception $e) { - return; - } - if (!$oldEntriesResult) { + private $mimeTypeIds = array(); + + /** + * @param Legacy $legacy + */ + public function __construct($legacy) { + $this->legacy = $legacy; + } + + /** + * Preform a shallow upgrade + * + * @param string $path + * @param int $mode + */ + function upgradePath($path, $mode = Scanner::SCAN_RECURSIVE) { + if (!$this->legacy->hasItems()) { return; } + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $path); - $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + if ($row = $this->legacy->get($path)) { + $data = $this->getNewData($row); + $this->insert($data); - while ($row = $oldEntriesResult->fetchRow()) { - if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { - continue; + $children = $this->legacy->getChildren($data['id']); + foreach ($children as $child) { + if ($mode == Scanner::SCAN_SHALLOW) { + $childData = $this->getNewData($child); + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); + $this->insert($childData); + } else { + $this->upgradePath($child['path']); + } } + } + } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath; - */ - $pathHash = md5($internalPath); - $storageId = self::getNumericId($storage); - $parentId = ($internalPath === '') ? -1 : $row['parent']; + /** + * @param array $data the data for the new cache + */ + function insert($data) { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` + ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); + $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], + $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); - $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; - $permissionsCache = self::getPermissionsCache($storage); - $permissionsCache->set($row['id'], $row['user'], $permissions); - } + $permissionsCache = $this->getPermissionsCache($data['storage_object']); + $permissionsCache->set($data['id'], $data['user'], $data['permissions']); + } + + /** + * get the new data array from the old one + * + * @param array $data the data from the old cache + * @return array + */ + function getNewData($data) { + $newData = $data; + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath; + */ + $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; } /** * @param \OC\Files\Storage\Storage $storage * @return Permissions */ - static function getPermissionsCache($storage) { + function getPermissionsCache($storage) { $storageId = $storage->getId(); - if (!isset(self::$permissionsCaches[$storageId])) { - self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + if (!isset($this->permissionsCaches[$storageId])) { + $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); } - return self::$permissionsCaches[$storageId]; + return $this->permissionsCaches[$storageId]; } /** @@ -73,12 +113,45 @@ class Upgrade { * @param \OC\Files\Storage\Storage $storage * @return int */ - static function getNumericId($storage) { + function getNumericId($storage) { $storageId = $storage->getId(); - if (!isset(self::$numericIds[$storageId])) { + if (!isset($this->numericIds[$storageId])) { + $cache = $storage->getCache(); + $this->numericIds[$storageId] = $cache->getNumericStorageId(); + } + return $this->numericIds[$storageId]; + } + + /** + * @param string $mimetype + * @param \OC\Files\Storage\Storage $storage + * @return int + */ + function getMimetypeId($mimetype, $storage) { + if (!isset($this->mimeTypeIds[$mimetype])) { $cache = new Cache($storage); - self::$numericIds[$storageId] = $cache->getNumericStorageId(); + $this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype); } - return self::$numericIds[$storageId]; + 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); } } -- cgit v1.2.3 From 7debfac0dc8f602168d8db480cfd4757b4d612b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Jan 2013 19:11:12 +0100 Subject: Cache: more efficient upgrading --- apps/files/ajax/upgrade.php | 2 ++ lib/files/cache/legacy.php | 10 +++++++++- lib/files/cache/upgrade.php | 24 +++++++++++++++--------- 3 files changed, 26 insertions(+), 10 deletions(-) (limited to 'lib/files') diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php index 965c0073b8a..7237b02c0b0 100644 --- a/apps/files/ajax/upgrade.php +++ b/apps/files/ajax/upgrade.php @@ -10,10 +10,12 @@ $legacy = new \OC\Files\Cache\Legacy($user); if ($legacy->hasItems()) { OC_Hook::connect('\OC\Files\Cache\Upgrade', 'migrate_path', $listener, 'upgradePath'); + OC_DB::beginTransaction(); $upgrade = new \OC\Files\Cache\Upgrade($legacy); $count = $legacy->getCount(); $eventSource->send('total', $count); $upgrade->upgradePath('/' . $user . '/files'); + OC_DB::commit(); } \OC\Files\Cache\Upgrade::upgradeDone($user); $eventSource->send('done', true); diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php index ee10a1c1350..33d4b8e7c9f 100644 --- a/lib/files/cache/legacy.php +++ b/lib/files/cache/legacy.php @@ -14,6 +14,8 @@ namespace OC\Files\Cache; class Legacy { private $user; + private $cacheHasItems = null; + public function __construct($user) { $this->user = $user; } @@ -34,17 +36,23 @@ class Legacy { * @return bool */ function hasItems() { + if (!is_null($this->cacheHasItems)) { + return $this->cacheHasItems; + } try { $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); } catch (\Exception $e) { + $this->cacheHasItems = false; return false; } try { $result = $query->execute(array($this->user)); } catch (\Exception $e) { + $this->cacheHasItems = false; return false; } - return (bool)$result->fetchRow(); + $this->cacheHasItems = (bool)$result->fetchRow(); + return $this->cacheHasItems; } /** diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 1032e0a844c..cd9a9e91a8c 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -43,15 +43,21 @@ class Upgrade { $data = $this->getNewData($row); $this->insert($data); - $children = $this->legacy->getChildren($data['id']); - foreach ($children as $child) { - if ($mode == Scanner::SCAN_SHALLOW) { - $childData = $this->getNewData($child); - \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); - $this->insert($childData); - } else { - $this->upgradePath($child['path']); - } + $this->upgradeChilds($data['id'], $mode); + } + } + + /** + * @param int $id + */ + 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']); + $this->insert($childData); + if ($mode == Scanner::SCAN_RECURSIVE) { + $this->upgradeChilds($child['id']); } } } -- cgit v1.2.3 From 29ec00797948d98ffa5dcb0baa1518630ab3ef56 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 19:11:33 +0100 Subject: Cache: dont migrate permissions, cache them on demain instead --- lib/files/cache/upgrade.php | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index cd9a9e91a8c..19e3d9ad575 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -14,8 +14,6 @@ class Upgrade { */ private $legacy; - private $permissionsCaches = array(); - private $numericIds = array(); private $mimeTypeIds = array(); @@ -72,9 +70,6 @@ class Upgrade { $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); - - $permissionsCache = $this->getPermissionsCache($data['storage_object']); - $permissionsCache->set($data['id'], $data['user'], $data['permissions']); } /** @@ -101,18 +96,6 @@ class Upgrade { return $newData; } - /** - * @param \OC\Files\Storage\Storage $storage - * @return Permissions - */ - function getPermissionsCache($storage) { - $storageId = $storage->getId(); - if (!isset($this->permissionsCaches[$storageId])) { - $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); - } - return $this->permissionsCaches[$storageId]; - } - /** * get the numeric storage id * -- cgit v1.2.3 From f9c42a196f03bb193b07a8f5f8ecf42b911ef4b5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:36:04 +0100 Subject: Cache: no longer using this file --- lib/files/file.php | 61 ------------------------------------------------------ 1 file changed, 61 deletions(-) delete mode 100644 lib/files/file.php (limited to 'lib/files') diff --git a/lib/files/file.php b/lib/files/file.php deleted file mode 100644 index 0d33cea7ee7..00000000000 --- a/lib/files/file.php +++ /dev/null @@ -1,61 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files; - -/** - * representation of the location a file or folder is stored - */ - -class File{ - /** - * @var Storage\Storage $storage - */ - private $storage; - /** - * @var string internalPath - */ - private $internalPath; - - public function __construct(Storage\Storage $storage, $internalPath){ - $this->storage = $storage; - $this->internalPath = $internalPath; - } - - public static function resolve($fullPath){ - $storage = null; - $internalPath = ''; - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); - return new File($storage, $internalPath); - } - - /** - * get the internal path of the file inside the filestorage - * @return string - */ - public function getInternalPath(){ - return $this->internalPath; - } - - /** - * get the storage the file is stored in - * @return \OC\Files\Storage\Storage - */ - public function getStorage(){ - return $this->storage; - } - - /** - * get the id of the storage the file is stored in - * @return string - */ - public function getStorageId(){ - return $this->storage->getId(); - } - -} -- cgit v1.2.3 From 6871a150bd1309af0ca22e45487043d9640bb356 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:58:17 +0100 Subject: Cache: use a database transition for scanning each folder gives a massive speed improvement while scanning files --- lib/files/cache/scanner.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index b62a093cec7..bf0ef01d6b3 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -83,14 +83,19 @@ class Scanner { * * @param string $path * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @param bool $onlyChilds * @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) { + public function scan($path, $recursive = self::SCAN_RECURSIVE, $onlyChilds = false) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); - $this->scanFile($path); + $childQueue = array(); + if (!$onlyChilds) { + $this->scanFile($path); + } $size = 0; if ($dh = $this->storage->opendir($path)) { + \OC_DB::beginTransaction(); while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { $child = ($path) ? $path . '/' . $file : $file; @@ -98,10 +103,12 @@ class Scanner { if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + $childQueue[] = $child; + $data['size'] = 0; } else { $data['size'] = -1; } + } else { } if ($data['size'] === -1) { $size = -1; @@ -111,6 +118,15 @@ class Scanner { } } } + \OC_DB::commit(); + foreach ($childQueue as $child) { + $childSize = $this->scan($child, self::SCAN_RECURSIVE, true); + if ($childSize === -1) { + $size = -1; + } else { + $size += $childSize; + } + } if ($size !== -1) { $this->cache->put($path, array('size' => $size)); } -- cgit v1.2.3 From 664f33a29c81701fbf6a7fb18eda81e1c4665ecc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 19 Jan 2013 21:04:25 -0500 Subject: Update mtimes of all parent folders after change inside --- lib/files/cache/updater.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 8b0d3835033..d04541c219f 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -35,7 +35,7 @@ class Updater { $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, $storage->filemtime($internalPath)); } } @@ -49,11 +49,17 @@ class Updater { $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, time()); } } - static public function eTagUpdate($path) { + /** + * 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 === '.') { @@ -68,8 +74,8 @@ class Updater { $cache = $storage->getCache(); $id = $cache->getId($internalPath); if ($id !== -1) { - $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::eTagUpdate($parent); + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + self::correctFolder($parent, $time); } } } -- cgit v1.2.3 From 42a1a17a30b8299a7dc4ea71aed57e607bdc2838 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:01:22 +0100 Subject: Cache: return non numberic storage id --- lib/files/cache/cache.php | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5c306c2ed16..7f6d191fee4 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -130,6 +130,7 @@ class Cache { $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['encrypted'] = (bool)$data['encrypted']; + $data['storage'] = $this->storageId; $data['mimetype'] = $this->getMimetype($data['mimetype']); $data['mimepart'] = $this->getMimetype($data['mimepart']); } -- cgit v1.2.3 From 7330fcf5e81e7d91ed37f01da7cc45833e10f1c4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:57:15 +0100 Subject: Cache: make mounts overwrite existing folders, prevents duplicate entries --- lib/files/view.php | 8 ++++++++ tests/lib/files/view.php | 12 ++++++++++++ 2 files changed, 20 insertions(+) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 06027910123..c50897603eb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -794,6 +794,14 @@ class View { $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; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 53271142672..586ad178425 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -98,6 +98,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testMountPointOverwrite() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(); + $storage1->mkdir('substorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + + $rootView = new \OC\Files\View(''); + $folderContent = $rootView->getDirectoryContent('/'); + $this->assertEquals(4, count($folderContent)); + } + function testCacheIncompleteFolder() { $storage1 = $this->getTestStorage(false); \OC\Files\Filesystem::mount($storage1, array(), '/'); -- cgit v1.2.3 From 9a1f65aab176604c90114891b4bc0346fbb7d561 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:58:09 +0100 Subject: Some style fixes --- lib/files/filesystem.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 28e8b046896..9a3d13e343b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -231,16 +231,16 @@ class Filesystem { } /** - * Initialize system and personal mount points for a user - * - * @param string $user - */ + * Initialize system and personal mount points for a user + * + * @param string $user + */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } // Load system mount points - if (is_file(\OC::$SERVERROOT.'/config/mount.php')) { + if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { @@ -277,8 +277,8 @@ class Filesystem { // Load personal mount points $root = \OC_User::getHome($user); self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); - if (is_file($root.'/mount.php')) { - $mountConfig = include $root.'/mount.php'; + if (is_file($root . '/mount.php')) { + $mountConfig = include $root . '/mount.php'; if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -370,7 +370,7 @@ class Filesystem { } else { // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); + $class = '\OC\Files\Storage\\' . substr($class, 15); } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } @@ -663,7 +663,7 @@ class Filesystem { * @param string $path * @return string */ - static public function getETag($path){ + static public function getETag($path) { return self::$defaultInstance->getETag($path); } } -- cgit v1.2.3 From f25db779d90814f1d54d594caf1bb830ea417b95 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 21:42:59 +0100 Subject: Filesystem: move mount management to it's own class --- lib/files/filesystem.php | 99 ++++++--------------------- lib/files/mount.php | 171 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 79 deletions(-) create mode 100644 lib/files/mount.php (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 9a3d13e343b..048116a44bb 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -30,8 +30,6 @@ namespace OC\Files; class Filesystem { - static private $storages = array(); - static private $mounts = array(); public static $loaded = false; /** * @var \OC\Files\View $defaultInstance @@ -143,19 +141,12 @@ class Filesystem { * @return string */ static public function getMountPoint($path) { - $path = self::normalizePath($path) . '/'; - \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); - $foundMountPoint = ''; - $mountPoints = array_keys(self::$mounts); - foreach ($mountPoints as $mountpoint) { - if ($mountpoint == $path) { - return $mountpoint; - } - if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { - $foundMountPoint = $mountpoint; - } + $mount = Mount::find($path); + if ($mount) { + return $mount->getMountPoint(); + } else { + return ''; } - return $foundMountPoint; } /** @@ -165,18 +156,10 @@ class Filesystem { * @return string[] */ static public function getMountPoints($path) { - $path = self::normalizePath($path); - if (strlen($path) > 1) { - $path .= '/'; - } - $pathLength = strlen($path); - - $mountPoints = array_keys(self::$mounts); $result = array(); - foreach ($mountPoints as $mountPoint) { - if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { - $result[] = $mountPoint; - } + $mounts = Mount::findIn($path); + foreach ($mounts as $mount) { + $result[] = $mount->getMountPoint(); } return $result; } @@ -188,11 +171,8 @@ class Filesystem { * @return \OC\Files\Storage\Storage */ public static function getStorage($mountPoint) { - if (!isset(self::$storages[$mountPoint])) { - $mount = self::$mounts[$mountPoint]; - self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); - } - return self::$storages[$mountPoint]; + $mount = Mount::find($mountPoint); + return $mount->getStorage(); } /** @@ -202,15 +182,9 @@ class Filesystem { * @return array consisting of the storage and the internal path */ static public function resolvePath($path) { - $mountpoint = self::getMountPoint($path); - if ($mountpoint) { - $storage = self::getStorage($mountpoint); - if ($mountpoint === $path or $mountpoint . '/' === $path) { - $internalPath = ''; - } else { - $internalPath = substr($path, strlen($mountpoint)); - } - return array($storage, $internalPath); + $mount = Mount::find($path); + if ($mount) { + return array($mount->getStorage(), $mount->getInternalPath($path)); } else { return array(null, null); } @@ -291,6 +265,7 @@ class Filesystem { * fill in the correct values for $user, and $password placeholders * * @param string $input + * @param string $input * @return string */ private static function setUserVars($user, $input) { @@ -310,28 +285,7 @@ class Filesystem { * tear down the filesystem, removing all storage providers */ static public function tearDown() { - self::$storages = array(); - } - - /** - * create a new storage of a specific type - * - * @param string $type - * @param array $arguments - * @return \OC\Files\Storage\Storage - */ - static private function createStorage($class, $arguments) { - if (class_exists($class)) { - try { - return new $class($arguments); - } catch (\Exception $exception) { - \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); - return false; - } - } else { - \OC_Log::write('core', 'storage backend ' . $class . ' not found', \OC_Log::ERROR); - return false; - } + self::clearMounts(); } /** @@ -348,8 +302,7 @@ class Filesystem { * clear all mounts and storage backends */ public static function clearMounts() { - self::$mounts = array(); - self::$storages = array(); + Mount::clear(); } /** @@ -360,20 +313,7 @@ class Filesystem { * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - $mountpoint = self::normalizePath($mountpoint); - if (strlen($mountpoint) > 1) { - $mountpoint .= '/'; - } - if ($class instanceof \OC\Files\Storage\Storage) { - self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); - self::$storages[$mountpoint] = $class; - } else { - // Update old classes to new namespace - if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\' . substr($class, 15); - } - self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); - } + new Mount($class, $mountpoint, $arguments); } /** @@ -578,6 +518,7 @@ class Filesystem { /** * check if a file or folder has been updated since $time * + * @param string $path * @param int $time * @return bool */ @@ -653,8 +594,8 @@ class Filesystem { * @param string $directory path under datadirectory * @return array */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); + public static function getDirectoryContent($directory) { + return self::$defaultInstance->getDirectoryContent($directory); } /** diff --git a/lib/files/mount.php b/lib/files/mount.php new file mode 100644 index 00000000000..c6746d2a337 --- /dev/null +++ b/lib/files/mount.php @@ -0,0 +1,171 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files; + +class Mount { + static private $mounts = array(); + + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage = null; + private $class; + private $storageId; + private $arguments = array(); + private $mountPoint; + + /** + * @param string|\OC\Files\Storage\Storage $storage + * @param string $mountpoint + * @param array $arguments + */ + public function __construct($storage, $mountpoint, $arguments = null) { + if (is_null($arguments)) { + $arguments = array(); + } + + $mountpoint = self::formatPath($mountpoint); + if ($storage instanceof \OC\Files\Storage\Storage) { + $this->class = get_class($storage); + $this->storage = $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; + + self::$mounts[$this->mountPoint] = $this; + } + + /** + * @return string + */ + public function getMountPoint() { + return $this->mountPoint; + } + + /** + * @return \OC\Files\Storage\Storage + */ + private function createStorage() { + if (class_exists($this->class)) { + try { + return new $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)) { + $this->storage = $this->createStorage(); + } + $this->storageId = $this->storage->getId(); + } + 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 static function formatPath($path) { + $path = Filesystem::normalizePath($path); + if (strlen($path) > 1) { + $path .= '/'; + } + return $path; + } + + /** + * Find the mount for $path + * + * @param $path + * @return Mount + */ + public static function find($path) { + $path = self::formatPath($path); + if (isset(self::$mounts[$path])) { + return self::$mounts[$path]; + } + + \OC_Hook::emit('OC_Filesystem', 'get_mountpoint', array('path' => $path)); + $foundMountPoint = ''; + $mountPoints = array_keys(self::$mounts); + foreach ($mountPoints as $mountpoint) { + if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { + $foundMountPoint = $mountpoint; + } + } + if (isset(self::$mounts[$foundMountPoint])) { + return self::$mounts[$foundMountPoint]; + } else { + return null; + } + } + + /** + * Find all mounts in $path + * + * @param $path + * @return Mount[] + */ + public static function findIn($path) { + $path = self::formatPath($path); + $result = array(); + $pathLength = strlen($path); + $mountPoints = array_keys(self::$mounts); + foreach ($mountPoints as $mountPoint) { + if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { + $result[] = self::$mounts[$mountPoint]; + } + } + return $result; + } + + public static function clear() { + self::$mounts = array(); + } +} -- cgit v1.2.3 From 03b947e3ece28325d3bc64319a228d66d493d182 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 26 Jan 2013 16:11:35 -0500 Subject: Don't check for updates for sub storages, these scans should be done in the background --- lib/files/view.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index c50897603eb..e6b52fb35b6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -769,9 +769,6 @@ class View { if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); $subScanner->scanFile(''); - } else { - $subWatcher = $subStorage->getWatcher(''); - $subWatcher->checkUpdate(''); } $rootEntry = $subCache->get(''); -- cgit v1.2.3 From 69f11151e90f0a17b02e58f7f94ca7f7a521f13a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 23:49:05 +0100 Subject: Filesystem: add Mount::findById --- lib/files/mount.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/mount.php b/lib/files/mount.php index c6746d2a337..e28b6471fe3 100644 --- a/lib/files/mount.php +++ b/lib/files/mount.php @@ -9,6 +9,9 @@ namespace OC\Files; class Mount { + /** + * @var Mount[] + */ static private $mounts = array(); /** @@ -23,7 +26,7 @@ class Mount { /** * @param string|\OC\Files\Storage\Storage $storage * @param string $mountpoint - * @param array $arguments + * @param array $arguments (optional) */ public function __construct($storage, $mountpoint, $arguments = null) { if (is_null($arguments)) { @@ -168,4 +171,17 @@ class Mount { public static function clear() { self::$mounts = array(); } + + /** + * @param string $id + * @return \OC\Files\Storage\Storage + */ + public static function findById($id) { + foreach (self::$mounts as $mount) { + if ($mount->getStorageId() === $id) { + return $mount; + } + } + return null; + } } -- cgit v1.2.3 From 9e2a066c7bf04dfcc3e2dcc539e1b33053ba70ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 23:59:29 +0100 Subject: Cache: add function to get storage id and internal path of a file by id --- lib/files/cache/cache.php | 24 ++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 7 +++++++ 2 files changed, 31 insertions(+) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7f6d191fee4..69cbaea8516 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -494,4 +494,28 @@ class Cache { return false; } } + + /** + * get the storage id of the storage for a file and the internal path of the file + * + * @return array, first element holding the storage id, second the path + */ + static public function getById($id) { + $query = \OC_DB::prepare('SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + $result = $query->execute(array($id)); + if ($row = $result->fetchRow()) { + $numericId = $row['storage']; + $path = $row['path']; + } else { + return null; + } + + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?'); + $result = $query->execute(array($numericId)); + if ($row = $result->fetchRow()) { + return array($row['id'], $path); + } else { + return null; + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 96a7623dac5..c466fbb63e7 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -197,6 +197,13 @@ class Cache extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $this->cache->getFolderContents('foo')); } + function testGetById() { + $storageId = $this->storage->getId(); + $data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $id = $this->cache->put('foo', $data); + $this->assertEquals(array($storageId, 'foo'), \OC\Files\Cache\Cache::getById($id)); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 17bcea15855784f00791ab19984d520a773aa0ca Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 27 Jan 2013 00:13:16 +0100 Subject: Filesystem: add View->getPath to the cache api --- lib/files/view.php | 15 +++++++++++++++ tests/lib/files/view.php | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index e6b52fb35b6..c2038f222a0 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -932,4 +932,19 @@ class View { 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); + $mount = Mount::findById($storage); + $fullPath = $mount->getMountPoint() . $internalPath; + return $this->getRelativePath($fullPath); + } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 586ad178425..a064e44f3ef 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -98,6 +98,29 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testGetPath() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $id1 = $cachedData['fileid']; + $this->assertEquals('/foo.txt', $rootView->getPath($id1)); + + $cachedData = $rootView->getFileInfo('/substorage/foo.txt'); + $id2 = $cachedData['fileid']; + $this->assertEquals('/substorage/foo.txt', $rootView->getPath($id2)); + + $folderView = new \OC\Files\View('/substorage'); + $this->assertEquals('/foo.txt', $folderView->getPath($id2)); + $this->assertNull($folderView->getPath($id1)); + } + function testMountPointOverwrite() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(); -- cgit v1.2.3 From 4cae1416733019fe4c7465f3e167a456fb790502 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 27 Jan 2013 00:18:15 +0100 Subject: Filesystem: also add getPath to \OC\Filesystem --- lib/files/filesystem.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 048116a44bb..262fde320a1 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -598,6 +598,18 @@ class Filesystem { return self::$defaultInstance->getDirectoryContent($directory); } + /** + * Get the path of a file by id + * + * 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 static function getPath($id) { + return self::$defaultInstance->getPath($id); + } + /** * get the ETag for a file or folder * -- cgit v1.2.3 From 577e3b11d7b486d09334f39215814638704e84b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 00:59:43 +0100 Subject: Filesystem: return all matching mounts in Mount::findById --- lib/files/mount.php | 7 ++++--- tests/lib/files/mount.php | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/files') diff --git a/lib/files/mount.php b/lib/files/mount.php index e28b6471fe3..74ee483b1be 100644 --- a/lib/files/mount.php +++ b/lib/files/mount.php @@ -174,14 +174,15 @@ class Mount { /** * @param string $id - * @return \OC\Files\Storage\Storage + * @return \OC\Files\Storage\Storage[] */ public static function findById($id) { + $result = array(); foreach (self::$mounts as $mount) { if ($mount->getStorageId() === $id) { - return $mount; + $result[] = $mount; } } - return null; + return $result; } } diff --git a/tests/lib/files/mount.php b/tests/lib/files/mount.php index 9f16b036275..f223f0f6c53 100644 --- a/tests/lib/files/mount.php +++ b/tests/lib/files/mount.php @@ -23,7 +23,8 @@ class Mount extends \PHPUnit_Framework_TestCase { $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); $this->assertEquals($rootMount, \OC\Files\Mount::find('/foo/bar')); - $mount = new \OC\Files\Mount(new Temporary(array()), '/foo'); + $storage = new Temporary(array()); + $mount = new \OC\Files\Mount($storage, '/foo'); $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); $this->assertEquals($mount, \OC\Files\Mount::find('/foo/bar')); @@ -32,6 +33,9 @@ class Mount extends \PHPUnit_Framework_TestCase { $this->assertEquals(2, count(\OC\Files\Mount::findIn('/'))); $id = $mount->getStorageId(); - $this->assertEquals($mount, \OC\Files\Mount::findById($id)); + $this->assertEquals(array($mount), \OC\Files\Mount::findById($id)); + + $mount2 = new \OC\Files\Mount($storage, '/foo/bar'); + $this->assertEquals(array($mount, $mount2), \OC\Files\Mount::findById($id)); } } -- cgit v1.2.3 From 3e59a8715390d659b433797c8a0ed080518e5e7d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 01:02:04 +0100 Subject: Filesystem: use the updated Mount::findById in getPath to ensure we get the correct path if the storage is also mounted outside the view --- lib/files/view.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index c2038f222a0..302232b5134 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -943,8 +943,16 @@ class View { */ public function getPath($id) { list($storage, $internalPath) = Cache\Cache::getById($id); - $mount = Mount::findById($storage); - $fullPath = $mount->getMountPoint() . $internalPath; - return $this->getRelativePath($fullPath); + $mounts = Mount::findById($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; } } -- cgit v1.2.3 From c9c919da5738f963247307ca3878e06beff87ade Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:34:15 +0100 Subject: Move streamwrappers to seperate files and put them in a namespace --- apps/files_external/lib/amazons3.php | 54 +++--- apps/files_external/lib/dropbox.php | 4 +- apps/files_external/lib/ftp.php | 2 +- apps/files_external/lib/google.php | 4 +- apps/files_external/lib/swift.php | 4 +- apps/files_external/lib/webdav.php | 6 +- apps/files_sharing/lib/sharedstorage.php | 2 +- lib/archive/tar.php | 2 +- lib/archive/zip.php | 2 +- lib/base.php | 7 +- lib/files/stream/close.php | 100 ++++++++++ lib/files/stream/dir.php | 47 +++++ lib/files/stream/staticstream.php | 191 ++++++++++++++++++++ lib/streamwrappers.php | 301 ------------------------------- tests/lib/streamwrappers.php | 76 ++++---- 15 files changed, 420 insertions(+), 382 deletions(-) create mode 100644 lib/files/stream/close.php create mode 100644 lib/files/stream/dir.php create mode 100644 lib/files/stream/staticstream.php delete mode 100644 lib/streamwrappers.php (limited to 'lib/files') diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index a209f0d0507..494885a1dd3 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -1,24 +1,24 @@ . -*/ + * ownCloud + * + * @author Michael Gapczynski + * @copyright 2012 Michael Gapczynski mtgap@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 . + */ namespace OC\Files\Storage; @@ -36,7 +36,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { - $this->id = 'amazon::'.$params['key'] . md5($params['secret']); + $this->id = 'amazon::' . $params['key'] . md5($params['secret']); $this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -51,7 +51,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $response; // This object could be a folder, a '/' must be at the end of the path } else if (substr($path, -1) != '/') { - $response = $this->s3->get_object_metadata($this->bucket, $path.'/'); + $response = $this->s3->get_object_metadata($this->bucket, $path . '/'); if ($response) { $this->objects[$path] = $response; return $response; @@ -61,7 +61,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - public function getId(){ + public function getId() { return $this->id; } @@ -104,8 +104,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { foreach ($response->body->CommonPrefixes as $object) { $files[] = basename($object->Prefix); } - \OC_FakeDirStream::$dirs['amazons3'.$path] = $files; - return opendir('fakedir://amazons3'.$path); + \OC\Files\Stream\Dir::register('amazons3' . $path, $files); + return opendir('fakedir://amazons3' . $path); } return false; } @@ -194,13 +194,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); } self::$tempFiles[$tmpFile] = $path; - return fopen('close://'.$tmpFile, $mode); + return fopen('close://' . $tmpFile, $mode); } return false; } @@ -209,8 +209,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { if (isset(self::$tempFiles[$tmpFile])) { $handle = fopen($tmpFile, 'r'); $response = $this->s3->create_object($this->bucket, - self::$tempFiles[$tmpFile], - array('fileUpload' => $handle)); + self::$tempFiles[$tmpFile], + array('fileUpload' => $handle)); if ($response->isOK()) { unlink($tmpFile); } diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 9223b4ca87b..11644e4a2c8 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -114,7 +114,7 @@ class Dropbox extends \OC\Files\Storage\Common { foreach ($contents as $file) { $files[] = basename($file['path']); } - \OC_FakeDirStream::$dirs['dropbox'.$path] = $files; + \OC\Files\Stream\Dir::register('dropbox'.$path, $files); return opendir('fakedir://dropbox'.$path); } return false; @@ -232,7 +232,7 @@ class Dropbox extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 973b33fbfd7..9a27b63323a 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -84,7 +84,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $this->getFile($path, $tmpFile); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 4c485773e7b..7396c7e3f27 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -273,7 +273,7 @@ class Google extends \OC\Files\Storage\Common { $this->entries[$name] = $entry; } } - \OC_FakeDirStream::$dirs['google'.$path] = $files; + \OC\Files\Stream\Dir::register('google'.$path, $files); return opendir('fakedir://google'.$path); } @@ -450,7 +450,7 @@ class Google extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index bd1f4c572a6..cbf2007052b 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -371,7 +371,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $subContainers=$this->getSubContainers($container); $files=array_merge($files, $subContainers); $id=$this->getContainerName($path); - \OC_FakeDirStream::$dirs[$id]=$files; + \OC\Files\Stream\Dir::register($id, $files); return opendir('fakedir://'.$id); } @@ -465,7 +465,7 @@ class SWIFT extends \OC\Files\Storage\Common{ case 'c': case 'c+': $tmpFile=$this->getTmpFile($path); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile, $mode); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 6d43a03058a..571b4d79ae2 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -104,13 +104,15 @@ class DAV extends \OC\Files\Storage\Common{ try { $response=$this->client->propfind($path, array(), 1); $id=md5('webdav'.$this->root.$path); + $content = array(); \OC_FakeDirStream::$dirs[$id]=array(); $files=array_keys($response); array_shift($files);//the first entry is the current directory foreach ($files as $file) { $file = urldecode(basename($file)); - \OC_FakeDirStream::$dirs[$id][]=$file; + $content[]=$file; } + \OC\Files\Stream\Dir::register($id, $content); return opendir('fakedir://'.$id); } catch(\Exception $e) { return false; @@ -194,7 +196,7 @@ class DAV extends \OC\Files\Storage\Common{ $ext=''; } $tmpFile = \OCP\Files::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if($this->file_exists($path)) { $this->getFile($path, $tmpFile); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b0be6843c56..ea28ca69b93 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -102,7 +102,7 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); - \OC_FakeDirStream::$dirs['shared'] = $files; + \OC\Files\Stream\Dir::register('shared', $files); return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); diff --git a/lib/archive/tar.php b/lib/archive/tar.php index 0fa633c6038..117d88e5f42 100644 --- a/lib/archive/tar.php +++ b/lib/archive/tar.php @@ -308,7 +308,7 @@ class OC_Archive_TAR extends OC_Archive{ if($mode=='r' or $mode=='rb') { return fopen($tmpFile, $mode); }else{ - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile, $mode); } diff --git a/lib/archive/zip.php b/lib/archive/zip.php index 1c967baa08f..8e31795ded1 100644 --- a/lib/archive/zip.php +++ b/lib/archive/zip.php @@ -171,7 +171,7 @@ class OC_Archive_ZIP extends OC_Archive{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if($this->fileExists($path)) { $this->extractFile($path, $tmpFile); } diff --git a/lib/base.php b/lib/base.php index e3baa617c32..45e2f633cb7 100644 --- a/lib/base.php +++ b/lib/base.php @@ -421,10 +421,9 @@ class OC } // register the stream wrappers - require_once 'streamwrappers.php'; - stream_wrapper_register("fakedir", "OC_FakeDirStream"); - stream_wrapper_register('static', 'OC_StaticStreamWrapper'); - stream_wrapper_register('close', 'OC_CloseStreamWrapper'); + stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir'); + stream_wrapper_register('static', 'OC\Files\Stream\StaticStream'); + stream_wrapper_register('close', 'OC\Files\Stream\Close'); self::checkConfig(); self::checkInstalled(); diff --git a/lib/files/stream/close.php b/lib/files/stream/close.php new file mode 100644 index 00000000000..80de3497c36 --- /dev/null +++ b/lib/files/stream/close.php @@ -0,0 +1,100 @@ + + * 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 new file mode 100644 index 00000000000..6ca884fc994 --- /dev/null +++ b/lib/files/stream/dir.php @@ -0,0 +1,47 @@ + + * 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/staticstream.php b/lib/files/stream/staticstream.php new file mode 100644 index 00000000000..7725a6a5a04 --- /dev/null +++ b/lib/files/stream/staticstream.php @@ -0,0 +1,191 @@ + + * 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 { + 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 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() { + $size = strlen(self::$data[$this->path]); + $time = time(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + + 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(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + return false; + } +} diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php deleted file mode 100644 index 981c280f0dd..00000000000 --- a/lib/streamwrappers.php +++ /dev/null @@ -1,301 +0,0 @@ -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; - } -} - -class OC_StaticStreamWrapper { - 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 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() { - $size = strlen(self::$data[$this->path]); - $time = time(); - return array( - 0 => 0, - 'dev' => 0, - 1 => 0, - 'ino' => 0, - 2 => 0777, - 'mode' => 0777, - 3 => 1, - 'nlink' => 1, - 4 => 0, - 'uid' => 0, - 5 => 0, - 'gid' => 0, - 6 => '', - 'rdev' => '', - 7 => $size, - 'size' => $size, - 8 => $time, - 'atime' => $time, - 9 => $time, - 'mtime' => $time, - 10 => $time, - 'ctime' => $time, - 11 => -1, - 'blksize' => -1, - 12 => -1, - 'blocks' => -1, - ); - } - - 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(); - return array( - 0 => 0, - 'dev' => 0, - 1 => 0, - 'ino' => 0, - 2 => 0777, - 'mode' => 0777, - 3 => 1, - 'nlink' => 1, - 4 => 0, - 'uid' => 0, - 5 => 0, - 'gid' => 0, - 6 => '', - 'rdev' => '', - 7 => $size, - 'size' => $size, - 8 => $time, - 'atime' => $time, - 9 => $time, - 'mtime' => $time, - 10 => $time, - 'ctime' => $time, - 11 => -1, - 'blksize' => -1, - 12 => -1, - 'blocks' => -1, - ); - } - return false; - } -} - -/** - * stream wrapper that provides a callback on stream close - */ -class OC_CloseStreamWrapper{ - public 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); - } -} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index aebbc93b902..e40f2e76128 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -1,41 +1,41 @@ . -* -*/ + * 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 . + * + */ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testFakeDir() { - $items=array('foo', 'bar'); - OC_FakeDirStream::$dirs['test']=$items; - $dh=opendir('fakedir://test'); - $result=array(); - while($file=readdir($dh)) { - $result[]=$file; + $items = array('foo', 'bar'); + \OC\Files\Stream\Dir::register('test', $items); + $dh = opendir('fakedir://test'); + $result = array(); + while ($file = readdir($dh)) { + $result[] = $file; $this->assertContains($file, $items); } $this->assertEquals(count($items), count($result)); } public function testStaticStream() { - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $staticFile='static://test'; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $staticFile = 'static://test'; $this->assertFalse(file_exists($staticFile)); file_put_contents($staticFile, file_get_contents($sourceFile)); $this->assertTrue(file_exists($staticFile)); @@ -47,27 +47,27 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testCloseStream() { //ensure all basic stream stuff works - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; $this->assertTrue(file_exists($file)); file_put_contents($file, file_get_contents($sourceFile)); $this->assertEquals(file_get_contents($sourceFile), file_get_contents($file)); unlink($file); clearstatcache(); $this->assertFalse(file_exists($file)); - + //test callback - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array('Test_StreamWrappers', 'closeCallBack'); - $fh=fopen($file, 'w'); + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; + \OC\Files\Stream\Close::registerCallback($tmpFile, array('Test_StreamWrappers', 'closeCallBack')); + $fh = fopen($file, 'w'); fwrite($fh, 'asd'); - try{ + try { fclose($fh); $this->fail('Expected exception'); - }catch(Exception $e) { - $path=$e->getMessage(); + } catch (Exception $e) { + $path = $e->getMessage(); $this->assertEquals($path, $tmpFile); } } -- cgit v1.2.3 From 232cc3211b2b312d4e32e7d0fb482a2b7affe89a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:35:30 +0100 Subject: add oc:// streamwrapper to provide access to ownCloud's virtual filesystem --- lib/base.php | 1 + lib/files/stream/oc.php | 129 +++++++++++++++++++++++++++++++++++++++++++ tests/lib/streamwrappers.php | 19 +++++++ 3 files changed, 149 insertions(+) create mode 100644 lib/files/stream/oc.php (limited to 'lib/files') diff --git a/lib/base.php b/lib/base.php index 45e2f633cb7..e6f00839aa2 100644 --- a/lib/base.php +++ b/lib/base.php @@ -424,6 +424,7 @@ class OC stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir'); stream_wrapper_register('static', 'OC\Files\Stream\StaticStream'); stream_wrapper_register('close', 'OC\Files\Stream\Close'); + stream_wrapper_register('oc', 'OC\Files\Stream\OC'); self::checkConfig(); self::checkInstalled(); diff --git a/lib/files/stream/oc.php b/lib/files/stream/oc.php new file mode 100644 index 00000000000..88e7e062df9 --- /dev/null +++ b/lib/files/stream/oc.php @@ -0,0 +1,129 @@ + + * 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/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index e40f2e76128..2237ee7d378 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -75,4 +75,23 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public static function closeCallBack($path) { throw new Exception($path); } + + public function testOC() { + \OC\Files\Mount::clear(); + $storage = new \OC\Files\Storage\Temporary(array()); + $storage->file_put_contents('foo.txt', 'asd'); + new \OC\Files\Mount($storage, '/'); + + $this->assertTrue(file_exists('oc:///foo.txt')); + $this->assertEquals('asd', file_get_contents('oc:///foo.txt')); + $this->assertEquals(array('.', '..', 'foo.txt'), scandir('oc:///')); + + file_put_contents('oc:///bar.txt', 'qwerty'); + $this->assertEquals('qwerty', $storage->file_get_contents('bar.txt')); + $this->assertEquals(array('.', '..', 'bar.txt', 'foo.txt'), scandir('oc:///')); + $this->assertEquals('qwerty', file_get_contents('oc:///bar.txt')); + + unlink('oc:///foo.txt'); + $this->assertEquals(array('.', '..', 'bar.txt'), scandir('oc:///')); + } } -- cgit v1.2.3 From af3b0e30ed2dd66212c3fc25bb5c406b77fa9e5d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 30 Jan 2013 18:17:56 +0100 Subject: Cache: don't insert duplicated during upgrade --- lib/files/cache/upgrade.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'lib/files') diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 19e3d9ad575..eb8c7297c3e 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -64,12 +64,25 @@ class Upgrade { * @param array $data the data for the new cache */ function insert($data) { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` - ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + if (!$this->inCache($data['storage'], $data['path_hash'])) { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` + ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], - $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); + $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], + $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); + } + } + + /** + * @param string $storage + * @param string $pathHash + * @return bool + */ + function inCache($storage, $pathHash) { + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($storage, $pathHash)); + return (bool)$result->fetchRow(); } /** -- cgit v1.2.3 From 42d59d5a1658dde5d428ae855de524411c311048 Mon Sep 17 00:00:00 2001 From: TheSFReader Date: Sat, 2 Feb 2013 23:18:29 +0100 Subject: Remove a warning by making sure the renamed file is a dir before trying and opening it --- lib/files/cache/scanner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index bf0ef01d6b3..8d504af6163 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -94,7 +94,7 @@ class Scanner { } $size = 0; - if ($dh = $this->storage->opendir($path)) { + if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) { \OC_DB::beginTransaction(); while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { -- cgit v1.2.3 From 6093d961a09022c289b34daebecc8ee88c31a50b Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 2 Feb 2013 18:50:40 -0500 Subject: Add getOwner to Filesystem and View classes --- lib/files/filesystem.php | 10 ++++++++++ lib/files/view.php | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 262fde320a1..c00b42d9c44 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -610,6 +610,16 @@ class Filesystem { 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 * diff --git a/lib/files/view.php b/lib/files/view.php index 302232b5134..a002ad5040d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -914,6 +914,16 @@ class View { 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 * -- cgit v1.2.3 From d03155a8d509685f64bc4b56ba3e76ef5a94c7d9 Mon Sep 17 00:00:00 2001 From: TheSFReader Date: Sun, 3 Feb 2013 11:06:26 +0100 Subject: translate the mimtype/mimepart to readable in the searchByMime function --- lib/files/cache/cache.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 69cbaea8516..dcb6e8fd39a 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -410,7 +410,13 @@ class Cache { ); $mimetype = $this->getMimetypeId($mimetype); $result = $query->execute(array($mimetype, $this->numericId)); - return $result->fetchAll(); + $files = array(); + while ($row = $result->fetchRow()) { + $row['mimetype'] = $this->getMimetype($row['mimetype']); + $row['mimepart'] = $this->getMimetype($row['mimepart']); + $files[] = $row; + } + return $files; } /** -- cgit v1.2.3 From 3def7f81873fef84b781174ad12f7e264b4caae5 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sun, 3 Feb 2013 23:03:06 +0100 Subject: Make fileblacklist configurable --- config/config.sample.php | 3 +++ lib/files/filesystem.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/files') diff --git a/config/config.sample.php b/config/config.sample.php index 5264e948200..163beaae2f4 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -32,6 +32,9 @@ $CONFIG = array( /* Force use of HTTPS connection (true = use HTTPS) */ "forcessl" => false, +/* Blacklist a specific file and disallow the upload of files with this name - WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING. */ +"blacklisted_files" => array('.htaccess'), + /* The automatic hostname detection of ownCloud can fail in certain reverse proxy situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */ "overwritehost" => "", diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 262fde320a1..47c09acf294 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -374,7 +374,7 @@ class Filesystem { * @param array $data from hook */ static public function isBlacklisted($data) { - $blacklist = array('.htaccess'); + $blacklist = \OC_Config::getValue('blacklisted_files', array('.htaccess')); if (isset($data['path'])) { $path = $data['path']; } else if (isset($data['newpath'])) { -- cgit v1.2.3 From 80dd8d7802f90ce088b03e46d62e12367dcad278 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 3 Feb 2013 23:34:27 +0100 Subject: Cache: check for invalid paths in getFileInfo/getDirectoryContent --- lib/files/view.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index 302232b5134..ff94d3e602b 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -670,6 +670,9 @@ class View { */ public function getFileInfo($path) { $data = array(); + if (!Filesystem::isValidPath($path)) { + return $data; + } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage @@ -724,6 +727,9 @@ class View { */ public function getDirectoryContent($directory, $mimetype_filter = '') { $result = array(); + if (!Filesystem::isValidPath($path)) { + return $data; + } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage -- cgit v1.2.3 From 7c33d0a5a763be92c7e6dbf526484ef372c7111f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 4 Feb 2013 13:28:31 +0100 Subject: Cache: fix copy-paste errors --- lib/files/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/view.php b/lib/files/view.php index ff94d3e602b..00c0c3b1159 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -727,8 +727,8 @@ class View { */ public function getDirectoryContent($directory, $mimetype_filter = '') { $result = array(); - if (!Filesystem::isValidPath($path)) { - return $data; + if (!Filesystem::isValidPath($directory)) { + return $result; } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** -- cgit v1.2.3 From 02e6adfdb3dd08684f426a2e101e5042dddce734 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 4 Feb 2013 20:49:01 +0100 Subject: fixing namespace --- lib/files/storage/local.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/files') diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index 9fc9d375bb3..a5db4ba9194 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -184,7 +184,7 @@ class Local extends \OC\Files\Storage\Common{ // Windows OS: we use COM to access the filesystem if (strpos($name, 'win') !== false) { if (class_exists('COM')) { - $fsobj = new COM("Scripting.FileSystemObject"); + $fsobj = new \COM("Scripting.FileSystemObject"); $f = $fsobj->GetFile($fullPath); return $f->Size; } @@ -197,7 +197,7 @@ class Local extends \OC\Files\Storage\Common{ 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); + \OC_Log::write('core', 'Unable to determine file size of "'.$fullPath.'". Unknown OS: '.$name, \OC_Log::ERROR); } return 0; -- cgit v1.2.3 From 1fd807a7d68d254cfd372105ff672d09f13b4bb7 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 31 Jan 2013 22:04:08 +0100 Subject: pass the argument to the ctor Conflicts: lib/files/storage/temporary.php --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index ffc55e27507..b8bb6192786 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -13,7 +13,7 @@ namespace OC\Files\Storage; */ class Temporary extends Local{ public function __construct($arguments) { - $this->datadir=\OC_Helper::tmpFolder(); + parent::__construct(array('datadir' => \OC_Helper::tmpFolder())); } public function cleanUp() { -- cgit v1.2.3 From 94460178219fcdcc3cfcb2015b1064cf19ff7f96 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Tue, 5 Feb 2013 16:24:40 +0100 Subject: spell check --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/files') diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index b8bb6192786..542d2cd9f48 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -9,7 +9,7 @@ namespace OC\Files\Storage; /** - * local storage backnd in temporary folder for testing purpores + * local storage backend in temporary folder for testing purpose */ class Temporary extends Local{ public function __construct($arguments) { -- cgit v1.2.3 From 50faddfa409f7afbb2a41fddaf9ce117e06d16d0 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 15:37:40 +0000 Subject: Minor improvement to comments --- lib/files/filesystem.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'lib/files') diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 65d9ffab485..71bf3d8708d 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -527,8 +527,7 @@ class Filesystem { } /** - * normalize a path - * + * @brief Fix common problems with a file path * @param string $path * @param bool $stripTrailingSlash * @return string @@ -537,21 +536,21 @@ class Filesystem { if ($path == '') { return '/'; } -//no windows style slashes + //no windows style slashes $path = str_replace('\\', '/', $path); -//add leading slash + //add leading slash if ($path[0] !== '/') { $path = '/' . $path; } -//remove duplicate slashes + //remove duplicate slashes while (strpos($path, '//') !== false) { $path = str_replace('//', '/', $path); } -//remove trailing slash + //remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } -//normalize unicode if possible + //normalize unicode if possible if (class_exists('Normalizer')) { $path = \Normalizer::normalize($path); } -- cgit v1.2.3 From fd8cb9974be30aaca0d65d1807d6a4f784da5f0b Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Wed, 6 Feb 2013 23:36:38 +0100 Subject: initial version of a local storage implementation which will use unique slugified filename on the local filesystem. This implementation will only be enabled on windows based system to solve the issues around UTF-8 file names with php on windows. --- db_structure.xml | 44 +++++ lib/files/mapper.php | 216 +++++++++++++++++++++++ lib/files/storage/local.php | 5 + lib/files/storage/mappedlocal.php | 335 ++++++++++++++++++++++++++++++++++++ lib/files/storage/temporary.php | 1 + tests/lib/files/storage/storage.php | 17 +- 6 files changed, 614 insertions(+), 4 deletions(-) create mode 100644 lib/files/mapper.php create mode 100644 lib/files/storage/mappedlocal.php (limited to 'lib/files') diff --git a/db_structure.xml b/db_structure.xml index f4111bfabd0..fc7f1082ffa 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -94,6 +94,50 @@
+ + + *dbprefix*file_map + + + + + logic_path + text + + true + 512 + + + + physic_path + text + + true + 512 + + + + file_map_lp_index + true + + logic_path + ascending + + + + + file_map_pp_index + true + + physic_path + ascending + + + + + +
+ *dbprefix*mimetypes diff --git a/lib/files/mapper.php b/lib/files/mapper.php new file mode 100644 index 00000000000..90e4e1ca669 --- /dev/null +++ b/lib/files/mapper.php @@ -0,0 +1,216 @@ +resolveLogicPath($logicPath); + if ($physicalPath !== null) { + return $physicalPath; + } + + return $this->create($logicPath, $create); + } + + /** + * @param string $physicalPath + * @return string|null + */ + 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 + */ + public function removePath($path, $isLogicPath, $recursive) { + if ($recursive) { + $path=$path.'%'; + } + + if ($isLogicPath) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); + $query->execute(array($path)); + } else { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?'); + $query->execute(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); + + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); + $result = $query->execute(array($path1.'%')); + $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' + .' SET `logic_path` = ?' + .' AND `physic_path` = ?' + .' 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 { + $updateQuery->execute(array($newLogic, $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); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` = ?'); + $result = $query->execute(array($logicPath)); + $result = $result->fetchRow(); + + return $result['physic_path']; + } + + private function resolvePhysicalPath($physicalPath) { + $physicalPath = $this->stripLast($physicalPath); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path` = ?'); + $result = $query->execute(array($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($physicalPath, $index++); + } + + // insert the new path mapping if requested + if ($store) { + $this->insert($logicPath, $physicalPath); + } + + return $physicalPath; + } + + private function insert($logicPath, $physicalPath) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*file_map`(`logic_path`,`physic_path`) VALUES(?,?)'); + $query->execute(array($logicPath, $physicalPath)); + } + + private function slugifyPath($path, $index=null) { + $pathElements = explode('/', $path); + $sluggedElements = array(); + + // skip slugging the drive letter on windows - TODO: test if local path + if (strpos(strtolower(php_uname('s')), 'win') !== false) { + $sluggedElements[]= $pathElements[0]; + array_shift($pathElements); + } + foreach ($pathElements as $pathElement) { + // TODO: remove file ext before slugify on last element + $sluggedElements[] = self::slugify($pathElement); + } + + // + // TODO: add the index before the file extension + // + if ($index !== null) { + $last= end($sluggedElements); + array_pop($sluggedElements); + array_push($sluggedElements, $last.'-'.$index); + } + return implode(DIRECTORY_SEPARATOR, $sluggedElements); + } + + /** + * 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 by - + $text = preg_replace('~[^\\pL\d]+~u', '-', $text); + + // trim + $text = trim($text, '-'); + + // transliterate + if (function_exists('iconv')) { + $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); + } + + // lowercase + $text = strtolower($text); + + // remove unwanted characters + $text = preg_replace('~[^-\w]+~', '', $text); + + if (empty($text)) + { + // TODO: we better generate a guid in this case + return 'n-a'; + } + + return $text; + } +} diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index a5db4ba9194..d387a898320 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -8,6 +8,10 @@ namespace OC\Files\Storage; +if (\OC_Util::runningOnWindows()) { + require_once 'mappedlocal.php'; +} else { + /** * for local filestore, we only have to map the paths */ @@ -245,3 +249,4 @@ class Local extends \OC\Files\Storage\Common{ return $this->filemtime($path)>$time; } } +} diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php new file mode 100644 index 00000000000..80dd79bc41f --- /dev/null +++ b/lib/files/storage/mappedlocal.php @@ -0,0 +1,335 @@ + + * 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 Local 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(); + } + 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) { + if ($result = @rmdir($this->buildPath($path))) { + $this->cleanMapper($path); + } + return $result; + } + public function opendir($path) { + $files = array('.', '..'); + $physicalPath= $this->buildPath($path); + + $logicalPath = $this->mapper->physicalToLogic($physicalPath); + $dh = opendir($physicalPath); + while ($file = readdir($dh)) { + if ($file === '.' or $file === '..') { + continue; + } + + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.DIRECTORY_SEPARATOR.$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) {//trigger_error("$path = ".var_export($path, 1)); + 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='', $isLogicPath=true) { + $files=array(); + $physicalDir = $this->buildPath($dir); + foreach (scandir($physicalDir) as $item) { + if ($item == '.' || $item == '..') + continue; + $physicalItem = $this->mapper->physicalToLogic($physicalDir.DIRECTORY_SEPARATOR.$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, $physicalItem, false)); + } + } + 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); + } + + return $path; + } +} diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index 542d2cd9f48..d84dbda2e39 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -21,6 +21,7 @@ class Temporary extends Local{ } public function __destruct() { + parent::__destruct(); $this->cleanUp(); } } diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 781c0f92c92..c74a16f509f 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -146,10 +146,19 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $localFolder = $this->instance->getLocalFolder('/folder'); $this->assertTrue(is_dir($localFolder)); - $this->assertTrue(file_exists($localFolder . '/lorem.txt')); - $this->assertEquals(file_get_contents($localFolder . '/lorem.txt'), file_get_contents($textFile)); - $this->assertEquals(file_get_contents($localFolder . '/bar.txt'), 'asd'); - $this->assertEquals(file_get_contents($localFolder . '/recursive/file.txt'), 'foo'); + + // test below require to use instance->getLocalFile because the physical storage might be different + $localFile = $this->instance->getLocalFile('/folder/lorem.txt'); + $this->assertTrue(file_exists($localFile)); + $this->assertEquals(file_get_contents($localFile), file_get_contents($textFile)); + + $localFile = $this->instance->getLocalFile('/folder/bar.txt'); + $this->assertTrue(file_exists($localFile)); + $this->assertEquals(file_get_contents($localFile), 'asd'); + + $localFile = $this->instance->getLocalFile('/folder/recursive/file.txt'); + $this->assertTrue(file_exists($localFile)); + $this->assertEquals(file_get_contents($localFile), 'foo'); } public function testStat() { -- cgit v1.2.3