2011-06-12 00:14:24 +04:00
< ? php
/**
2015-03-26 13:44:34 +03:00
* @ author Bart Visscher < bartv @ thisnet . nl >
* @ author Björn Schießle < schiessle @ owncloud . com >
* @ author Joas Schilling < nickvergessen @ owncloud . com >
* @ author Michael Gapczynski < GapczynskiM @ gmail . com >
* @ author Morris Jobke < hey @ morrisjobke . de >
* @ author Robin Appelman < icewind @ owncloud . com >
2016-01-12 17:02:16 +03:00
* @ author Robin McCorkell < robin @ mccorkell . me . uk >
2015-10-26 15:54:55 +03:00
* @ author Roeland Jago Douma < rullzer @ owncloud . com >
2015-03-26 13:44:34 +03:00
* @ author scambra < sergio @ entrecables . com >
* @ author Vincent Petry < pvince81 @ owncloud . com >
2011-06-12 00:14:24 +04:00
*
2016-01-12 17:02:16 +03:00
* @ copyright Copyright ( c ) 2016 , ownCloud , Inc .
2015-03-26 13:44:34 +03:00
* @ license AGPL - 3.0
2011-06-12 00:14:24 +04:00
*
2015-03-26 13:44:34 +03:00
* This code is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License , version 3 ,
* as published by the Free Software Foundation .
2011-06-12 00:14:24 +04:00
*
2015-03-26 13:44:34 +03:00
* This program is distributed in the hope that it will be useful ,
2011-06-12 00:14:24 +04:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2015-03-26 13:44:34 +03:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
2011-06-12 00:14:24 +04:00
*
2015-03-26 13:44:34 +03:00
* You should have received a copy of the GNU Affero General Public License , version 3 ,
* along with this program . If not , see < http :// www . gnu . org / licenses />
2011-06-12 00:14:24 +04:00
*
*/
2015-02-26 13:37:37 +03:00
2012-09-07 20:30:48 +04:00
namespace OC\Files\Storage ;
2015-03-09 18:20:18 +03:00
2014-05-22 03:41:27 +04:00
use OC\Files\Filesystem ;
2016-03-10 15:38:48 +03:00
use OC\Files\Cache\FailedCache ;
2014-06-10 15:50:52 +04:00
use OCA\Files_Sharing\ISharedStorage ;
2016-01-29 15:05:53 +03:00
use OCP\Constants ;
2016-01-22 15:01:37 +03:00
use OCP\Files\Cache\ICacheEntry ;
use OCP\Files\Storage\IStorage ;
2015-05-04 15:21:34 +03:00
use OCP\Lock\ILockingProvider ;
2012-09-07 20:30:48 +04:00
2011-06-16 22:40:21 +04:00
/**
* Convert target path to source path and pass the function call to the correct storage provider
*/
2014-06-10 15:50:52 +04:00
class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
2012-08-29 10:42:49 +04:00
2014-04-14 13:33:10 +04:00
private $share ; // the shared resource
2012-07-24 04:08:05 +04:00
private $files = array ();
2012-08-29 10:42:49 +04:00
2015-06-29 20:13:39 +03:00
/**
* @ var \OC\Files\View
*/
private $ownerView ;
2015-09-04 17:43:41 +03:00
/**
* @ var string
*/
private $user ;
2015-09-04 17:48:45 +03:00
private $initialized = false ;
2016-01-22 15:01:37 +03:00
/**
* @ var ICacheEntry
*/
private $sourceRootInfo ;
/**
* @ var IStorage
*/
private $sourceStorage ;
2016-03-09 18:44:57 +03:00
/**
* @ var \OCP\ILogger
*/
private $logger ;
2011-07-12 21:10:29 +04:00
public function __construct ( $arguments ) {
2014-04-14 13:33:10 +04:00
$this -> share = $arguments [ 'share' ];
2015-06-29 20:13:39 +03:00
$this -> ownerView = $arguments [ 'ownerView' ];
2015-09-04 17:43:41 +03:00
$this -> user = $arguments [ 'user' ];
2016-03-09 18:44:57 +03:00
$this -> logger = \OC :: $server -> getLogger ();
2011-06-16 22:40:21 +04:00
}
2012-06-23 01:43:04 +04:00
2015-09-03 14:46:08 +03:00
private function init () {
2015-09-04 17:48:45 +03:00
if ( $this -> initialized ) {
return ;
}
$this -> initialized = true ;
2016-03-09 18:44:57 +03:00
try {
Filesystem :: initMountPoints ( $this -> share [ 'uid_owner' ]);
$sourcePath = $this -> ownerView -> getPath ( $this -> share [ 'file_source' ]);
list ( $this -> sourceStorage , $sourceInternalPath ) = $this -> ownerView -> resolvePath ( $sourcePath );
$this -> sourceRootInfo = $this -> sourceStorage -> getCache () -> get ( $sourceInternalPath );
} catch ( \Exception $e ) {
$this -> logger -> logException ( $e );
}
2015-09-03 14:46:08 +03:00
}
2016-01-29 15:05:53 +03:00
private function isValid () {
2016-03-08 13:23:20 +03:00
$this -> init ();
2016-03-09 18:44:57 +03:00
return $this -> sourceRootInfo && ( $this -> sourceRootInfo -> getPermissions () & Constants :: PERMISSION_SHARE ) === Constants :: PERMISSION_SHARE ;
2016-01-29 15:05:53 +03:00
}
2014-04-04 20:32:49 +04:00
/**
2014-05-19 19:50:53 +04:00
* get id of the mount point
2015-03-09 18:20:18 +03:00
*
2014-04-04 20:32:49 +04:00
* @ return string
*/
2013-11-11 20:58:20 +04:00
public function getId () {
2014-04-14 13:33:10 +04:00
return 'shared::' . $this -> getMountPoint ();
2011-06-27 19:47:36 +04:00
}
2012-06-23 01:43:04 +04:00
2014-04-04 20:32:49 +04:00
/**
2014-05-19 19:50:53 +04:00
* get file cache of the shared item source
2015-03-09 18:20:18 +03:00
*
2014-08-13 20:06:28 +04:00
* @ return int
2014-04-04 20:32:49 +04:00
*/
public function getSourceId () {
2015-03-09 18:20:18 +03:00
return ( int ) $this -> share [ 'file_source' ];
2014-04-04 20:32:49 +04:00
}
2012-07-24 04:08:05 +04:00
/**
2014-05-19 19:50:53 +04:00
* Get the source file path , permissions , and owner for a shared file
2015-03-09 18:20:18 +03:00
*
2014-05-15 16:19:32 +04:00
* @ param string $target Shared target file path
2015-05-19 16:27:50 +03:00
* @ return array Returns array with the keys path , permissions , and owner or false if not found
2013-11-11 20:58:20 +04:00
*/
2013-11-05 16:58:14 +04:00
public function getFile ( $target ) {
2015-09-03 14:46:08 +03:00
$this -> init ();
2012-12-16 04:44:46 +04:00
if ( ! isset ( $this -> files [ $target ])) {
2013-02-24 00:32:59 +04:00
// Check for partial files
if ( pathinfo ( $target , PATHINFO_EXTENSION ) === 'part' ) {
2015-08-05 16:41:29 +03:00
$source = \OC_Share_Backend_File :: getSource ( substr ( $target , 0 , - 5 ), $this -> getShare ());
2013-02-24 00:32:59 +04:00
if ( $source ) {
2013-03-08 02:14:34 +04:00
$source [ 'path' ] .= '.part' ;
2013-02-24 00:32:59 +04:00
// All partial files have delete permission
2014-11-25 18:28:41 +03:00
$source [ 'permissions' ] |= \OCP\Constants :: PERMISSION_DELETE ;
2013-02-24 00:32:59 +04:00
}
} else {
2015-08-05 16:41:29 +03:00
$source = \OC_Share_Backend_File :: getSource ( $target , $this -> getShare ());
2012-12-29 20:09:57 +04:00
}
2012-12-16 04:44:46 +04:00
$this -> files [ $target ] = $source ;
2012-12-29 20:09:57 +04:00
}
return $this -> files [ $target ];
}
/**
2014-05-19 19:50:53 +04:00
* Get the source file path for a shared file
2015-03-09 18:20:18 +03:00
*
2014-05-15 16:19:32 +04:00
* @ param string $target Shared target file path
2015-01-16 21:31:15 +03:00
* @ return string | false source file path or false if not found
2013-11-11 20:58:20 +04:00
*/
2013-11-05 16:58:14 +04:00
public function getSourcePath ( $target ) {
2016-01-29 15:05:53 +03:00
if ( ! $this -> isValid ()){
return false ;
}
2012-12-29 20:09:57 +04:00
$source = $this -> getFile ( $target );
if ( $source ) {
2013-03-07 20:12:59 +04:00
if ( ! isset ( $source [ 'fullPath' ])) {
\OC\Files\Filesystem :: initMountPoints ( $source [ 'fileOwner' ]);
2013-04-26 02:01:36 +04:00
$mount = \OC\Files\Filesystem :: getMountByNumericId ( $source [ 'storage' ]);
2014-04-21 14:35:52 +04:00
if ( is_array ( $mount ) && ! empty ( $mount )) {
2013-11-11 20:58:20 +04:00
$this -> files [ $target ][ 'fullPath' ] = $mount [ key ( $mount )] -> getMountPoint () . $source [ 'path' ];
2013-03-07 20:12:59 +04:00
} else {
$this -> files [ $target ][ 'fullPath' ] = false ;
2014-04-21 14:35:52 +04:00
\OCP\Util :: writeLog ( 'files_sharing' , " Unable to get mount for shared storage ' " . $source [ 'storage' ] . " ' user ' " . $source [ 'fileOwner' ] . " ' " , \OCP\Util :: ERROR );
2013-03-07 20:12:59 +04:00
}
}
return $this -> files [ $target ][ 'fullPath' ];
2012-07-24 04:08:05 +04:00
}
2012-12-29 20:09:57 +04:00
return false ;
2012-07-24 04:08:05 +04:00
}
/**
2014-05-19 19:50:53 +04:00
* Get the permissions granted for a shared file
2015-03-09 18:20:18 +03:00
*
2014-05-15 16:19:32 +04:00
* @ param string $target Shared target file path
2014-05-07 18:49:07 +04:00
* @ return int CRUDS permissions granted
2013-11-11 20:58:20 +04:00
*/
2014-05-23 19:15:05 +04:00
public function getPermissions ( $target = '' ) {
2016-01-29 15:05:53 +03:00
if ( ! $this -> isValid ()) {
return 0 ;
}
2014-05-07 18:49:07 +04:00
$permissions = $this -> share [ 'permissions' ];
2014-06-03 21:47:23 +04:00
// part files and the mount point always have delete permissions
if ( $target === '' || pathinfo ( $target , PATHINFO_EXTENSION ) === 'part' ) {
2014-11-25 18:28:41 +03:00
$permissions |= \OCP\Constants :: PERMISSION_DELETE ;
2012-07-24 04:08:05 +04:00
}
2014-05-13 17:22:18 +04:00
2015-04-01 13:06:04 +03:00
if ( \OCP\Util :: isSharingDisabledForUser ()) {
2014-11-25 18:28:41 +03:00
$permissions &= ~ \OCP\Constants :: PERMISSION_SHARE ;
2014-05-13 17:22:18 +04:00
}
2014-05-07 18:49:07 +04:00
return $permissions ;
2012-07-06 14:22:21 +04:00
}
2011-06-16 22:40:21 +04:00
public function mkdir ( $path ) {
2012-07-25 01:42:07 +04:00
if ( $path == '' || $path == '/' || ! $this -> isCreatable ( dirname ( $path ))) {
2012-08-29 10:42:49 +04:00
return false ;
2012-07-24 04:08:05 +04:00
} else if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> mkdir ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2014-05-27 13:05:31 +04:00
/**
* Delete the directory if DELETE permission is granted
2015-03-09 18:20:18 +03:00
*
2014-05-27 13:05:31 +04:00
* @ param string $path
* @ return boolean
*/
2011-06-16 22:40:21 +04:00
public function rmdir ( $path ) {
2014-05-27 13:05:31 +04:00
// never delete a share mount point
2015-03-09 18:20:18 +03:00
if ( empty ( $path )) {
2014-05-27 13:05:31 +04:00
return false ;
}
2012-07-25 01:42:07 +04:00
if (( $source = $this -> getSourcePath ( $path )) && $this -> isDeletable ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> rmdir ( $internalPath );
2012-07-24 04:08:05 +04:00
}
return false ;
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function opendir ( $path ) {
2014-04-08 21:57:07 +04:00
$source = $this -> getSourcePath ( $path );
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
return $storage -> opendir ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-11 02:56:22 +04:00
2011-06-16 22:40:21 +04:00
public function is_dir ( $path ) {
2014-04-09 20:00:00 +04:00
$source = $this -> getSourcePath ( $path );
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
return $storage -> is_dir ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-11 02:56:22 +04:00
2011-06-16 22:40:21 +04:00
public function is_file ( $path ) {
2012-07-11 02:56:22 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> is_file ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-11 02:56:22 +04:00
2011-06-16 22:40:21 +04:00
public function stat ( $path ) {
2012-07-11 02:56:22 +04:00
if ( $path == '' || $path == '/' ) {
$stat [ 'size' ] = $this -> filesize ( $path );
$stat [ 'mtime' ] = $this -> filemtime ( $path );
2011-06-18 21:29:16 +04:00
return $stat ;
2012-07-24 04:08:05 +04:00
} else if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> stat ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-11 02:56:22 +04:00
2011-06-16 22:40:21 +04:00
public function filetype ( $path ) {
2012-07-24 04:08:05 +04:00
if ( $path == '' || $path == '/' ) {
return 'dir' ;
} else if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> filetype ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-11 02:56:22 +04:00
2011-06-16 22:40:21 +04:00
public function filesize ( $path ) {
2014-05-26 14:37:43 +04:00
$source = $this -> getSourcePath ( $path );
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
return $storage -> filesize ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2011-08-20 23:43:18 +04:00
2012-07-25 01:42:07 +04:00
public function isCreatable ( $path ) {
2014-11-25 18:28:41 +03:00
return ( $this -> getPermissions ( $path ) & \OCP\Constants :: PERMISSION_CREATE );
2012-07-25 01:42:07 +04:00
}
public function isReadable ( $path ) {
2016-01-29 15:05:53 +03:00
if ( ! $this -> isValid ()) {
return false ;
2015-05-12 19:49:25 +03:00
}
2016-01-29 15:05:53 +03:00
if ( ! $this -> file_exists ( $path )) {
return false ;
}
list ( $storage , $internalPath ) = $this -> resolvePath ( $path );
return $storage -> isReadable ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-25 01:42:07 +04:00
public function isUpdatable ( $path ) {
2014-11-25 18:28:41 +03:00
return ( $this -> getPermissions ( $path ) & \OCP\Constants :: PERMISSION_UPDATE );
2011-06-16 22:40:21 +04:00
}
2012-07-25 01:42:07 +04:00
public function isDeletable ( $path ) {
2014-11-25 18:28:41 +03:00
return ( $this -> getPermissions ( $path ) & \OCP\Constants :: PERMISSION_DELETE );
2012-07-25 01:42:07 +04:00
}
public function isSharable ( $path ) {
2015-12-08 15:02:57 +03:00
if ( \OCP\Util :: isSharingDisabledForUser () || ! \OC\Share\Share :: isResharingAllowed ()) {
2014-05-13 17:22:18 +04:00
return false ;
}
2014-11-25 18:28:41 +03:00
return ( $this -> getPermissions ( $path ) & \OCP\Constants :: PERMISSION_SHARE );
2012-07-25 01:42:07 +04:00
}
2011-06-16 22:40:21 +04:00
public function file_exists ( $path ) {
2012-07-24 04:08:05 +04:00
if ( $path == '' || $path == '/' ) {
2011-06-18 21:29:16 +04:00
return true ;
2012-07-24 04:08:05 +04:00
} else if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> file_exists ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function filemtime ( $path ) {
2014-04-08 21:57:07 +04:00
$source = $this -> getSourcePath ( $path );
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
return $storage -> filemtime ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function file_get_contents ( $path ) {
2012-06-23 01:43:04 +04:00
$source = $this -> getSourcePath ( $path );
2011-06-16 22:40:21 +04:00
if ( $source ) {
2012-05-30 19:46:49 +04:00
$info = array (
2014-04-14 13:33:10 +04:00
'target' => $this -> getMountPoint () . $path ,
2012-05-30 19:46:49 +04:00
'source' => $source ,
);
2012-10-10 15:18:36 +04:00
\OCP\Util :: emitHook ( '\OC\Files\Storage\Shared' , 'file_get_contents' , $info );
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> file_get_contents ( $internalPath );
2011-06-16 22:40:21 +04:00
}
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function file_put_contents ( $path , $data ) {
2012-08-16 20:20:14 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
// Check if permission is granted
2013-02-15 01:37:49 +04:00
if (( $this -> file_exists ( $path ) && ! $this -> isUpdatable ( $path ))
2013-11-11 20:58:20 +04:00
|| ( $this -> is_dir ( $path ) && ! $this -> isCreatable ( $path ))
) {
2012-08-16 20:20:14 +04:00
return false ;
2011-07-31 00:03:32 +04:00
}
2012-08-16 20:20:14 +04:00
$info = array (
2014-04-14 13:33:10 +04:00
'target' => $this -> getMountPoint () . '/' . $path ,
2013-11-11 20:58:20 +04:00
'source' => $source ,
);
2012-10-10 15:18:36 +04:00
\OCP\Util :: emitHook ( '\OC\Files\Storage\Shared' , 'file_put_contents' , $info );
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
$result = $storage -> file_put_contents ( $internalPath , $data );
2012-08-16 20:20:14 +04:00
return $result ;
2011-06-16 22:40:21 +04:00
}
2012-08-16 20:20:14 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2014-05-27 13:05:31 +04:00
/**
* Delete the file if DELETE permission is granted
2015-03-09 18:20:18 +03:00
*
2014-05-27 13:05:31 +04:00
* @ param string $path
* @ return boolean
*/
2011-06-16 22:40:21 +04:00
public function unlink ( $path ) {
2014-05-27 13:05:31 +04:00
// never delete a share mount point
if ( empty ( $path )) {
return false ;
}
2012-09-07 08:01:52 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
if ( $this -> isDeletable ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> unlink ( $internalPath );
2012-09-07 08:01:52 +04:00
}
2012-07-24 22:22:07 +04:00
}
return false ;
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function rename ( $path1 , $path2 ) {
2015-09-03 14:46:08 +03:00
$this -> init ();
2014-05-28 01:50:44 +04:00
// we need the paths relative to data/user/files
$relPath1 = $this -> getMountPoint () . '/' . $path1 ;
$relPath2 = $this -> getMountPoint () . '/' . $path2 ;
2015-03-19 23:55:56 +03:00
$pathinfo = pathinfo ( $relPath1 );
2014-04-04 20:32:49 +04:00
2015-03-19 23:55:56 +03:00
$isPartFile = ( isset ( $pathinfo [ 'extension' ]) && $pathinfo [ 'extension' ] === 'part' );
2015-01-30 16:19:23 +03:00
$targetExists = $this -> file_exists ( $path2 );
2015-03-19 23:55:56 +03:00
$sameFolder = ( dirname ( $relPath1 ) === dirname ( $relPath2 ));
if ( $targetExists || ( $sameFolder && ! $isPartFile )) {
// note that renaming a share mount point is always allowed
if ( ! $this -> isUpdatable ( '' )) {
return false ;
}
} else {
if ( ! $this -> isCreatable ( '' )) {
return false ;
2014-04-30 14:49:16 +04:00
}
2012-07-24 22:22:07 +04:00
}
2014-04-16 18:41:23 +04:00
2015-05-12 18:02:55 +03:00
/**
* @ var \OC\Files\Storage\Storage $sourceStorage
*/
list ( $sourceStorage , $sourceInternalPath ) = $this -> resolvePath ( $path1 );
/**
* @ var \OC\Files\Storage\Storage $targetStorage
*/
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $path2 );
return $targetStorage -> moveFromStorage ( $sourceStorage , $sourceInternalPath , $targetInternalPath );
2011-06-16 22:40:21 +04:00
}
2012-08-29 10:42:49 +04:00
2011-06-16 22:40:21 +04:00
public function copy ( $path1 , $path2 ) {
2012-07-24 22:22:07 +04:00
// Copy the file if CREATE permission is granted
2012-08-23 04:48:16 +04:00
if ( $this -> isCreatable ( dirname ( $path2 ))) {
2015-05-12 18:02:55 +03:00
/**
* @ var \OC\Files\Storage\Storage $sourceStorage
*/
list ( $sourceStorage , $sourceInternalPath ) = $this -> resolvePath ( $path1 );
/**
* @ var \OC\Files\Storage\Storage $targetStorage
*/
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $path2 );
return $targetStorage -> copyFromStorage ( $sourceStorage , $sourceInternalPath , $targetInternalPath );
2012-07-24 22:22:07 +04:00
}
2012-08-23 04:48:16 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-26 01:08:18 +04:00
2011-06-16 22:40:21 +04:00
public function fopen ( $path , $mode ) {
2012-07-24 04:08:05 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
2012-08-08 19:25:24 +04:00
switch ( $mode ) {
case 'r+' :
case 'rb+' :
case 'w+' :
case 'wb+' :
case 'x+' :
case 'xb+' :
case 'a+' :
case 'ab+' :
case 'w' :
case 'wb' :
case 'x' :
case 'xb' :
case 'a' :
case 'ab' :
2015-01-30 16:19:23 +03:00
$creatable = $this -> isCreatable ( $path );
$updatable = $this -> isUpdatable ( $path );
// if neither permissions given, no need to continue
if ( ! $creatable && ! $updatable ) {
2013-11-11 20:58:20 +04:00
return false ;
}
2015-01-30 16:19:23 +03:00
$exists = $this -> file_exists ( $path );
// if a file exists, updatable permissions are required
if ( $exists && ! $updatable ) {
2013-11-11 20:58:20 +04:00
return false ;
}
2015-01-30 16:19:23 +03:00
// part file is allowed if !$creatable but the final file is $updatable
if ( pathinfo ( $path , PATHINFO_EXTENSION ) !== 'part' ) {
if ( ! $exists && ! $creatable ) {
return false ;
}
}
2012-08-08 19:25:24 +04:00
}
2012-05-30 19:46:49 +04:00
$info = array (
2014-04-14 13:33:10 +04:00
'target' => $this -> getMountPoint () . $path ,
2012-05-30 19:46:49 +04:00
'source' => $source ,
'mode' => $mode ,
);
2012-10-10 15:18:36 +04:00
\OCP\Util :: emitHook ( '\OC\Files\Storage\Shared' , 'fopen' , $info );
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> fopen ( $internalPath , $mode );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-24 22:50:43 +04:00
2011-06-16 22:40:21 +04:00
public function getMimeType ( $path ) {
2012-07-24 04:08:05 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> getMimeType ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-06-16 22:40:21 +04:00
}
2012-07-26 01:13:48 +04:00
2011-06-16 22:40:21 +04:00
public function free_space ( $path ) {
2012-06-23 01:43:04 +04:00
$source = $this -> getSourcePath ( $path );
2011-06-16 22:40:21 +04:00
if ( $source ) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> free_space ( $internalPath );
2011-06-16 22:40:21 +04:00
}
2014-08-19 16:05:08 +04:00
return \OCP\Files\FileInfo :: SPACE_UNKNOWN ;
2011-06-16 22:40:21 +04:00
}
2011-08-20 04:05:57 +04:00
public function getLocalFile ( $path ) {
2012-07-24 04:08:05 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> getLocalFile ( $internalPath );
2011-08-20 04:05:57 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2011-08-20 04:05:57 +04:00
}
2013-11-11 20:58:20 +04:00
2012-07-24 04:08:05 +04:00
public function touch ( $path , $mtime = null ) {
if ( $source = $this -> getSourcePath ( $path )) {
2012-12-16 04:44:46 +04:00
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
2012-10-10 19:46:29 +04:00
return $storage -> touch ( $internalPath , $mtime );
2012-03-01 02:42:40 +04:00
}
2012-07-24 04:08:05 +04:00
return false ;
2012-03-01 02:42:40 +04:00
}
2012-05-11 03:56:25 +04:00
2014-04-14 13:33:10 +04:00
/**
2014-04-30 18:56:09 +04:00
* return mount point of share , relative to data / user / files
*
* @ return string
2014-04-14 13:33:10 +04:00
*/
2014-04-30 18:56:09 +04:00
public function getMountPoint () {
return $this -> share [ 'file_target' ];
2014-04-14 13:33:10 +04:00
}
2014-05-22 03:41:27 +04:00
public function setMountPoint ( $path ) {
2014-04-15 13:19:31 +04:00
$this -> share [ 'file_target' ] = $path ;
}
2014-05-22 03:41:27 +04:00
public function getShareType () {
return $this -> share [ 'share_type' ];
}
/**
* does the group share already has a user specific unique name
2015-03-09 18:20:18 +03:00
*
2014-05-22 03:41:27 +04:00
* @ return bool
*/
public function uniqueNameSet () {
return ( isset ( $this -> share [ 'unique_name' ]) && $this -> share [ 'unique_name' ]);
}
2014-04-14 14:04:12 +04:00
/**
2014-05-19 19:50:53 +04:00
* the share now uses a unique name of this user
2014-04-30 18:56:09 +04:00
*
* @ brief the share now uses a unique name of this user
2014-04-14 14:04:12 +04:00
*/
2014-05-22 03:41:27 +04:00
public function setUniqueName () {
2014-04-14 14:04:12 +04:00
$this -> share [ 'unique_name' ] = true ;
}
2014-04-14 13:33:10 +04:00
/**
2014-05-22 03:41:27 +04:00
* get share ID
2015-03-09 18:20:18 +03:00
*
2014-05-22 03:41:27 +04:00
* @ return integer unique share ID
*/
public function getShareId () {
return $this -> share [ 'id' ];
}
/**
* get the user who shared the file
2015-03-09 18:20:18 +03:00
*
2014-04-08 18:37:34 +04:00
* @ return string
*/
public function getSharedFrom () {
2014-04-14 13:33:10 +04:00
return $this -> share [ 'uid_owner' ];
2014-04-08 18:37:34 +04:00
}
2014-05-22 03:41:27 +04:00
/**
* @ return array
*/
public function getShare () {
return $this -> share ;
}
2014-04-02 14:04:51 +04:00
/**
2014-05-19 19:50:53 +04:00
* return share type , can be " file " or " folder "
2015-03-09 18:20:18 +03:00
*
2014-04-02 14:04:51 +04:00
* @ return string
*/
2014-04-14 13:33:10 +04:00
public function getItemType () {
return $this -> share [ 'item_type' ];
2014-04-02 14:04:51 +04:00
}
2013-01-01 20:19:33 +04:00
public function hasUpdated ( $path , $time ) {
return $this -> filemtime ( $path ) > $time ;
}
2014-06-12 19:23:34 +04:00
public function getCache ( $path = '' , $storage = null ) {
2016-03-08 13:23:20 +03:00
$this -> init ();
2016-03-09 18:44:57 +03:00
if ( is_null ( $this -> sourceStorage )) {
return new FailedCache ( false );
}
2014-06-12 19:23:34 +04:00
if ( ! $storage ) {
$storage = $this ;
}
2016-01-22 15:01:37 +03:00
return new \OC\Files\Cache\Shared_Cache ( $storage , $this -> sourceStorage , $this -> sourceRootInfo );
2012-06-15 18:43:24 +04:00
}
2012-09-23 03:51:00 +04:00
2014-06-12 19:23:34 +04:00
public function getScanner ( $path = '' , $storage = null ) {
if ( ! $storage ) {
$storage = $this ;
}
2015-01-14 14:35:24 +03:00
return new \OC\Files\Cache\SharedScanner ( $storage );
2013-01-01 23:47:25 +04:00
}
2015-11-10 18:14:08 +03:00
public function getPropagator ( $storage = null ) {
if ( ! $storage ) {
$storage = $this ;
}
return new \OCA\Files_Sharing\SharedPropagator ( $storage );
}
2012-12-16 04:44:46 +04:00
public function getOwner ( $path ) {
2013-01-01 20:19:33 +04:00
if ( $path == '' ) {
2014-04-14 13:33:10 +04:00
$path = $this -> getMountPoint ();
2013-01-01 20:19:33 +04:00
}
2012-12-29 20:09:57 +04:00
$source = $this -> getFile ( $path );
if ( $source ) {
2013-03-07 20:12:59 +04:00
return $source [ 'fileOwner' ];
2012-12-16 04:44:46 +04:00
}
2012-12-29 20:09:57 +04:00
return false ;
2012-12-16 04:44:46 +04:00
}
public function getETag ( $path ) {
2013-01-19 09:02:40 +04:00
if ( $source = $this -> getSourcePath ( $path )) {
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $source );
return $storage -> getETag ( $internalPath );
}
return null ;
2012-12-16 04:44:46 +04:00
}
2014-07-31 13:55:59 +04:00
/**
* unshare complete storage , also the grouped shares
2014-09-25 13:29:57 +04:00
*
* @ return bool
2014-07-31 13:55:59 +04:00
*/
public function unshareStorage () {
$result = true ;
if ( ! empty ( $this -> share [ 'grouped' ])) {
foreach ( $this -> share [ 'grouped' ] as $share ) {
$result = $result && \OCP\Share :: unshareFromSelf ( $share [ 'item_type' ], $share [ 'file_target' ]);
}
}
$result = $result && \OCP\Share :: unshareFromSelf ( $this -> getItemType (), $this -> getMountPoint ());
return $result ;
}
2015-04-14 13:35:53 +03:00
/**
* Resolve the path for the source of the share
*
* @ param string $path
* @ return array
*/
2016-01-11 18:09:30 +03:00
public function resolvePath ( $path ) {
2015-01-19 15:44:37 +03:00
$source = $this -> getSourcePath ( $path );
return \OC\Files\Filesystem :: resolvePath ( $source );
}
/**
* @ param \OCP\Files\Storage $sourceStorage
* @ param string $sourceInternalPath
* @ param string $targetInternalPath
* @ return bool
*/
public function copyFromStorage ( \OCP\Files\Storage $sourceStorage , $sourceInternalPath , $targetInternalPath ) {
/** @var \OCP\Files\Storage $targetStorage */
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $targetInternalPath );
2015-03-19 17:26:47 +03:00
return $targetStorage -> copyFromStorage ( $sourceStorage , $sourceInternalPath , $targetInternalPath );
2015-01-19 15:44:37 +03:00
}
/**
* @ param \OCP\Files\Storage $sourceStorage
* @ param string $sourceInternalPath
* @ param string $targetInternalPath
* @ return bool
*/
public function moveFromStorage ( \OCP\Files\Storage $sourceStorage , $sourceInternalPath , $targetInternalPath ) {
/** @var \OCP\Files\Storage $targetStorage */
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $targetInternalPath );
2015-03-19 17:26:47 +03:00
return $targetStorage -> moveFromStorage ( $sourceStorage , $sourceInternalPath , $targetInternalPath );
2015-01-19 15:44:37 +03:00
}
2015-05-04 15:21:34 +03:00
/**
* @ param string $path
* @ param int $type \OCP\Lock\ILockingProvider :: LOCK_SHARED or \OCP\Lock\ILockingProvider :: LOCK_EXCLUSIVE
* @ param \OCP\Lock\ILockingProvider $provider
* @ throws \OCP\Lock\LockedException
*/
public function acquireLock ( $path , $type , ILockingProvider $provider ) {
/** @var \OCP\Files\Storage $targetStorage */
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $path );
$targetStorage -> acquireLock ( $targetInternalPath , $type , $provider );
2015-06-29 20:13:39 +03:00
// lock the parent folders of the owner when locking the share as recipient
if ( $path === '' ) {
$sourcePath = $this -> ownerView -> getPath ( $this -> share [ 'file_source' ]);
2015-06-30 14:49:54 +03:00
$this -> ownerView -> lockFile ( dirname ( $sourcePath ), ILockingProvider :: LOCK_SHARED , true );
2015-06-29 20:13:39 +03:00
}
2015-05-04 15:21:34 +03:00
}
/**
* @ param string $path
* @ param int $type \OCP\Lock\ILockingProvider :: LOCK_SHARED or \OCP\Lock\ILockingProvider :: LOCK_EXCLUSIVE
* @ param \OCP\Lock\ILockingProvider $provider
*/
public function releaseLock ( $path , $type , ILockingProvider $provider ) {
/** @var \OCP\Files\Storage $targetStorage */
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $path );
$targetStorage -> releaseLock ( $targetInternalPath , $type , $provider );
2015-06-29 20:13:39 +03:00
// unlock the parent folders of the owner when unlocking the share as recipient
if ( $path === '' ) {
$sourcePath = $this -> ownerView -> getPath ( $this -> share [ 'file_source' ]);
2015-06-30 14:49:54 +03:00
$this -> ownerView -> unlockFile ( dirname ( $sourcePath ), ILockingProvider :: LOCK_SHARED , true );
2015-06-29 20:13:39 +03:00
}
2015-05-04 15:21:34 +03:00
}
2015-05-29 15:40:06 +03:00
/**
* @ param string $path
* @ param int $type \OCP\Lock\ILockingProvider :: LOCK_SHARED or \OCP\Lock\ILockingProvider :: LOCK_EXCLUSIVE
* @ param \OCP\Lock\ILockingProvider $provider
*/
public function changeLock ( $path , $type , ILockingProvider $provider ) {
/** @var \OCP\Files\Storage $targetStorage */
list ( $targetStorage , $targetInternalPath ) = $this -> resolvePath ( $path );
$targetStorage -> changeLock ( $targetInternalPath , $type , $provider );
}
2015-08-21 00:43:46 +03:00
/**
* @ return array [ available , last_checked ]
*/
public function getAvailability () {
// shares do not participate in availability logic
return [
'available' => true ,
'last_checked' => 0
];
}
/**
* @ param bool $available
*/
public function setAvailability ( $available ) {
// shares do not participate in availability logic
}
2016-01-11 15:58:22 +03:00
public function isLocal () {
$this -> init ();
$ownerPath = $this -> ownerView -> getPath ( $this -> share [ 'item_source' ]);
list ( $targetStorage ) = $this -> ownerView -> resolvePath ( $ownerPath );
return $targetStorage -> isLocal ();
}
2016-02-24 12:39:04 +03:00
public function getSourceStorage () {
return $this -> sourceStorage ;
}
2012-05-11 03:56:25 +04:00
}