diff options
author | Robin Appelman <icewind@owncloud.com> | 2012-01-20 00:40:52 +0100 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2012-01-20 00:48:00 +0100 |
commit | 11c848b2215ba00ea5db33690942e1d6df27ae1b (patch) | |
tree | de6ff6d2fed8f0957615482c0fecb34bc334cda4 /lib/filesystem.php | |
parent | a1dfe16d0a130c4d27bad8418a3801fdd5774735 (diff) | |
download | nextcloud-server-11c848b2215ba00ea5db33690942e1d6df27ae1b.tar.gz nextcloud-server-11c848b2215ba00ea5db33690942e1d6df27ae1b.zip |
initial work on filesystemview
Diffstat (limited to 'lib/filesystem.php')
-rw-r--r-- | lib/filesystem.php | 345 |
1 files changed, 98 insertions, 247 deletions
diff --git a/lib/filesystem.php b/lib/filesystem.php index eeca27d3a9a..f17213cd389 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -46,8 +46,10 @@ class OC_Filesystem{ static private $storages=array(); static private $mounts=array(); - static private $fakeRoot=''; static private $storageTypes=array(); + private $fakeRoot=''; + static private $defaultInstance; + /** * classname which used for hooks handling @@ -134,6 +136,71 @@ class OC_Filesystem{ * 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){ + if(!$path){ + $path='/'; + } + if(substr($path,0,1)!=='/'){ + $path='/'.$path; + } + if(substr($path,-1)!=='/'){ + $path=$path.'/'; + } + $foundMountPoint=''; + foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){ + if(substr($mountpoint,-1)!=='/'){ + $mountpoint=$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_Filestorage + */ + 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]; + } + } + + static public function init($root){ + if(self::$defaultInstance){ + return false; + } + self::$defaultInstance=new OC_FilesystemView($root); + } /** * tear down the filesystem, removing all storage providers @@ -165,12 +232,7 @@ class OC_Filesystem{ * @return bool */ static public function chroot($fakeRoot){ - if(!$fakeRoot==''){ - if($fakeRoot[0]!=='/'){ - $fakeRoot='/'.$fakeRoot; - } - } - self::$fakeRoot=$fakeRoot; + return self::$defaultInstance->chroot($path); } /** @@ -178,21 +240,9 @@ class OC_Filesystem{ * @return string */ static public function getRoot(){ - return self::$fakeRoot; - } - - /** - * 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); - $path=self::$fakeRoot.$path; - $internalPath=substr($path,strlen($mountPoint)); - return $internalPath; + return self::$defaultInstance->getRoot(); } - + /** * mount an OC_Filestorage in our virtual filesystem * @param OC_Filestorage storage @@ -206,65 +256,13 @@ class OC_Filesystem{ } /** - * get the storage object for a path - * @param string path - * @return OC_Filestorage - */ - 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]; - } - } - - /** - * get the mountpoint of the storage object for a path - ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account - * - * @param string path - * @return string - */ - static public function getMountPoint($path){ - if(!$path){ - $path='/'; - } - if(substr($path,0,1)!=='/'){ - $path='/'.$path; - } - if(substr($path,-1)!=='/'){ - $path=$path.'/'; - } - $path=self::$fakeRoot.$path; - $foundMountPoint=''; - foreach(self::$mounts as $mountpoint=>$storage){ - if(substr($mountpoint,-1)!=='/'){ - $mountpoint=$mountpoint.'/'; - } - if($mountpoint==$path){ - return $mountpoint; - } - if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)){ - $foundMountPoint=$mountpoint; - } - } - return $foundMountPoint; - } - - /** * 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){ - $parent=substr($path,0,strrpos($path,'/')); - if(self::isValidPath($parent) and $storage=self::getStorage($path)){ - return $storage->getLocalFile(self::getInternalPath($path)); - } + return self::$defaultInstance->getLocalFile($path); } /** @@ -285,232 +283,85 @@ class OC_Filesystem{ * following functions are equivilent to their php buildin equivilents for arguments/return values. */ static public function mkdir($path){ - return self::basicOperation('mkdir',$path,array('create','write')); + return self::$defaultInstance->mkdir($path); } static public function rmdir($path){ - return self::basicOperation('rmdir',$path,array('delete')); + return self::$defaultInstance->rmdir($path); } static public function opendir($path){ - return self::basicOperation('opendir',$path,array('read')); + return self::$defaultInstance->opendir($path); } static public function is_dir($path){ - if($path=='/'){ - return true; - } - return self::basicOperation('is_dir',$path); + return self::$defaultInstance->is_dir($path); } static public function is_file($path){ - if($path=='/'){ - return false; - } - return self::basicOperation('is_file',$path); + return self::$defaultInstance->is_file($path); } static public function stat($path){ - return self::basicOperation('stat',$path); + return self::$defaultInstance->stat($path); } static public function filetype($path){ - return self::basicOperation('filetype',$path); + return self::$defaultInstance->filetype($path); } static public function filesize($path){ - return self::basicOperation('filesize',$path); + return self::$defaultInstance->filesize($path); } static public function readfile($path){ - return self::basicOperation('readfile',$path,array('read')); + return self::$defaultInstance->readfile($path); } static public function is_readable($path){ - return self::basicOperation('is_readable',$path); + return self::$defaultInstance->is_readable($path); } static public function is_writeable($path){ - return self::basicOperation('is_writeable',$path); + return self::$defaultInstance->is_writeable($path); } static public function file_exists($path){ - if($path=='/'){ - return true; - } - return self::basicOperation('file_exists',$path); + return self::$defaultInstance->file_exists($path); } static public function filectime($path){ - return self::basicOperation('filectime',$path); + return self::$defaultInstance->filectime($path); } static public function filemtime($path){ - return self::basicOperation('filemtime',$path); + return self::$defaultInstance->filemtime($path); } static public function file_get_contents($path){ - return self::basicOperation('file_get_contents',$path,array('read')); + return self::$defaultInstance->file_get_contents($path); } static public function file_put_contents($path,$data){ - return self::basicOperation('file_put_contents',$path,array('create','write'),$data); + return self::$defaultInstance->file_put_contents($path,$data); } static public function unlink($path){ - return self::basicOperation('unlink',$path,array('delete')); + return self::$defaultInstance->unlink($path); } static public function rename($path1,$path2){ - if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and self::is_writeable($path1) and self::isValidPath($path2)){ - $run=true; - OC_Hook::emit( self::CLASSNAME, self::signal_rename, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run)); - if($run){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - $result=$storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); - } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - $result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2)); - $storage1->unlink(self::getInternalPath($path1)); - } - OC_Hook::emit( self::CLASSNAME, self::signal_post_rename, array( self::signal_param_oldpath => $path1, self::signal_param_newpath=>$path2)); - return $result; - } - } + return self::$defaultInstance->rename($path1,$path2); } static public function copy($path1,$path2){ - if(OC_FileProxy::runPreProxies('copy',$path1,$path2) and self::is_readable($path1) and self::isValidPath($path2)){ - $run=true; - OC_Hook::emit( self::CLASSNAME, self::signal_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run)); - $exists=self::file_exists($path2); - if($run and !$exists){ - OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path2, self::signal_param_run => &$run)); - } - if($run){ - OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path2, self::signal_param_run => &$run)); - } - if($run){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - $result=$storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); - } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - $result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2)); - } - OC_Hook::emit( self::CLASSNAME, self::signal_post_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2)); - if(!$exists){ - OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path2)); - } - OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path2)); - return $result; - } - } + return self::$defaultInstance->copy($path1,$path2); } static public function fopen($path,$mode){ - $hooks=array(); - switch($mode){ - case 'r': - $hooks[]='read'; - break; - case 'r+': - case 'w+': - case 'x+': - case 'a+': - $hooks[]='read'; - $hooks[]='write'; - break; - case 'w': - case 'x': - case 'a': - $hooks[]='write'; - break; - default: - OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR); - } - - return self::basicOperation('fopen',$path,$hooks,$mode); + return self::$defaultInstance->fopen($path,$mode); } static public function toTmpFile($path){ - if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::isValidPath($path) and $storage=self::getStorage($path)){ - OC_Hook::emit( self::CLASSNAME, self::signal_read, array( self::signal_param_path => $path)); - return $storage->toTmpFile(self::getInternalPath($path)); - } + return self::$defaultInstance->toTmpFile($path); } static public function fromTmpFile($tmpFile,$path){ - if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and self::isValidPath($path) and $storage=self::getStorage($path)){ - $run=true; - $exists=self::file_exists($path); - if(!$exists){ - OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path, self::signal_param_run => &$run)); - } - if($run){ - OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path, self::signal_param_run => &$run)); - } - if($run){ - $result=$storage->fromTmpFile($tmpFile,self::getInternalPath($path)); - if(!$exists){ - OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path)); - } - OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path)); - return $result; - } - } + return self::$defaultInstance->fromTmpFile($tmpFile,$path); } static public function getMimeType($path){ - return self::basicOperation('getMimeType',$path); + return self::$defaultInstance->getMimeType($path); } static public function hash($type,$path){ - return self::basicOperation('hash',$path,array('read')); + return self::$defaultInstance->hash($type,$path); } static public function free_space($path='/'){ - return self::basicOperation('free_space',$path); + return self::$defaultInstance->free_space($path); } static public function search($query){ - $files=array(); - $fakeRoot=self::$fakeRoot; - $fakeRootLength=strlen($fakeRoot); - $results=OC_FileCache::search($query); - if(is_array($results)){ - foreach($results as $result){ - $file=str_replace('//','/',$mountpoint.$result); - if(substr($file,0,$fakeRootLength)==$fakeRoot){ - $file=substr($file,$fakeRootLength); - $files[]=$file; - } - } - } - return $files; - - } - - /** - * abstraction for running most basic operations - * @param string $operation - * @param string #path - * @param array (optional) hooks - * @param mixed (optional) $extraParam - * @return mixed - */ - private static function basicOperation($operation,$path,$hooks=array(),$extraParam=null){ - if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::isValidPath($path) and $storage=self::getStorage($path)){ - $interalPath=self::getInternalPath($path); - $run=true; - foreach($hooks as $hook){ - if($hook!='read'){ - OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path, self::signal_param_run => &$run)); - }else{ - OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path)); - } - } - if($run){ - if($extraParam){ - $result=$storage->$operation($interalPath,$extraParam); - }else{ - $result=$storage->$operation($interalPath); - } - $result=OC_FileProxy::runPostProxies($operation,$path,$result); - foreach($hooks as $hook){ - if($hook!='read'){ - OC_Hook::emit( self::CLASSNAME, 'post_'.$hook, array( self::signal_param_path => $path)); - } - } - return $result; - } - } - return null; + return self::$defaultInstance->search($query); } } |