2012-01-20 03:40:52 +04:00
< ? php
/**
2012-05-31 20:02:35 +04:00
* ownCloud
*
* @ author Frank Karlitschek
* @ copyright 2012 Frank Karlitschek frank @ owncloud . org
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation ; either
* version 3 of the License , or any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details .
*
* You should have received a copy of the GNU Affero General Public
* License along with this library . If not , see < http :// www . gnu . org / licenses />.
*/
/**
2012-07-21 23:44:10 +04:00
* 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
2012-05-31 20:32:34 +04:00
* OC_Filesystem are merely a wrapper for OC_FilesystemView ) .
2012-07-21 23:44:10 +04:00
*
2012-05-31 20:32:34 +04:00
* 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
2012-07-21 23:44:10 +04:00
* built - in file manipulation functions . This will ensure all hooks and proxies
2012-05-31 20:32:34 +04:00
* are triggered correctly .
2012-05-31 20:57:34 +04:00
*
2012-07-21 23:44:10 +04:00
* Filesystem functions are not called directly ; they are passed to the correct
2012-05-31 20:57:34 +04:00
* OC_Filestorage object
2012-05-31 20:02:35 +04:00
*/
2012-01-20 03:40:52 +04:00
class OC_FilesystemView {
private $fakeRoot = '' ;
2012-06-08 22:47:11 +04:00
private $internal_path_cache = array ();
private $storage_cache = array ();
2012-03-27 04:24:52 +04:00
2012-07-21 23:44:10 +04:00
public function __construct ( $root ) {
2012-01-20 03:40:52 +04:00
$this -> fakeRoot = $root ;
}
2012-03-27 04:24:52 +04:00
2012-07-21 23:44:10 +04:00
public function getAbsolutePath ( $path ) {
2012-09-07 17:22:01 +04:00
if ( ! $path ) {
2012-01-20 03:40:52 +04:00
$path = '/' ;
}
2012-09-07 17:22:01 +04:00
if ( $path [ 0 ] !== '/' ) {
2012-01-20 03:40:52 +04:00
$path = '/' . $path ;
}
2012-08-17 03:22:26 +04:00
return $this -> fakeRoot . $path ;
2012-01-20 03:40:52 +04:00
}
2012-08-29 10:38:33 +04:00
2012-01-20 03:40:52 +04:00
/**
* change the root to a fake toor
* @ param string fakeRoot
* @ return bool
*/
2012-07-21 23:44:10 +04:00
public function chroot ( $fakeRoot ) {
2012-09-07 17:22:01 +04:00
if ( ! $fakeRoot == '' ) {
2012-07-21 23:44:10 +04:00
if ( $fakeRoot [ 0 ] !== '/' ) {
2012-01-20 03:40:52 +04:00
$fakeRoot = '/' . $fakeRoot ;
}
}
$this -> fakeRoot = $fakeRoot ;
}
/**
* get the fake root
* @ return string
*/
2012-07-21 23:44:10 +04:00
public function getRoot () {
2012-01-20 03:40:52 +04:00
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
*/
2012-07-21 23:44:10 +04:00
public function getInternalPath ( $path ) {
2012-06-08 22:47:11 +04:00
if ( ! isset ( $this -> internal_path_cache [ $path ])) {
$this -> internal_path_cache [ $path ] = OC_Filesystem :: getInternalPath ( $this -> getAbsolutePath ( $path ));
}
return $this -> internal_path_cache [ $path ];
2012-01-20 03:40:52 +04:00
}
2012-06-09 19:33:57 +04:00
/**
* get path relative to the root of the view
* @ param string path
* @ return string
*/
2012-07-21 23:44:10 +04:00
public function getRelativePath ( $path ) {
if ( $this -> fakeRoot == '' ) {
2012-06-09 19:33:57 +04:00
return $path ;
}
2012-07-21 23:44:10 +04:00
if ( strpos ( $path , $this -> fakeRoot ) !== 0 ) {
2012-06-09 19:33:57 +04:00
return null ;
} else {
2012-08-14 05:07:14 +04:00
$path = substr ( $path , strlen ( $this -> fakeRoot ));
2012-09-07 17:22:01 +04:00
if ( strlen ( $path ) === 0 ) {
2012-08-14 05:07:14 +04:00
return '/' ;
} else {
return $path ;
}
2012-06-09 19:33:57 +04:00
}
}
2012-07-21 23:44:10 +04:00
2012-01-20 03:40:52 +04:00
/**
* get the storage object for a path
* @ param string path
* @ return OC_Filestorage
*/
2012-07-21 23:44:10 +04:00
public function getStorage ( $path ) {
2012-06-08 22:47:11 +04:00
if ( ! isset ( $this -> storage_cache [ $path ])) {
$this -> storage_cache [ $path ] = OC_Filesystem :: getStorage ( $this -> getAbsolutePath ( $path ));
}
return $this -> storage_cache [ $path ];
2012-01-20 03:40:52 +04:00
}
/**
* 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
*/
2012-07-21 23:44:10 +04:00
public function getMountPoint ( $path ) {
2012-01-20 03:40:52 +04:00
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
*/
2012-07-21 23:44:10 +04:00
public function getLocalFile ( $path ) {
2012-10-29 02:58:08 +04:00
$parent = substr ( $path , 0 , strrpos ( $path , '/' ));
2012-07-21 23:44:10 +04:00
if ( OC_Filesystem :: isValidPath ( $parent ) and $storage = $this -> getStorage ( $path )) {
2012-01-20 03:40:52 +04:00
return $storage -> getLocalFile ( $this -> getInternalPath ( $path ));
}
}
2012-08-19 04:42:15 +04:00
/**
* @ param string path
* @ return string
*/
public function getLocalFolder ( $path ) {
2012-10-29 02:58:08 +04:00
$parent = substr ( $path , 0 , strrpos ( $path , '/' ));
2012-08-19 04:42:15 +04:00
if ( OC_Filesystem :: isValidPath ( $parent ) and $storage = $this -> getStorage ( $path )) {
return $storage -> getLocalFolder ( $this -> getInternalPath ( $path ));
}
}
2012-01-20 03:40:52 +04:00
/**
2012-07-21 23:44:10 +04:00
* the following functions operate with arguments and return values identical
* to those of their PHP built - in equivalents . Mostly they are merely wrappers
2012-05-31 20:57:34 +04:00
* for OC_Filestorage via basicOperation () .
2012-01-20 03:40:52 +04:00
*/
2012-07-21 23:44:10 +04:00
public function mkdir ( $path ) {
return $this -> basicOperation ( 'mkdir' , $path , array ( 'create' , 'write' ));
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function rmdir ( $path ) {
return $this -> basicOperation ( 'rmdir' , $path , array ( 'delete' ));
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function opendir ( $path ) {
return $this -> basicOperation ( 'opendir' , $path , array ( 'read' ));
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function readdir ( $handle ) {
2012-06-19 22:42:40 +04:00
$fsLocal = new OC_Filestorage_Local ( array ( 'datadir' => '/' ) );
return $fsLocal -> readdir ( $handle );
}
2012-07-21 23:44:10 +04:00
public function is_dir ( $path ) {
2012-09-07 17:22:01 +04:00
if ( $path == '/' ) {
2012-01-20 03:40:52 +04:00
return true ;
}
2012-07-21 23:44:10 +04:00
return $this -> basicOperation ( 'is_dir' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function is_file ( $path ) {
2012-09-07 17:22:01 +04:00
if ( $path == '/' ) {
2012-01-20 03:40:52 +04:00
return false ;
}
2012-07-21 23:44:10 +04:00
return $this -> basicOperation ( 'is_file' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function stat ( $path ) {
return $this -> basicOperation ( 'stat' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function filetype ( $path ) {
return $this -> basicOperation ( 'filetype' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function filesize ( $path ) {
return $this -> basicOperation ( 'filesize' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function readfile ( $path ) {
2012-04-25 02:09:14 +04:00
@ ob_end_clean ();
2012-07-21 23:44:10 +04:00
$handle = $this -> fopen ( $path , 'rb' );
2012-04-01 10:38:26 +04:00
if ( $handle ) {
2012-05-05 18:49:22 +04:00
$chunkSize = 8192 ; // 8 MB chunks
2012-04-01 10:38:26 +04:00
while ( ! feof ( $handle )) {
echo fread ( $handle , $chunkSize );
flush ();
}
2012-04-25 02:09:14 +04:00
$size = $this -> filesize ( $path );
return $size ;
2012-02-26 06:54:21 +04:00
}
2012-04-01 10:38:26 +04:00
return false ;
2012-01-20 03:40:52 +04:00
}
2012-07-25 01:42:07 +04:00
/**
* @ deprecated Replaced by isReadable () as part of CRUDS
*/
2012-09-07 17:22:01 +04:00
public function is_readable ( $path ) {
2012-10-29 02:58:08 +04:00
return $this -> basicOperation ( 'isReadable' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-25 01:42:07 +04:00
/**
* @ deprecated Replaced by isCreatable (), isUpdatable (), isDeletable () as part of CRUDS
*/
2012-09-07 17:22:01 +04:00
public function is_writable ( $path ) {
2012-10-29 02:58:08 +04:00
return $this -> basicOperation ( 'isUpdatable' , $path );
2012-07-25 01:42:07 +04:00
}
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 );
2012-01-20 03:40:52 +04:00
}
2012-07-25 01:42:07 +04:00
public function isSharable ( $path ) {
return $this -> basicOperation ( 'isSharable' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function file_exists ( $path ) {
2012-09-07 17:22:01 +04:00
if ( $path == '/' ) {
2012-01-20 03:40:52 +04:00
return true ;
}
2012-07-21 23:44:10 +04:00
return $this -> basicOperation ( 'file_exists' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function filectime ( $path ) {
return $this -> basicOperation ( 'filectime' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function filemtime ( $path ) {
return $this -> basicOperation ( 'filemtime' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function touch ( $path , $mtime = null ) {
2012-10-23 18:34:58 +04:00
if ( ! is_null ( $mtime ) and ! is_numeric ( $mtime )){
$mtime = strtotime ( $mtime );
}
2012-02-14 12:59:54 +04:00
return $this -> basicOperation ( 'touch' , $path , array ( 'write' ), $mtime );
2012-02-10 14:30:38 +04:00
}
2012-07-21 23:44:10 +04:00
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
2012-08-17 03:22:26 +04:00
$absolutePath = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path ));
2012-07-27 07:10:21 +04:00
if ( OC_FileProxy :: runPreProxies ( 'file_put_contents' , $absolutePath , $data ) && OC_Filesystem :: isValidPath ( $path )) {
2012-07-27 06:53:55 +04:00
$path = $this -> getRelativePath ( $absolutePath );
$exists = $this -> file_exists ( $path );
$run = true ;
2012-09-18 00:12:17 +04:00
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
)
);
}
2012-07-27 06:53:55 +04:00
OC_Hook :: emit (
OC_Filesystem :: CLASSNAME ,
2012-09-18 00:12:17 +04:00
OC_Filesystem :: signal_write ,
2012-07-27 06:53:55 +04:00
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 );
2012-09-18 00:12:17 +04:00
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 )
);
}
2012-07-27 06:53:55 +04:00
OC_Hook :: emit (
OC_Filesystem :: CLASSNAME ,
2012-09-18 00:12:17 +04:00
OC_Filesystem :: signal_post_write ,
2012-07-27 06:53:55 +04:00
array ( OC_Filesystem :: signal_param_path => $path )
);
2012-09-13 02:12:10 +04:00
}
2012-07-27 17:37:11 +04:00
OC_FileProxy :: runPostProxies ( 'file_put_contents' , $absolutePath , $count );
2012-07-27 06:53:55 +04:00
return $count > 0 ;
} else {
return false ;
2012-04-25 02:09:14 +04:00
}
2012-02-15 19:23:00 +04:00
}
} else {
2012-07-21 23:44:10 +04:00
return $this -> basicOperation ( 'file_put_contents' , $path , array ( 'create' , 'write' ), $data );
2012-02-15 19:23:00 +04:00
}
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function unlink ( $path ) {
return $this -> basicOperation ( 'unlink' , $path , array ( 'delete' ));
2012-01-20 03:40:52 +04:00
}
2012-06-21 21:07:21 +04:00
public function deleteAll ( $directory , $empty = false ) {
return $this -> basicOperation ( 'deleteAll' , $directory , array ( 'delete' ), $empty );
}
2012-07-21 23:44:10 +04:00
public function rename ( $path1 , $path2 ) {
2012-10-29 02:58:08 +04:00
$postFix1 = ( substr ( $path1 , - 1 , 1 ) === '/' ) ? '/' : '' ;
$postFix2 = ( substr ( $path2 , - 1 , 1 ) === '/' ) ? '/' : '' ;
2012-08-17 03:22:26 +04:00
$absolutePath1 = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path1 ));
$absolutePath2 = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path2 ));
2012-07-21 23:44:10 +04:00
if ( OC_FileProxy :: runPreProxies ( 'rename' , $absolutePath1 , $absolutePath2 ) and OC_Filesystem :: isValidPath ( $path2 )) {
$path1 = $this -> getRelativePath ( $absolutePath1 );
$path2 = $this -> getRelativePath ( $absolutePath2 );
2012-08-29 10:38:33 +04:00
2012-07-21 23:44:10 +04:00
if ( $path1 == null or $path2 == null ) {
2012-06-09 19:33:57 +04:00
return false ;
}
2012-01-20 03:40:52 +04:00
$run = true ;
2012-09-18 00:12:17 +04:00
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
)
);
}
2012-07-21 23:44:10 +04:00
if ( $run ) {
2012-08-17 03:22:26 +04:00
$mp1 = $this -> getMountPoint ( $path1 . $postFix1 );
$mp2 = $this -> getMountPoint ( $path2 . $postFix2 );
2012-07-21 23:44:10 +04:00
if ( $mp1 == $mp2 ) {
if ( $storage = $this -> getStorage ( $path1 )) {
2012-08-17 03:22:26 +04:00
$result = $storage -> rename ( $this -> getInternalPath ( $path1 . $postFix1 ), $this -> getInternalPath ( $path2 . $postFix2 ));
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
} else {
2012-08-17 03:22:26 +04:00
$source = $this -> fopen ( $path1 . $postFix1 , 'r' );
$target = $this -> fopen ( $path2 . $postFix2 , 'w' );
2012-07-21 23:44:10 +04:00
$count = OC_Helper :: streamCopy ( $source , $target );
$storage1 = $this -> getStorage ( $path1 );
2012-08-17 03:22:26 +04:00
$storage1 -> unlink ( $this -> getInternalPath ( $path1 . $postFix1 ));
2012-07-21 23:44:10 +04:00
$result = $count > 0 ;
2012-08-29 10:38:33 +04:00
}
2012-09-18 00:12:17 +04:00
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
)
);
}
2012-01-20 03:40:52 +04:00
return $result ;
}
}
}
2012-07-21 23:44:10 +04:00
public function copy ( $path1 , $path2 ) {
2012-10-29 02:58:08 +04:00
$postFix1 = ( substr ( $path1 , - 1 , 1 ) === '/' ) ? '/' : '' ;
$postFix2 = ( substr ( $path2 , - 1 , 1 ) === '/' ) ? '/' : '' ;
2012-08-17 03:22:26 +04:00
$absolutePath1 = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path1 ));
$absolutePath2 = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path2 ));
2012-07-21 23:44:10 +04:00
if ( OC_FileProxy :: runPreProxies ( 'copy' , $absolutePath1 , $absolutePath2 ) and OC_Filesystem :: isValidPath ( $path2 )) {
$path1 = $this -> getRelativePath ( $absolutePath1 );
$path2 = $this -> getRelativePath ( $absolutePath2 );
2012-08-29 10:38:33 +04:00
2012-07-21 23:44:10 +04:00
if ( $path1 == null or $path2 == null ) {
2012-06-09 19:33:57 +04:00
return false ;
}
2012-01-20 03:40:52 +04:00
$run = true ;
2012-09-18 00:12:17 +04:00
if ( $this -> fakeRoot == OC_Filesystem :: getRoot () ){
2012-07-21 23:44:10 +04:00
OC_Hook :: emit (
OC_Filesystem :: CLASSNAME ,
2012-09-18 00:12:17 +04:00
OC_Filesystem :: signal_copy ,
2012-07-21 23:44:10 +04:00
array (
2012-09-18 00:12:17 +04:00
OC_Filesystem :: signal_param_oldpath => $path1 ,
OC_Filesystem :: signal_param_newpath => $path2 ,
2012-07-21 23:44:10 +04:00
OC_Filesystem :: signal_param_run => & $run
)
);
2012-09-18 00:12:17 +04:00
$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
)
);
}
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
if ( $run ) {
2012-08-17 03:22:26 +04:00
$mp1 = $this -> getMountPoint ( $path1 . $postFix1 );
$mp2 = $this -> getMountPoint ( $path2 . $postFix2 );
2012-09-07 17:22:01 +04:00
if ( $mp1 == $mp2 ) {
2012-08-17 03:22:26 +04:00
if ( $storage = $this -> getStorage ( $path1 . $postFix1 )) {
$result = $storage -> copy ( $this -> getInternalPath ( $path1 . $postFix1 ), $this -> getInternalPath ( $path2 . $postFix2 ));
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
} else {
2012-08-17 03:22:26 +04:00
$source = $this -> fopen ( $path1 . $postFix1 , 'r' );
$target = $this -> fopen ( $path2 . $postFix2 , 'w' );
2012-07-21 23:44:10 +04:00
$result = OC_Helper :: streamCopy ( $source , $target );
2012-01-20 03:40:52 +04:00
}
2012-09-18 00:12:17 +04:00
if ( $this -> fakeRoot == OC_Filesystem :: getRoot () ){
2012-07-21 23:44:10 +04:00
OC_Hook :: emit (
OC_Filesystem :: CLASSNAME ,
2012-09-18 00:12:17 +04:00
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 )
2012-07-21 23:44:10 +04:00
);
2012-09-28 20:47:54 +04:00
} 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
2012-09-26 19:03:54 +04:00
OC_FileCache_Update :: update ( $path2 , $this -> fakeRoot );
2012-09-28 20:47:54 +04:00
OC_Filesystem :: removeETagHook ( array ( " path " => $path2 ), $this -> fakeRoot );
2012-01-20 03:40:52 +04:00
}
return $result ;
}
}
}
2012-07-21 23:44:10 +04:00
public function fopen ( $path , $mode ) {
2012-01-20 03:40:52 +04:00
$hooks = array ();
2012-07-21 23:44:10 +04:00
switch ( $mode ) {
2012-01-20 03:40:52 +04:00
case 'r' :
2012-02-26 18:32:58 +04:00
case 'rb' :
2012-01-20 03:40:52 +04:00
$hooks [] = 'read' ;
break ;
case 'r+' :
2012-02-26 18:32:58 +04:00
case 'rb+' :
2012-01-20 03:40:52 +04:00
case 'w+' :
2012-02-26 18:32:58 +04:00
case 'wb+' :
2012-01-20 03:40:52 +04:00
case 'x+' :
2012-02-26 18:32:58 +04:00
case 'xb+' :
2012-01-20 03:40:52 +04:00
case 'a+' :
2012-02-26 18:32:58 +04:00
case 'ab+' :
2012-01-20 03:40:52 +04:00
$hooks [] = 'read' ;
$hooks [] = 'write' ;
break ;
case 'w' :
2012-02-26 18:32:58 +04:00
case 'wb' :
2012-01-20 03:40:52 +04:00
case 'x' :
2012-02-26 18:32:58 +04:00
case 'xb' :
2012-01-20 03:40:52 +04:00
case 'a' :
2012-02-26 18:32:58 +04:00
case 'ab' :
2012-01-20 03:40:52 +04:00
$hooks [] = 'write' ;
break ;
default :
2012-10-29 02:58:08 +04:00
OC_Log :: write ( 'core' , 'invalid mode (' . $mode . ') for ' . $path , OC_Log :: ERROR );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
return $this -> basicOperation ( 'fopen' , $path , $hooks , $mode );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function toTmpFile ( $path ) {
if ( OC_Filesystem :: isValidPath ( $path )) {
$source = $this -> fopen ( $path , 'r' );
if ( $source ) {
2012-04-14 01:02:29 +04:00
$extension = '' ;
2012-07-21 23:44:10 +04:00
$extOffset = strpos ( $path , '.' );
2012-04-14 01:01:37 +04:00
if ( $extOffset !== false ) {
2012-10-29 02:58:08 +04:00
$extension = substr ( $path , strrpos ( $path , '.' ));
2012-04-14 01:01:37 +04:00
}
2012-07-21 23:44:10 +04:00
$tmpFile = OC_Helper :: tmpFile ( $extension );
file_put_contents ( $tmpFile , $source );
2012-03-27 04:24:52 +04:00
return $tmpFile ;
2012-02-11 18:48:31 +04:00
}
2012-01-20 03:40:52 +04:00
}
}
2012-07-21 23:44:10 +04:00
public function fromTmpFile ( $tmpFile , $path ) {
if ( OC_Filesystem :: isValidPath ( $path )) {
if ( ! $tmpFile ) {
2012-02-21 23:48:14 +04:00
debug_print_backtrace ();
}
2012-07-21 23:44:10 +04:00
$source = fopen ( $tmpFile , 'r' );
if ( $source ) {
$this -> file_put_contents ( $path , $source );
2012-02-11 18:48:31 +04:00
unlink ( $tmpFile );
return true ;
2012-07-21 23:44:10 +04:00
} else {
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
} else {
2012-02-21 23:48:14 +04:00
return false ;
2012-01-20 03:40:52 +04:00
}
}
2012-07-21 23:44:10 +04:00
public function getMimeType ( $path ) {
return $this -> basicOperation ( 'getMimeType' , $path );
2012-01-20 03:40:52 +04:00
}
2012-07-26 00:54:46 +04:00
public function hash ( $type , $path , $raw = false ) {
2012-10-29 02:58:08 +04:00
$postFix = ( substr ( $path , - 1 , 1 ) === '/' ) ? '/' : '' ;
2012-08-17 03:22:26 +04:00
$absolutePath = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path ));
2012-07-26 00:54:46 +04:00
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 )
);
}
2012-08-17 03:22:26 +04:00
if ( $storage = $this -> getStorage ( $path . $postFix )) {
$result = $storage -> hash ( $type , $this -> getInternalPath ( $path . $postFix ), $raw );
2012-07-26 00:54:46 +04:00
$result = OC_FileProxy :: runPostProxies ( 'hash' , $absolutePath , $result );
return $result ;
}
}
return null ;
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
public function free_space ( $path = '/' ) {
return $this -> basicOperation ( 'free_space' , $path );
2012-01-20 03:40:52 +04:00
}
/**
2012-05-31 20:57:34 +04:00
* @ brief abstraction layer for basic filesystem functions : wrapper for OC_Filestorage
2012-01-20 03:40:52 +04:00
* @ param string $operation
* @ param string #path
* @ param array ( optional ) hooks
* @ param mixed ( optional ) $extraParam
* @ return mixed
2012-07-21 23:44:10 +04:00
*
* 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
2012-05-31 20:57:34 +04:00
* OC_Filestorage for delegation to a storage backend for execution
2012-01-20 03:40:52 +04:00
*/
2012-07-21 23:44:10 +04:00
private function basicOperation ( $operation , $path , $hooks = array (), $extraParam = null ) {
2012-10-29 02:58:08 +04:00
$postFix = ( substr ( $path , - 1 , 1 ) === '/' ) ? '/' : '' ;
2012-08-17 03:22:26 +04:00
$absolutePath = OC_Filesystem :: normalizePath ( $this -> getAbsolutePath ( $path ));
2012-07-21 23:44:10 +04:00
if ( OC_FileProxy :: runPreProxies ( $operation , $absolutePath , $extraParam ) and OC_Filesystem :: isValidPath ( $path )) {
$path = $this -> getRelativePath ( $absolutePath );
if ( $path == null ) {
2012-06-09 19:33:57 +04:00
return false ;
}
2012-08-17 03:22:26 +04:00
$internalPath = $this -> getInternalPath ( $path . $postFix );
2012-10-29 02:58:08 +04:00
$run = $this -> runHooks ( $hooks , $path );
2012-08-17 03:22:26 +04:00
if ( $run and $storage = $this -> getStorage ( $path . $postFix )) {
2012-07-21 23:44:10 +04:00
if ( ! is_null ( $extraParam )) {
$result = $storage -> $operation ( $internalPath , $extraParam );
} else {
$result = $storage -> $operation ( $internalPath );
2012-01-20 03:40:52 +04:00
}
2012-07-21 23:44:10 +04:00
$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
2012-10-29 02:58:08 +04:00
$this -> runHooks ( $hooks , $path , true );
2012-01-20 03:40:52 +04:00
}
}
return $result ;
}
}
return null ;
}
2012-06-15 19:42:39 +04:00
2012-09-07 17:22:01 +04:00
private function runHooks ( $hooks , $path , $post = false ) {
2012-08-17 03:22:26 +04:00
$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 ;
}
2012-06-15 19:42:39 +04:00
/**
* check if a file or folder has been updated since $time
* @ param int $time
* @ return bool
*/
2012-07-21 23:44:10 +04:00
public function hasUpdated ( $path , $time ) {
return $this -> basicOperation ( 'hasUpdated' , $path , array (), $time );
2012-06-15 19:42:39 +04:00
}
2012-01-20 03:40:52 +04:00
}