commit
0cde86ac55
|
@ -12,10 +12,12 @@ $files = isset($_POST["file"]) ? stripslashes($_POST["file"]) : stripslashes($_P
|
|||
|
||||
$files = json_decode($files);
|
||||
$filesWithError = '';
|
||||
|
||||
$success = true;
|
||||
|
||||
//Now delete
|
||||
foreach ($files as $file) {
|
||||
if (!OC_Files::delete($dir, $file)) {
|
||||
if (($dir === '' && $file === 'Shared') || !\OC\Files\Filesystem::unlink($dir . '/' . $file)) {
|
||||
$filesWithError .= $file . "\n";
|
||||
$success = false;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -11,15 +11,19 @@ $dir = stripslashes($_POST["dir"]);
|
|||
$file = stripslashes($_POST["file"]);
|
||||
$target = stripslashes(rawurldecode($_POST["target"]));
|
||||
|
||||
$l=OC_L10N::get('files');
|
||||
|
||||
if(OC_Filesystem::file_exists($target . '/' . $file)) {
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s - File with this name already exists", array($file)) )));
|
||||
if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
|
||||
OCP\JSON::error(array("data" => array( "message" => "Could not move $file - File with this name already exists" )));
|
||||
exit;
|
||||
}
|
||||
|
||||
if(OC_Files::move($dir, $file, $target, $file)) {
|
||||
OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file )));
|
||||
} else {
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s", array($file)) )));
|
||||
if ($dir != '' || $file != 'Shared') {
|
||||
$targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
|
||||
$sourceFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file);
|
||||
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {
|
||||
OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file )));
|
||||
} else {
|
||||
OCP\JSON::error(array("data" => array( "message" => "Could not move $file" )));
|
||||
}
|
||||
}else{
|
||||
OCP\JSON::error(array("data" => array( "message" => "Could not move $file" )));
|
||||
}
|
||||
|
|
|
@ -63,13 +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) {
|
||||
$target = OC_Filesystem::normalizePath($target);
|
||||
$meta = OC_FileCache::get($target);
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($target);
|
||||
$mime=$meta['mimetype'];
|
||||
$id = OC_FileCache::getId($target);
|
||||
$eventSource->send('success', array('mime'=>$mime, 'size'=>OC_Filesystem::filesize($target), 'id' => $id));
|
||||
$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,15 +76,15 @@ if($source) {
|
|||
exit();
|
||||
} else {
|
||||
if($content) {
|
||||
if(OC_Filesystem::file_put_contents($dir.'/'.$filename, $content)) {
|
||||
$meta = OC_FileCache::get($dir.'/'.$filename);
|
||||
$id = OC_FileCache::getId($dir.'/'.$filename);
|
||||
if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename);
|
||||
$id = $meta['fileid'];
|
||||
OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id)));
|
||||
exit();
|
||||
}
|
||||
}elseif(OC_Files::newFile($dir, $filename, 'file')) {
|
||||
$meta = OC_FileCache::get($dir.'/'.$filename);
|
||||
$id = OC_FileCache::getId($dir.'/'.$filename);
|
||||
}elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename);
|
||||
$id = $meta['fileid'];
|
||||
OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id)));
|
||||
exit();
|
||||
}
|
||||
|
|
|
@ -19,13 +19,14 @@ if(strpos($foldername, '/')!==false) {
|
|||
exit();
|
||||
}
|
||||
|
||||
if(OC_Files::newFile($dir, stripslashes($foldername), 'dir')) {
|
||||
if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($foldername))) {
|
||||
if ( $dir != '/') {
|
||||
$path = $dir.'/'.$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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -11,10 +11,14 @@ $dir = stripslashes($_GET["dir"]);
|
|||
$file = stripslashes($_GET["file"]);
|
||||
$newname = stripslashes($_GET["newname"]);
|
||||
|
||||
// Delete
|
||||
if( $newname !== '.' and OC_Files::move( $dir, $file, $dir, $newname )) {
|
||||
OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname )));
|
||||
} else {
|
||||
$l=OC_L10N::get('files');
|
||||
OCP\JSON::error(array("data" => array( "message" => $l->t("Unable to rename file") )));
|
||||
if ( $newname !== '.' and ($dir != '' || $file != 'Shared') and $newname !== '.') {
|
||||
$targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname);
|
||||
$sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file);
|
||||
if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) {
|
||||
OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname )));
|
||||
} else {
|
||||
OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" )));
|
||||
}
|
||||
}else{
|
||||
OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" )));
|
||||
}
|
||||
|
|
|
@ -1,44 +1,71 @@
|
|||
<?php
|
||||
|
||||
set_time_limit(0);//scanning can take ages
|
||||
|
||||
$force=isset($_GET['force']) and $_GET['force']=='true';
|
||||
$dir=isset($_GET['dir'])?$_GET['dir']:'';
|
||||
$checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true';
|
||||
|
||||
$eventSource=false;
|
||||
if(!$checkOnly) {
|
||||
$eventSource=new OC_EventSource();
|
||||
}
|
||||
|
||||
set_time_limit(0); //scanning can take ages
|
||||
session_write_close();
|
||||
|
||||
//create the file cache if necessary
|
||||
if($force or !OC_FileCache::inCache('')) {
|
||||
if(!$checkOnly) {
|
||||
OCP\DB::beginTransaction();
|
||||
$force = (isset($_GET['force']) and ($_GET['force'] === 'true'));
|
||||
$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
|
||||
|
||||
if(OC_Cache::isFast()) {
|
||||
OC_Cache::clear('fileid/'); //make sure the old fileid's don't mess things up
|
||||
$eventSource = new OC_EventSource();
|
||||
ScanListener::$eventSource = $eventSource;
|
||||
ScanListener::$view = \OC\Files\Filesystem::getView();
|
||||
|
||||
OC_Hook::connect('\OC\Files\Cache\Scanner', 'scan_folder', 'ScanListener', 'folder');
|
||||
OC_Hook::connect('\OC\Files\Cache\Scanner', 'scan_file', 'ScanListener', 'file');
|
||||
|
||||
$absolutePath = \OC\Files\Filesystem::getView()->getAbsolutePath($dir);
|
||||
|
||||
$mountPoints = \OC\Files\Filesystem::getMountPoints($absolutePath);
|
||||
$mountPoints[] = \OC\Files\Filesystem::getMountPoint($absolutePath);
|
||||
$mountPoints = array_reverse($mountPoints); //start with the mount point of $dir
|
||||
|
||||
foreach ($mountPoints as $mountPoint) {
|
||||
$storage = \OC\Files\Filesystem::getStorage($mountPoint);
|
||||
if ($storage) {
|
||||
ScanListener::$mountPoints[$storage->getId()] = $mountPoint;
|
||||
$scanner = $storage->getScanner();
|
||||
if ($force) {
|
||||
$scanner->scan('');
|
||||
} else {
|
||||
$scanner->backgroundScan();
|
||||
}
|
||||
|
||||
OC_FileCache::scan($dir, $eventSource);
|
||||
OC_FileCache::clean();
|
||||
OCP\DB::commit();
|
||||
$eventSource->send('success', true);
|
||||
} else {
|
||||
OCP\JSON::success(array('data'=>array('done'=>true)));
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
if($checkOnly) {
|
||||
OCP\JSON::success(array('data'=>array('done'=>false)));
|
||||
exit;
|
||||
}
|
||||
if(isset($eventSource)) {
|
||||
$eventSource->send('success', false);
|
||||
} else {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$eventSource->send('done', ScanListener::$fileCount);
|
||||
$eventSource->close();
|
||||
|
||||
class ScanListener {
|
||||
|
||||
static public $fileCount = 0;
|
||||
static public $lastCount = 0;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\View $view
|
||||
*/
|
||||
static public $view;
|
||||
|
||||
/**
|
||||
* @var array $mountPoints map storage ids to mountpoints
|
||||
*/
|
||||
static public $mountPoints = array();
|
||||
|
||||
/**
|
||||
* @var \OC_EventSource event source to pass events to
|
||||
*/
|
||||
static public $eventSource;
|
||||
|
||||
static function folder($params) {
|
||||
$internalPath = $params['path'];
|
||||
$mountPoint = self::$mountPoints[$params['storage']];
|
||||
$path = self::$view->getRelativePath($mountPoint . $internalPath);
|
||||
self::$eventSource->send('folder', $path);
|
||||
}
|
||||
|
||||
static function file() {
|
||||
self::$fileCount++;
|
||||
if (self::$fileCount > self::$lastCount + 20) { //send a count update every 20 files
|
||||
self::$lastCount = self::$fileCount;
|
||||
self::$eventSource->send('count', self::$fileCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
set_time_limit(0); //scanning can take ages
|
||||
session_write_close();
|
||||
|
||||
$user = OC_User::getUser();
|
||||
$eventSource = new OC_EventSource();
|
||||
$listener = new UpgradeListener($eventSource);
|
||||
$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);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,13 +21,13 @@ if (!isset($_FILES['files'])) {
|
|||
foreach ($_FILES['files']['error'] as $error) {
|
||||
if ($error != 0) {
|
||||
$errors = array(
|
||||
UPLOAD_ERR_OK => $l->t('There is no error, the file uploaded with success'),
|
||||
UPLOAD_ERR_INI_SIZE => $l->t('The uploaded file exceeds the upload_max_filesize directive in php.ini: ')
|
||||
UPLOAD_ERR_OK => $l->t('There is no error, the file uploaded with success'),
|
||||
UPLOAD_ERR_INI_SIZE => $l->t('The uploaded file exceeds the upload_max_filesize directive in php.ini: ')
|
||||
. ini_get('upload_max_filesize'),
|
||||
UPLOAD_ERR_FORM_SIZE => $l->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified'
|
||||
UPLOAD_ERR_FORM_SIZE => $l->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified'
|
||||
. ' in the HTML form'),
|
||||
UPLOAD_ERR_PARTIAL => $l->t('The uploaded file was only partially uploaded'),
|
||||
UPLOAD_ERR_NO_FILE => $l->t('No file was uploaded'),
|
||||
UPLOAD_ERR_PARTIAL => $l->t('The uploaded file was only partially uploaded'),
|
||||
UPLOAD_ERR_NO_FILE => $l->t('No file was uploaded'),
|
||||
UPLOAD_ERR_NO_TMP_DIR => $l->t('Missing a temporary folder'),
|
||||
UPLOAD_ERR_CANT_WRITE => $l->t('Failed to write to disk'),
|
||||
);
|
||||
|
@ -40,12 +40,17 @@ $files = $_FILES['files'];
|
|||
$dir = $_POST['dir'];
|
||||
$error = '';
|
||||
|
||||
$maxUploadFilesize = OCP\Util::maxUploadFilesize($dir);
|
||||
$maxHumanFilesize = OCP\Util::humanFileSize($maxUploadFilesize);
|
||||
|
||||
$totalSize = 0;
|
||||
foreach ($files['size'] as $size) {
|
||||
$totalSize += $size;
|
||||
}
|
||||
if ($totalSize > OC_Filesystem::free_space($dir)) {
|
||||
OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Not enough storage available')), $storageStats)));
|
||||
if ($totalSize > \OC\Files\Filesystem::free_space($dir)) {
|
||||
OCP\JSON::error(array('data' => array('message' => $l->t('Not enough space available'),
|
||||
'uploadMaxFilesize' => $maxUploadFilesize,
|
||||
'maxHumanFilesize' => $maxHumanFilesize)));
|
||||
exit();
|
||||
}
|
||||
|
||||
|
@ -55,19 +60,19 @@ if (strpos($dir, '..') === false) {
|
|||
for ($i = 0; $i < $fileCount; $i++) {
|
||||
$target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]);
|
||||
// $path needs to be normalized - this failed within drag'n'drop upload to a sub-folder
|
||||
$target = OC_Filesystem::normalizePath($target);
|
||||
if (is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) {
|
||||
$meta = OC_FileCache::get($target);
|
||||
$id = OC_FileCache::getId($target);
|
||||
|
||||
$target = \OC\Files\Filesystem::normalizePath($target);
|
||||
if (is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($target);
|
||||
// updated max file size after upload
|
||||
$storageStats = \OCA\files\lib\Helper::buildFileStorageStatistics($dir);
|
||||
|
||||
$result[] = array_merge(array('status' => 'success',
|
||||
'mime' => $meta['mimetype'],
|
||||
'size' => $meta['size'],
|
||||
'id' => $id,
|
||||
'name' => basename($target)), $storageStats
|
||||
$result[] = array('status' => 'success',
|
||||
'mime' => $meta['mimetype'],
|
||||
'size' => $meta['size'],
|
||||
'id' => $meta['fileid'],
|
||||
'name' => basename($target),
|
||||
'uploadMaxFilesize' => $maxUploadFilesize,
|
||||
'maxHumanFilesize' => $maxHumanFilesize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
$l=OC_L10N::get('files');
|
||||
$l = OC_L10N::get('files');
|
||||
|
||||
OCP\App::registerAdmin('files', 'admin');
|
||||
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<description>File Management</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Robin Appelman</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<standalone/>
|
||||
<default_enable/>
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.1.6
|
||||
1.1.7
|
||||
|
|
|
@ -132,4 +132,12 @@ table.dragshadow td.filename {
|
|||
}
|
||||
table.dragshadow td.size {
|
||||
padding-right:8px;
|
||||
}
|
||||
}
|
||||
#upgrade {
|
||||
width: 400px;
|
||||
position: absolute;
|
||||
top: 200px;
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
margin-left: -200px;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,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);
|
||||
|
@ -34,7 +34,7 @@ if(!OC_Filesystem::file_exists($filename)) {
|
|||
exit;
|
||||
}
|
||||
|
||||
$ftype=OC_Filesystem::getMimeType( $filename );
|
||||
$ftype=\OC\Files\Filesystem::getMimeType( $filename );
|
||||
|
||||
header('Content-Type:'.$ftype);
|
||||
if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) {
|
||||
|
@ -44,7 +44,7 @@ if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) {
|
|||
. '; filename="' . rawurlencode( basename($filename) ) . '"' );
|
||||
}
|
||||
OCP\Response::disableCaching();
|
||||
header('Content-Length: '.OC_Filesystem::filesize($filename));
|
||||
header('Content-Length: '.\OC\Files\Filesystem::filesize($filename));
|
||||
|
||||
OC_Util::obEnd();
|
||||
OC_Filesystem::readfile( $filename );
|
||||
\OC\Files\Filesystem::readfile( $filename );
|
||||
|
|
|
@ -29,22 +29,39 @@ OCP\Util::addStyle('files', 'files');
|
|||
OCP\Util::addscript('files', 'jquery.iframe-transport');
|
||||
OCP\Util::addscript('files', 'jquery.fileupload');
|
||||
OCP\Util::addscript('files', 'jquery-visibility');
|
||||
OCP\Util::addscript('files', 'files');
|
||||
OCP\Util::addscript('files', 'filelist');
|
||||
OCP\Util::addscript('files', 'fileactions');
|
||||
OCP\Util::addscript('files', 'keyboardshortcuts');
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
|
||||
$files = array();
|
||||
foreach (OC_Files::getdirectorycontent($dir) as $i) {
|
||||
$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']);
|
||||
|
@ -55,12 +72,12 @@ foreach (OC_Files::getdirectorycontent($dir) as $i) {
|
|||
$i['extension'] = '';
|
||||
}
|
||||
}
|
||||
if ($i['directory'] == '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
$i['directory'] = $dir;
|
||||
$files[] = $i;
|
||||
}
|
||||
|
||||
usort($files, "fileCmp");
|
||||
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
|
@ -81,34 +98,42 @@ $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
|||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files', 'index.php') . '?dir=', false);
|
||||
|
||||
$maxUploadFilesize=OCP\Util::maxUploadFilesize($dir);
|
||||
|
||||
$permissions = OCP\PERMISSION_READ;
|
||||
if (OC_Filesystem::isCreatable($dir . '/')) {
|
||||
if (\OC\Files\Filesystem::isCreatable($dir . '/')) {
|
||||
$permissions |= OCP\PERMISSION_CREATE;
|
||||
}
|
||||
if (OC_Filesystem::isUpdatable($dir . '/')) {
|
||||
if (\OC\Files\Filesystem::isUpdatable($dir . '/')) {
|
||||
$permissions |= OCP\PERMISSION_UPDATE;
|
||||
}
|
||||
if (OC_Filesystem::isDeletable($dir . '/')) {
|
||||
if (\OC\Files\Filesystem::isDeletable($dir . '/')) {
|
||||
$permissions |= OCP\PERMISSION_DELETE;
|
||||
}
|
||||
if (OC_Filesystem::isSharable($dir . '/')) {
|
||||
if (\OC\Files\Filesystem::isSharable($dir . '/')) {
|
||||
$permissions |= OCP\PERMISSION_SHARE;
|
||||
}
|
||||
|
||||
// information about storage capacities
|
||||
$storageInfo=OC_Helper::getStorageInfo();
|
||||
if ($needUpgrade) {
|
||||
OCP\Util::addscript('files', 'upgrade');
|
||||
$tmpl = new OCP\Template('files', 'upgrade', 'user');
|
||||
$tmpl->printPage();
|
||||
} else {
|
||||
// information about storage capacities
|
||||
$storageInfo=OC_Helper::getStorageInfo();
|
||||
$maxUploadFilesize=OCP\Util::maxUploadFilesize($dir);
|
||||
|
||||
$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('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->assign('usedSpacePercent', (int)$storageInfo['relative']);
|
||||
$tmpl->printPage();
|
||||
OCP\Util::addscript('files', 'fileactions');
|
||||
OCP\Util::addscript('files', 'files');
|
||||
OCP\Util::addscript('files', 'keyboardshortcuts');
|
||||
$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->assign('usedSpacePercent', (int)$storageInfo['relative']);
|
||||
$tmpl->printPage();
|
||||
}
|
||||
|
|
|
@ -670,12 +670,8 @@ $(document).ready(function() {
|
|||
});
|
||||
});
|
||||
|
||||
//check if we need to scan the filesystem
|
||||
$.get(OC.filePath('files','ajax','scan.php'),{checkonly:'true'}, function(response) {
|
||||
if(response.data.done){
|
||||
scanFiles();
|
||||
}
|
||||
}, "json");
|
||||
//do a background scan if needed
|
||||
scanFiles();
|
||||
|
||||
var lastWidth = 0;
|
||||
var breadcrumbs = [];
|
||||
|
@ -774,27 +770,23 @@ $(document).ready(function() {
|
|||
}
|
||||
});
|
||||
|
||||
function scanFiles(force,dir){
|
||||
function scanFiles(force, dir){
|
||||
if(!dir){
|
||||
dir='';
|
||||
dir = '';
|
||||
}
|
||||
force=!!force; //cast to bool
|
||||
scanFiles.scanning=true;
|
||||
$('#scanning-message').show();
|
||||
$('#fileList').remove();
|
||||
var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
|
||||
scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
|
||||
scannerEventSource.listen('scanning',function(data){
|
||||
$('#scan-count').text(t('files', '{count} files scanned', {count: data.count}));
|
||||
$('#scan-current').text(data.file+'/');
|
||||
force = !!force; //cast to bool
|
||||
scanFiles.scanning = true;
|
||||
var scannerEventSource = new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
|
||||
scanFiles.cancel = scannerEventSource.close.bind(scannerEventSource);
|
||||
scannerEventSource.listen('count',function(count){
|
||||
console.log(count + 'files scanned')
|
||||
});
|
||||
scannerEventSource.listen('success',function(success){
|
||||
scannerEventSource.listen('folder',function(path){
|
||||
console.log('now scanning ' + path)
|
||||
});
|
||||
scannerEventSource.listen('done',function(count){
|
||||
scanFiles.scanning=false;
|
||||
if(success){
|
||||
window.location.reload();
|
||||
}else{
|
||||
alert(t('files', 'error while scanning'));
|
||||
}
|
||||
console.log('done after ' + count + 'files');
|
||||
});
|
||||
}
|
||||
scanFiles.scanning=false;
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -32,7 +32,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;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
$name = str_replace('%2F', '/', $name);
|
||||
$directory = str_replace('+', '%20', urlencode($file['directory']));
|
||||
$directory = str_replace('%2F', '/', $directory); ?>
|
||||
<tr data-id="<?php echo $file['id']; ?>"
|
||||
<tr data-id="<?php echo $file['fileid']; ?>"
|
||||
data-file="<?php echo $name;?>"
|
||||
data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>"
|
||||
data-mime="<?php echo $file['mimetype']?>"
|
||||
|
@ -28,7 +28,7 @@
|
|||
>
|
||||
<?php if(!isset($_['readonly']) || !$_['readonly']): ?><input type="checkbox" /><?php endif; ?>
|
||||
<?php if($file['type'] == 'dir'): ?>
|
||||
<a class="name" href="<?php $_['baseURL'].$directory.'/'.$name; ?>)" title="">
|
||||
<a class="name" href="<?php echo $_['baseURL'].$directory.'/'.$name; ?>)" title="">
|
||||
<?php else: ?>
|
||||
<a class="name" href="<?php echo $_['downloadURL'].$directory.'/'.$name; ?>" title="">
|
||||
<?php endif; ?>
|
||||
|
@ -61,4 +61,4 @@
|
|||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
||||
<?php endforeach;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div id="upgrade">
|
||||
<?php echo $l->t('Upgrading filesystem cache...');?>
|
||||
<div id="progressbar" />
|
||||
</div>
|
|
@ -12,8 +12,10 @@ $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');
|
||||
if ( ! $view->file_exists('')) $view->mkdir('');
|
||||
$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files_external/uploads');
|
||||
if (!$view->file_exists('')){
|
||||
$view->mkdir('');
|
||||
}
|
||||
|
||||
$isValid = openssl_pkey_get_public($data);
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
OC::$CLASSPATH['OC_FileStorage_StreamWrapper']='apps/files_external/lib/streamwrapper.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_SMB']='apps/files_external/lib/smb.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_AmazonS3']='apps/files_external/lib/amazons3.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Dropbox']='apps/files_external/lib/dropbox.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\StreamWrapper']='apps/files_external/lib/streamwrapper.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\FTP']='apps/files_external/lib/ftp.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\DAV']='apps/files_external/lib/webdav.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\Google']='apps/files_external/lib/google.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\SWIFT']='apps/files_external/lib/swift.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\SMB']='apps/files_external/lib/smb.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\AmazonS3']='apps/files_external/lib/amazons3.php';
|
||||
OC::$CLASSPATH['OC\Files\Storage\Dropbox']='apps/files_external/lib/dropbox.php';
|
||||
OC::$CLASSPATH['OC_Mount_Config']='apps/files_external/lib/config.php';
|
||||
|
||||
OCP\App::registerAdmin('files_external', 'settings');
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<description>Mount external storage sources</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Robin Appelman, Michael Gapczynski</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<types>
|
||||
<filesystem/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$(document).ready(function() {
|
||||
|
||||
$('#externalStorage tbody tr.OC_Filestorage_Dropbox').each(function() {
|
||||
$('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Dropbox').each(function() {
|
||||
var configured = $(this).find('[data-parameter="configured"]');
|
||||
if ($(configured).val() == 'true') {
|
||||
$(this).find('.configuration input').attr('disabled', 'disabled');
|
||||
|
@ -38,7 +38,7 @@ $(document).ready(function() {
|
|||
|
||||
$('#externalStorage tbody tr input').live('keyup', function() {
|
||||
var tr = $(this).parent().parent();
|
||||
if ($(tr).hasClass('OC_Filestorage_Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') {
|
||||
if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') {
|
||||
var config = $(tr).find('.configuration');
|
||||
if ($(tr).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '') {
|
||||
if ($(tr).find('.dropbox').length == 0) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$(document).ready(function() {
|
||||
|
||||
$('#externalStorage tbody tr.OC_Filestorage_Google').each(function() {
|
||||
$('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google').each(function() {
|
||||
var configured = $(this).find('[data-parameter="configured"]');
|
||||
if ($(configured).val() == 'true') {
|
||||
$(this).find('.configuration')
|
||||
|
@ -34,7 +34,8 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
$('#externalStorage tbody tr').live('change', function() {
|
||||
if ($(this).hasClass('OC_Filestorage_Google') && $(this).find('[data-parameter="configured"]').val() != 'true') {
|
||||
console.log('hello');
|
||||
if ($(this).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(this).find('[data-parameter="configured"]').val() != 'true') {
|
||||
if ($(this).find('.mountPoint input').val() != '') {
|
||||
if ($(this).find('.google').length == 0) {
|
||||
$(this).find('.configuration').append('<a class="button google">'+t('files_external', 'Grant access')+'</a>');
|
||||
|
@ -45,7 +46,7 @@ $(document).ready(function() {
|
|||
|
||||
$('#externalStorage tbody tr .mountPoint input').live('keyup', function() {
|
||||
var tr = $(this).parent().parent();
|
||||
if ($(tr).hasClass('OC_Filestorage_Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) {
|
||||
if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) {
|
||||
if ($(this).val() != '') {
|
||||
$(tr).find('.google').show();
|
||||
} else {
|
||||
|
|
|
@ -100,7 +100,7 @@ $(document).ready(function() {
|
|||
td.append('<input type="text" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
|
||||
}
|
||||
});
|
||||
if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass).length == 1) {
|
||||
if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) {
|
||||
OC.addScript('files_external', parameters['custom']);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1,39 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
require_once 'aws-sdk/sdk.class.php';
|
||||
|
||||
class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
||||
class AmazonS3 extends \OC\Files\Storage\Common {
|
||||
|
||||
private $s3;
|
||||
private $bucket;
|
||||
private $objects = array();
|
||||
private $id;
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
||||
// TODO options: storage class, encryption server side, encrypt before upload?
|
||||
|
||||
public function __construct($params) {
|
||||
$this->s3 = new AmazonS3(array('key' => $params['key'], 'secret' => $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'];
|
||||
}
|
||||
|
||||
|
@ -47,7 +51,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_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;
|
||||
|
@ -57,6 +61,10 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
// Folders in Amazon S3 are 0 byte objects with a '/' at the end of the name
|
||||
if (substr($path, -1) != '/') {
|
||||
|
@ -96,8 +104,8 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_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;
|
||||
}
|
||||
|
@ -107,15 +115,10 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
|||
$stat['size'] = $this->s3->get_bucket_filesize($this->bucket);
|
||||
$stat['atime'] = time();
|
||||
$stat['mtime'] = $stat['atime'];
|
||||
$stat['ctime'] = $stat['atime'];
|
||||
} else {
|
||||
$object = $this->getObject($path);
|
||||
if ($object) {
|
||||
$stat['size'] = $object['Size'];
|
||||
$stat['atime'] = time();
|
||||
$stat['mtime'] = strtotime($object['LastModified']);
|
||||
$stat['ctime'] = $stat['mtime'];
|
||||
}
|
||||
} else if ($object = $this->getObject($path)) {
|
||||
$stat['size'] = $object['Size'];
|
||||
$stat['atime'] = time();
|
||||
$stat['mtime'] = strtotime($object['LastModified']);
|
||||
}
|
||||
if (isset($stat)) {
|
||||
return $stat;
|
||||
|
@ -166,7 +169,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
|||
switch ($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
$tmpFile = OC_Helper::tmpFile();
|
||||
$tmpFile = \OC_Helper::tmpFile();
|
||||
$handle = fopen($tmpFile, 'w');
|
||||
$response = $this->s3->get_object($this->bucket, $path, array('fileDownload' => $handle));
|
||||
if ($response->isOK()) {
|
||||
|
@ -190,14 +193,14 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common {
|
|||
} else {
|
||||
$ext = '';
|
||||
}
|
||||
$tmpFile = OC_Helper::tmpFile($ext);
|
||||
OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack');
|
||||
$tmpFile = \OC_Helper::tmpFile($ext);
|
||||
\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;
|
||||
}
|
||||
|
@ -206,8 +209,8 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_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);
|
||||
}
|
||||
|
|
|
@ -38,20 +38,20 @@ class OC_Mount_Config {
|
|||
* @return array
|
||||
*/
|
||||
public static function getBackends() {
|
||||
|
||||
$backends['OC_Filestorage_Local']=array(
|
||||
|
||||
$backends['\OC\Files\Storage\Local']=array(
|
||||
'backend' => 'Local',
|
||||
'configuration' => array(
|
||||
'datadir' => 'Location'));
|
||||
|
||||
$backends['OC_Filestorage_AmazonS3']=array(
|
||||
$backends['\OC\Files\Storage\AmazonS3']=array(
|
||||
'backend' => 'Amazon S3',
|
||||
'configuration' => array(
|
||||
'key' => 'Key',
|
||||
'secret' => '*Secret',
|
||||
'bucket' => 'Bucket'));
|
||||
|
||||
$backends['OC_Filestorage_Dropbox']=array(
|
||||
$backends['\OC\Files\Storage\Dropbox']=array(
|
||||
'backend' => 'Dropbox',
|
||||
'configuration' => array(
|
||||
'configured' => '#configured',
|
||||
|
@ -61,7 +61,7 @@ class OC_Mount_Config {
|
|||
'token_secret' => '#token_secret'),
|
||||
'custom' => 'dropbox');
|
||||
|
||||
if(OC_Mount_Config::checkphpftp()) $backends['OC_Filestorage_FTP']=array(
|
||||
if(OC_Mount_Config::checkphpftp()) $backends['\OC\Files\Storage\FTP']=array(
|
||||
'backend' => 'FTP',
|
||||
'configuration' => array(
|
||||
'host' => 'URL',
|
||||
|
@ -70,15 +70,15 @@ class OC_Mount_Config {
|
|||
'root' => '&Root',
|
||||
'secure' => '!Secure ftps://'));
|
||||
|
||||
$backends['OC_Filestorage_Google']=array(
|
||||
$backends['\OC\Files\Storage\Google']=array(
|
||||
'backend' => 'Google Drive',
|
||||
'configuration' => array(
|
||||
'configured' => '#configured',
|
||||
'token' => '#token',
|
||||
'token_secret' => '#token secret'),
|
||||
'custom' => 'google');
|
||||
|
||||
$backends['OC_Filestorage_SWIFT']=array(
|
||||
|
||||
$backends['\OC\Files\Storage\SWIFT']=array(
|
||||
'backend' => 'OpenStack Swift',
|
||||
'configuration' => array(
|
||||
'host' => 'URL',
|
||||
|
@ -86,8 +86,8 @@ class OC_Mount_Config {
|
|||
'token' => '*Token',
|
||||
'root' => '&Root',
|
||||
'secure' => '!Secure ftps://'));
|
||||
|
||||
if(OC_Mount_Config::checksmbclient()) $backends['OC_Filestorage_SMB']=array(
|
||||
|
||||
if(OC_Mount_Config::checksmbclient()) $backends['\OC\Files\Storage\SMB']=array(
|
||||
'backend' => 'SMB / CIFS',
|
||||
'configuration' => array(
|
||||
'host' => 'URL',
|
||||
|
@ -95,8 +95,8 @@ class OC_Mount_Config {
|
|||
'password' => '*Password',
|
||||
'share' => 'Share',
|
||||
'root' => '&Root'));
|
||||
|
||||
$backends['OC_Filestorage_DAV']=array(
|
||||
|
||||
$backends['\OC\Files\Storage\DAV']=array(
|
||||
'backend' => 'ownCloud / WebDAV',
|
||||
'configuration' => array(
|
||||
'host' => 'URL',
|
||||
|
@ -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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// Remove '/uid/files/' from mount point
|
||||
$personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'],
|
||||
'backend' => $backends[$mount['class']]['backend'],
|
||||
|
@ -178,22 +190,6 @@ 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
|
||||
*/
|
||||
private static function addMountPointDirectory($view, $path) {
|
||||
$dir = '';
|
||||
foreach ( explode('/', $path) as $pathPart) {
|
||||
$dir = $dir.'/'.$pathPart;
|
||||
if ( !$view->file_exists($dir)) {
|
||||
$view->mkdir($dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a mount point to the filesystem
|
||||
* @param string Mount point
|
||||
|
@ -213,36 +209,11 @@ class OC_Mount_Config {
|
|||
if ($isPersonal) {
|
||||
// Verify that the mount point applies for the current user
|
||||
// Prevent non-admin users from mounting local storage
|
||||
if ($applicable != OCP\User::getUser() || $class == 'OC_Filestorage_Local') {
|
||||
if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') {
|
||||
return false;
|
||||
}
|
||||
$view = new OC_FilesystemView('/'.OCP\User::getUser().'/files');
|
||||
self::addMountPointDirectory($view, ltrim($mountPoint, '/'));
|
||||
$mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/');
|
||||
} else {
|
||||
$view = new OC_FilesystemView('/');
|
||||
switch ($mountType) {
|
||||
case 'user':
|
||||
if ($applicable == "all") {
|
||||
$users = OCP\User::getUsers();
|
||||
foreach ( $users as $user ) {
|
||||
$path = $user.'/files/'.ltrim($mountPoint, '/');
|
||||
self::addMountPointDirectory($view, $path);
|
||||
}
|
||||
} else {
|
||||
$path = $applicable.'/files/'.ltrim($mountPoint, '/');
|
||||
self::addMountPointDirectory($view, $path);
|
||||
}
|
||||
break;
|
||||
case 'group' :
|
||||
$groupMembers = OC_Group::usersInGroups(array($applicable));
|
||||
foreach ( $groupMembers as $user ) {
|
||||
$path = $user.'/files/'.ltrim($mountPoint, '/');
|
||||
self::addMountPointDirectory($view, $path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$mountPoint = '/$user/files/'.ltrim($mountPoint, '/');
|
||||
}
|
||||
$mount = array($applicable => array($mountPoint => array('class' => $class, 'options' => $classOptions)));
|
||||
|
|
|
@ -20,12 +20,15 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
require_once 'Dropbox/autoload.php';
|
||||
|
||||
class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
||||
class Dropbox extends \OC\Files\Storage\Common {
|
||||
|
||||
private $dropbox;
|
||||
private $root;
|
||||
private $id;
|
||||
private $metaData = array();
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
@ -37,13 +40,14 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
&& isset($params['token'])
|
||||
&& isset($params['token_secret'])
|
||||
) {
|
||||
$this->id = 'dropbox::'.$params['app_key'] . $params['token']. '/' . $params['root'];
|
||||
$this->root=isset($params['root'])?$params['root']:'';
|
||||
$oauth = new Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
|
||||
$oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']);
|
||||
$oauth->setToken($params['token'], $params['token_secret']);
|
||||
$this->dropbox = new Dropbox_API($oauth, 'dropbox');
|
||||
$this->dropbox = new \Dropbox_API($oauth, 'dropbox');
|
||||
$this->mkdir('');
|
||||
} else {
|
||||
throw new Exception('Creating OC_Filestorage_Dropbox storage failed');
|
||||
throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,8 +59,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
if ($list) {
|
||||
try {
|
||||
$response = $this->dropbox->getMetaData($path);
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
if ($response && isset($response['contents'])) {
|
||||
|
@ -76,21 +80,25 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
$response = $this->dropbox->getMetaData($path, 'false');
|
||||
$this->metaData[$path] = $response;
|
||||
return $response;
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
$path = $this->root.$path;
|
||||
try {
|
||||
$this->dropbox->createFolder($path);
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +114,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_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;
|
||||
|
@ -118,7 +126,6 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_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;
|
||||
|
@ -163,8 +170,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
try {
|
||||
$this->dropbox->delete($path);
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -175,8 +182,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
try {
|
||||
$this->dropbox->move($path1, $path2);
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +194,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
try {
|
||||
$this->dropbox->copy($path1, $path2);
|
||||
return true;
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -198,13 +205,13 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
switch ($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
$tmpFile = OC_Helper::tmpFile();
|
||||
$tmpFile = \OC_Helper::tmpFile();
|
||||
try {
|
||||
$data = $this->dropbox->getFile($path);
|
||||
file_put_contents($tmpFile, $data);
|
||||
return fopen($tmpFile, 'r');
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
case 'w':
|
||||
|
@ -224,8 +231,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
} else {
|
||||
$ext = '';
|
||||
}
|
||||
$tmpFile = OC_Helper::tmpFile($ext);
|
||||
OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack');
|
||||
$tmpFile = \OC_Helper::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
file_put_contents($tmpFile, $source);
|
||||
|
@ -242,8 +249,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
try {
|
||||
$this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle);
|
||||
unlink($tmpFile);
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -264,8 +271,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
|
|||
try {
|
||||
$info = $this->dropbox->getAccountInfo();
|
||||
return $info['quota_info']['quota'] - $info['quota_info']['normal'];
|
||||
} catch (Exception $exception) {
|
||||
OCP\Util::writeLog('files_external', $exception->getMessage(), OCP\Util::ERROR);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
class FTP extends \OC\Files\Storage\StreamWrapper{
|
||||
private $password;
|
||||
private $user;
|
||||
private $host;
|
||||
|
@ -38,9 +40,13 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
|
|||
}
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct the ftp url
|
||||
* @param string path
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function constructUrl($path) {
|
||||
|
@ -51,7 +57,8 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
|
|||
$url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
|
||||
return $url;
|
||||
}
|
||||
public function fopen($path, $mode) {
|
||||
public function fopen($path,$mode) {
|
||||
$this->init();
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
|
@ -61,7 +68,7 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
|
|||
case 'ab':
|
||||
//these are supported by the wrapper
|
||||
$context = stream_context_create(array('ftp' => array('overwrite' => true)));
|
||||
return fopen($this->constructUrl($path), $mode, false, $context);
|
||||
return fopen($this->constructUrl($path),$mode, false,$context);
|
||||
case 'r+':
|
||||
case 'w+':
|
||||
case 'wb+':
|
||||
|
@ -77,16 +84,18 @@ class OC_FileStorage_FTP extends OC_FileStorage_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);
|
||||
}
|
||||
self::$tempFiles[$tmpFile]=$path;
|
||||
return fopen('close://'.$tmpFile, $mode);
|
||||
return fopen('close://'.$tmpFile,$mode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
$this->init();
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
|
||||
unlink($tmpFile);
|
||||
|
|
|
@ -20,14 +20,17 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
require_once 'Google/common.inc.php';
|
||||
|
||||
class OC_Filestorage_Google extends OC_Filestorage_Common {
|
||||
class Google extends \OC\Files\Storage\Common {
|
||||
|
||||
private $consumer;
|
||||
private $oauth_token;
|
||||
private $sig_method;
|
||||
private $entries;
|
||||
private $id;
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
||||
|
@ -38,12 +41,13 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
) {
|
||||
$consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous';
|
||||
$consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous';
|
||||
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
|
||||
$this->oauth_token = new OAuthToken($params['token'], $params['token_secret']);
|
||||
$this->sig_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->id = 'google::' . $params['token'];
|
||||
$this->consumer = new \OAuthConsumer($consumer_key, $consumer_secret);
|
||||
$this->oauth_token = new \OAuthToken($params['token'], $params['token_secret']);
|
||||
$this->sig_method = new \OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->entries = array();
|
||||
} else {
|
||||
throw new Exception('Creating OC_Filestorage_Google storage failed');
|
||||
throw new \Exception('Creating \OC\Files\Storage\Google storage failed');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +72,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
$tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
|
||||
}
|
||||
$uri = preg_replace('/&/', '?', $tempStr, 1);
|
||||
$request = OAuthRequest::from_consumer_and_token($this->consumer,
|
||||
$request = \OAuthRequest::from_consumer_and_token($this->consumer,
|
||||
$this->oauth_token,
|
||||
$httpMethod,
|
||||
$uri,
|
||||
|
@ -110,7 +114,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
if ($isDownload) {
|
||||
$tmpFile = OC_Helper::tmpFile();
|
||||
$tmpFile = \OC_Helper::tmpFile();
|
||||
$handle = fopen($tmpFile, 'w');
|
||||
curl_setopt($curl, CURLOPT_FILE, $handle);
|
||||
}
|
||||
|
@ -139,7 +143,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
private function getFeed($feedUri, $httpMethod, $postData = null) {
|
||||
$result = $this->sendRequest($feedUri, $httpMethod, $postData);
|
||||
if ($result) {
|
||||
$dom = new DOMDocument();
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadXML($result);
|
||||
return $dom;
|
||||
}
|
||||
|
@ -194,6 +198,9 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
}
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
$collection = dirname($path);
|
||||
|
@ -266,7 +273,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
$this->entries[$name] = $entry;
|
||||
}
|
||||
}
|
||||
OC_FakeDirStream::$dirs['google'.$path] = $files;
|
||||
\OC\Files\Stream\Dir::register('google'.$path, $files);
|
||||
return opendir('fakedir://google'.$path);
|
||||
}
|
||||
|
||||
|
@ -287,7 +294,6 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
//$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)) {
|
||||
|
@ -443,8 +449,8 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
} else {
|
||||
$ext = '';
|
||||
}
|
||||
$tmpFile = OC_Helper::tmpFile($ext);
|
||||
OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack');
|
||||
$tmpFile = \OC_Helper::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
file_put_contents($tmpFile, $source);
|
||||
|
@ -482,7 +488,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
}
|
||||
if (isset($uploadUri) && $handle = fopen($path, 'r')) {
|
||||
$uploadUri .= '?convert=false';
|
||||
$mimetype = OC_Helper::getMimeType($path);
|
||||
$mimetype = \OC_Helper::getMimeType($path);
|
||||
$size = filesize($path);
|
||||
$headers = array('X-Upload-Content-Type: ' => $mimetype, 'X-Upload-Content-Length: ' => $size);
|
||||
$postData = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
|
@ -590,4 +596,4 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
require_once 'smb4php/smb.php';
|
||||
|
||||
class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
|
||||
class SMB extends \OC\Files\Storage\StreamWrapper{
|
||||
private $password;
|
||||
private $user;
|
||||
private $host;
|
||||
|
@ -30,14 +32,13 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
|
|||
if ( ! $this->share || $this->share[0]!='/') {
|
||||
$this->share='/'.$this->share;
|
||||
}
|
||||
if (substr($this->share, -1, 1)=='/') {
|
||||
$this->share=substr($this->share, 0, -1);
|
||||
if(substr($this->share, -1, 1)=='/') {
|
||||
$this->share = substr($this->share,0,-1);
|
||||
}
|
||||
}
|
||||
|
||||
//create the root folder if necesary
|
||||
if ( ! $this->is_dir('')) {
|
||||
$this->mkdir('');
|
||||
}
|
||||
public function getId(){
|
||||
return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root;
|
||||
}
|
||||
|
||||
public function constructUrl($path) {
|
||||
|
@ -65,11 +66,13 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
|
|||
|
||||
/**
|
||||
* check if a file or folder has been updated since $time
|
||||
* @param string $path
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUpdated($path, $time) {
|
||||
if ( ! $path and $this->root=='/') {
|
||||
public function hasUpdated($path,$time) {
|
||||
$this->init();
|
||||
if(!$path and $this->root=='/') {
|
||||
// mtime doesn't work for shares, but giving the nature of the backend,
|
||||
// doing a full update is still just fast enough
|
||||
return true;
|
||||
|
|
|
@ -6,16 +6,33 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
abstract class StreamWrapper extends \OC\Files\Storage\Common{
|
||||
private $ready = false;
|
||||
|
||||
protected function init(){
|
||||
if($this->ready){
|
||||
return;
|
||||
}
|
||||
$this->ready = true;
|
||||
|
||||
//create the root folder if necesary
|
||||
if(!$this->is_dir('')) {
|
||||
$this->mkdir('');
|
||||
}
|
||||
}
|
||||
|
||||
abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{
|
||||
abstract public function constructUrl($path);
|
||||
|
||||
public function mkdir($path) {
|
||||
$this->init();
|
||||
return mkdir($this->constructUrl($path));
|
||||
}
|
||||
|
||||
public function rmdir($path) {
|
||||
if ($this->file_exists($path)) {
|
||||
$this->init();
|
||||
if($this->file_exists($path)) {
|
||||
$succes = rmdir($this->constructUrl($path));
|
||||
clearstatcache();
|
||||
return $succes;
|
||||
|
@ -25,10 +42,12 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function opendir($path) {
|
||||
$this->init();
|
||||
return opendir($this->constructUrl($path));
|
||||
}
|
||||
|
||||
public function filetype($path) {
|
||||
$this->init();
|
||||
return filetype($this->constructUrl($path));
|
||||
}
|
||||
|
||||
|
@ -41,46 +60,54 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function file_exists($path) {
|
||||
$this->init();
|
||||
return file_exists($this->constructUrl($path));
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
$this->init();
|
||||
$succes = unlink($this->constructUrl($path));
|
||||
clearstatcache();
|
||||
return $succes;
|
||||
}
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
return fopen($this->constructUrl($path), $mode);
|
||||
public function fopen($path,$mode) {
|
||||
$this->init();
|
||||
return fopen($this->constructUrl($path),$mode);
|
||||
}
|
||||
|
||||
public function free_space($path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function touch($path, $mtime = null) {
|
||||
if (is_null($mtime)) {
|
||||
$fh = $this->fopen($path, 'a');
|
||||
fwrite($fh, '');
|
||||
public function touch($path,$mtime=null) {
|
||||
$this->init();
|
||||
if(is_null($mtime)) {
|
||||
$fh = $this->fopen($path,'a');
|
||||
fwrite($fh,'');
|
||||
fclose($fh);
|
||||
} else {
|
||||
return false;//not supported
|
||||
}
|
||||
}
|
||||
|
||||
public function getFile($path, $target) {
|
||||
return copy($this->constructUrl($path), $target);
|
||||
public function getFile($path,$target) {
|
||||
$this->init();
|
||||
return copy($this->constructUrl($path),$target);
|
||||
}
|
||||
|
||||
public function uploadFile($path, $target) {
|
||||
return copy($path, $this->constructUrl($target));
|
||||
public function uploadFile($path,$target) {
|
||||
$this->init();
|
||||
return copy($path,$this->constructUrl($target));
|
||||
}
|
||||
|
||||
public function rename($path1, $path2) {
|
||||
return rename($this->constructUrl($path1), $this->constructUrl($path2));
|
||||
public function rename($path1,$path2) {
|
||||
$this->init();
|
||||
return rename($this->constructUrl($path1),$this->constructUrl($path2));
|
||||
}
|
||||
|
||||
public function stat($path) {
|
||||
$this->init();
|
||||
return stat($this->constructUrl($path));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,24 +6,28 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
require_once 'php-cloudfiles/cloudfiles.php';
|
||||
|
||||
class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
class SWIFT extends \OC\Files\Storage\Common{
|
||||
private $id;
|
||||
private $host;
|
||||
private $root;
|
||||
private $user;
|
||||
private $token;
|
||||
private $secure;
|
||||
private $ready = false;
|
||||
/**
|
||||
* @var CF_Authentication auth
|
||||
* @var \CF_Authentication auth
|
||||
*/
|
||||
private $auth;
|
||||
/**
|
||||
* @var CF_Connection conn
|
||||
* @var \CF_Connection conn
|
||||
*/
|
||||
private $conn;
|
||||
/**
|
||||
* @var CF_Container rootContainer
|
||||
* @var \CF_Container rootContainer
|
||||
*/
|
||||
private $rootContainer;
|
||||
|
||||
|
@ -35,18 +39,18 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* translate directory path to container name
|
||||
* @param string path
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
private function getContainerName($path) {
|
||||
$path=trim(trim($this->root, '/')."/".$path, '/.');
|
||||
$path=trim(trim($this->root, '/') . "/".$path, '/.');
|
||||
return str_replace('/', '\\', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* get container by path
|
||||
* @param string path
|
||||
* @return CF_Container
|
||||
* @param string $path
|
||||
* @return \CF_Container
|
||||
*/
|
||||
private function getContainer($path) {
|
||||
if ($path=='' or $path=='/') {
|
||||
|
@ -59,15 +63,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
$container=$this->conn->get_container($this->getContainerName($path));
|
||||
$this->containers[$path]=$container;
|
||||
return $container;
|
||||
} catch(NoSuchContainerException $e) {
|
||||
} catch(\NoSuchContainerException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create container
|
||||
* @param string path
|
||||
* @return CF_Container
|
||||
* @param string $path
|
||||
* @return \CF_Container
|
||||
*/
|
||||
private function createContainer($path) {
|
||||
if ($path=='' or $path=='/' or $path=='.') {
|
||||
|
@ -89,8 +93,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* get object by path
|
||||
* @param string path
|
||||
* @return CF_Object
|
||||
* @param string $path
|
||||
* @return \CF_Object
|
||||
*/
|
||||
private function getObject($path) {
|
||||
if (isset($this->objects[$path])) {
|
||||
|
@ -107,7 +111,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
$obj=$container->get_object(basename($path));
|
||||
$this->objects[$path]=$obj;
|
||||
return $obj;
|
||||
} catch(NoSuchObjectException $e) {
|
||||
} catch(\NoSuchObjectException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -132,8 +136,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* create object
|
||||
* @param string path
|
||||
* @return CF_Object
|
||||
* @param string $path
|
||||
* @return \CF_Object
|
||||
*/
|
||||
private function createObject($path) {
|
||||
$container=$this->getContainer(dirname($path));
|
||||
|
@ -154,7 +158,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* check if container for path exists
|
||||
* @param string path
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
private function containerExists($path) {
|
||||
|
@ -163,15 +167,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* get the list of emulated sub containers
|
||||
* @param CF_Container container
|
||||
* @param \CF_Container $container
|
||||
* @return array
|
||||
*/
|
||||
private function getSubContainers($container) {
|
||||
$tmpFile=OCP\Files::tmpFile();
|
||||
$tmpFile=\OCP\Files::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try {
|
||||
$obj->save_to_filename($tmpFile);
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return array();
|
||||
}
|
||||
$obj->save_to_filename($tmpFile);
|
||||
|
@ -185,15 +189,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* add an emulated sub container
|
||||
* @param CF_Container container
|
||||
* @param string name
|
||||
* @param \CF_Container $container
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
private function addSubContainer($container, $name) {
|
||||
if ( ! $name) {
|
||||
return false;
|
||||
}
|
||||
$tmpFile=OCP\Files::tmpFile();
|
||||
$tmpFile=\OCP\Files::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try {
|
||||
$obj->save_to_filename($tmpFile);
|
||||
|
@ -201,16 +205,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
foreach ($containers as &$sub) {
|
||||
$sub=trim($sub);
|
||||
}
|
||||
if (array_search($name, $containers)!==false) {
|
||||
if(array_search($name, $containers) !== false) {
|
||||
unlink($tmpFile);
|
||||
return false;
|
||||
} else {
|
||||
$fh=fopen($tmpFile, 'a');
|
||||
fwrite($fh, $name."\n");
|
||||
fwrite($fh,$name . "\n");
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
$containers=array();
|
||||
file_put_contents($tmpFile, $name."\n");
|
||||
} catch(\Exception $e) {
|
||||
file_put_contents($tmpFile, $name . "\n");
|
||||
}
|
||||
|
||||
$obj->load_from_filename($tmpFile);
|
||||
|
@ -220,20 +223,20 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* remove an emulated sub container
|
||||
* @param CF_Container container
|
||||
* @param string name
|
||||
* @param \CF_Container $container
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
private function removeSubContainer($container, $name) {
|
||||
if ( ! $name) {
|
||||
return false;
|
||||
}
|
||||
$tmpFile=OCP\Files::tmpFile();
|
||||
$tmpFile=\OCP\Files::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try {
|
||||
$obj->save_to_filename($tmpFile);
|
||||
$containers=file($tmpFile);
|
||||
} catch (Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
foreach ($containers as &$sub) {
|
||||
|
@ -255,8 +258,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* ensure a subcontainer file exists and return it's object
|
||||
* @param CF_Container container
|
||||
* @return CF_Object
|
||||
* @param \CF_Container $container
|
||||
* @return \CF_Object
|
||||
*/
|
||||
private function getSubContainerFile($container) {
|
||||
try {
|
||||
|
@ -283,10 +286,19 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
if ( ! $this->root || $this->root[0]!='/') {
|
||||
$this->root='/'.$this->root;
|
||||
}
|
||||
$this->auth = new CF_Authentication($this->user, $this->token, null, $this->host);
|
||||
|
||||
}
|
||||
|
||||
private function init(){
|
||||
if($this->ready){
|
||||
return;
|
||||
}
|
||||
$this->ready = true;
|
||||
|
||||
$this->auth = new \CF_Authentication($this->user, $this->token, null, $this->host);
|
||||
$this->auth->authenticate();
|
||||
|
||||
$this->conn = new CF_Connection($this->auth);
|
||||
$this->conn = new \CF_Connection($this->auth);
|
||||
|
||||
if ( ! $this->containerExists('/')) {
|
||||
$this->rootContainer=$this->createContainer('/');
|
||||
|
@ -295,8 +307,13 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
|
||||
public function mkdir($path) {
|
||||
$this->init();
|
||||
if ($this->containerExists($path)) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -306,7 +323,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function rmdir($path) {
|
||||
if ( ! $this->containerExists($path)) {
|
||||
$this->init();
|
||||
if (!$this->containerExists($path)) {
|
||||
return false;
|
||||
} else {
|
||||
$this->emptyContainer($path);
|
||||
|
@ -343,6 +361,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function opendir($path) {
|
||||
$this->init();
|
||||
$container=$this->getContainer($path);
|
||||
$files=$this->getObjects($container);
|
||||
$i=array_search(self::SUBCONTAINER_FILE, $files);
|
||||
|
@ -352,11 +371,12 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_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);
|
||||
}
|
||||
|
||||
public function filetype($path) {
|
||||
$this->init();
|
||||
if ($this->containerExists($path)) {
|
||||
return 'dir';
|
||||
} else {
|
||||
|
@ -373,6 +393,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function file_exists($path) {
|
||||
$this->init();
|
||||
if ($this->is_dir($path)) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -381,6 +402,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function file_get_contents($path) {
|
||||
$this->init();
|
||||
$obj=$this->getObject($path);
|
||||
if (is_null($obj)) {
|
||||
return false;
|
||||
|
@ -389,6 +411,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function file_put_contents($path, $content) {
|
||||
$this->init();
|
||||
$obj=$this->getObject($path);
|
||||
if (is_null($obj)) {
|
||||
$container=$this->getContainer(dirname($path));
|
||||
|
@ -402,6 +425,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function unlink($path) {
|
||||
$this->init();
|
||||
if ($this->containerExists($path)) {
|
||||
return $this->rmdir($path);
|
||||
}
|
||||
|
@ -415,6 +439,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
$this->init();
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
|
@ -440,7 +465,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_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);
|
||||
}
|
||||
|
@ -458,6 +483,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function touch($path, $mtime=null) {
|
||||
$this->init();
|
||||
$obj=$this->getObject($path);
|
||||
if (is_null($obj)) {
|
||||
return false;
|
||||
|
@ -472,6 +498,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function rename($path1, $path2) {
|
||||
$this->init();
|
||||
$sourceContainer=$this->getContainer(dirname($path1));
|
||||
$targetContainer=$this->getContainer(dirname($path2));
|
||||
$result=$sourceContainer->move_object_to(basename($path1), $targetContainer, basename($path2));
|
||||
|
@ -484,6 +511,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function copy($path1, $path2) {
|
||||
$this->init();
|
||||
$sourceContainer=$this->getContainer(dirname($path1));
|
||||
$targetContainer=$this->getContainer(dirname($path2));
|
||||
$result=$sourceContainer->copy_object_to(basename($path1), $targetContainer, basename($path2));
|
||||
|
@ -495,6 +523,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function stat($path) {
|
||||
$this->init();
|
||||
$container=$this->getContainer($path);
|
||||
if ( ! is_null($container)) {
|
||||
return array(
|
||||
|
@ -523,17 +552,19 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
private function getTmpFile($path) {
|
||||
$this->init();
|
||||
$obj=$this->getObject($path);
|
||||
if ( ! is_null($obj)) {
|
||||
$tmpFile=OCP\Files::tmpFile();
|
||||
$tmpFile=\OCP\Files::tmpFile();
|
||||
$obj->save_to_filename($tmpFile);
|
||||
return $tmpFile;
|
||||
} else {
|
||||
return OCP\Files::tmpFile();
|
||||
return \OCP\Files::tmpFile();
|
||||
}
|
||||
}
|
||||
|
||||
private function fromTmpFile($tmpFile, $path) {
|
||||
$this->init();
|
||||
$obj=$this->getObject($path);
|
||||
if (is_null($obj)) {
|
||||
$obj=$this->createObject($path);
|
||||
|
@ -544,7 +575,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
|||
|
||||
/**
|
||||
* remove custom mtime metadata
|
||||
* @param CF_Object obj
|
||||
* @param \CF_Object $obj
|
||||
*/
|
||||
private function resetMTime($obj) {
|
||||
if (isset($obj->metadata['Mtime'])) {
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
class DAV extends \OC\Files\Storage\Common{
|
||||
private $password;
|
||||
private $user;
|
||||
private $host;
|
||||
private $secure;
|
||||
private $root;
|
||||
private $ready;
|
||||
/**
|
||||
* @var Sabre_DAV_Client
|
||||
* @var \Sabre_DAV_Client
|
||||
*/
|
||||
private $client;
|
||||
|
||||
|
@ -43,6 +46,13 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
if (substr($this->root, -1, 1)!='/') {
|
||||
$this->root.='/';
|
||||
}
|
||||
}
|
||||
|
||||
private function init(){
|
||||
if($this->ready){
|
||||
return;
|
||||
}
|
||||
$this->ready = true;
|
||||
|
||||
$settings = array(
|
||||
'baseUri' => $this->createBaseUri(),
|
||||
|
@ -50,7 +60,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
'password' => $this->password,
|
||||
);
|
||||
|
||||
$this->client = new Sabre_DAV_Client($settings);
|
||||
$this->client = new \Sabre_DAV_Client($settings);
|
||||
|
||||
$caview = \OCP\Files::getStorage('files_external');
|
||||
if ($caview) {
|
||||
|
@ -63,6 +73,10 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
$this->mkdir('');
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root;
|
||||
}
|
||||
|
||||
private function createBaseUri() {
|
||||
$baseUri='http';
|
||||
if ($this->secure) {
|
||||
|
@ -73,40 +87,46 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
return $this->simpleResponse('MKCOL', $path, null, 201);
|
||||
}
|
||||
|
||||
public function rmdir($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
return $this->simpleResponse('DELETE', $path, null, 204);
|
||||
}
|
||||
|
||||
public function opendir($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->propfind($path, array(), 1);
|
||||
$id=md5('webdav'.$this->root.$path);
|
||||
OC_FakeDirStream::$dirs[$id]=array();
|
||||
$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) {
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function filetype($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->propfind($path, array('{DAV:}resourcetype'));
|
||||
$responseType=$response["{DAV:}resourcetype"]->resourceType;
|
||||
return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
\OCP\Util::writeLog("webdav client", \OCP\Util::sanitizeHTML($e->getMessage()), \OCP\Util::ERROR);
|
||||
return false;
|
||||
|
@ -122,20 +142,23 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function file_exists($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$this->client->propfind($path, array('{DAV:}resourcetype'));
|
||||
return true;//no 404 exception
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
return $this->simpleResponse('DELETE', $path, null, 204);
|
||||
$this->init();
|
||||
return $this->simpleResponse('DELETE', $path, null ,204);
|
||||
}
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
public function fopen($path,$mode) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
|
@ -172,9 +195,9 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
} else {
|
||||
$ext='';
|
||||
}
|
||||
$tmpFile=OCP\Files::tmpFile($ext);
|
||||
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack');
|
||||
if ($this->file_exists($path)) {
|
||||
$tmpFile = \OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if($this->file_exists($path)) {
|
||||
$this->getFile($path, $tmpFile);
|
||||
}
|
||||
self::$tempFiles[$tmpFile]=$path;
|
||||
|
@ -190,6 +213,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
}
|
||||
|
||||
public function free_space($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->propfind($path, array('{DAV:}quota-available-bytes'));
|
||||
|
@ -198,12 +222,13 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
} else {
|
||||
return 0;
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function touch($path, $mtime=null) {
|
||||
$this->init();
|
||||
if (is_null($mtime)) {
|
||||
$mtime=time();
|
||||
}
|
||||
|
@ -211,12 +236,14 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
$this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime));
|
||||
}
|
||||
|
||||
public function getFile($path, $target) {
|
||||
$source=$this->fopen($path, 'r');
|
||||
file_put_contents($target, $source);
|
||||
public function getFile($path,$target) {
|
||||
$this->init();
|
||||
$source=$this->fopen($path,'r');
|
||||
file_put_contents($target,$source);
|
||||
}
|
||||
|
||||
public function uploadFile($path, $target) {
|
||||
public function uploadFile($path,$target) {
|
||||
$this->init();
|
||||
$source=fopen($path, 'r');
|
||||
|
||||
$curl = curl_init();
|
||||
|
@ -230,47 +257,46 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
curl_close ($curl);
|
||||
}
|
||||
|
||||
public function rename($path1, $path2) {
|
||||
public function rename($path1,$path2) {
|
||||
$this->init();
|
||||
$path1=$this->cleanPath($path1);
|
||||
$path2=$this->root.$this->cleanPath($path2);
|
||||
try {
|
||||
$this->client->request('MOVE', $path1, null, array('Destination'=>$path2));
|
||||
return true;
|
||||
} catch(Exception $e) {
|
||||
echo $e;
|
||||
echo 'fail';
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function copy($path1, $path2) {
|
||||
public function copy($path1,$path2) {
|
||||
$this->init();
|
||||
$path1=$this->cleanPath($path1);
|
||||
$path2=$this->root.$this->cleanPath($path2);
|
||||
try {
|
||||
$this->client->request('COPY', $path1, null, array('Destination'=>$path2));
|
||||
return true;
|
||||
} catch(Exception $e) {
|
||||
echo $e;
|
||||
echo 'fail';
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function stat($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->propfind($path, array('{DAV:}getlastmodified', '{DAV:}getcontentlength'));
|
||||
return array(
|
||||
'mtime'=>strtotime($response['{DAV:}getlastmodified']),
|
||||
'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0,
|
||||
'ctime'=>-1,
|
||||
);
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public function getMimeType($path) {
|
||||
$this->init();
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->propfind($path, array('{DAV:}getcontenttype', '{DAV:}resourcetype'));
|
||||
|
@ -283,7 +309,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -296,12 +322,12 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
|||
}
|
||||
}
|
||||
|
||||
private function simpleResponse($method, $path, $body, $expected) {
|
||||
private function simpleResponse($method,$path,$body,$expected) {
|
||||
$path=$this->cleanPath($path);
|
||||
try {
|
||||
$response=$this->client->request($method, $path, $body);
|
||||
return $response['statusCode']==$expected;
|
||||
} catch(Exception $e) {
|
||||
} catch(\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ OCP\Util::addScript('files_external', 'settings');
|
|||
OCP\Util::addStyle('files_external', 'settings');
|
||||
$backends = OC_Mount_Config::getBackends();
|
||||
// Remove local storage
|
||||
unset($backends['OC_Filestorage_Local']);
|
||||
unset($backends['\OC\Files\Storage\Local']);
|
||||
$tmpl = new OCP\Template('files_external', 'settings');
|
||||
$tmpl->assign('isAdminPage', false, false);
|
||||
$tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints());
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_AmazonS3 extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class AmazonS3 extends Storage {
|
||||
|
||||
private $config;
|
||||
private $id;
|
||||
|
@ -32,12 +34,12 @@ class Test_Filestorage_AmazonS3 extends Test_FileStorage {
|
|||
$this->markTestSkipped('AmazonS3 backend not configured');
|
||||
}
|
||||
$this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in
|
||||
$this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']);
|
||||
$this->instance = new \OC\Files\Storage\AmazonS3($this->config['amazons3']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$s3 = new AmazonS3(array('key' => $this->config['amazons3']['key'],
|
||||
$s3 = new \AmazonS3(array('key' => $this->config['amazons3']['key'],
|
||||
'secret' => $this->config['amazons3']['secret']));
|
||||
if ($s3->delete_all_objects($this->id)) {
|
||||
$s3->delete_bucket($this->id);
|
||||
|
|
|
@ -8,7 +8,7 @@ return array(
|
|||
'root'=>'/test',
|
||||
),
|
||||
'webdav'=>array(
|
||||
'run'=>false,
|
||||
'run'=>true,
|
||||
'host'=>'localhost',
|
||||
'user'=>'test',
|
||||
'password'=>'test',
|
||||
|
@ -30,7 +30,7 @@ return array(
|
|||
'root'=>'/',
|
||||
),
|
||||
'smb'=>array(
|
||||
'run'=>false,
|
||||
'run'=>true,
|
||||
'user'=>'test',
|
||||
'password'=>'test',
|
||||
'host'=>'localhost',
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_Dropbox extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class Dropbox extends Storage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -16,7 +18,7 @@ class Test_Filestorage_Dropbox extends Test_FileStorage {
|
|||
$this->markTestSkipped('Dropbox backend not configured');
|
||||
}
|
||||
$this->config['dropbox']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_Dropbox($this->config['dropbox']);
|
||||
$this->instance = new \OC\Files\Storage\Dropbox($this->config['dropbox']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_FTP extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class FTP extends Storage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -16,12 +18,12 @@ class Test_Filestorage_FTP extends Test_FileStorage {
|
|||
$this->markTestSkipped('FTP backend not configured');
|
||||
}
|
||||
$this->config['ftp']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_FTP($this->config['ftp']);
|
||||
$this->instance = new \OC\Files\Storage\FTP($this->config['ftp']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
\OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_Google extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class Google extends Storage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -31,7 +32,7 @@ class Test_Filestorage_Google extends Test_FileStorage {
|
|||
$this->markTestSkipped('Google backend not configured');
|
||||
}
|
||||
$this->config['google']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_Google($this->config['google']);
|
||||
$this->instance = new \OC\Files\Storage\Google($this->config['google']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_SMB extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class SMB extends Storage {
|
||||
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -16,12 +19,12 @@ class Test_Filestorage_SMB extends Test_FileStorage {
|
|||
$this->markTestSkipped('Samba backend not configured');
|
||||
}
|
||||
$this->config['smb']['root'] .= $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_SMB($this->config['smb']);
|
||||
$this->instance = new \OC\Files\Storage\SMB($this->config['smb']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
\OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_SWIFT extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class SWIFT extends Storage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -16,7 +18,7 @@ class Test_Filestorage_SWIFT extends Test_FileStorage {
|
|||
$this->markTestSkipped('OpenStack SWIFT backend not configured');
|
||||
}
|
||||
$this->config['swift']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_SWIFT($this->config['swift']);
|
||||
$this->instance = new \OC\Files\Storage\SWIFT($this->config['swift']);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class Test_Filestorage_DAV extends Test_FileStorage {
|
||||
namespace Test\Files\Storage;
|
||||
|
||||
class DAV extends Storage {
|
||||
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
|
@ -16,7 +19,7 @@ class Test_Filestorage_DAV extends Test_FileStorage {
|
|||
$this->markTestSkipped('WebDAV backend not configured');
|
||||
}
|
||||
$this->config['webdav']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_DAV($this->config['webdav']);
|
||||
$this->instance = new \OC\Files\Storage\DAV($this->config['webdav']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/lib/share/file.php";
|
||||
OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/lib/sharedstorage.php";
|
||||
OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup');
|
||||
OC::$CLASSPATH['OC\Files\Storage\Shared'] = "apps/files_sharing/lib/sharedstorage.php";
|
||||
OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'apps/files_sharing/lib/cache.php';
|
||||
OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'apps/files_sharing/lib/permissions.php';
|
||||
OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'apps/files_sharing/lib/watcher.php';
|
||||
OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
|
||||
OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
|
||||
OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
|
||||
OCP\Util::addScript('files_sharing', 'share');
|
||||
OCP\Util::addScript('files_sharing', 'share');
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<description>File sharing between users</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Michael Gapczynski</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<default_enable/>
|
||||
<types>
|
||||
|
|
|
@ -9,10 +9,12 @@ if (version_compare($installedVersion, '0.3', '<')) {
|
|||
OC_User::useBackend(new OC_User_Database());
|
||||
OC_Group::useBackend(new OC_Group_Database());
|
||||
OC_App::loadApps(array('authentication'));
|
||||
$rootView = new \OC\Files\View('');
|
||||
while ($row = $result->fetchRow()) {
|
||||
$itemSource = OC_FileCache::getId($row['source'], '');
|
||||
$meta = $rootView->getFileInfo($$row['source']);
|
||||
$itemSource = $meta['fileid'];
|
||||
if ($itemSource != -1) {
|
||||
$file = OC_FileCache::get($row['source'], '');
|
||||
$file = $meta;
|
||||
if ($file['mimetype'] == 'httpd/unix-directory') {
|
||||
$itemType = 'folder';
|
||||
} else {
|
||||
|
@ -68,6 +70,6 @@ if (version_compare($installedVersion, '0.3.3', '<')) {
|
|||
OC_App::loadApps(array('authentication'));
|
||||
$users = OC_User::getUsers();
|
||||
foreach ($users as $user) {
|
||||
OC_FileCache::delete('Shared', '/'.$user.'/files/');
|
||||
// OC_FileCache::delete('Shared', '/'.$user.'/files/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache;
|
||||
|
||||
/**
|
||||
* Metadata cache for shared files
|
||||
*
|
||||
* don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead
|
||||
*/
|
||||
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 $target Shared target file path
|
||||
* @return \OC\Files\Cache\Cache
|
||||
*/
|
||||
private function getSourceCache($target) {
|
||||
$source = \OC_Share_Backend_File::getSource($target);
|
||||
if (isset($source['path'])) {
|
||||
$source['path'] = '/' . $source['uid_owner'] . '/' . $source['path'];
|
||||
\OC\Files\Filesystem::initMountPoints($source['uid_owner']);
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']);
|
||||
if ($storage) {
|
||||
$this->files[$target] = $internalPath;
|
||||
$cache = $storage->getCache();
|
||||
$this->storageId = $storage->getId();
|
||||
$this->numericId = $cache->getNumericStorageId();
|
||||
return $cache;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the stored metadata of a file or folder
|
||||
*
|
||||
* @param string/int $file
|
||||
* @return array
|
||||
*/
|
||||
public function get($file) {
|
||||
if ($file == '') {
|
||||
return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT);
|
||||
} else if (is_string($file)) {
|
||||
if ($cache = $this->getSourceCache($file)) {
|
||||
return $cache->get($this->files[$file]);
|
||||
}
|
||||
} else {
|
||||
$query = \OC_DB::prepare(
|
||||
'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`
|
||||
FROM `*PREFIX*filecache` WHERE `fileid` = ?');
|
||||
$result = $query->execute(array($file));
|
||||
$data = $result->fetchRow();
|
||||
$data['fileid'] = (int)$data['fileid'];
|
||||
$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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the metadata of all files stored in $folder
|
||||
*
|
||||
* @param string $folder
|
||||
* @return array
|
||||
*/
|
||||
public function getFolderContents($folder) {
|
||||
if ($folder == '') {
|
||||
$files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS);
|
||||
foreach ($files as &$file) {
|
||||
$file['mimetype'] = $this->getMimetype($file['mimetype']);
|
||||
$file['mimepart'] = $this->getMimetype($file['mimepart']);
|
||||
}
|
||||
return $files;
|
||||
} else {
|
||||
if ($cache = $this->getSourceCache($folder)) {
|
||||
return $cache->getFolderContents($this->files[$folder]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* store meta data for a file or folder
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
*
|
||||
* @return int file id
|
||||
*/
|
||||
public function put($file, array $data) {
|
||||
if ($cache = $this->getSourceCache($file)) {
|
||||
return $cache->put($this->files[$file], $data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id for a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getId($file) {
|
||||
if ($cache = $this->getSourceCache($file)) {
|
||||
return $cache->getId($this->files[$file]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file is available in the cache
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($file) {
|
||||
if ($file == '') {
|
||||
return true;
|
||||
}
|
||||
return parent::inCache($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file or folder from the cache
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function remove($file) {
|
||||
if ($cache = $this->getSourceCache($file)) {
|
||||
$cache->remove($this->files[$file]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a file or folder in the cache
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*/
|
||||
public function move($source, $target) {
|
||||
if ($cache = $this->getSourceCache($source)) {
|
||||
$targetPath = \OC_Share_Backend_File::getSourcePath(dirname($target));
|
||||
if ($targetPath) {
|
||||
$targetPath .= '/' . basename($target);
|
||||
$cache->move($this->files[$source], $targetPath);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all entries for files that are stored on the storage from the cache
|
||||
*/
|
||||
public function clear() {
|
||||
// Not a valid action for Shared Cache
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
|
||||
*/
|
||||
public function getStatus($file) {
|
||||
if ($file == '') {
|
||||
return self::COMPLETE;
|
||||
}
|
||||
if ($cache = $this->getSourceCache($file)) {
|
||||
return $cache->getStatus($this->files[$file]);
|
||||
}
|
||||
return self::NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files matching $pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
* @return array of file data
|
||||
*/
|
||||
public function search($pattern) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* 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` = ?';
|
||||
}
|
||||
$mimetype = $this->getMimetypeId($mimetype);
|
||||
$ids = $this->getAll();
|
||||
$placeholders = join(',', array_fill(0, count($ids), '?'));
|
||||
$query = \OC_DB::prepare('
|
||||
SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`
|
||||
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN (' . $placeholders . ')'
|
||||
);
|
||||
$result = $query->execute(array_merge(array($mimetype), $ids));
|
||||
return $result->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the size of a folder and set it in the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function calculateFolderSize($path) {
|
||||
if ($cache = $this->getSourceCache($path)) {
|
||||
return $cache->calculateFolderSize($this->files[$path]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all file ids on the files on the storage
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAll() {
|
||||
return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace OC\Files\Cache;
|
||||
|
||||
class Shared_Permissions extends Permissions {
|
||||
|
||||
/**
|
||||
* get the permissions for a single file
|
||||
*
|
||||
* @param int $fileId
|
||||
* @param string $user
|
||||
* @return int (-1 if file no permissions set)
|
||||
*/
|
||||
public function get($fileId, $user) {
|
||||
if ($fileId == -1) {
|
||||
return \OCP\PERMISSION_READ;
|
||||
}
|
||||
$source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE, null, true);
|
||||
if ($source) {
|
||||
return $source['permissions'];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the permissions of a file
|
||||
*
|
||||
* @param int $fileId
|
||||
* @param string $user
|
||||
* @param int $permissions
|
||||
*/
|
||||
public function set($fileId, $user, $permissions) {
|
||||
// Not a valid action for Shared Permissions
|
||||
}
|
||||
|
||||
/**
|
||||
* get the permissions of multiply files
|
||||
*
|
||||
* @param int[] $fileIds
|
||||
* @param string $user
|
||||
* @return int[]
|
||||
*/
|
||||
public function getMultiple($fileIds, $user) {
|
||||
if (count($fileIds) === 0) {
|
||||
return array();
|
||||
}
|
||||
foreach ($fileIds as $fileId) {
|
||||
$filePermissions[$fileId] = self::get($fileId, $user);
|
||||
}
|
||||
return $filePermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the permissions for a file
|
||||
*
|
||||
* @param int $fileId
|
||||
* @param string $user
|
||||
*/
|
||||
public function remove($fileId, $user) {
|
||||
// Not a valid action for Shared Permissions
|
||||
}
|
||||
|
||||
public function removeMultiple($fileIds, $user) {
|
||||
// Not a valid action for Shared Permissions
|
||||
}
|
||||
}
|
|
@ -22,16 +22,18 @@
|
|||
class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
||||
|
||||
const FORMAT_SHARED_STORAGE = 0;
|
||||
const FORMAT_FILE_APP = 1;
|
||||
const FORMAT_GET_FOLDER_CONTENTS = 1;
|
||||
const FORMAT_FILE_APP_ROOT = 2;
|
||||
const FORMAT_OPENDIR = 3;
|
||||
const FORMAT_GET_ALL = 4;
|
||||
|
||||
private $path;
|
||||
|
||||
public function isValidSource($itemSource, $uidOwner) {
|
||||
$path = OC_FileCache::getPath($itemSource, $uidOwner);
|
||||
if ($path) {
|
||||
$this->path = $path;
|
||||
$query = \OC_DB::prepare('SELECT `name` FROM `*PREFIX*filecache` WHERE `fileid` = ?');
|
||||
$result = $query->execute(array($itemSource));
|
||||
if ($row = $result->fetchRow()) {
|
||||
$this->path = $row['name'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -70,37 +72,21 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
public function formatItems($items, $format, $parameters = null) {
|
||||
if ($format == self::FORMAT_SHARED_STORAGE) {
|
||||
// Only 1 item should come through for this format call
|
||||
return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']);
|
||||
} else if ($format == self::FORMAT_FILE_APP) {
|
||||
if (isset($parameters['mimetype_filter']) && $parameters['mimetype_filter']) {
|
||||
$mimetype_filter = $parameters['mimetype_filter'];
|
||||
}
|
||||
return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions'], 'uid_owner' => $items[key($items)]['uid_owner']);
|
||||
} else if ($format == self::FORMAT_GET_FOLDER_CONTENTS) {
|
||||
$files = array();
|
||||
foreach ($items as $item) {
|
||||
if (isset($mimetype_filter)
|
||||
&& strpos($item['mimetype'], $mimetype_filter) !== 0
|
||||
&& $item['mimetype'] != 'httpd/unix-directory') {
|
||||
continue;
|
||||
}
|
||||
$file = array();
|
||||
$file['id'] = $item['file_source'];
|
||||
$file['fileid'] = $item['file_source'];
|
||||
$file['storage'] = $item['storage'];
|
||||
$file['path'] = $item['file_target'];
|
||||
$file['parent'] = $item['file_parent'];
|
||||
$file['name'] = basename($item['file_target']);
|
||||
$file['ctime'] = $item['ctime'];
|
||||
$file['mtime'] = $item['mtime'];
|
||||
$file['mimetype'] = $item['mimetype'];
|
||||
$file['mimepart'] = $item['mimepart'];
|
||||
$file['size'] = $item['size'];
|
||||
$file['mtime'] = $item['mtime'];
|
||||
$file['encrypted'] = $item['encrypted'];
|
||||
$file['versioned'] = $item['versioned'];
|
||||
$file['directory'] = $parameters['folder'];
|
||||
$file['type'] = ($item['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file';
|
||||
$file['permissions'] = $item['permissions'];
|
||||
if ($file['type'] == 'file') {
|
||||
// Remove Create permission if type is file
|
||||
$file['permissions'] &= ~OCP\PERMISSION_CREATE;
|
||||
}
|
||||
// NOTE: Temporary fix to allow unsharing of files in root of Shared directory
|
||||
$file['permissions'] |= OCP\PERMISSION_DELETE;
|
||||
$files[] = $file;
|
||||
}
|
||||
return $files;
|
||||
|
@ -111,17 +97,48 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
|
|||
if ($item['mtime'] > $mtime) {
|
||||
$mtime = $item['mtime'];
|
||||
}
|
||||
$size += $item['size'];
|
||||
$size += (int)$item['size'];
|
||||
}
|
||||
return array(0 => array('id' => -1, 'name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false, 'type' => 'dir', 'directory' => '', 'permissions' => OCP\PERMISSION_READ));
|
||||
return array('fileid' => -1, 'name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size);
|
||||
} else if ($format == self::FORMAT_OPENDIR) {
|
||||
$files = array();
|
||||
foreach ($items as $item) {
|
||||
$files[] = basename($item['file_target']);
|
||||
}
|
||||
return $files;
|
||||
} else if ($format == self::FORMAT_GET_ALL) {
|
||||
$ids = array();
|
||||
foreach ($items as $item) {
|
||||
$ids[] = $item['file_source'];
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function getSource($target) {
|
||||
if ($target == '') {
|
||||
return false;
|
||||
}
|
||||
$target = '/'.$target;
|
||||
$target = rtrim($target, '/');
|
||||
$pos = strpos($target, '/', 1);
|
||||
// Get shared folder name
|
||||
if ($pos !== false) {
|
||||
$folder = substr($target, 0, $pos);
|
||||
$source = \OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
if ($source) {
|
||||
$source['path'] = $source['path'].substr($target, strlen($folder));
|
||||
return $source;
|
||||
}
|
||||
} else {
|
||||
$source = \OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
if ($source) {
|
||||
return $source;
|
||||
}
|
||||
}
|
||||
\OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,47 +21,26 @@
|
|||
|
||||
class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share_Backend_Collection {
|
||||
|
||||
public function formatItems($items, $format, $parameters = null) {
|
||||
if ($format == self::FORMAT_SHARED_STORAGE) {
|
||||
// Only 1 item should come through for this format call
|
||||
return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']);
|
||||
} else if ($format == self::FORMAT_FILE_APP && isset($parameters['folder'])) {
|
||||
// Only 1 item should come through for this format call
|
||||
$folder = $items[key($items)];
|
||||
if (isset($parameters['mimetype_filter'])) {
|
||||
$mimetype_filter = $parameters['mimetype_filter'];
|
||||
} else {
|
||||
$mimetype_filter = '';
|
||||
}
|
||||
$path = $folder['path'].substr($parameters['folder'], 7 + strlen($folder['file_target']));
|
||||
$files = OC_FileCache::getFolderContent($path, '', $mimetype_filter);
|
||||
foreach ($files as &$file) {
|
||||
$file['directory'] = $parameters['folder'];
|
||||
$file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file';
|
||||
$file['permissions'] = $folder['permissions'];
|
||||
if ($file['type'] == 'file') {
|
||||
// Remove Create permission if type is file
|
||||
$file['permissions'] &= ~OCP\PERMISSION_CREATE;
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getChildren($itemSource) {
|
||||
$children = array();
|
||||
$parents = array($itemSource);
|
||||
$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?');
|
||||
$result = $query->execute(array('httpd/unix-directory'));
|
||||
if ($row = $result->fetchRow()) {
|
||||
$mimetype = $row['id'];
|
||||
} else {
|
||||
$mimetype = -1;
|
||||
}
|
||||
while (!empty($parents)) {
|
||||
$parents = "'".implode("','", $parents)."'";
|
||||
$query = OC_DB::prepare('SELECT `id`, `name`, `mimetype` FROM `*PREFIX*fscache` WHERE `parent` IN ('.$parents.')');
|
||||
$query = OC_DB::prepare('SELECT `fileid`, `name`, `mimetype` FROM `*PREFIX*filecache` WHERE `parent` IN ('.$parents.')');
|
||||
$result = $query->execute();
|
||||
$parents = array();
|
||||
while ($file = $result->fetchRow()) {
|
||||
$children[] = array('source' => $file['id'], 'file_path' => $file['name']);
|
||||
$children[] = array('source' => $file['fileid'], 'file_path' => $file['name']);
|
||||
// If a child folder is found look inside it
|
||||
if ($file['mimetype'] == 'httpd/unix-directory') {
|
||||
$parents[] = $file['id'];
|
||||
if ($file['mimetype'] == $mimetype) {
|
||||
$parents[] = $file['fileid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
/**
|
||||
* Convert target path to source path and pass the function call to the correct storage provider
|
||||
*/
|
||||
class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
class Shared extends \OC\Files\Storage\Common {
|
||||
|
||||
private $sharedFolder;
|
||||
private $files = array();
|
||||
|
@ -32,54 +34,36 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
$this->sharedFolder = $arguments['sharedFolder'];
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return 'shared::' . $this->sharedFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the source file path and the permissions granted for a shared file
|
||||
* @brief Get the source file path, permissions, and owner for a shared file
|
||||
* @param string Shared target file path
|
||||
* @return Returns array with the keys path and permissions or false if not found
|
||||
* @return Returns array with the keys path, permissions, and owner or false if not found
|
||||
*/
|
||||
private function getFile($target) {
|
||||
$target = '/'.$target;
|
||||
$target = rtrim($target, '/');
|
||||
if (isset($this->files[$target])) {
|
||||
return $this->files[$target];
|
||||
} else {
|
||||
$pos = strpos($target, '/', 1);
|
||||
// Get shared folder name
|
||||
if ($pos !== false) {
|
||||
$folder = substr($target, 0, $pos);
|
||||
if (isset($this->files[$folder])) {
|
||||
$file = $this->files[$folder];
|
||||
} else {
|
||||
$file = OCP\Share::getItemSharedWith('folder', $folder, OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
}
|
||||
if ($file) {
|
||||
$this->files[$target]['path'] = $file['path'].substr($target, strlen($folder));
|
||||
$this->files[$target]['permissions'] = $file['permissions'];
|
||||
return $this->files[$target];
|
||||
}
|
||||
} else {
|
||||
$file = OCP\Share::getItemSharedWith('file', $target, OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
if ($file) {
|
||||
$this->files[$target] = $file;
|
||||
return $this->files[$target];
|
||||
}
|
||||
if (!isset($this->files[$target])) {
|
||||
$source = \OC_Share_Backend_File::getSource($target);
|
||||
if ($source) {
|
||||
$source['path'] = '/'.$source['uid_owner'].'/'.$source['path'];
|
||||
}
|
||||
OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, OCP\Util::ERROR);
|
||||
return false;
|
||||
$this->files[$target] = $source;
|
||||
}
|
||||
return $this->files[$target];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the source file path for a shared file
|
||||
* @param string Shared target file path
|
||||
* @return Returns source file path or false if not found
|
||||
* @return string source file path or false if not found
|
||||
*/
|
||||
private function getSourcePath($target) {
|
||||
$file = $this->getFile($target);
|
||||
if (isset($file['path'])) {
|
||||
$uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1);
|
||||
OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => OC_User::getHome($uid)), $uid);
|
||||
return $file['path'];
|
||||
$source = $this->getFile($target);
|
||||
if ($source) {
|
||||
\OC\Files\Filesystem::initMountPoints($source['uid_owner']);
|
||||
return $source['path'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -87,61 +71,42 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
/**
|
||||
* @brief Get the permissions granted for a shared file
|
||||
* @param string Shared target file path
|
||||
* @return Returns CRUDS permissions granted or false if not found
|
||||
* @return int CRUDS permissions granted or false if not found
|
||||
*/
|
||||
private function getPermissions($target) {
|
||||
$file = $this->getFile($target);
|
||||
if (isset($file['permissions'])) {
|
||||
return $file['permissions'];
|
||||
public function getPermissions($target) {
|
||||
$source = $this->getFile($target);
|
||||
if ($source) {
|
||||
return $source['permissions'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the internal path to pass to the storage filesystem call
|
||||
* @param string Source file path
|
||||
* @return Source file path with mount point stripped out
|
||||
*/
|
||||
private function getInternalPath($path) {
|
||||
$mountPoint = OC_Filesystem::getMountPoint($path);
|
||||
$internalPath = substr($path, strlen($mountPoint));
|
||||
return $internalPath;
|
||||
}
|
||||
|
||||
public function getOwner($target) {
|
||||
$shared_item = OCP\Share::getItemSharedWith('folder', $target, OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
if ($shared_item) {
|
||||
return $shared_item[0]["uid_owner"];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) {
|
||||
return false;
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_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_Filesystem::getStorage($source);
|
||||
return $storage->rmdir($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->rmdir($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function opendir($path) {
|
||||
if ($path == '' || $path == '/') {
|
||||
$files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_Folder::FORMAT_OPENDIR);
|
||||
OC_FakeDirStream::$dirs['shared'] = $files;
|
||||
$files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR);
|
||||
\OC\Files\Stream\Dir::register('shared', $files);
|
||||
return opendir('fakedir://shared');
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->opendir($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->opendir($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -150,16 +115,16 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($path == '' || $path == '/') {
|
||||
return true;
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_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_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;
|
||||
}
|
||||
|
@ -168,11 +133,10 @@ class OC_Filestorage_Shared extends OC_Filestorage_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)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->stat($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->stat($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -181,8 +145,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($path == '' || $path == '/') {
|
||||
return 'dir';
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->filetype($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->filetype($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -191,8 +155,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($path == '' || $path == '/' || $this->is_dir($path)) {
|
||||
return 0;
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->filesize($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->filesize($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -201,7 +165,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($path == '') {
|
||||
return false;
|
||||
}
|
||||
return ($this->getPermissions($path) & OCP\PERMISSION_CREATE);
|
||||
return ($this->getPermissions($path) & \OCP\PERMISSION_CREATE);
|
||||
}
|
||||
|
||||
public function isReadable($path) {
|
||||
|
@ -212,54 +176,33 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($path == '') {
|
||||
return false;
|
||||
}
|
||||
return ($this->getPermissions($path) & OCP\PERMISSION_UPDATE);
|
||||
return ($this->getPermissions($path) & \OCP\PERMISSION_UPDATE);
|
||||
}
|
||||
|
||||
public function isDeletable($path) {
|
||||
if ($path == '') {
|
||||
return true;
|
||||
}
|
||||
return ($this->getPermissions($path) & OCP\PERMISSION_DELETE);
|
||||
return ($this->getPermissions($path) & \OCP\PERMISSION_DELETE);
|
||||
}
|
||||
|
||||
public function isSharable($path) {
|
||||
if ($path == '') {
|
||||
return false;
|
||||
}
|
||||
return ($this->getPermissions($path) & OCP\PERMISSION_SHARE);
|
||||
return ($this->getPermissions($path) & \OCP\PERMISSION_SHARE);
|
||||
}
|
||||
|
||||
public function file_exists($path) {
|
||||
if ($path == '' || $path == '/') {
|
||||
return true;
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_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;
|
||||
}
|
||||
|
||||
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) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->filectime($this->getInternalPath($source));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function filemtime($path) {
|
||||
if ($path == '' || $path == '/') {
|
||||
$mtime = 0;
|
||||
|
@ -275,8 +218,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
} else {
|
||||
$source = $this->getSourcePath($path);
|
||||
if ($source) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->filemtime($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->filemtime($internalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,9 +231,9 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
'target' => $this->sharedFolder.$path,
|
||||
'source' => $source,
|
||||
);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_get_contents', $info);
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->file_get_contents($this->getInternalPath($source));
|
||||
\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info);
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->file_get_contents($internalPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,9 +247,9 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
'target' => $this->sharedFolder.$path,
|
||||
'source' => $source,
|
||||
);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
$result = $storage->file_put_contents($this->getInternalPath($source), $data);
|
||||
\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info);
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
$result = $storage->file_put_contents($internalPath, $data);
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
|
@ -316,8 +259,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
// Delete the file if DELETE permission is granted
|
||||
if ($source = $this->getSourcePath($path)) {
|
||||
if ($this->isDeletable($path)) {
|
||||
$storage = OC_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)) {
|
||||
|
@ -325,7 +268,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
} else {
|
||||
$itemType = 'file';
|
||||
}
|
||||
return OCP\Share::unshareFromSelf($itemType, $path);
|
||||
return \OCP\Share::unshareFromSelf($itemType, $path);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -340,8 +283,9 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if (dirname($path1) == dirname($path2)) {
|
||||
// Rename the file if UPDATE permission is granted
|
||||
if ($this->isUpdatable($path1)) {
|
||||
$storage = OC_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
|
||||
|
@ -355,8 +299,9 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
return $this->unlink($path1);
|
||||
}
|
||||
} else {
|
||||
$storage = OC_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +314,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
if ($this->isCreatable(dirname($path2))) {
|
||||
$source = $this->fopen($path1, 'r');
|
||||
$target = $this->fopen($path2, 'w');
|
||||
return OC_Helper::streamCopy($source, $target);
|
||||
return \OC_Helper::streamCopy($source, $target);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -400,9 +345,9 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
'source' => $source,
|
||||
'mode' => $mode,
|
||||
);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'fopen', $info);
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->fopen($this->getInternalPath($source), $mode);
|
||||
\OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info);
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->fopen($internalPath, $mode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -412,47 +357,88 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
|||
return 'httpd/unix-directory';
|
||||
}
|
||||
if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->getMimeType($this->getInternalPath($source));
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->getMimeType($internalPath);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function free_space($path) {
|
||||
if ($path == '') {
|
||||
return -1;
|
||||
}
|
||||
$source = $this->getSourcePath($path);
|
||||
if ($source) {
|
||||
$storage = OC_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_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_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;
|
||||
}
|
||||
|
||||
public static function setup($options) {
|
||||
$user_dir = $options['user_dir'];
|
||||
OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/');
|
||||
if (\OCP\Share::getItemsSharedWith('file')) {
|
||||
$user_dir = $options['user_dir'];
|
||||
\OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file or folder has been updated since $time
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUpdated($path, $time) {
|
||||
//TODO
|
||||
if ($path == '') {
|
||||
return false;
|
||||
}
|
||||
return $this->filemtime($path) > $time;
|
||||
}
|
||||
|
||||
public function getCache($path = '') {
|
||||
return new \OC\Files\Cache\Shared_Cache($this);
|
||||
}
|
||||
|
||||
public function getScanner($path = '') {
|
||||
return new \OC\Files\Cache\Scanner($this);
|
||||
}
|
||||
|
||||
public function getPermissionsCache($path = '') {
|
||||
return new \OC\Files\Cache\Shared_Permissions($this);
|
||||
}
|
||||
|
||||
public function getWatcher($path = '') {
|
||||
return new \OC\Files\Cache\Shared_Watcher($this);
|
||||
}
|
||||
|
||||
public function getOwner($path) {
|
||||
if ($path == '') {
|
||||
return false;
|
||||
}
|
||||
$source = $this->getFile($path);
|
||||
if ($source) {
|
||||
return $source['uid_owner'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getETag($path) {
|
||||
if ($path == '') {
|
||||
return parent::getETag($path);
|
||||
}
|
||||
if ($source = $this->getSourcePath($path)) {
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source);
|
||||
return $storage->getETag($internalPath);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache;
|
||||
|
||||
/**
|
||||
* check the storage backends for updates and change the cache accordingly
|
||||
*/
|
||||
class Shared_Watcher extends Watcher {
|
||||
|
||||
/**
|
||||
* check $path for updates
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function checkUpdate($path) {
|
||||
if ($path != '') {
|
||||
parent::checkUpdate($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove deleted files in $path from the cache
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function cleanFolder($path) {
|
||||
if ($path != '') {
|
||||
parent::cleanFolder($path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -9,9 +9,10 @@ if (isset($_GET['token'])) {
|
|||
unset($_GET['file']);
|
||||
$qry = \OC_DB::prepare('SELECT `source` FROM `*PREFIX*sharing` WHERE `target` = ?', 1);
|
||||
$filepath = $qry->execute(array($_GET['token']))->fetchOne();
|
||||
if(isset($filepath)) {
|
||||
$info = OC_FileCache_Cached::get($filepath, '');
|
||||
if(strtolower($info['mimetype']) == 'httpd/unix-directory') {
|
||||
if (isset($filepath)) {
|
||||
$rootView = new \OC\Files\View('');
|
||||
$info = $rootView->getFileInfo($filepath, '');
|
||||
if (strtolower($info['mimetype']) == 'httpd/unix-directory') {
|
||||
$_GET['dir'] = $filepath;
|
||||
} else {
|
||||
$_GET['file'] = $filepath;
|
||||
|
@ -25,7 +26,7 @@ if (isset($_GET['token'])) {
|
|||
function getID($path) {
|
||||
// use the share table from the db to find the item source if the file was reshared because shared files
|
||||
//are not stored in the file cache.
|
||||
if (substr(OC_Filesystem::getMountPoint($path), -7, 6) == "Shared") {
|
||||
if (substr(\OC\Files\Filesystem::getMountPoint($path), -7, 6) == "Shared") {
|
||||
$path_parts = explode('/', $path, 5);
|
||||
$user = $path_parts[1];
|
||||
$intPath = '/'.$path_parts[4];
|
||||
|
@ -37,16 +38,19 @@ function getID($path) {
|
|||
$row = $result->fetchRow();
|
||||
$fileSource = $row['item_source'];
|
||||
} else {
|
||||
$fileSource = OC_Filecache::getId($path, '');
|
||||
$rootView = new \OC\Files\View('');
|
||||
$meta = $rootView->getFileInfo($path);
|
||||
$fileSource = $meta['fileid'];
|
||||
}
|
||||
|
||||
return $fileSource;
|
||||
}
|
||||
|
||||
// Enf of backward compatibility
|
||||
|
||||
/**
|
||||
* lookup file path and owner by fetching it from the fscache
|
||||
* needed becaus OC_FileCache::getPath($id, $user) already requires the user
|
||||
* needed because OC_FileCache::getPath($id, $user) already requires the user
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
|
@ -86,41 +90,43 @@ if (isset($_GET['t'])) {
|
|||
OC_Util::setupFS($fileOwner);
|
||||
}
|
||||
}
|
||||
} else if (isset($_GET['file']) || isset($_GET['dir'])) {
|
||||
OCP\Util::writeLog('share', 'Missing token, trying fallback file/dir links', \OCP\Util::DEBUG);
|
||||
if (isset($_GET['dir'])) {
|
||||
$type = 'folder';
|
||||
$path = $_GET['dir'];
|
||||
if(strlen($path)>1 and substr($path, -1, 1)==='/') {
|
||||
$path=substr($path, 0, -1);
|
||||
} else {
|
||||
if (isset($_GET['file']) || isset($_GET['dir'])) {
|
||||
OCP\Util::writeLog('share', 'Missing token, trying fallback file/dir links', \OCP\Util::DEBUG);
|
||||
if (isset($_GET['dir'])) {
|
||||
$type = 'folder';
|
||||
$path = $_GET['dir'];
|
||||
if (strlen($path) > 1 and substr($path, -1, 1) === '/') {
|
||||
$path = substr($path, 0, -1);
|
||||
}
|
||||
$baseDir = $path;
|
||||
$dir = $baseDir;
|
||||
} else {
|
||||
$type = 'file';
|
||||
$path = $_GET['file'];
|
||||
if (strlen($path) > 1 and substr($path, -1, 1) === '/') {
|
||||
$path = substr($path, 0, -1);
|
||||
}
|
||||
}
|
||||
$baseDir = $path;
|
||||
$dir = $baseDir;
|
||||
} else {
|
||||
$type = 'file';
|
||||
$path = $_GET['file'];
|
||||
if(strlen($path)>1 and substr($path, -1, 1)==='/') {
|
||||
$path=substr($path, 0, -1);
|
||||
}
|
||||
}
|
||||
$shareOwner = substr($path, 1, strpos($path, '/', 1) - 1);
|
||||
$shareOwner = substr($path, 1, strpos($path, '/', 1) - 1);
|
||||
|
||||
if (OCP\User::userExists($shareOwner)) {
|
||||
OC_Util::setupFS($shareOwner);
|
||||
$fileSource = getId($path);
|
||||
if ($fileSource != -1 ) {
|
||||
$linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $shareOwner);
|
||||
$pathAndUser['path'] = $path;
|
||||
$path_parts = explode('/', $path, 5);
|
||||
$pathAndUser['user'] = $path_parts[1];
|
||||
$fileOwner = $path_parts[1];
|
||||
if (OCP\User::userExists($shareOwner)) {
|
||||
OC_Util::setupFS($shareOwner);
|
||||
$fileSource = getId($path);
|
||||
if ($fileSource != -1) {
|
||||
$linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $shareOwner);
|
||||
$pathAndUser['path'] = $path;
|
||||
$path_parts = explode('/', $path, 5);
|
||||
$pathAndUser['user'] = $path_parts[1];
|
||||
$fileOwner = $path_parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($linkItem) {
|
||||
if (!isset($linkItem['item_type'])) {
|
||||
OCP\Util::writeLog('share', 'No item type set for share id: '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
|
@ -128,11 +134,13 @@ if ($linkItem) {
|
|||
}
|
||||
if (isset($linkItem['share_with'])) {
|
||||
// Authenticate share_with
|
||||
$url = OCP\Util::linkToPublic('files').'&t='.$token;
|
||||
$url = OCP\Util::linkToPublic('files') . '&t=' . $token;
|
||||
if (isset($_GET['file'])) {
|
||||
$url .= '&file='.urlencode($_GET['file']);
|
||||
} else if (isset($_GET['dir'])) {
|
||||
$url .= '&dir='.urlencode($_GET['dir']);
|
||||
$url .= '&file=' . urlencode($_GET['file']);
|
||||
} else {
|
||||
if (isset($_GET['dir'])) {
|
||||
$url .= '&dir=' . urlencode($_GET['dir']);
|
||||
}
|
||||
}
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
|
@ -173,13 +181,13 @@ if ($linkItem) {
|
|||
}
|
||||
}
|
||||
}
|
||||
$basePath = substr($pathAndUser['path'], strlen('/'.$fileOwner.'/files'));
|
||||
$basePath = substr($pathAndUser['path'], strlen('/' . $fileOwner . '/files'));
|
||||
$path = $basePath;
|
||||
if (isset($_GET['path'])) {
|
||||
$path .= $_GET['path'];
|
||||
}
|
||||
if (!$path || !OC_Filesystem::isValidPath($path) || !OC_Filesystem::file_exists($path)) {
|
||||
OCP\Util::writeLog('share', 'Invalid path '.$path.' for share id '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
if (!$path || !\OC\Files\Filesystem::isValidPath($path) || !\OC\Files\Filesystem::file_exists($path)) {
|
||||
OCP\Util::writeLog('share', 'Invalid path ' . $path . ' for share id ' . $linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
|
@ -189,13 +197,15 @@ if ($linkItem) {
|
|||
$file = basename($path);
|
||||
// Download the file
|
||||
if (isset($_GET['download'])) {
|
||||
if (isset($_GET['path']) && $_GET['path'] !== '' ) {
|
||||
if ( isset($_GET['files']) ) { // download selected files
|
||||
if (isset($_GET['path']) && $_GET['path'] !== '') {
|
||||
if (isset($_GET['files'])) { // download selected files
|
||||
OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else if (isset($_GET['path']) && $_GET['path'] != '' ) { // download a file from a shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else { // download the whole shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else {
|
||||
if (isset($_GET['path']) && $_GET['path'] != '') { // download a file from a shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else { // download the whole shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
}
|
||||
} else { // download a single shared file
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
|
@ -210,7 +220,7 @@ if ($linkItem) {
|
|||
$tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner));
|
||||
$tmpl->assign('dir', $dir);
|
||||
$tmpl->assign('filename', $file);
|
||||
$tmpl->assign('mimetype', OC_Filesystem::getMimeType($path));
|
||||
$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
|
||||
if (isset($_GET['path'])) {
|
||||
$getPath = $_GET['path'];
|
||||
} else {
|
||||
|
@ -221,7 +231,7 @@ if ($linkItem) {
|
|||
.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'')
|
||||
.(isset($_GET['file'])?'&file='.$_GET['file']:'');
|
||||
// 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');
|
||||
|
@ -232,9 +242,9 @@ if ($linkItem) {
|
|||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : '';
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.' . $fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = '/'.substr($i['directory'], $rootLength);
|
||||
$i['directory'] = '/' . substr($i['directory'], $rootLength);
|
||||
if ($i['directory'] == '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
|
@ -251,9 +261,137 @@ if ($linkItem) {
|
|||
//add subdir breadcrumbs
|
||||
foreach (explode('/', urldecode($getPath)) as $i) {
|
||||
if ($i != '') {
|
||||
$pathtohere .= '/'.$i;
|
||||
$pathtohere .= '/' . $i;
|
||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $i);
|
||||
$path = $linkItem['path'];
|
||||
if (isset($_GET['path'])) {
|
||||
$path .= $_GET['path'];
|
||||
$dir .= $_GET['path'];
|
||||
if (!\OC\Files\Filesystem::file_exists($path)) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('publicListView', true);
|
||||
$list->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=', false);
|
||||
$list->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=', false);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=', false);
|
||||
$folder = new OCP\Template('files', 'index', '');
|
||||
$folder->assign('fileList', $list->fetchPage(), false);
|
||||
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
||||
$folder->assign('isCreatable', false);
|
||||
$folder->assign('permissions', 0);
|
||||
$folder->assign('files', $files);
|
||||
$folder->assign('uploadMaxFilesize', 0);
|
||||
$folder->assign('uploadMaxHumanFilesize', 0);
|
||||
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('folder', $folder->fetchPage(), false);
|
||||
$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath));
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
if ($type == 'file') {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download');
|
||||
} else {
|
||||
OCP\Util::addStyle('files_sharing', 'public');
|
||||
OCP\Util::addScript('files_sharing', 'public');
|
||||
OCP\Util::addScript('files', 'fileactions');
|
||||
$tmpl = new OCP\Template('files_sharing', 'public', 'base');
|
||||
$tmpl->assign('owner', $uidOwner);
|
||||
// Show file list
|
||||
if (\OC\Files\Filesystem::is_dir($path)) {
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addScript('files', 'files');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
$files = array();
|
||||
$rootLength = strlen($baseDir) + 1;
|
||||
foreach (OC_Files::getDirectoryContent($path) as $i) {
|
||||
$i['date'] = OCP\Util::formatDate($i['mtime']);
|
||||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.' . $fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = '/' . substr('/' . $uidOwner . '/files' . $i['directory'], $rootLength);
|
||||
if ($i['directory'] == '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
$i['permissions'] = OCP\PERMISSION_READ;
|
||||
$files[] = $i;
|
||||
}
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
$count = 1;
|
||||
foreach (explode('/', $dir) as $i) {
|
||||
if ($i != '') {
|
||||
if ($i != $baseDir) {
|
||||
$pathtohere .= '/' . $i;
|
||||
}
|
||||
if (strlen($pathtohere) < strlen($_GET['dir'])) {
|
||||
continue;
|
||||
}
|
||||
$breadcrumb[] = array('dir' => str_replace($_GET['dir'], "", $pathtohere, $count), 'name' => $i);
|
||||
}
|
||||
}
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('publicListView', true);
|
||||
$list->assign('baseURL', OCP\Util::linkToPublic('files') . '&dir=' . urlencode($_GET['dir']) . '&path=', false);
|
||||
$list->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=', false);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . '&dir=' . urlencode($_GET['dir']) . '&path=', false);
|
||||
$folder = new OCP\Template('files', 'index', '');
|
||||
$folder->assign('fileList', $list->fetchPage(), false);
|
||||
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
||||
$folder->assign('dir', basename($dir));
|
||||
$folder->assign('isCreatable', false);
|
||||
$folder->assign('permissions', 0);
|
||||
$folder->assign('files', $files);
|
||||
$folder->assign('uploadMaxFilesize', 0);
|
||||
$folder->assign('uploadMaxHumanFilesize', 0);
|
||||
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('folder', $folder->fetchPage(), false);
|
||||
$tmpl->assign('uidOwner', $uidOwner);
|
||||
$tmpl->assign('dir', basename($dir));
|
||||
$tmpl->assign('filename', basename($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'];
|
||||
} else {
|
||||
$getPath = '';
|
||||
}
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=' . urlencode($getPath), false);
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
$tmpl->assign('uidOwner', $uidOwner);
|
||||
$tmpl->assign('dir', dirname($path));
|
||||
$tmpl->assign('filename', basename($path));
|
||||
$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
|
||||
if ($type == 'file') {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&file=' . urlencode($_GET['file']) . '&download', false);
|
||||
} else {
|
||||
if (isset($_GET['path'])) {
|
||||
$getPath = $_GET['path'];
|
||||
} else {
|
||||
$getPath = '';
|
||||
}
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=' . urlencode($getPath), false);
|
||||
}
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
|
@ -279,21 +417,11 @@ if ($linkItem) {
|
|||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files')
|
||||
.$urlLinkIdentifiers.'&download&path='.urlencode($getPath));
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
if ($type == 'file') {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files')
|
||||
.$urlLinkIdentifiers.'&download');
|
||||
} else {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files')
|
||||
.$urlLinkIdentifiers.'&download&path='.urlencode($getPath));
|
||||
}
|
||||
OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG);
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG);
|
||||
}
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<name>Versions</name>
|
||||
<licence>AGPL</licence>
|
||||
<author>Frank Karlitschek</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<description>Versioning of files</description>
|
||||
<types>
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
@ -39,15 +39,15 @@ class Hooks {
|
|||
* cleanup the versions directory if the actual file gets deleted
|
||||
*/
|
||||
public static function remove_hook($params) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
|
||||
$versions = new Storage( new \OC_FilesystemView('') );
|
||||
|
||||
$path = $params[\OC_Filesystem::signal_param_path];
|
||||
|
||||
if($path<>'') $versions->delete( $path );
|
||||
|
||||
}
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
|
||||
$versions = new Storage( new \OC_FilesystemView('') );
|
||||
|
||||
$path = $params[\OC\Files\Filesystem::signal_param_path];
|
||||
|
||||
if($path<>'') $versions->delete( $path );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,15 +58,15 @@ class Hooks {
|
|||
* of the stored versions along the actual file
|
||||
*/
|
||||
public static function rename_hook($params) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
|
||||
$versions = new Storage( new \OC_FilesystemView('') );
|
||||
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
|
||||
$versions = new Storage( new \OC_FilesystemView('') );
|
||||
|
||||
$oldpath = $params['oldpath'];
|
||||
$newpath = $params['newpath'];
|
||||
|
||||
if($oldpath<>'' && $newpath<>'') $versions->rename( $oldpath, $newpath );
|
||||
|
||||
$newpath = $params['newpath'];
|
||||
|
||||
if($oldpath<>'' && $newpath<>'') $versions->rename( $oldpath, $newpath );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ class Storage {
|
|||
private static $max_versions_per_interval = array(
|
||||
1 => array('intervalEndsAfter' => 10, //first 10sec, one version every 2sec
|
||||
'step' => 2),
|
||||
2 => array('intervalEndsAfter' => 60, //next minute, one version every 10sec
|
||||
2 => array('intervalEndsAfter' => 60, //next minute, one version every 10sec
|
||||
'step' => 10),
|
||||
3 => array('intervalEndsAfter' => 3600, //next hour, one version every minute
|
||||
'step' => 60),
|
||||
4 => array('intervalEndsAfter' => 86400, //next 24h, one version every hour
|
||||
'step' => 3600),
|
||||
5 => array('intervalEndsAfter' => 2592000, //next 30days, one version per day
|
||||
5 => array('intervalEndsAfter' => 2592000, //next 30days, one version per day
|
||||
'step' => 86400),
|
||||
6 => array('intervalEndsAfter' => -1, //until the end one version per week
|
||||
6 => array('intervalEndsAfter' => -1, //until the end one version per week
|
||||
'step' => 604800),
|
||||
);
|
||||
|
||||
|
@ -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('/'.\OCP\User::getUser() .'/files');
|
||||
$users_view = new \OC\Files\View('/'.\OCP\User::getUser());
|
||||
|
||||
//check if source file already exist as version to avoid recursions.
|
||||
// todo does this check work?
|
||||
|
@ -86,8 +86,8 @@ class Storage {
|
|||
|
||||
// store a new version of a file
|
||||
$result = $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
|
||||
if ( ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
|
||||
$versionsSize = self::calculateSize($uid);
|
||||
if ( ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
|
||||
$versionsSize = self::calculateSize($uid);
|
||||
}
|
||||
$versionsSize += $users_view->filesize('files'.$filename);
|
||||
|
||||
|
@ -105,42 +105,42 @@ class Storage {
|
|||
* Delete versions of a file
|
||||
*/
|
||||
public static function delete($filename) {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid .'/files_versions');
|
||||
|
||||
$abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$filename.'.v';
|
||||
if( ($versions = self::getVersions($filename)) ) {
|
||||
if ( ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
|
||||
$versionsSize = self::calculateSize($uid);
|
||||
}
|
||||
foreach ($versions as $v) {
|
||||
unlink($abs_path . $v['version']);
|
||||
$versionsSize -= $v['size'];
|
||||
}
|
||||
\OCP\Config::setAppValue('files_versions', 'size', $versionsSize);
|
||||
|
||||
$abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$filename.'.v';
|
||||
if( ($versions = self::getVersions($filename)) ) {
|
||||
if ( ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
|
||||
$versionsSize = self::calculateSize($uid);
|
||||
}
|
||||
foreach ($versions as $v) {
|
||||
unlink($abs_path . $v['version']);
|
||||
$versionsSize -= $v['size'];
|
||||
}
|
||||
\OCP\Config::setAppValue('files_versions', 'size', $versionsSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rename versions of a file
|
||||
*/
|
||||
public static function rename($oldpath, $newpath) {
|
||||
/**
|
||||
* rename versions of a file
|
||||
*/
|
||||
public static function rename($oldpath, $newpath) {
|
||||
list($uid, $oldpath) = self::getUidAndFilename($oldpath);
|
||||
list($uidn, $newpath) = self::getUidAndFilename($newpath);
|
||||
list($uidn, $newpath) = self::getUidAndFilename($newpath);
|
||||
$versions_view = new \OC_FilesystemView('/'.$uid .'/files_versions');
|
||||
$files_view = new \OC_FilesystemView('/'.$uid .'/files');
|
||||
$abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_view->getAbsolutePath('').$newpath;
|
||||
|
||||
$abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_view->getAbsolutePath('').$newpath;
|
||||
|
||||
if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
|
||||
$versions_view->rename($oldpath, $newpath);
|
||||
} else if ( ($versions = Storage::getVersions($oldpath)) ) {
|
||||
$info=pathinfo($abs_newpath);
|
||||
if(!file_exists($info['dirname'])) mkdir($info['dirname'], 0750, true);
|
||||
$versions = Storage::getVersions($oldpath);
|
||||
} else if ( ($versions = Storage::getVersions($oldpath)) ) {
|
||||
$info=pathinfo($abs_newpath);
|
||||
if(!file_exists($info['dirname'])) mkdir($info['dirname'], 0750, true);
|
||||
$versions = Storage::getVersions($oldpath);
|
||||
foreach ($versions as $v) {
|
||||
$versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
|
||||
}
|
||||
}
|
||||
$versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +150,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);
|
||||
$versionCreated = false;
|
||||
|
||||
//first create a new version
|
||||
|
@ -184,7 +184,7 @@ class Storage {
|
|||
public static function getVersions( $filename, $count = 0 ) {
|
||||
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('/' . \OCP\User::getUser() . '/files_versions');
|
||||
|
||||
$versionsName = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
|
||||
$versions = array();
|
||||
|
@ -202,7 +202,7 @@ class Storage {
|
|||
$key = $version.'#'.$filename;
|
||||
$versions[$key]['cur'] = 0;
|
||||
$versions[$key]['version'] = $version;
|
||||
$versions[$key]['path'] = $filename;
|
||||
$versions[$key]['path'] = $filename;
|
||||
$versions[$key]['size'] = $versions_fileview->filesize($filename.'.v'.$version);
|
||||
|
||||
// if file with modified date exists, flag it in array as currently enabled version
|
||||
|
@ -236,29 +236,29 @@ class Storage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the size of all stored versions from a given user
|
||||
* @param $uid id from the user
|
||||
* @return size of vesions
|
||||
*/
|
||||
private static function calculateSize($uid) {
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
$versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
/**
|
||||
* @brief get the size of all stored versions from a given user
|
||||
* @param $uid id from the user
|
||||
* @return size of vesions
|
||||
*/
|
||||
private static function calculateSize($uid) {
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
$versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
$size = 0;
|
||||
|
||||
foreach ($iterator as $path) {
|
||||
if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) {
|
||||
|
||||
foreach ($iterator as $path) {
|
||||
if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) {
|
||||
$relpath = substr($path, strlen($versionsRoot)-1);
|
||||
$size += $versions_fileview->filesize($relpath);
|
||||
}
|
||||
$size += $versions_fileview->filesize($relpath);
|
||||
}
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,11 +267,11 @@ class Storage {
|
|||
* @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename
|
||||
*/
|
||||
private static function getAllVersions($uid) {
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
$versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
$versions = array();
|
||||
|
||||
|
@ -280,7 +280,7 @@ class Storage {
|
|||
$relpath = substr($path, strlen($versionsRoot)-1);
|
||||
$versions[$match[1].'#'.$relpath] = array('path' => $relpath, 'timestamp' => $match[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($versions);
|
||||
|
||||
|
@ -288,20 +288,20 @@ class Storage {
|
|||
|
||||
$result = array();
|
||||
|
||||
foreach( $versions as $key => $value ) {
|
||||
foreach( $versions as $key => $value ) {
|
||||
$i++;
|
||||
$size = $versions_fileview->filesize($value['path']);
|
||||
$filename = substr($value['path'], 0, -strlen($value['timestamp'])-2);
|
||||
|
||||
|
||||
$result['all'][$key]['version'] = $value['timestamp'];
|
||||
$result['all'][$key]['path'] = $filename;
|
||||
$result['all'][$key]['path'] = $filename;
|
||||
$result['all'][$key]['size'] = $size;
|
||||
|
||||
$filename = substr($value['path'], 0, -strlen($value['timestamp'])-2);
|
||||
$result['by_file'][$filename][$key]['version'] = $value['timestamp'];
|
||||
$result['by_file'][$filename][$key]['path'] = $filename;
|
||||
$result['by_file'][$filename][$key]['path'] = $filename;
|
||||
$result['by_file'][$filename][$key]['size'] = $size;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -322,7 +322,7 @@ class Storage {
|
|||
$quota = \OCP\Util::computerFileSize(\OC_Appconfig::getValue('files', 'default_quota'));
|
||||
}
|
||||
if ( $quota == null ) {
|
||||
$quota = \OC_Filesystem::free_space('/');
|
||||
$quota = \OC\Files\Filesystem::free_space('/');
|
||||
}
|
||||
|
||||
// make sure that we have the current size of the version history
|
||||
|
@ -332,7 +332,7 @@ class Storage {
|
|||
}
|
||||
}
|
||||
|
||||
// calculate available space for version history
|
||||
// calculate available space for version history
|
||||
$rootInfo = \OC_FileCache::get('', '/'. $uid . '/files');
|
||||
$free = $quota-$rootInfo['size']; // remaining free space for user
|
||||
if ( $free > 0 ) {
|
||||
|
@ -394,7 +394,7 @@ class Storage {
|
|||
$nextVersion = $prevTimestamp - $step;
|
||||
if ( Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1 ) {
|
||||
$nextInterval = -1;
|
||||
} else {
|
||||
} else {
|
||||
$nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'];
|
||||
}
|
||||
$newInterval = true; // we changed the interval -> check same version with new interval
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
This app is not compatible to the WebDAV user backend.</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Dominik Schmidt and Arthur Schiwon</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<types>
|
||||
<authentication/>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
This app is not compatible to the LDAP user and group backend.</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Frank Karlitschek</author>
|
||||
<require>4.9</require>
|
||||
<require>4.91</require>
|
||||
<shipped>true</shipped>
|
||||
<types>
|
||||
<authentication/>
|
||||
|
|
296
db_structure.xml
296
db_structure.xml
|
@ -60,16 +60,96 @@
|
|||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*fscache</name>
|
||||
<name>*dbprefix*storages</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>id</name>
|
||||
<autoincrement>1</autoincrement>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>numeric_id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>storages_id_index</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>id</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*mimetypes</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mimetype</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>mimetype_id_index</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>mimetype</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*filecache</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>fileid</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>storage</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
|
@ -92,9 +172,9 @@
|
|||
<field>
|
||||
<name>parent</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
|
@ -102,7 +182,122 @@
|
|||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>300</length>
|
||||
<length>250</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mimetype</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mimepart</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>size</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mtime</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>encrypted</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>etag</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>40</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>fs_storage_path_hash</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>storage</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>path_hash</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>fs_parent_name_hash</name>
|
||||
<field>
|
||||
<name>parent</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>name</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>fs_storage_mimetype</name>
|
||||
<field>
|
||||
<name>storage</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>mimetype</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>fs_storage_mimepart</name>
|
||||
<field>
|
||||
<name>storage</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>mimepart</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*permissions</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>fileid</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
|
@ -114,101 +309,22 @@
|
|||
</field>
|
||||
|
||||
<field>
|
||||
<name>size</name>
|
||||
<name>permissions</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>ctime</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mtime</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>8</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mimetype</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>96</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>mimepart</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>32</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>encrypted</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>1</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>versioned</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>1</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>writable</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<length>1</length>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>fscache_path_hash_index</name>
|
||||
<name>id_user_index</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>path_hash</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>parent_index</name>
|
||||
<field>
|
||||
<name>parent</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>name_index</name>
|
||||
<field>
|
||||
<name>name</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
||||
<index>
|
||||
<name>parent_name_index</name>
|
||||
<field>
|
||||
<name>parent</name>
|
||||
<name>fileid</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
<field>
|
||||
<name>name</name>
|
||||
<name>user</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
|
|
|
@ -803,16 +803,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 '.$appid.', user not logged in', OC_Log::ERROR);
|
||||
return false;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
10
lib/base.php
10
lib/base.php
|
@ -112,6 +112,8 @@ class OC
|
|||
$path = str_replace('\\', '/', $className) . '.php';
|
||||
} elseif (strpos($className, 'Test_') === 0) {
|
||||
$path = 'tests/lib/' . strtolower(str_replace('_', '/', substr($className, 5)) . '.php');
|
||||
} elseif (strpos($className, 'Test\\') === 0) {
|
||||
$path = 'tests/lib/' . strtolower(str_replace('\\', '/', substr($className, 5)) . '.php');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -420,10 +422,10 @@ 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');
|
||||
stream_wrapper_register('oc', 'OC\Files\Stream\OC');
|
||||
|
||||
self::checkConfig();
|
||||
self::checkInstalled();
|
||||
|
|
|
@ -15,11 +15,11 @@ class OC_Cache_File{
|
|||
}
|
||||
if(OC_User::isLoggedIn()) {
|
||||
$subdir = 'cache';
|
||||
$view = new OC_FilesystemView('/'.OC_User::getUser());
|
||||
$view = new \OC\Files\View('/'.OC_User::getUser());
|
||||
if(!$view->file_exists($subdir)) {
|
||||
$view->mkdir($subdir);
|
||||
}
|
||||
$this->storage = new OC_FilesystemView('/'.OC_User::getUser().'/'.$subdir);
|
||||
$this->storage = new \OC\Files\View('/'.OC_User::getUser().'/'.$subdir);
|
||||
return $this->storage;
|
||||
}else{
|
||||
OC_Log::write('core', 'Can\'t get cache storage, user not logged in', OC_Log::ERROR);
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -116,12 +116,13 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
|||
* @return Sabre_DAV_INode[]
|
||||
*/
|
||||
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'];
|
||||
$properties[$this->path.'/'.$info['name']][self::GETETAG_PROPERTYNAME] = $info['etag'];
|
||||
}
|
||||
$properties = array_fill_keys($paths, array());
|
||||
if(count($paths)>0) {
|
||||
//
|
||||
// the number of arguments within IN conditions are limited in most databases
|
||||
|
@ -160,7 +161,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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -173,7 +174,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -184,10 +185,10 @@ 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_Filesystem::free_space()
|
||||
\OC\Files\Filesystem::free_space()
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -98,16 +98,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
|
|||
if (isset($properties[self::GETETAG_PROPERTYNAME])) {
|
||||
return $properties[self::GETETAG_PROPERTYNAME];
|
||||
}
|
||||
return $this->getETagPropertyForPath($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
return OC_Filesystem::hash('md5', $path);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +113,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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,12 @@ 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;
|
||||
|
||||
$query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ? WHERE `userid` = ? AND `propertypath` = ?' );
|
||||
$query->execute( array( $newPath, OC_User::getUser(), $oldPath ));
|
||||
$query->execute( array( $newPath,OC_User::getUser(), $oldPath ));
|
||||
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,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::getFileInfo($this->path)) {
|
||||
} else {
|
||||
$fileinfo_cache = OC_Filesystem::stat($this->path);
|
||||
$fileinfo_cache = \OC\Files\Filesystem::stat($this->path);
|
||||
}
|
||||
|
||||
$this->fileinfo_cache = $fileinfo_cache;
|
||||
|
@ -134,7 +134,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,10 +159,10 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
|||
} else {
|
||||
if(!array_key_exists( $propertyName, $existing )) {
|
||||
$query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
|
||||
$query->execute( array( OC_User::getUser(), $this->path, $propertyName, $propertyValue ));
|
||||
$query->execute( array( OC_User::getUser(), $this->path, $propertyName,$propertyValue ));
|
||||
} else {
|
||||
$query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ? WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
|
||||
$query->execute( array( $propertyValue, OC_User::getUser(), $this->path, $propertyName ));
|
||||
$query->execute( array( $propertyValue,OC_User::getUser(), $this->path, $propertyName ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
|||
while( $row = $result->fetchRow()) {
|
||||
$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
|
||||
}
|
||||
$this->property_cache[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path);
|
||||
}
|
||||
|
||||
// if the array was empty, we need to return everything
|
||||
|
@ -205,57 +206,16 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the ETag surrounded by double-quotes for this path.
|
||||
* 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);
|
||||
if (empty($tag)) {
|
||||
return null;
|
||||
$data = \OC\Files\Filesystem::getFileInfo($path);
|
||||
if (isset($data['etag'])) {
|
||||
return '"'.$data['etag'].'"';
|
||||
}
|
||||
$etag = '"'.$tag.'"';
|
||||
$query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
|
||||
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag ));
|
||||
return $etag;
|
||||
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 ));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
|
|||
$uri='/'.$uri;
|
||||
}
|
||||
list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri);
|
||||
if ($length > OC_Filesystem::free_space($parentUri)) {
|
||||
if ($length > \OC\Files\Filesystem::free_space($parentUri)) {
|
||||
throw new Sabre_DAV_Exception_InsufficientStorage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,539 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @author Robin Appelman
|
||||
* @copyright 2011 Robin Appelman icewind1991@gmail.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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* provide caching for filesystem info in the database
|
||||
*
|
||||
* not used by OC_Filesystem for reading filesystem info,
|
||||
* instead apps should use OC_FileCache::get where possible
|
||||
*
|
||||
* It will try to keep the data up to date but changes from outside
|
||||
* ownCloud can invalidate the cache
|
||||
*
|
||||
* Methods that take $path and $root params expect $path to be relative, like
|
||||
* /admin/files/file.txt, if $root is false
|
||||
*
|
||||
*/
|
||||
class OC_FileCache{
|
||||
|
||||
/**
|
||||
* get the filesystem info from the cache
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @return array
|
||||
*
|
||||
* returns an associative array with the following keys:
|
||||
* - size
|
||||
* - mtime
|
||||
* - ctime
|
||||
* - mimetype
|
||||
* - encrypted
|
||||
* - versioned
|
||||
*/
|
||||
public static function get($path, $root=false) {
|
||||
if(OC_FileCache_Update::hasUpdated($path, $root)) {
|
||||
if($root===false) {//filesystem hooks are only valid for the default root
|
||||
OC_Hook::emit('OC_Filesystem', 'post_write', array('path'=>$path));
|
||||
}else{
|
||||
OC_FileCache_Update::update($path, $root);
|
||||
}
|
||||
}
|
||||
return OC_FileCache_Cached::get($path, $root);
|
||||
}
|
||||
|
||||
/**
|
||||
* put filesystem info in the cache
|
||||
* @param string $path
|
||||
* @param array data
|
||||
* @param string root (optional)
|
||||
* @note $data is an associative array in the same format as returned
|
||||
* by get
|
||||
*/
|
||||
public static function put($path, $data, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$fullpath=OC_Filesystem::normalizePath($root.'/'.$path);
|
||||
$parent=self::getParentId($fullpath);
|
||||
$id=self::getId($fullpath, '');
|
||||
if(isset(OC_FileCache_Cached::$savedData[$fullpath])) {
|
||||
$data=array_merge(OC_FileCache_Cached::$savedData[$fullpath], $data);
|
||||
unset(OC_FileCache_Cached::$savedData[$fullpath]);
|
||||
}
|
||||
if($id!=-1) {
|
||||
self::update($id, $data);
|
||||
return;
|
||||
}
|
||||
|
||||
// add parent directory to the file cache if it does not exist yet.
|
||||
if ($parent == -1 && $fullpath != $root) {
|
||||
$parentDir = dirname($path);
|
||||
self::scanFile($parentDir);
|
||||
$parent = self::getParentId($fullpath);
|
||||
}
|
||||
|
||||
if(!isset($data['size']) or !isset($data['mtime'])) {//save incomplete data for the next time we write it
|
||||
OC_FileCache_Cached::$savedData[$fullpath]=$data;
|
||||
return;
|
||||
}
|
||||
if(!isset($data['encrypted'])) {
|
||||
$data['encrypted']=false;
|
||||
}
|
||||
if(!isset($data['versioned'])) {
|
||||
$data['versioned']=false;
|
||||
}
|
||||
$mimePart=dirname($data['mimetype']);
|
||||
$data['size']=(int)$data['size'];
|
||||
$data['ctime']=(int)$data['mtime'];
|
||||
$data['writable']=(int)$data['writable'];
|
||||
$data['encrypted']=(int)$data['encrypted'];
|
||||
$data['versioned']=(int)$data['versioned'];
|
||||
$user=OC_User::getUser();
|
||||
$query=OC_DB::prepare('INSERT INTO `*PREFIX*fscache`(`parent`, `name`, `path`, `path_hash`, `size`, `mtime`, `ctime`, `mimetype`, `mimepart`,`user`,`writable`,`encrypted`,`versioned`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
$result=$query->execute(array($parent, basename($fullpath), $fullpath, md5($fullpath), $data['size'], $data['mtime'], $data['ctime'], $data['mimetype'], $mimePart, $user, $data['writable'], $data['encrypted'], $data['versioned']));
|
||||
if(OC_DB::isError($result)) {
|
||||
OC_Log::write('files', 'error while writing file('.$fullpath.') to cache', OC_Log::ERROR);
|
||||
}
|
||||
|
||||
if($cache=OC_Cache::getUserCache(true)) {
|
||||
$cache->remove('fileid/'.$fullpath);//ensure we don't have -1 cached
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update filesystem info of a file
|
||||
* @param int $id
|
||||
* @param array $data
|
||||
*/
|
||||
private static function update($id, $data) {
|
||||
$arguments=array();
|
||||
$queryParts=array();
|
||||
foreach(array('size','mtime','ctime','mimetype','encrypted','versioned', 'writable') as $attribute) {
|
||||
if(isset($data[$attribute])) {
|
||||
//Convert to int it args are false
|
||||
if($data[$attribute] === false) {
|
||||
$arguments[] = 0;
|
||||
}else{
|
||||
$arguments[] = $data[$attribute];
|
||||
}
|
||||
$queryParts[]='`'.$attribute.'`=?';
|
||||
}
|
||||
}
|
||||
if(isset($data['mimetype'])) {
|
||||
$arguments[]=dirname($data['mimetype']);
|
||||
$queryParts[]='`mimepart`=?';
|
||||
}
|
||||
$arguments[]=$id;
|
||||
|
||||
if(!empty($queryParts)) {
|
||||
$sql = 'UPDATE `*PREFIX*fscache` SET '.implode(' , ', $queryParts).' WHERE `id`=?';
|
||||
$query=OC_DB::prepare($sql);
|
||||
$result=$query->execute($arguments);
|
||||
if(OC_DB::isError($result)) {
|
||||
OC_Log::write('files', 'error while updating file('.$id.') in cache', OC_Log::ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* register a file move in the cache
|
||||
* @param string oldPath
|
||||
* @param string newPath
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function move($oldPath, $newPath, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
// If replacing an existing file, delete the file
|
||||
if (self::inCache($newPath, $root)) {
|
||||
self::delete($newPath, $root);
|
||||
}
|
||||
$oldPath=$root.$oldPath;
|
||||
$newPath=$root.$newPath;
|
||||
$newParent=self::getParentId($newPath);
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `parent`=? ,`name`=?, `path`=?, `path_hash`=? WHERE `path_hash`=?');
|
||||
$query->execute(array($newParent, basename($newPath), $newPath, md5($newPath), md5($oldPath)));
|
||||
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)) {
|
||||
$cache->set('fileid/'.$newPath, $cache->get('fileid/'.$oldPath));
|
||||
$cache->remove('fileid/'.$oldPath);
|
||||
}
|
||||
|
||||
$query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `path` LIKE ?');
|
||||
$oldLength=strlen($oldPath);
|
||||
$updateQuery=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `path`=?, `path_hash`=? WHERE `path_hash`=?');
|
||||
while($row= $query->execute(array($oldPath.'/%'))->fetchRow()) {
|
||||
$old=$row['path'];
|
||||
$new=$newPath.substr($old, $oldLength);
|
||||
$updateQuery->execute(array($new, md5($new), md5($old)));
|
||||
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)) {
|
||||
$cache->set('fileid/'.$new, $cache->get('fileid/'.$old));
|
||||
$cache->remove('fileid/'.$old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete info from the cache
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function delete($path, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `path_hash`=?');
|
||||
$query->execute(array(md5($root.$path)));
|
||||
|
||||
//delete everything inside the folder
|
||||
$query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `path` LIKE ?');
|
||||
$query->execute(array($root.$path.'/%'));
|
||||
|
||||
OC_Cache::remove('fileid/'.$root.$path);
|
||||
}
|
||||
|
||||
/**
|
||||
* return array of filenames matching the querty
|
||||
* @param string $query
|
||||
* @param boolean $returnData
|
||||
* @param string root (optional)
|
||||
* @return array of filepaths
|
||||
*/
|
||||
public static function search($search, $returnData=false, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$rootLen=strlen($root);
|
||||
if(!$returnData) {
|
||||
$select = '`path`';
|
||||
}else{
|
||||
$select = '*';
|
||||
}
|
||||
if (OC_Config::getValue('dbtype') === 'oci8') {
|
||||
$where = 'LOWER(`name`) LIKE LOWER(?) AND `user`=?';
|
||||
} else {
|
||||
$where = '`name` LIKE ? AND `user`=?';
|
||||
}
|
||||
$query=OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*fscache` WHERE '.$where);
|
||||
$result=$query->execute(array("%$search%", OC_User::getUser()));
|
||||
$names=array();
|
||||
while($row=$result->fetchRow()) {
|
||||
if(!$returnData) {
|
||||
$names[]=substr($row['path'], $rootLen);
|
||||
}else{
|
||||
$row['path']=substr($row['path'], $rootLen);
|
||||
$names[]=$row;
|
||||
}
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all files and folders in a folder
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @return array
|
||||
*
|
||||
* returns an array of assiciative arrays with the following keys:
|
||||
* - name
|
||||
* - size
|
||||
* - mtime
|
||||
* - ctime
|
||||
* - mimetype
|
||||
* - encrypted
|
||||
* - versioned
|
||||
*/
|
||||
public static function getFolderContent($path, $root=false, $mimetype_filter='') {
|
||||
if(OC_FileCache_Update::hasUpdated($path, $root, true)) {
|
||||
OC_FileCache_Update::updateFolder($path, $root);
|
||||
}
|
||||
return OC_FileCache_Cached::getFolderContent($path, $root, $mimetype_filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file or folder is in the cache
|
||||
* @param string $path
|
||||
* @param string root (optional)
|
||||
* @return bool
|
||||
*/
|
||||
public static function inCache($path, $root=false) {
|
||||
return self::getId($path, $root)!=-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id as used in the cache
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @return int
|
||||
*/
|
||||
public static function getId($path, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
|
||||
$fullPath=$root.$path;
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)) {
|
||||
return $cache->get('fileid/'.$fullPath);
|
||||
}
|
||||
|
||||
$query=OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `path_hash`=?');
|
||||
$result=$query->execute(array(md5($fullPath)));
|
||||
if(OC_DB::isError($result)) {
|
||||
OC_Log::write('files', 'error while getting file id of '.$path, OC_Log::ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
$result=$result->fetchRow();
|
||||
if(is_array($result)) {
|
||||
$id=$result['id'];
|
||||
}else{
|
||||
$id=-1;
|
||||
}
|
||||
if($cache=OC_Cache::getUserCache(true)) {
|
||||
$cache->set('fileid/'.$fullPath, $id);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file path from the id, relative to the home folder of the user
|
||||
* @param int id
|
||||
* @param string user (optional)
|
||||
* @return string
|
||||
*/
|
||||
public static function getPath($id, $user='') {
|
||||
if(!$user) {
|
||||
$user=OC_User::getUser();
|
||||
}
|
||||
$query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `id`=? AND `user`=?');
|
||||
$result=$query->execute(array($id, $user));
|
||||
$row=$result->fetchRow();
|
||||
$path=$row['path'];
|
||||
$root='/'.$user.'/files';
|
||||
if(substr($path, 0, strlen($root))!=$root) {
|
||||
return false;
|
||||
}
|
||||
return substr($path, strlen($root));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id of the parent folder, taking into account '/' has no parent
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
private static function getParentId($path) {
|
||||
if($path=='/') {
|
||||
return -1;
|
||||
}else{
|
||||
return self::getId(dirname($path), '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* adjust the size of the parent folders
|
||||
* @param string $path
|
||||
* @param int $sizeDiff
|
||||
* @param string root (optinal)
|
||||
*/
|
||||
public static function increaseSize($path, $sizeDiff, $root=false) {
|
||||
if($sizeDiff==0) return;
|
||||
$item = OC_FileCache_Cached::get($path);
|
||||
//stop walking up the filetree if we hit a non-folder or reached the root folder
|
||||
if($path == '/' || $path=='' || $item['mimetype'] !== 'httpd/unix-directory') {
|
||||
return;
|
||||
}
|
||||
$id = $item['id'];
|
||||
while($id!=-1) {//walk up the filetree increasing the size of all parent folders
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `size`=`size`+? WHERE `id`=?');
|
||||
$query->execute(array($sizeDiff, $id));
|
||||
$path=dirname($path);
|
||||
if($path == '' or $path =='/') {
|
||||
return;
|
||||
}
|
||||
$parent = OC_FileCache_Cached::get($path);
|
||||
$id = $parent['id'];
|
||||
//stop walking up the filetree if we hit a non-folder
|
||||
if($parent['mimetype'] !== 'httpd/unix-directory') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively scan the filesystem and fill the cache
|
||||
* @param string $path
|
||||
* @param OC_EventSource $eventSource (optional)
|
||||
* @param int $count (optional)
|
||||
* @param string $root (optional)
|
||||
*/
|
||||
public static function scan($path, $eventSource=false,&$count=0, $root=false) {
|
||||
if($eventSource) {
|
||||
$eventSource->send('scanning', array('file'=>$path, 'count'=>$count));
|
||||
}
|
||||
$lastSend=$count;
|
||||
// NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache)
|
||||
if (substr($path, 0, 7) == '/Shared') {
|
||||
return;
|
||||
}
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
self::scanFile($path, $root);
|
||||
$dh=$view->opendir($path.'/');
|
||||
$totalSize=0;
|
||||
if($dh) {
|
||||
while (($filename = readdir($dh)) !== false) {
|
||||
if($filename != '.' and $filename != '..') {
|
||||
$file=$path.'/'.$filename;
|
||||
if($view->is_dir($file.'/')) {
|
||||
self::scan($file, $eventSource, $count, $root);
|
||||
}else{
|
||||
$totalSize+=self::scanFile($file, $root);
|
||||
$count++;
|
||||
if($count>$lastSend+25 and $eventSource) {
|
||||
$lastSend=$count;
|
||||
$eventSource->send('scanning', array('file'=>$path, 'count'=>$count));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OC_FileCache_Update::cleanFolder($path, $root);
|
||||
self::increaseSize($path, $totalSize, $root);
|
||||
}
|
||||
|
||||
/**
|
||||
* scan a single file
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @return int size of the scanned file
|
||||
*/
|
||||
public static function scanFile($path, $root=false) {
|
||||
// NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache)
|
||||
if (substr($path, 0, 7) == '/Shared') {
|
||||
return;
|
||||
}
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
if(!$view->is_readable($path)) return; //cant read, nothing we can do
|
||||
clearstatcache();
|
||||
$mimetype=$view->getMimeType($path);
|
||||
$stat=$view->stat($path);
|
||||
if($mimetype=='httpd/unix-directory') {
|
||||
$stat['size'] = 0;
|
||||
$writable=$view->is_writable($path.'/');
|
||||
}else{
|
||||
$writable=$view->is_writable($path);
|
||||
}
|
||||
$stat['mimetype']=$mimetype;
|
||||
$stat['writable']=$writable;
|
||||
if($path=='/') {
|
||||
$path='';
|
||||
}
|
||||
self::put($path, $stat, $root);
|
||||
return $stat['size'];
|
||||
}
|
||||
|
||||
/**
|
||||
* find files by mimetype
|
||||
* @param string $part1
|
||||
* @param string $part2 (optional)
|
||||
* @param string root (optional)
|
||||
* @return array of file paths
|
||||
*
|
||||
* $part1 and $part2 together form the complete mimetype.
|
||||
* e.g. searchByMime('text', 'plain')
|
||||
*
|
||||
* seccond mimetype part can be ommited
|
||||
* e.g. searchByMime('audio')
|
||||
*/
|
||||
public static function searchByMime($part1, $part2=null, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$rootLen=strlen($root);
|
||||
$root .= '%';
|
||||
$user=OC_User::getUser();
|
||||
if(!$part2) {
|
||||
$query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimepart`=? AND `user`=? AND `path` LIKE ?');
|
||||
$result=$query->execute(array($part1, $user, $root));
|
||||
}else{
|
||||
$query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimetype`=? AND `user`=? AND `path` LIKE ? ');
|
||||
$result=$query->execute(array($part1.'/'.$part2, $user, $root));
|
||||
}
|
||||
$names=array();
|
||||
while($row=$result->fetchRow()) {
|
||||
$names[]=substr($row['path'], $rootLen);
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* clean old pre-path_hash entries
|
||||
*/
|
||||
public static function clean() {
|
||||
$query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE LENGTH(`path_hash`)<30');
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* clear filecache entries
|
||||
* @param string user (optonal)
|
||||
*/
|
||||
public static function clear($user='') {
|
||||
if($user) {
|
||||
$query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `user`=?');
|
||||
$query->execute(array($user));
|
||||
}else{
|
||||
$query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache`');
|
||||
$query->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger an update for the cache by setting the mtimes to 0
|
||||
* @param string $user (optional)
|
||||
*/
|
||||
public static function triggerUpdate($user='') {
|
||||
if($user) {
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 WHERE `user`=? AND `mimetype`= ? ');
|
||||
$query->execute(array($user,'httpd/unix-directory'));
|
||||
}else{
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 AND `mimetype`= ? ');
|
||||
$query->execute(array('httpd/unix-directory'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//watch for changes and try to keep the cache up to date
|
||||
OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_FileCache_Update', 'fileSystemWatcherWrite');
|
||||
OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_FileCache_Update', 'fileSystemWatcherDelete');
|
||||
OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_FileCache_Update', 'fileSystemWatcherRename');
|
||||
OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_FileCache_Update', 'deleteFromUser');
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* get data from the filecache without checking for updates
|
||||
*/
|
||||
class OC_FileCache_Cached{
|
||||
public static $savedData=array();
|
||||
|
||||
public static function get($path, $root=false) {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$path=$root.$path;
|
||||
$stmt=OC_DB::prepare('SELECT `id`, `path`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `path_hash`=?');
|
||||
if ( ! OC_DB::isError($stmt) ) {
|
||||
$result=$stmt->execute(array(md5($path)));
|
||||
if ( ! OC_DB::isError($result) ) {
|
||||
$result = $result->fetchRow();
|
||||
} else {
|
||||
OC:Log::write('OC_FileCache_Cached', 'could not execute get: '. OC_DB::getErrorMessage($result), OC_Log::ERROR);
|
||||
$result = false;
|
||||
}
|
||||
} else {
|
||||
OC_Log::write('OC_FileCache_Cached', 'could not prepare get: '. OC_DB::getErrorMessage($stmt), OC_Log::ERROR);
|
||||
$result = false;
|
||||
}
|
||||
if(is_array($result)) {
|
||||
if(isset(self::$savedData[$path])) {
|
||||
$result=array_merge($result, self::$savedData[$path]);
|
||||
}
|
||||
return $result;
|
||||
}else{
|
||||
if(isset(self::$savedData[$path])) {
|
||||
return self::$savedData[$path];
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get all files and folders in a folder
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @return array
|
||||
*
|
||||
* returns an array of assiciative arrays with the following keys:
|
||||
* - path
|
||||
* - name
|
||||
* - size
|
||||
* - mtime
|
||||
* - ctime
|
||||
* - mimetype
|
||||
* - encrypted
|
||||
* - versioned
|
||||
*/
|
||||
public static function getFolderContent($path, $root=false, $mimetype_filter='') {
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$parent=OC_FileCache::getId($path, $root);
|
||||
if($parent==-1) {
|
||||
return array();
|
||||
}
|
||||
$query=OC_DB::prepare('SELECT `id`,`path`,`name`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `parent`=? AND (`mimetype` LIKE ? OR `mimetype` = ?)');
|
||||
$result=$query->execute(array($parent, $mimetype_filter.'%', 'httpd/unix-directory'))->fetchAll();
|
||||
if(is_array($result)) {
|
||||
return $result;
|
||||
}else{
|
||||
OC_Log::write('files', 'getFolderContent(): file not found in cache ('.$path.')', OC_Log::DEBUG);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,227 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* handles updating the filecache according to outside changes
|
||||
*/
|
||||
class OC_FileCache_Update{
|
||||
/**
|
||||
* check if a file or folder is updated outside owncloud
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
* @param boolean folder
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasUpdated($path, $root=false, $folder=false) {
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
if(!$view->file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
$cachedData=OC_FileCache_Cached::get($path, $root);
|
||||
if(isset($cachedData['mtime'])) {
|
||||
$cachedMTime=$cachedData['mtime'];
|
||||
if($folder) {
|
||||
return $view->hasUpdated($path.'/', $cachedMTime);
|
||||
}else{
|
||||
return $view->hasUpdated($path, $cachedMTime);
|
||||
}
|
||||
}else{//file not in cache, so it has to be updated
|
||||
if(($path=='/' or $path=='') and $root===false) {//dont auto update the home folder, it will be scanned
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* delete non existing files from the cache
|
||||
*/
|
||||
public static function cleanFolder($path, $root=false) {
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
|
||||
$cachedContent=OC_FileCache_Cached::getFolderContent($path, $root);
|
||||
foreach($cachedContent as $fileData) {
|
||||
$path=$fileData['path'];
|
||||
$file=$view->getRelativePath($path);
|
||||
if(!$view->file_exists($file)) {
|
||||
if($root===false) {//filesystem hooks are only valid for the default root
|
||||
OC_Hook::emit('OC_Filesystem', 'post_delete', array('path'=>$file));
|
||||
}else{
|
||||
self::delete($file, $root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update the cache according to changes in the folder
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function updateFolder($path, $root=false) {
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
$dh=$view->opendir($path.'/');
|
||||
if($dh) {//check for changed/new files
|
||||
while (($filename = readdir($dh)) !== false) {
|
||||
if($filename != '.' and $filename != '..' and $filename != '') {
|
||||
$file=$path.'/'.$filename;
|
||||
$isDir=$view->is_dir($file);
|
||||
if(self::hasUpdated($file, $root, $isDir)) {
|
||||
if($isDir) {
|
||||
self::updateFolder($file, $root);
|
||||
}elseif($root===false) {//filesystem hooks are only valid for the default root
|
||||
OC_Hook::emit('OC_Filesystem', 'post_write', array('path'=>$file));
|
||||
}else{
|
||||
self::update($file, $root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::cleanFolder($path, $root);
|
||||
|
||||
//update the folder last, so we can calculate the size correctly
|
||||
if($root===false) {//filesystem hooks are only valid for the default root
|
||||
OC_Hook::emit('OC_Filesystem', 'post_write', array('path'=>$path));
|
||||
}else{
|
||||
self::update($path, $root);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* called when changes are made to files
|
||||
* @param array $params
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function fileSystemWatcherWrite($params) {
|
||||
$path=$params['path'];
|
||||
self::update($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* called when files are deleted
|
||||
* @param array $params
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function fileSystemWatcherDelete($params) {
|
||||
$path=$params['path'];
|
||||
self::delete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* called when files are deleted
|
||||
* @param array $params
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function fileSystemWatcherRename($params) {
|
||||
$oldPath=$params['oldpath'];
|
||||
$newPath=$params['newpath'];
|
||||
self::rename($oldPath, $newPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the filecache according to changes to the filesystem
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function update($path, $root=false) {
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
|
||||
$mimetype=$view->getMimeType($path);
|
||||
|
||||
$size=0;
|
||||
$cached=OC_FileCache_Cached::get($path, $root);
|
||||
$cachedSize=isset($cached['size'])?$cached['size']:0;
|
||||
|
||||
if($view->is_dir($path.'/')) {
|
||||
if(OC_FileCache::inCache($path, $root)) {
|
||||
$cachedContent=OC_FileCache_Cached::getFolderContent($path, $root);
|
||||
foreach($cachedContent as $file) {
|
||||
$size+=$file['size'];
|
||||
}
|
||||
$mtime=$view->filemtime($path.'/');
|
||||
$ctime=$view->filectime($path.'/');
|
||||
$writable=$view->is_writable($path.'/');
|
||||
OC_FileCache::put($path, array('size'=>$size,'mtime'=>$mtime,'ctime'=>$ctime,'mimetype'=>$mimetype, 'writable'=>$writable));
|
||||
}else{
|
||||
$count=0;
|
||||
OC_FileCache::scan($path, null, $count, $root);
|
||||
return; //increaseSize is already called inside scan
|
||||
}
|
||||
}else{
|
||||
$size=OC_FileCache::scanFile($path, $root);
|
||||
}
|
||||
if($path !== '' and $path !== '/') {
|
||||
OC_FileCache::increaseSize(dirname($path), $size-$cachedSize, $root);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update the filesystem after a delete has been detected
|
||||
* @param string path
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function delete($path, $root=false) {
|
||||
$cached=OC_FileCache_Cached::get($path, $root);
|
||||
if(!isset($cached['size'])) {
|
||||
return;
|
||||
}
|
||||
$size=$cached['size'];
|
||||
OC_FileCache::increaseSize(dirname($path), -$size, $root);
|
||||
OC_FileCache::delete($path, $root);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the filesystem after a rename has been detected
|
||||
* @param string oldPath
|
||||
* @param string newPath
|
||||
* @param string root (optional)
|
||||
*/
|
||||
public static function rename($oldPath, $newPath, $root=false) {
|
||||
if(!OC_FileCache::inCache($oldPath, $root)) {
|
||||
return;
|
||||
}
|
||||
if($root===false) {
|
||||
$view=OC_Filesystem::getView();
|
||||
}else{
|
||||
$view=new OC_FilesystemView($root);
|
||||
}
|
||||
|
||||
$cached=OC_FileCache_Cached::get($oldPath, $root);
|
||||
$oldSize=$cached['size'];
|
||||
OC_FileCache::increaseSize(dirname($oldPath), -$oldSize, $root);
|
||||
OC_FileCache::increaseSize(dirname($newPath), $oldSize, $root);
|
||||
OC_FileCache::move($oldPath, $newPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete files owned by user from the cache
|
||||
* @param string $parameters$parameters["uid"])
|
||||
*/
|
||||
public static function deleteFromUser($parameters) {
|
||||
OC_FileCache::clear($parameters["uid"]);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ class OC_FileProxy_FileOperations extends OC_FileProxy{
|
|||
static $rootView;
|
||||
|
||||
public function premkdir($path) {
|
||||
if(!self::$rootView) {
|
||||
self::$rootView = new OC_FilesystemView('');
|
||||
if(!self::$rootView){
|
||||
self::$rootView = new \OC\Files\View('');
|
||||
}
|
||||
return !self::$rootView->file_exists($path);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* user quota managment
|
||||
* user quota management
|
||||
*/
|
||||
|
||||
class OC_FileProxy_Quota extends OC_FileProxy{
|
||||
|
@ -57,23 +57,25 @@ class OC_FileProxy_Quota extends OC_FileProxy{
|
|||
* @return int
|
||||
*/
|
||||
private function getFreeSpace($path) {
|
||||
$storage=OC_Filesystem::getStorage($path);
|
||||
$owner=$storage->getOwner($path);
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path);
|
||||
$owner=$storage->getOwner($internalPath);
|
||||
if (!$owner) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$totalSpace=$this->getQuota($owner);
|
||||
if($totalSpace==-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
|
@ -93,8 +95,8 @@ class OC_FileProxy_Quota extends OC_FileProxy{
|
|||
}
|
||||
|
||||
public function preCopy($path1, $path2) {
|
||||
if(!self::$rootView) {
|
||||
self::$rootView = new OC_FilesystemView('');
|
||||
if(!self::$rootView){
|
||||
self::$rootView = new \OC\Files\View('');
|
||||
}
|
||||
return (self::$rootView->filesize($path1)<$this->getFreeSpace($path2) or $this->getFreeSpace($path2)==-1);
|
||||
}
|
||||
|
|
446
lib/files.php
446
lib/files.php
|
@ -1,144 +1,48 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for fileserver access
|
||||
*
|
||||
*/
|
||||
class OC_Files {
|
||||
static $tmpFiles=array();
|
||||
static $tmpFiles = array();
|
||||
|
||||
static public function getFileInfo($path){
|
||||
return \OC\Files\Filesystem::getFileInfo($path);
|
||||
}
|
||||
|
||||
static public function getDirectoryContent($path){
|
||||
return \OC\Files\Filesystem::getDirectoryContent($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the filesystem info
|
||||
* @param string path
|
||||
* @return array
|
||||
* return the content of a file or return a zip file containing multiple files
|
||||
*
|
||||
* returns an associative array with the following keys:
|
||||
* - size
|
||||
* - mtime
|
||||
* - ctime
|
||||
* - mimetype
|
||||
* - encrypted
|
||||
* - versioned
|
||||
* @param string $dir
|
||||
* @param string $file ; separated list of files to download
|
||||
* @param boolean $only_header ; boolean to only send header of the request
|
||||
*/
|
||||
public static function getFileInfo($path) {
|
||||
$path = OC_Filesystem::normalizePath($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 = array();
|
||||
if (OC_Filesystem::file_exists($path)) {
|
||||
$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['encrypted'] = false;
|
||||
$info['versioned'] = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$info = OC_FileCache::get($path);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the content of a directory
|
||||
* @param dir $directory path under datadirectory
|
||||
*/
|
||||
public static function getDirectoryContent($directory, $mimetype_filter = '') {
|
||||
$directory=OC_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\PERMISSION_READ;
|
||||
// NOTE: Remove check when new encryption is merged
|
||||
if (!$file['encrypted']) {
|
||||
$permissions |= OCP\PERMISSION_SHARE;
|
||||
}
|
||||
if ($file['type'] == 'dir' && $file['writable']) {
|
||||
$permissions |= OCP\PERMISSION_CREATE;
|
||||
}
|
||||
if ($file['writable']) {
|
||||
$permissions |= OCP\PERMISSION_UPDATE | OCP\PERMISSION_DELETE;
|
||||
}
|
||||
$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));
|
||||
}
|
||||
}
|
||||
usort($files, "fileCmp");//TODO: remove this once ajax is merged
|
||||
return $files;
|
||||
}
|
||||
|
||||
public static function searchByMime($mimetype_filter) {
|
||||
$files = array();
|
||||
$dirs_to_check = array('');
|
||||
while (!empty($dirs_to_check)) {
|
||||
// get next subdir to check
|
||||
$dir = array_pop($dirs_to_check);
|
||||
$dir_content = self::getDirectoryContent($dir, $mimetype_filter);
|
||||
foreach($dir_content as $file) {
|
||||
if ($file['type'] == 'file') {
|
||||
$files[] = $dir.'/'.$file['name'];
|
||||
}
|
||||
else {
|
||||
$dirs_to_check[] = $dir.'/'.$file['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the content of a file or return a zip file containning multiply files
|
||||
*
|
||||
* @param dir $dir
|
||||
* @param file $file ; seperated list of files to download
|
||||
* @param boolean $only_header ; boolean to only send header of the request
|
||||
*/
|
||||
public static function get($dir, $files, $only_header = false) {
|
||||
$xsendfile = false;
|
||||
if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) ||
|
||||
|
@ -149,7 +53,7 @@ class OC_Files {
|
|||
$files=explode(';', $files);
|
||||
}
|
||||
|
||||
if(is_array($files)) {
|
||||
if (is_array($files)) {
|
||||
self::validateZipDownload($dir, $files);
|
||||
$executionTime = intval(ini_get('max_execution_time'));
|
||||
set_time_limit(0);
|
||||
|
@ -162,19 +66,20 @@ class OC_Files {
|
|||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
|
||||
exit("cannot open <$filename>\n");
|
||||
}
|
||||
foreach($files as $file) {
|
||||
$file=$dir.'/'.$file;
|
||||
if(OC_Filesystem::is_file($file)) {
|
||||
$tmpFile=OC_Filesystem::toTmpFile($file);
|
||||
self::$tmpFiles[]=$tmpFile;
|
||||
foreach ($files as $file) {
|
||||
$file = $dir . '/' . $file;
|
||||
if (\OC\Files\Filesystem::is_file($file)) {
|
||||
$tmpFile = \OC\Files\Filesystem::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();
|
||||
$name = basename($dir) . '.zip';
|
||||
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);
|
||||
|
@ -187,53 +92,55 @@ class OC_Files {
|
|||
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
|
||||
exit("cannot open <$filename>\n");
|
||||
}
|
||||
$file=$dir.'/'.$files;
|
||||
$file = $dir . '/' . $files;
|
||||
self::zipAddDir($file, $zip);
|
||||
$zip->close();
|
||||
$name = $files . '.zip';
|
||||
set_time_limit($executionTime);
|
||||
}else{
|
||||
$zip=false;
|
||||
$filename=$dir.'/'.$files;
|
||||
} else {
|
||||
$zip = false;
|
||||
$filename = $dir . '/' . $files;
|
||||
$name = $files;
|
||||
}
|
||||
OC_Util::obEnd();
|
||||
if($zip or OC_Filesystem::is_readable($filename)) {
|
||||
if ($zip or \OC\Files\Filesystem::isReadable($filename)) {
|
||||
if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) {
|
||||
header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' );
|
||||
header( 'Content-Disposition: attachment; filename="' . rawurlencode($name) . '"' );
|
||||
} else {
|
||||
header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) )
|
||||
. '; filename="' . rawurlencode( basename($filename) ) . '"' );
|
||||
header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($name)
|
||||
. '; filename="' . rawurlencode($name) . '"' );
|
||||
}
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
OC_Response::disableCaching();
|
||||
if($zip) {
|
||||
if ($zip) {
|
||||
ini_set('zlib.output_compression', 'off');
|
||||
header('Content-Type: application/zip');
|
||||
header('Content-Length: ' . filesize($filename));
|
||||
self::addSendfileHeader($filename);
|
||||
}else{
|
||||
header('Content-Type: '.OC_Filesystem::getMimeType($filename));
|
||||
header("Content-Length: ".OC_Filesystem::filesize($filename));
|
||||
$storage = OC_Filesystem::getStorage($filename);
|
||||
if ($storage instanceof OC_Filestorage_Local) {
|
||||
self::addSendfileHeader(OC_Filesystem::getLocalFile($filename));
|
||||
header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename));
|
||||
header("Content-Length: ".\OC\Files\Filesystem::filesize($filename));
|
||||
list($storage) = \OC\Files\Filesystem::resolvePath($filename);
|
||||
if ($storage instanceof \OC\File\Storage\Local) {
|
||||
self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($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);
|
||||
$tmpl = new OC_Template('', '404', 'guest');
|
||||
$tmpl->assign('file', $name);
|
||||
$tmpl->printPage();
|
||||
}else{
|
||||
} else {
|
||||
header("HTTP/1.0 403 Forbidden");
|
||||
die('403 Forbidden');
|
||||
}
|
||||
if($only_header) {
|
||||
return ;
|
||||
}
|
||||
if($zip) {
|
||||
$handle=fopen($filename, 'r');
|
||||
if ($zip) {
|
||||
$handle = fopen($filename, 'r');
|
||||
if ($handle) {
|
||||
$chunkSize = 8*1024;// 1 MB chunks
|
||||
$chunkSize = 8 * 1024; // 1 MB chunks
|
||||
while (!feof($handle)) {
|
||||
echo fread($handle, $chunkSize);
|
||||
flush();
|
||||
|
@ -243,10 +150,10 @@ 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)) {
|
||||
foreach (self::$tmpFiles as $tmpFile) {
|
||||
if (file_exists($tmpFile) and is_file($tmpFile)) {
|
||||
unlink($tmpFile);
|
||||
}
|
||||
}
|
||||
|
@ -269,97 +176,27 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* move a file or folder
|
||||
*
|
||||
* @param dir $sourceDir
|
||||
* @param file $source
|
||||
* @param dir $targetDir
|
||||
* @param file $target
|
||||
*/
|
||||
public static function move($sourceDir, $source, $targetDir, $target) {
|
||||
if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) {
|
||||
$targetFile=self::normalizePath($targetDir.'/'.$target);
|
||||
$sourceFile=self::normalizePath($sourceDir.'/'.$source);
|
||||
return OC_Filesystem::rename($sourceFile, $targetFile);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* copy a file or folder
|
||||
*
|
||||
* @param dir $sourceDir
|
||||
* @param file $source
|
||||
* @param dir $targetDir
|
||||
* @param file $target
|
||||
*/
|
||||
public static function copy($sourceDir, $source, $targetDir, $target) {
|
||||
if(OC_User::isLoggedIn()) {
|
||||
$targetFile=$targetDir.'/'.$target;
|
||||
$sourceFile=$sourceDir.'/'.$source;
|
||||
return OC_Filesystem::copy($sourceFile, $targetFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new file or folder
|
||||
*
|
||||
* @param dir $dir
|
||||
* @param file $name
|
||||
* @param type $type
|
||||
*/
|
||||
public static function newFile($dir, $name, $type) {
|
||||
if(OC_User::isLoggedIn()) {
|
||||
$file=$dir.'/'.$name;
|
||||
if($type=='dir') {
|
||||
return OC_Filesystem::mkdir($file);
|
||||
}elseif($type=='file') {
|
||||
$fileHandle=OC_Filesystem::fopen($file, 'w');
|
||||
if($fileHandle) {
|
||||
fclose($fileHandle);
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a file or folder
|
||||
*
|
||||
* @param dir $dir
|
||||
* @param file $name
|
||||
*/
|
||||
public static function delete($dir, $file) {
|
||||
if(OC_User::isLoggedIn() && ($dir!= '' || $file != 'Shared')) {
|
||||
$file=$dir.'/'.$file;
|
||||
return OC_Filesystem::unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the selected files are within the size constraint. If not, outputs an error page.
|
||||
*
|
||||
* @param dir $dir
|
||||
* @param files $files
|
||||
*/
|
||||
* checks if the selected files are within the size constraint. If not, outputs an error page.
|
||||
*
|
||||
* @param dir $dir
|
||||
* @param files $files
|
||||
*/
|
||||
static function validateZipDownload($dir, $files) {
|
||||
if(!OC_Config::getValue('allowZipDownload', true)) {
|
||||
if (!OC_Config::getValue('allowZipDownload', true)) {
|
||||
$l = OC_L10N::get('lib');
|
||||
header("HTTP/1.0 409 Conflict");
|
||||
$tmpl = new OC_Template( '', 'error', 'user' );
|
||||
$tmpl = new OC_Template('', 'error', 'user');
|
||||
$errors = array(
|
||||
array(
|
||||
'error' => $l->t('ZIP download is turned off.'),
|
||||
|
@ -372,19 +209,19 @@ class OC_Files {
|
|||
}
|
||||
|
||||
$zipLimit = OC_Config::getValue('maxZipInputSize', OC_Helper::computerFileSize('800 MB'));
|
||||
if($zipLimit > 0) {
|
||||
if ($zipLimit > 0) {
|
||||
$totalsize = 0;
|
||||
if(is_array($files)) {
|
||||
foreach($files as $file) {
|
||||
$totalsize += OC_Filesystem::filesize($dir.'/'.$file);
|
||||
if (is_array($files)) {
|
||||
foreach ($files as $file) {
|
||||
$totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $file);
|
||||
}
|
||||
}else{
|
||||
$totalsize += OC_Filesystem::filesize($dir.'/'.$files);
|
||||
} else {
|
||||
$totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $files);
|
||||
}
|
||||
if($totalsize > $zipLimit) {
|
||||
if ($totalsize > $zipLimit) {
|
||||
$l = OC_L10N::get('lib');
|
||||
header("HTTP/1.0 409 Conflict");
|
||||
$tmpl = new OC_Template( '', 'error', 'user' );
|
||||
$tmpl = new OC_Template('', 'error', 'user');
|
||||
$errors = array(
|
||||
array(
|
||||
'error' => $l->t('Selected files too large to generate zip file.'),
|
||||
|
@ -398,79 +235,32 @@ class OC_Files {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* try to detect the mime type of a file
|
||||
*
|
||||
* @param string path
|
||||
* @return string guessed mime type
|
||||
*/
|
||||
static function getMimeType($path) {
|
||||
return OC_Filesystem::getMimeType($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a file tree
|
||||
*
|
||||
* @param string path
|
||||
* @return array
|
||||
*/
|
||||
static function getTree($path) {
|
||||
return OC_Filesystem::getTree($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* pull a file from a remote server
|
||||
* @param string source
|
||||
* @param string token
|
||||
* @param string dir
|
||||
* @param string file
|
||||
* @return string guessed mime type
|
||||
*/
|
||||
static function pull($source, $token, $dir, $file) {
|
||||
$tmpfile=tempnam(get_temp_dir(), 'remoteCloudFile');
|
||||
$fp=fopen($tmpfile, 'w+');
|
||||
$url=$source.="/files/pull.php?token=$token";
|
||||
$ch=curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_exec($ch);
|
||||
fclose($fp);
|
||||
$info=curl_getinfo($ch);
|
||||
$httpCode=$info['http_code'];
|
||||
curl_close($ch);
|
||||
if($httpCode==200 or $httpCode==0) {
|
||||
OC_Filesystem::fromTmpFile($tmpfile, $dir.'/'.$file);
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the maximum upload size limit for apache hosts using .htaccess
|
||||
*
|
||||
* @param int size filesisze in bytes
|
||||
* @return false on failure, size on success
|
||||
*/
|
||||
static function setUploadLimit($size) {
|
||||
//don't allow user to break his config -- upper boundary
|
||||
if($size > PHP_INT_MAX) {
|
||||
if ($size > PHP_INT_MAX) {
|
||||
//max size is always 1 byte lower than computerFileSize returns
|
||||
if($size > PHP_INT_MAX+1)
|
||||
if ($size > PHP_INT_MAX + 1)
|
||||
return false;
|
||||
$size -=1;
|
||||
$size -= 1;
|
||||
} else {
|
||||
$size=OC_Helper::humanFileSize($size);
|
||||
$size=substr($size, 0, -1);//strip the B
|
||||
$size=str_replace(' ', '', $size); //remove the space between the size and the postfix
|
||||
$size = OC_Helper::humanFileSize($size);
|
||||
$size = substr($size, 0, -1); //strip the B
|
||||
$size = str_replace(' ', '', $size); //remove the space between the size and the postfix
|
||||
}
|
||||
|
||||
//don't allow user to break his config -- broken or malicious size input
|
||||
if(intval($size) == 0) {
|
||||
if (intval($size) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$htaccess = @file_get_contents(OC::$SERVERROOT.'/.htaccess'); //supress errors in case we don't have permissions for
|
||||
if(!$htaccess) {
|
||||
$htaccess = @file_get_contents(OC::$SERVERROOT . '/.htaccess'); //supress errors in case we don't have permissions for
|
||||
if (!$htaccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -479,52 +269,26 @@ class OC_Files {
|
|||
'post_max_size'
|
||||
);
|
||||
|
||||
foreach($phpValueKeys as $key) {
|
||||
$pattern = '/php_value '.$key.' (\S)*/';
|
||||
$setting = 'php_value '.$key.' '.$size;
|
||||
$hasReplaced = 0;
|
||||
$content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced);
|
||||
if($content !== null) {
|
||||
foreach ($phpValueKeys as $key) {
|
||||
$pattern = '/php_value ' . $key . ' (\S)*/';
|
||||
$setting = 'php_value ' . $key . ' ' . $size;
|
||||
$hasReplaced = 0;
|
||||
$content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced);
|
||||
if ($content !== null) {
|
||||
$htaccess = $content;
|
||||
}
|
||||
if($hasReplaced == 0) {
|
||||
if ($hasReplaced == 0) {
|
||||
$htaccess .= "\n" . $setting;
|
||||
}
|
||||
}
|
||||
|
||||
//check for write permissions
|
||||
if(is_writable(OC::$SERVERROOT.'/.htaccess')) {
|
||||
file_put_contents(OC::$SERVERROOT.'/.htaccess', $htaccess);
|
||||
if (is_writable(OC::$SERVERROOT . '/.htaccess')) {
|
||||
file_put_contents(OC::$SERVERROOT . '/.htaccess', $htaccess);
|
||||
return OC_Helper::computerFileSize($size);
|
||||
} else {
|
||||
OC_Log::write('files', 'Can\'t write upload limit to '.OC::$SERVERROOT.'/.htaccess. Please check the file permissions', OC_Log::WARN);
|
||||
OC_Log::write('files', 'Can\'t write upload limit to ' . OC::$SERVERROOT . '/.htaccess. Please check the file permissions', OC_Log::WARN);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* normalize a path, removing any double, add leading /, etc
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
static public function normalizePath($path) {
|
||||
$path='/'.$path;
|
||||
$old='';
|
||||
while($old!=$path) {//replace any multiplicity of slashes with a single one
|
||||
$old=$path;
|
||||
$path=str_replace('//', '/', $path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,521 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
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
|
||||
const SHALLOW = 2; //folder in cache, but not all child files are completely scanned
|
||||
const COMPLETE = 3;
|
||||
|
||||
/**
|
||||
* @var array partial data for the cache
|
||||
*/
|
||||
private $partial = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $storageId;
|
||||
|
||||
/**
|
||||
* numeric storage id
|
||||
*
|
||||
* @var int $numericId
|
||||
*/
|
||||
private $numericId;
|
||||
|
||||
private $mimetypeIds = array();
|
||||
private $mimetypes = array();
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @param string/int $file
|
||||
* @return array
|
||||
*/
|
||||
public function get($file) {
|
||||
if (is_string($file) or $file == '') {
|
||||
$where = 'WHERE `storage` = ? AND `path_hash` = ?';
|
||||
$params = array($this->numericId, md5($file));
|
||||
} else { //file id
|
||||
$where = 'WHERE `fileid` = ?';
|
||||
$params = array($file);
|
||||
}
|
||||
$query = \OC_DB::prepare(
|
||||
'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
|
||||
FROM `*PREFIX*filecache` ' . $where);
|
||||
$result = $query->execute($params);
|
||||
$data = $result->fetchRow();
|
||||
|
||||
//merge partial data
|
||||
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'];
|
||||
$data['encrypted'] = (bool)$data['encrypted'];
|
||||
$data['storage'] = $this->storageId;
|
||||
$data['mimetype'] = $this->getMimetype($data['mimetype']);
|
||||
$data['mimepart'] = $this->getMimetype($data['mimepart']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the metadata of all files stored in $folder
|
||||
*
|
||||
* @param string $folder
|
||||
* @return array
|
||||
*/
|
||||
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`, `encrypted`, `etag`
|
||||
FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC');
|
||||
$result = $query->execute(array($fileId));
|
||||
$files = $result->fetchAll();
|
||||
foreach ($files as &$file) {
|
||||
$file['mimetype'] = $this->getMimetype($file['mimetype']);
|
||||
$file['mimepart'] = $this->getMimetype($file['mimepart']);
|
||||
}
|
||||
return $files;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* store meta data for a file or folder
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
*
|
||||
* @return int file id
|
||||
*/
|
||||
public function put($file, array $data) {
|
||||
if (($id = $this->getId($file)) > -1) {
|
||||
$this->update($id, $data);
|
||||
return $id;
|
||||
} else {
|
||||
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
|
||||
$this->partial[$file] = $data;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
$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`';
|
||||
$params[] = $this->numericId;
|
||||
$valuesPlaceholder = array_fill(0, count($queryParts), '?');
|
||||
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')');
|
||||
$query->execute($params);
|
||||
|
||||
return (int)\OC_DB::insertid('*PREFIX*filecache');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update the metadata in the cache
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $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 = ?');
|
||||
$query->execute($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* extract query parts and params array from data array
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
function buildParts(array $data) {
|
||||
$fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag');
|
||||
$params = array();
|
||||
$queryParts = array();
|
||||
foreach ($data as $name => $value) {
|
||||
if (array_search($name, $fields) !== false) {
|
||||
if ($name === 'path') {
|
||||
$params[] = md5($value);
|
||||
$queryParts[] = '`path_hash`';
|
||||
} elseif ($name === 'mimetype') {
|
||||
$params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/')));
|
||||
$queryParts[] = '`mimepart`';
|
||||
$value = $this->getMimetypeId($value);
|
||||
}
|
||||
$params[] = $value;
|
||||
$queryParts[] = '`' . $name . '`';
|
||||
}
|
||||
}
|
||||
return array($queryParts, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id for a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
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($this->numericId, $pathHash));
|
||||
|
||||
if ($row = $result->fetchRow()) {
|
||||
return $row['fileid'];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the id of the parent folder of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getParentId($file) {
|
||||
if ($file === '') {
|
||||
return -1;
|
||||
} else {
|
||||
$parent = dirname($file);
|
||||
if ($parent === '.') {
|
||||
$parent = '';
|
||||
}
|
||||
return $this->getId($parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file is available in the cache
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($file) {
|
||||
return $this->getId($file) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file or folder from the cache
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function remove($file) {
|
||||
$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']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function clear() {
|
||||
$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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?');
|
||||
$result = $query->execute(array($this->numericId, $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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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`, `etag`
|
||||
FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'
|
||||
);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files by mimetype
|
||||
*
|
||||
* @param string $mimetype
|
||||
* @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`, `etag`
|
||||
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'
|
||||
);
|
||||
$mimetype = $this->getMimetypeId($mimetype);
|
||||
$result = $query->execute(array($mimetype, $this->numericId));
|
||||
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
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
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->numericId));
|
||||
$totalSize = 0;
|
||||
$hasChilds = 0;
|
||||
while ($row = $result->fetchRow()) {
|
||||
$hasChilds = true;
|
||||
$size = (int)$row['size'];
|
||||
if ($size === -1) {
|
||||
$totalSize = -1;
|
||||
break;
|
||||
} else {
|
||||
$totalSize += $size;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasChilds) {
|
||||
$this->update($id, array('size' => $totalSize));
|
||||
}
|
||||
return $totalSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->numericId));
|
||||
$ids = array();
|
||||
while ($row = $result->fetchRow()) {
|
||||
$ids[] = $row['fileid'];
|
||||
}
|
||||
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->numericId));
|
||||
if ($row = $query->fetchRow()) {
|
||||
return $row['path'];
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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;
|
||||
|
||||
private $cacheHasItems = null;
|
||||
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
$this->cacheHasItems = (bool)$result->fetchRow();
|
||||
return $this->cacheHasItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 {
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @param int $fileId
|
||||
* @param string $user
|
||||
* @return int (-1 if file no permissions set)
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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[]
|
||||
*/
|
||||
public function getMultiple($fileIds, $user) {
|
||||
if (count($fileIds) === 0) {
|
||||
return array();
|
||||
}
|
||||
$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
|
||||
*/
|
||||
public function remove($fileId, $user) {
|
||||
$query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?');
|
||||
$query->execute(array($fileId, $user));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 {
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var string $storageId
|
||||
*/
|
||||
private $storageId;
|
||||
|
||||
/**
|
||||
* @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->storageId = $this->storage->getId();
|
||||
$this->cache = $storage->getCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* get all the metadata of a file or folder
|
||||
* *
|
||||
*
|
||||
* @param string $path
|
||||
* @return array with metadata of the file
|
||||
*/
|
||||
public function getData($path) {
|
||||
$data = array();
|
||||
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
|
||||
} else {
|
||||
$data['size'] = $this->storage->filesize($path);
|
||||
}
|
||||
$data['etag'] = $this->storage->getETag($path);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* scan a single file and store it in the cache
|
||||
*
|
||||
* @param string $file
|
||||
* @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 ($data) {
|
||||
if ($file) {
|
||||
$parent = dirname($file);
|
||||
if ($parent === '.') {
|
||||
$parent = '';
|
||||
}
|
||||
if (!$this->cache->inCache($parent)) {
|
||||
$this->scanFile($parent);
|
||||
}
|
||||
}
|
||||
$id = $this->cache->put($file, $data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* scan all the files in a folder and store them in the cache
|
||||
*
|
||||
* @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, $onlyChilds = false) {
|
||||
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId));
|
||||
$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;
|
||||
$data = $this->scanFile($child);
|
||||
if ($data) {
|
||||
if ($data['mimetype'] === 'httpd/unix-directory') {
|
||||
if ($recursive === self::SCAN_RECURSIVE) {
|
||||
$childQueue[] = $child;
|
||||
$data['size'] = 0;
|
||||
} else {
|
||||
$data['size'] = -1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if ($data['size'] === -1) {
|
||||
$size = -1;
|
||||
} elseif ($size !== -1) {
|
||||
$size += $data['size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\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));
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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);
|
||||
if ($storage) {
|
||||
$cache = $storage->getCache($internalPath);
|
||||
$scanner = $storage->getScanner($internalPath);
|
||||
$scanner->scan($internalPath, Scanner::SCAN_SHALLOW);
|
||||
$cache->correctFolderSize($internalPath);
|
||||
self::correctFolder($path, $storage->filemtime($internalPath));
|
||||
}
|
||||
}
|
||||
|
||||
static public function deleteUpdate($path) {
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
list($storage, $internalPath) = self::resolvePath($path);
|
||||
if ($storage) {
|
||||
$cache = $storage->getCache($internalPath);
|
||||
$cache->remove($internalPath);
|
||||
$cache->correctFolderSize($internalPath);
|
||||
self::correctFolder($path, time());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 === '.') {
|
||||
$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('mtime' => $time, 'etag' => $storage->getETag($internalPath)));
|
||||
self::correctFolder($parent, $time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 {
|
||||
/**
|
||||
* @var Legacy $legacy
|
||||
*/
|
||||
private $legacy;
|
||||
|
||||
private $numericIds = array();
|
||||
|
||||
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);
|
||||
|
||||
if ($row = $this->legacy->get($path)) {
|
||||
$data = $this->getNewData($row);
|
||||
$this->insert($data);
|
||||
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data the data for the new cache
|
||||
*/
|
||||
function insert($data) {
|
||||
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']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the numeric storage id
|
||||
*
|
||||
* @param \OC\Files\Storage\Storage $storage
|
||||
* @return int
|
||||
*/
|
||||
function getNumericId($storage) {
|
||||
$storageId = $storage->getId();
|
||||
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);
|
||||
$this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 ($this->storage->is_dir($path)) {
|
||||
$this->scanner->scan($path, Scanner::SCAN_SHALLOW);
|
||||
} else {
|
||||
$this->scanner->scanFile($path);
|
||||
}
|
||||
if ($cachedEntry['mimetype'] === 'httpd/unix-directory') {
|
||||
$this->cleanFolder($path);
|
||||
}
|
||||
$this->cache->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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,628 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 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 emitted in that order)
|
||||
* post_rename(oldpath,newpath)
|
||||
*
|
||||
* the &run parameter can be set to false to prevent the operation from occurring
|
||||
*/
|
||||
|
||||
namespace OC\Files;
|
||||
|
||||
class Filesystem {
|
||||
public static $loaded = false;
|
||||
/**
|
||||
* @var \OC\Files\View $defaultInstance
|
||||
*/
|
||||
static private $defaultInstance;
|
||||
|
||||
|
||||
/**
|
||||
* classname which used for hooks handling
|
||||
* used as signalclass in OC_Hooks::emit()
|
||||
*/
|
||||
const CLASSNAME = 'OC_Filesystem';
|
||||
|
||||
/**
|
||||
* signalname emitted before file renaming
|
||||
*
|
||||
* @param string $oldpath
|
||||
* @param string $newpath
|
||||
*/
|
||||
const signal_rename = 'rename';
|
||||
|
||||
/**
|
||||
* signal emitted after file renaming
|
||||
*
|
||||
* @param string $oldpath
|
||||
* @param string $newpath
|
||||
*/
|
||||
const signal_post_rename = 'post_rename';
|
||||
|
||||
/**
|
||||
* signal emitted before file/dir creation
|
||||
*
|
||||
* @param string $path
|
||||
* @param bool $run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_create = 'create';
|
||||
|
||||
/**
|
||||
* signal emitted after file/dir creation
|
||||
*
|
||||
* @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 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 string $oldpath
|
||||
* @param string $newpath
|
||||
*/
|
||||
const signal_post_copy = 'post_copy';
|
||||
|
||||
/**
|
||||
* signal emits before file/dir save
|
||||
*
|
||||
* @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 string $path
|
||||
*/
|
||||
const signal_post_write = 'post_write';
|
||||
|
||||
/**
|
||||
* signal emits when reading file/dir
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
const signal_read = 'read';
|
||||
|
||||
/**
|
||||
* signal emits when removing file/dir
|
||||
*
|
||||
* @param string $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) {
|
||||
$mount = Mount::find($path);
|
||||
if ($mount) {
|
||||
return $mount->getMountPoint();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of all mount points in a directory
|
||||
*
|
||||
* @param string $path
|
||||
* @return string[]
|
||||
*/
|
||||
static public function getMountPoints($path) {
|
||||
$result = array();
|
||||
$mounts = Mount::findIn($path);
|
||||
foreach ($mounts as $mount) {
|
||||
$result[] = $mount->getMountPoint();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the storage mounted at $mountPoint
|
||||
*
|
||||
* @param string $mountPoint
|
||||
* @return \OC\Files\Storage\Storage
|
||||
*/
|
||||
public static function getStorage($mountPoint) {
|
||||
$mount = Mount::find($mountPoint);
|
||||
return $mount->getStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$mount = Mount::find($path);
|
||||
if ($mount) {
|
||||
return array($mount->getStorage(), $mount->getInternalPath($path));
|
||||
} else {
|
||||
return array(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
static public function init($root) {
|
||||
if (self::$defaultInstance) {
|
||||
return false;
|
||||
}
|
||||
self::$defaultInstance = new View($root);
|
||||
|
||||
//load custom mount config
|
||||
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($user, $group)) {
|
||||
foreach ($mounts as $mountPoint => $options) {
|
||||
$mountPoint = self::setUserVars($user, $mountPoint);
|
||||
foreach ($options as &$option) {
|
||||
$option = self::setUserVars($user, $option);
|
||||
}
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($mountConfig['user'])) {
|
||||
foreach ($mountConfig['user'] as $mountUser => $mounts) {
|
||||
if ($user === 'all' or strtolower($mountUser) === strtolower($user)) {
|
||||
foreach ($mounts as $mountPoint => $options) {
|
||||
$mountPoint = self::setUserVars($user, $mountPoint);
|
||||
foreach ($options as &$option) {
|
||||
$option = self::setUserVars($user, $option);
|
||||
}
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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])) {
|
||||
foreach ($mountConfig['user'][$user] as $mountPoint => $options) {
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fill in the correct values for $user, and $password placeholders
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
private static function setUserVars($user, $input) {
|
||||
return str_replace('$user', $user, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the default filesystem view
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
static public function getView() {
|
||||
return self::$defaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* tear down the filesystem, removing all storage providers
|
||||
*/
|
||||
static public function tearDown() {
|
||||
self::clearMounts();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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() {
|
||||
Mount::clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* mount an \OC\Files\Storage\Storage in our virtual filesystem
|
||||
*
|
||||
* @param \OC\Files\Storage\Storage|string $class
|
||||
* @param array $arguments
|
||||
* @param string $mountpoint
|
||||
*/
|
||||
static public function mount($class, $arguments, $mountpoint) {
|
||||
new Mount($class, $mountpoint, $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) {
|
||||
$path = self::normalizePath($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);
|
||||
}
|
||||
|
||||
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 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 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
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
static public function hasUpdated($path, $time) {
|
||||
return self::$defaultInstance->hasUpdated($path, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @param string $directory path under datadirectory
|
||||
* @return array
|
||||
*/
|
||||
public static function getDirectoryContent($directory) {
|
||||
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
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
static public function getETag($path) {
|
||||
return self::$defaultInstance->getETag($path);
|
||||
}
|
||||
}
|
||||
|
||||
\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();
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files;
|
||||
|
||||
class Mount {
|
||||
/**
|
||||
* @var 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 (optional)
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return \OC\Files\Storage\Storage[]
|
||||
*/
|
||||
public static function findById($id) {
|
||||
$result = array();
|
||||
foreach (self::$mounts as $mount) {
|
||||
if ($mount->getStorageId() === $id) {
|
||||
$result[] = $mount;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,51 +1,34 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski GapczynskiM@gmail.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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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_Filestorage_Common is never used directly; it is extended by all other
|
||||
* \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_Filestorage_Common methods call functions which are first defined
|
||||
* Some \OC\Files\Storage\Common methods call functions which are first defined
|
||||
* in classes which extend it, e.g. $this->stat() .
|
||||
*/
|
||||
|
||||
abstract class OC_Filestorage_Common extends OC_Filestorage {
|
||||
abstract class Common implements \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
|
||||
|
@ -55,29 +38,40 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
|
|||
}
|
||||
}
|
||||
public function isCreatable($path) {
|
||||
return $this->isUpdatable($path);
|
||||
if ($this->is_dir($path) && $this->isUpdatable($path)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// 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 getPermissions($path){
|
||||
$permissions = 0;
|
||||
if($this->isCreatable($path)){
|
||||
$permissions |= \OCP\PERMISSION_CREATE;
|
||||
}
|
||||
if($this->isReadable($path)){
|
||||
$permissions |= \OCP\PERMISSION_READ;
|
||||
}
|
||||
if($this->isUpdatable($path)){
|
||||
$permissions |= \OCP\PERMISSION_UPDATE;
|
||||
}
|
||||
if($this->isDeletable($path)){
|
||||
$permissions |= \OCP\PERMISSION_DELETE;
|
||||
}
|
||||
if($this->isSharable($path)){
|
||||
$permissions |= \OCP\PERMISSION_SHARE;
|
||||
}
|
||||
return $permissions;
|
||||
}
|
||||
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) {
|
||||
|
@ -89,94 +83,58 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
|
|||
}
|
||||
return fread($handle, $size);
|
||||
}
|
||||
public function file_put_contents($path, $data) {
|
||||
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)) {
|
||||
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);
|
||||
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
|
||||
* @param string $directory The directory whose contents will be deleted
|
||||
* @param bool $empty Flag indicating whether directory will be emptied
|
||||
* @returns bool
|
||||
*
|
||||
* @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 );
|
||||
|
||||
}
|
||||
$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 ) ) {
|
||||
|
||||
} elseif( !$this->isReadable( \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 );
|
||||
|
||||
$this->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;
|
||||
}
|
||||
|
||||
|
@ -188,73 +146,71 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
|
|||
if($this->is_dir($path)) {
|
||||
return 'httpd/unix-directory';
|
||||
}
|
||||
$source=$this->fopen($path, 'r');
|
||||
$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);
|
||||
$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);
|
||||
$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);
|
||||
public function hash($type,$path,$raw = false) {
|
||||
$tmpFile=$this->getLocalFile($path);
|
||||
$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');
|
||||
private function toTmpFile($path) {//no longer in the storage api, still useful here
|
||||
$source=$this->fopen($path,'r');
|
||||
if(!$source) {
|
||||
return false;
|
||||
}
|
||||
if($pos=strrpos($path, '.')) {
|
||||
$extension=substr($path, $pos);
|
||||
if($pos=strrpos($path,'.')) {
|
||||
$extension=substr($path,$pos);
|
||||
}else{
|
||||
$extension='';
|
||||
}
|
||||
$tmpFile=OC_Helper::tmpFile($extension);
|
||||
$target=fopen($tmpFile, 'w');
|
||||
OC_Helper::streamCopy($source, $target);
|
||||
$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);
|
||||
$baseDir=\OC_Helper::tmpFolder();
|
||||
$this->addLocalFolder($path,$baseDir);
|
||||
return $baseDir;
|
||||
}
|
||||
private function addLocalFolder($path, $target) {
|
||||
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);
|
||||
$this->addLocalFolder($path.'/'.$file,$target.'/'.$file);
|
||||
}else{
|
||||
$tmp=$this->toTmpFile($path.'/'.$file);
|
||||
rename($tmp, $target.'/'.$file);
|
||||
rename($tmp,$target.'/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// abstract public function touch($path, $mtime=null);
|
||||
|
||||
protected function searchInDir($query, $dir='') {
|
||||
protected function searchInDir($query,$dir='') {
|
||||
$files=array();
|
||||
$dh=$this->opendir($dir);
|
||||
if($dh) {
|
||||
|
@ -264,7 +220,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
|
|||
$files[]=$dir.'/'.$item;
|
||||
}
|
||||
if($this->is_dir($dir.'/'.$item)) {
|
||||
$files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item));
|
||||
$files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,19 +229,52 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
|
|||
|
||||
/**
|
||||
* check if a file or folder has been updated since $time
|
||||
* @param string $path
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUpdated($path, $time) {
|
||||
public function hasUpdated($path,$time) {
|
||||
return $this->filemtime($path)>$time;
|
||||
}
|
||||
|
||||
public function getCache($path=''){
|
||||
return new \OC\Files\Cache\Cache($this);
|
||||
}
|
||||
|
||||
public function getScanner($path=''){
|
||||
return new \OC\Files\Cache\Scanner($this);
|
||||
}
|
||||
|
||||
public function getPermissionsCache($path=''){
|
||||
return new \OC\Files\Cache\Permissions($this);
|
||||
}
|
||||
|
||||
public function getWatcher($path=''){
|
||||
return new \OC\Files\Cache\Watcher($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the owner of a path
|
||||
* @param $path The path to get the owner
|
||||
* @param string $path The path to get the owner
|
||||
* @return string uid or false
|
||||
*/
|
||||
public function getOwner($path) {
|
||||
return OC_User::getUser();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,20 +22,25 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* test implementation for OC_FileStorage_Common with OC_FileStorage_Local
|
||||
* test implementation for \OC\Files\Storage\Common with \OC\Files\Storage\Local
|
||||
*/
|
||||
|
||||
class OC_Filestorage_CommonTest extends OC_Filestorage_Common{
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
class CommonTest extends \OC\Files\Storage\Common{
|
||||
/**
|
||||
* underlying local storage used for missing functions
|
||||
* @var OC_FileStorage_Local
|
||||
* @var \OC\Files\Storage\Local
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
public function __construct($params) {
|
||||
$this->storage=new OC_Filestorage_Local($params);
|
||||
$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);
|
||||
}
|
|
@ -1,8 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 OC_Filestorage_Local extends OC_Filestorage_Common{
|
||||
class Local extends \OC\Files\Storage\Common{
|
||||
protected $datadir;
|
||||
public function __construct($arguments) {
|
||||
$this->datadir=$arguments['datadir'];
|
||||
|
@ -10,6 +19,9 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
|
|||
$this->datadir.='/';
|
||||
}
|
||||
}
|
||||
public function getId(){
|
||||
return 'local::'.$this->datadir;
|
||||
}
|
||||
public function mkdir($path) {
|
||||
return @mkdir($this->datadir.$path);
|
||||
}
|
||||
|
@ -20,7 +32,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
|
|||
return opendir($this->datadir.$path);
|
||||
}
|
||||
public function is_dir($path) {
|
||||
if(substr($path, -1)=='/') {
|
||||
if(substr($path,-1)=='/') {
|
||||
$path=substr($path, 0, -1);
|
||||
}
|
||||
return is_dir($this->datadir.$path);
|
||||
|
@ -68,9 +80,6 @@ class OC_Filestorage_Local extends OC_Filestorage_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);
|
||||
}
|
||||
|
@ -100,11 +109,11 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
|
|||
}
|
||||
public function rename($path1, $path2) {
|
||||
if (!$this->isUpdatable($path1)) {
|
||||
OC_Log::write('core', 'unable to rename, file is not writable : '.$path1, OC_Log::ERROR);
|
||||
\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);
|
||||
\OC_Log::write('core','unable to rename, file does not exists : '.$path1,\OC_Log::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -143,7 +152,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
|
|||
|
||||
public function getMimeType($path) {
|
||||
if($this->isReadable($path)) {
|
||||
return OC_Helper::getMimeType($this->datadir.$path);
|
||||
return \OC_Helper::getMimeType($this->datadir . $path);
|
||||
}else{
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
/**
|
||||
* Provide a common interface to all different storage options
|
||||
*/
|
||||
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
|
||||
* @return bool
|
||||
*
|
||||
* hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
|
||||
* returning true for other changes in the folder is optional
|
||||
*/
|
||||
public function hasUpdated($path,$time);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return \OC\Files\Cache\Cache
|
||||
*/
|
||||
public function getCache($path='');
|
||||
/**
|
||||
* @param string $path
|
||||
* @return \OC\Files\Cache\Scanner
|
||||
*/
|
||||
public function getScanner($path='');
|
||||
|
||||
public function getOwner($path);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return \OC\Files\Cache\Permissions
|
||||
*/
|
||||
public function getPermissionsCache($path='');
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return \OC\Files\Cache\Watcher
|
||||
*/
|
||||
public function getWatcher($path='');
|
||||
|
||||
/**
|
||||
* get the ETag for a file or folder
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getETag($path);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 Local{
|
||||
public function __construct($arguments) {
|
||||
$this->datadir=\OC_Helper::tmpFolder();
|
||||
}
|
||||
|
||||
public function cleanUp() {
|
||||
\OC_Helper::rmdirr($this->datadir);
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->cleanUp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -1,54 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
class OC_FakeDirStream{
|
||||
public static $dirs=array();
|
||||
private $name;
|
||||
private $index;
|
||||
namespace OC\Files\Stream;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
class OC_StaticStreamWrapper {
|
||||
class StaticStream {
|
||||
public $context;
|
||||
protected static $data = array();
|
||||
|
||||
protected $path = '';
|
||||
protected $path = '';
|
||||
protected $pointer = 0;
|
||||
protected $writable = false;
|
||||
|
||||
public function stream_close() {}
|
||||
public function stream_close() {
|
||||
}
|
||||
|
||||
public function stream_eof() {
|
||||
return $this->pointer >= strlen(self::$data[$this->path]);
|
||||
}
|
||||
|
||||
public function stream_flush() {}
|
||||
public function stream_flush() {
|
||||
}
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
switch ($mode[0]) {
|
||||
|
@ -213,89 +189,3 @@ class OC_StaticStreamWrapper {
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,958 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* 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 root
|
||||
*
|
||||
* @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 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 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 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
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
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);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
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 filemtime($path) {
|
||||
return $this->basicOperation('filemtime', $path);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 = 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 == Filesystem::getRoot()) {
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_create,
|
||||
array(
|
||||
Filesystem::signal_param_path => $path,
|
||||
Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_write,
|
||||
array(
|
||||
Filesystem::signal_param_path => $path,
|
||||
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 == Filesystem::getRoot()) {
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_post_create,
|
||||
array(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);
|
||||
return $count > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} 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 = 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);
|
||||
|
||||
if ($path1 == null or $path2 == null) {
|
||||
return false;
|
||||
}
|
||||
$run = true;
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME, Filesystem::signal_rename,
|
||||
array(
|
||||
Filesystem::signal_param_oldpath => $path1,
|
||||
Filesystem::signal_param_newpath => $path2,
|
||||
Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($run) {
|
||||
$mp1 = $this->getMountPoint($path1 . $postFix1);
|
||||
$mp2 = $this->getMountPoint($path2 . $postFix2);
|
||||
if ($mp1 == $mp2) {
|
||||
list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
|
||||
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
|
||||
if ($storage) {
|
||||
$result = $storage->rename($internalPath1, $internalPath2);
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
} else {
|
||||
$source = $this->fopen($path1 . $postFix1, 'r');
|
||||
$target = $this->fopen($path2 . $postFix2, 'w');
|
||||
$count = \OC_Helper::streamCopy($source, $target);
|
||||
list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
|
||||
$storage1->unlink($internalPath1);
|
||||
$result = $count > 0;
|
||||
}
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_post_rename,
|
||||
array(
|
||||
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 = 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);
|
||||
|
||||
if ($path1 == null or $path2 == null) {
|
||||
return false;
|
||||
}
|
||||
$run = true;
|
||||
$exists = $this->file_exists($path2);
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_copy,
|
||||
array(
|
||||
Filesystem::signal_param_oldpath => $path1,
|
||||
Filesystem::signal_param_newpath => $path2,
|
||||
Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
if ($run and !$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_create,
|
||||
array(
|
||||
Filesystem::signal_param_path => $path2,
|
||||
Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($run) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_write,
|
||||
array(
|
||||
Filesystem::signal_param_path => $path2,
|
||||
Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($run) {
|
||||
$mp1 = $this->getMountPoint($path1 . $postFix1);
|
||||
$mp2 = $this->getMountPoint($path2 . $postFix2);
|
||||
if ($mp1 == $mp2) {
|
||||
list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
|
||||
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
|
||||
if ($storage) {
|
||||
$result = $storage->copy($internalPath1, $internalPath2);
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
} else {
|
||||
$source = $this->fopen($path1 . $postFix1, 'r');
|
||||
$target = $this->fopen($path2 . $postFix2, 'w');
|
||||
$result = \OC_Helper::streamCopy($source, $target);
|
||||
}
|
||||
if ($this->fakeRoot == Filesystem::getRoot()) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_post_copy,
|
||||
array(
|
||||
Filesystem::signal_param_oldpath => $path1,
|
||||
Filesystem::signal_param_newpath => $path2
|
||||
)
|
||||
);
|
||||
if (!$exists) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_post_create,
|
||||
array(Filesystem::signal_param_path => $path2)
|
||||
);
|
||||
}
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_post_write,
|
||||
array(Filesystem::signal_param_path => $path2)
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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 (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;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function fromTmpFile($tmpFile, $path) {
|
||||
if (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 {
|
||||
return false;
|
||||
}
|
||||
} 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 = Filesystem::normalizePath($this->getAbsolutePath($path));
|
||||
if (\OC_FileProxy::runPreProxies('hash', $absolutePath) && Filesystem::isValidPath($path)) {
|
||||
$path = $this->getRelativePath($absolutePath);
|
||||
if ($path == null) {
|
||||
return false;
|
||||
}
|
||||
if (Filesystem::$loaded && $this->fakeRoot == Filesystem::getRoot()) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
Filesystem::signal_read,
|
||||
array(Filesystem::signal_param_path => $path)
|
||||
);
|
||||
}
|
||||
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
|
||||
if ($storage) {
|
||||
$result = $storage->hash($type, $internalPath, $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 $hooks (optional)
|
||||
* @param mixed $extraParam (optional)
|
||||
* @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 = 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;
|
||||
}
|
||||
$run = $this->runHooks($hooks, $path);
|
||||
list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
|
||||
if ($run and $storage) {
|
||||
if (!is_null($extraParam)) {
|
||||
$result = $storage->$operation($internalPath, $extraParam);
|
||||
} else {
|
||||
$result = $storage->$operation($internalPath);
|
||||
}
|
||||
$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);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function runHooks($hooks, $path, $post = false) {
|
||||
$prefix = ($post) ? 'post_' : '';
|
||||
$run = true;
|
||||
if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) {
|
||||
foreach ($hooks as $hook) {
|
||||
if ($hook != 'read') {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
$prefix . $hook,
|
||||
array(
|
||||
Filesystem::signal_param_run => &$run,
|
||||
Filesystem::signal_param_path => $path
|
||||
)
|
||||
);
|
||||
} elseif (!$post) {
|
||||
\OC_Hook::emit(
|
||||
Filesystem::CLASSNAME,
|
||||
$prefix . $hook,
|
||||
array(
|
||||
Filesystem::signal_param_path => $path
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $run;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->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) {
|
||||
$data = array();
|
||||
$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
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);
|
||||
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
|
||||
} else {
|
||||
$watcher = $storage->getWatcher($internalPath);
|
||||
$watcher->checkUpdate($internalPath);
|
||||
}
|
||||
|
||||
$data = $cache->get($internalPath);
|
||||
|
||||
if ($data and $data['fileid']) {
|
||||
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);
|
||||
if ($subStorage) {
|
||||
$subCache = $subStorage->getCache('');
|
||||
$rootEntry = $subCache->get('');
|
||||
$data['size'] += $rootEntry['size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$permissions = $permissionsCache->get($data['fileid'], $user);
|
||||
if ($permissions === -1) {
|
||||
$permissions = $storage->getPermissions($internalPath);
|
||||
$permissionsCache->set($data['fileid'], $user, $permissions);
|
||||
}
|
||||
$data['permissions'] = $permissions;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the content of a directory
|
||||
*
|
||||
* @param string $directory path under datadirectory
|
||||
* @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);
|
||||
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);
|
||||
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
|
||||
} else {
|
||||
$watcher = $storage->getWatcher($internalPath);
|
||||
$watcher->checkUpdate($internalPath);
|
||||
}
|
||||
|
||||
$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'];
|
||||
|
||||
$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
|
||||
$mountPoints = Filesystem::getMountPoints($path);
|
||||
$dirLength = strlen($path);
|
||||
foreach ($mountPoints as $mountPoint) {
|
||||
$subStorage = Filesystem::getStorage($mountPoint);
|
||||
if ($subStorage) {
|
||||
$subCache = $subStorage->getCache('');
|
||||
|
||||
if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) {
|
||||
$subScanner = $subStorage->getScanner('');
|
||||
$subScanner->scanFile('');
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
//remove any existing entry with the same name
|
||||
foreach ($files as $i => $file) {
|
||||
if ($file['name'] === $rootEntry['name']) {
|
||||
unset($files[$i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$files[] = $rootEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* change file metadata
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @return int
|
||||
*
|
||||
* returns the fileid of the updated file
|
||||
*/
|
||||
public function putFileInfo($path, $data) {
|
||||
$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage $storage
|
||||
* @var string $internalPath
|
||||
*/
|
||||
list($storage, $internalPath) = Filesystem::resolvePath($path);
|
||||
if ($storage) {
|
||||
$cache = $storage->getCache($path);
|
||||
|
||||
if (!$cache->inCache($internalPath)) {
|
||||
$scanner = $storage->getScanner($internalPath);
|
||||
$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
|
||||
}
|
||||
|
||||
return $cache->put($internalPath, $data);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files with the name matching $query
|
||||
*
|
||||
* @param string $query
|
||||
* @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);
|
||||
|
||||
$mountPoint = Filesystem::getMountPoint($this->fakeRoot);
|
||||
$storage = Filesystem::getStorage($mountPoint);
|
||||
if ($storage) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
if ($storage) {
|
||||
return $storage->getETag($internalPath);
|
||||
} else {
|
||||
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);
|
||||
$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;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide a common interface to all different storage options
|
||||
*/
|
||||
abstract class OC_Filestorage{
|
||||
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);
|
||||
abstract public function getOwner($path);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* local storage backnd in temporary folder for testing purpores
|
||||
*/
|
||||
class OC_Filestorage_Temporary extends OC_Filestorage_Local{
|
||||
public function __construct($arguments) {
|
||||
$this->datadir=OC_Helper::tmpFolder();
|
||||
}
|
||||
|
||||
public function cleanUp() {
|
||||
OC_Helper::rmdirr($this->datadir);
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->cleanUp();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue