aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/files/filesystem.php629
-rw-r--r--lib/files/view.php (renamed from lib/filesystemview.php)387
-rw-r--r--lib/filesystem.php562
3 files changed, 835 insertions, 743 deletions
diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php
new file mode 100644
index 00000000000..d0a96b59a0e
--- /dev/null
+++ b/lib/files/filesystem.php
@@ -0,0 +1,629 @@
+<?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 emited in that order)
+ * post_create(path)
+ * delete(path, &run)
+ * post_delete(path)
+ * rename(oldpath,newpath, &run)
+ * post_rename(oldpath,newpath)
+ * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order)
+ * post_rename(oldpath,newpath)
+ *
+ * the &run parameter can be set to false to prevent the operation from occuring
+ */
+
+namespace OC\Files;
+
+class Filesystem {
+ static private $storages = array();
+ static private $mounts = array();
+ public static $loaded = false;
+ /**
+ * @var \OC\Files\Storage\Storage $defaultInstance
+ */
+ static private $defaultInstance;
+
+
+ /**
+ * classname which used for hooks handling
+ * used as signalclass in OC_Hooks::emit()
+ */
+ const CLASSNAME = 'OC_Filesystem';
+
+ /**
+ * signalname emited before file renaming
+ *
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_rename = 'rename';
+
+ /**
+ * signal emited after file renaming
+ *
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_rename = 'post_rename';
+
+ /**
+ * signal emited before file/dir creation
+ *
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_create = 'create';
+
+ /**
+ * signal emited after file/dir creation
+ *
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_post_create = 'post_create';
+
+ /**
+ * signal emits before file/dir copy
+ *
+ * @param oldpath
+ * @param newpath
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_copy = 'copy';
+
+ /**
+ * signal emits after file/dir copy
+ *
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_copy = 'post_copy';
+
+ /**
+ * signal emits before file/dir save
+ *
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_write = 'write';
+
+ /**
+ * signal emits after file/dir save
+ *
+ * @param path
+ */
+ const signal_post_write = 'post_write';
+
+ /**
+ * signal emits when reading file/dir
+ *
+ * @param path
+ */
+ const signal_read = 'read';
+
+ /**
+ * signal emits when removing file/dir
+ *
+ * @param path
+ */
+ const signal_delete = 'delete';
+
+ /**
+ * parameters definitions for signals
+ */
+ const signal_param_path = 'path';
+ const signal_param_oldpath = 'oldpath';
+ const signal_param_newpath = 'newpath';
+
+ /**
+ * run - changing this flag to false in hook handler will cancel event
+ */
+ const signal_param_run = 'run';
+
+ /**
+ * get the mountpoint of the storage object for a path
+ ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
+ *
+ * @param string path
+ * @return string
+ */
+ static public function getMountPoint($path) {
+ OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path));
+ if (!$path) {
+ $path = '/';
+ }
+ if ($path[0] !== '/') {
+ $path = '/' . $path;
+ }
+ $path = str_replace('//', '/', $path);
+ $foundMountPoint = '';
+ $mountPoints = array_keys(OC_Filesystem::$mounts);
+ foreach ($mountPoints as $mountpoint) {
+ if ($mountpoint == $path) {
+ return $mountpoint;
+ }
+ if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) {
+ $foundMountPoint = $mountpoint;
+ }
+ }
+ return $foundMountPoint;
+ }
+
+ /**
+ * get the part of the path relative to the mountpoint of the storage it's stored in
+ *
+ * @param string path
+ * @return bool
+ */
+ static public function getInternalPath($path) {
+ $mountPoint = self::getMountPoint($path);
+ $internalPath = substr($path, strlen($mountPoint));
+ return $internalPath;
+ }
+
+ /**
+ * get the storage object for a path
+ *
+ * @param string path
+ * @return \OC\Files\Storage\Storage
+ */
+ static public function getStorage($path) {
+ $mountpoint = self::getMountPoint($path);
+ if ($mountpoint) {
+ if (!isset(OC_Filesystem::$storages[$mountpoint])) {
+ $mount = OC_Filesystem::$mounts[$mountpoint];
+ OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']);
+ }
+ return OC_Filesystem::$storages[$mountpoint];
+ }
+ }
+
+ /**
+ * resolve a path to a storage and internal path
+ *
+ * @param string $path
+ * @return array consisting of the storage and the internal path
+ */
+ static public function resolvePath($path) {
+ $mountpoint = self::getMountPoint($path);
+ if ($mountpoint) {
+ if (!isset(OC_Filesystem::$storages[$mountpoint])) {
+ $mount = OC_Filesystem::$mounts[$mountpoint];
+ OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']);
+ }
+ $storage = OC_Filesystem::$storages[$mountpoint];
+ $internalPath = substr($path, strlen($mountpoint));
+ return array($storage, $internalPath);
+ }
+ }
+
+ static public function init($root) {
+ if (self::$defaultInstance) {
+ return false;
+ }
+ self::$defaultInstance = new OC_FilesystemView($root);
+
+//load custom mount config
+ if (is_file(OC::$SERVERROOT . '/config/mount.php')) {
+ $mountConfig = include(OC::$SERVERROOT . '/config/mount.php');
+ if (isset($mountConfig['global'])) {
+ foreach ($mountConfig['global'] as $mountPoint => $options) {
+ self::mount($options['class'], $options['options'], $mountPoint);
+ }
+ }
+
+ if (isset($mountConfig['group'])) {
+ foreach ($mountConfig['group'] as $group => $mounts) {
+ if (OC_Group::inGroup(OC_User::getUser(), $group)) {
+ foreach ($mounts as $mountPoint => $options) {
+ $mountPoint = self::setUserVars($mountPoint);
+ foreach ($options as &$option) {
+ $option = self::setUserVars($option);
+ }
+ self::mount($options['class'], $options['options'], $mountPoint);
+ }
+ }
+ }
+ }
+
+ if (isset($mountConfig['user'])) {
+ foreach ($mountConfig['user'] as $user => $mounts) {
+ if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) {
+ foreach ($mounts as $mountPoint => $options) {
+ $mountPoint = self::setUserVars($mountPoint);
+ foreach ($options as &$option) {
+ $option = self::setUserVars($option);
+ }
+ self::mount($options['class'], $options['options'], $mountPoint);
+ }
+ }
+ }
+ }
+ }
+
+ self::$loaded = true;
+ }
+
+ /**
+ * fill in the correct values for $user, and $password placeholders
+ *
+ * @param string intput
+ * @return string
+ */
+ private static function setUserVars($input) {
+ return str_replace('$user', OC_User::getUser(), $input);
+ }
+
+ /**
+ * get the default filesystem view
+ *
+ * @return OC_FilesystemView
+ */
+ static public function getView() {
+ return self::$defaultInstance;
+ }
+
+ /**
+ * tear down the filesystem, removing all storage providers
+ */
+ static public function tearDown() {
+ self::$storages = array();
+ }
+
+ /**
+ * create a new storage of a specific type
+ *
+ * @param string type
+ * @param array arguments
+ * @return \OC\Files\Storage\Storage
+ */
+ static private function createStorage($class, $arguments) {
+ if (class_exists($class)) {
+ try {
+ return new $class($arguments);
+ } catch (Exception $exception) {
+ OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR);
+ return false;
+ }
+ } else {
+ OC_Log::write('core', 'storage backend ' . $class . ' not found', OC_Log::ERROR);
+ return false;
+ }
+ }
+
+ /**
+ * change the root to a fake root
+ *
+ * @param string fakeRoot
+ * @return bool
+ */
+ static public function chroot($fakeRoot) {
+ return self::$defaultInstance->chroot($fakeRoot);
+ }
+
+ /**
+ * @brief get the relative path of the root data directory for the current user
+ * @return string
+ *
+ * Returns path like /admin/files
+ */
+ static public function getRoot() {
+ return self::$defaultInstance->getRoot();
+ }
+
+ /**
+ * clear all mounts and storage backends
+ */
+ public static function clearMounts() {
+ self::$mounts = array();
+ self::$storages = array();
+ }
+
+ /**
+ * mount an \OC\Files\Storage\Storage in our virtual filesystem
+ *
+ * @param \OC\Files\Storage\Storage storage
+ * @param string mountpoint
+ */
+ static public function mount($class, $arguments, $mountpoint) {
+ if ($mountpoint[0] != '/') {
+ $mountpoint = '/' . $mountpoint;
+ }
+ if (substr($mountpoint, -1) !== '/') {
+ $mountpoint = $mountpoint . '/';
+ }
+ self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments);
+ }
+
+ /**
+ * return the path to a local version of the file
+ * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed
+ *
+ * @param string path
+ * @return string
+ */
+ static public function getLocalFile($path) {
+ return self::$defaultInstance->getLocalFile($path);
+ }
+
+ /**
+ * @param string path
+ * @return string
+ */
+ static public function getLocalFolder($path) {
+ return self::$defaultInstance->getLocalFolder($path);
+ }
+
+ /**
+ * return path to file which reflects one visible in browser
+ *
+ * @param string path
+ * @return string
+ */
+ static public function getLocalPath($path) {
+ $datadir = OC_User::getHome(OC_User::getUser()) . '/files';
+ $newpath = $path;
+ if (strncmp($newpath, $datadir, strlen($datadir)) == 0) {
+ $newpath = substr($path, strlen($datadir));
+ }
+ return $newpath;
+ }
+
+ /**
+ * check if the requested path is valid
+ *
+ * @param string path
+ * @return bool
+ */
+ static public function isValidPath($path) {
+ if (!$path || $path[0] !== '/') {
+ $path = '/' . $path;
+ }
+ if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * checks if a file is blacklisted for storage in the filesystem
+ * Listens to write and rename hooks
+ *
+ * @param array $data from hook
+ */
+ static public function isBlacklisted($data) {
+ $blacklist = array('.htaccess');
+ if (isset($data['path'])) {
+ $path = $data['path'];
+ } else if (isset($data['newpath'])) {
+ $path = $data['newpath'];
+ }
+ if (isset($path)) {
+ $filename = strtolower(basename($path));
+ if (in_array($filename, $blacklist)) {
+ $data['run'] = false;
+ }
+ }
+ }
+
+ /**
+ * following functions are equivalent to their php builtin equivalents for arguments/return values.
+ */
+ static public function mkdir($path) {
+ return self::$defaultInstance->mkdir($path);
+ }
+
+ static public function rmdir($path) {
+ return self::$defaultInstance->rmdir($path);
+ }
+
+ static public function opendir($path) {
+ return self::$defaultInstance->opendir($path);
+ }
+
+ static public function readdir($path) {
+ return self::$defaultInstance->readdir($path);
+ }
+
+ static public function is_dir($path) {
+ return self::$defaultInstance->is_dir($path);
+ }
+
+ static public function is_file($path) {
+ return self::$defaultInstance->is_file($path);
+ }
+
+ static public function stat($path) {
+ return self::$defaultInstance->stat($path);
+ }
+
+ static public function filetype($path) {
+ return self::$defaultInstance->filetype($path);
+ }
+
+ static public function filesize($path) {
+ return self::$defaultInstance->filesize($path);
+ }
+
+ static public function readfile($path) {
+ return self::$defaultInstance->readfile($path);
+ }
+
+ /**
+ * @deprecated Replaced by isReadable() as part of CRUDS
+ */
+ static public function is_readable($path) {
+ return self::$defaultInstance->is_readable($path);
+ }
+
+ /**
+ * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS
+ */
+ static public function is_writable($path) {
+ return self::$defaultInstance->is_writable($path);
+ }
+
+ static public function isCreatable($path) {
+ return self::$defaultInstance->isCreatable($path);
+ }
+
+ static public function isReadable($path) {
+ return self::$defaultInstance->isReadable($path);
+ }
+
+ static public function isUpdatable($path) {
+ return self::$defaultInstance->isUpdatable($path);
+ }
+
+ static public function isDeletable($path) {
+ return self::$defaultInstance->isDeletable($path);
+ }
+
+ static public function isSharable($path) {
+ return self::$defaultInstance->isSharable($path);
+ }
+
+ static public function file_exists($path) {
+ return self::$defaultInstance->file_exists($path);
+ }
+
+ static public function filectime($path) {
+ return self::$defaultInstance->filectime($path);
+ }
+
+ static public function filemtime($path) {
+ return self::$defaultInstance->filemtime($path);
+ }
+
+ static public function touch($path, $mtime = null) {
+ return self::$defaultInstance->touch($path, $mtime);
+ }
+
+ static public function file_get_contents($path) {
+ return self::$defaultInstance->file_get_contents($path);
+ }
+
+ static public function file_put_contents($path, $data) {
+ return self::$defaultInstance->file_put_contents($path, $data);
+ }
+
+ static public function unlink($path) {
+ return self::$defaultInstance->unlink($path);
+ }
+
+ static public function rename($path1, $path2) {
+ return self::$defaultInstance->rename($path1, $path2);
+ }
+
+ static public function copy($path1, $path2) {
+ return self::$defaultInstance->copy($path1, $path2);
+ }
+
+ static public function fopen($path, $mode) {
+ return self::$defaultInstance->fopen($path, $mode);
+ }
+
+ static public function toTmpFile($path) {
+ return self::$defaultInstance->toTmpFile($path);
+ }
+
+ static public function fromTmpFile($tmpFile, $path) {
+ return self::$defaultInstance->fromTmpFile($tmpFile, $path);
+ }
+
+ static public function getMimeType($path) {
+ return self::$defaultInstance->getMimeType($path);
+ }
+
+ static public function hash($type, $path, $raw = false) {
+ return self::$defaultInstance->hash($type, $path, $raw);
+ }
+
+ static public function free_space($path = '/') {
+ return self::$defaultInstance->free_space($path);
+ }
+
+ static public function search($query) {
+ return OC_FileCache::search($query);
+ }
+
+ /**
+ * check if a file or folder has been updated since $time
+ *
+ * @param int $time
+ * @return bool
+ */
+ static public function hasUpdated($path, $time) {
+ return self::$defaultInstance->hasUpdated($path, $time);
+ }
+
+ static public function removeETagHook($params, $root = false) {
+ if (isset($params['path'])) {
+ $path = $params['path'];
+ } else {
+ $path = $params['oldpath'];
+ }
+
+ if ($root) { // reduce path to the required part of it (no 'username/files')
+ $fakeRootView = new OC_FilesystemView($root);
+ $count = 1;
+ $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count);
+ }
+
+ $path = self::normalizePath($path);
+ OC_Connector_Sabre_Node::removeETagPropertyForPath($path);
+ }
+
+ /**
+ * normalize a path
+ *
+ * @param string path
+ * @param bool $stripTrailingSlash
+ * @return string
+ */
+ public static function normalizePath($path, $stripTrailingSlash = true) {
+ if ($path == '') {
+ return '/';
+ }
+//no windows style slashes
+ $path = str_replace('\\', '/', $path);
+//add leading slash
+ if ($path[0] !== '/') {
+ $path = '/' . $path;
+ }
+//remove trainling slash
+ if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') {
+ $path = substr($path, 0, -1);
+ }
+//remove duplicate slashes
+ while (strpos($path, '//') !== false) {
+ $path = str_replace('//', '/', $path);
+ }
+//normalize unicode if possible
+ if (class_exists('Normalizer')) {
+ $path = Normalizer::normalize($path);
+ }
+ return $path;
+ }
+}
+
+OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook');
+OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook');
+OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook');
+
+OC_Util::setupFS();
diff --git a/lib/filesystemview.php b/lib/files/view.php
index 071fc781f12..8c3f288f445 100644
--- a/lib/filesystemview.php
+++ b/lib/files/view.php
@@ -1,26 +1,11 @@
<?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/>.
+ * 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
@@ -38,41 +23,45 @@
* \OC\Files\Storage\Storage object
*/
-class OC_FilesystemView {
- private $fakeRoot='';
- private $internal_path_cache=array();
- private $storage_cache=array();
+namespace OC\Files;
+
+class View {
+ private $fakeRoot = '';
+ private $internal_path_cache = array();
+ private $storage_cache = array();
public function __construct($root) {
- $this->fakeRoot=$root;
+ $this->fakeRoot = $root;
}
public function getAbsolutePath($path) {
- if(!$path) {
- $path='/';
+ if (!$path) {
+ $path = '/';
}
- if($path[0]!=='/') {
- $path='/'.$path;
+ if ($path[0] !== '/') {
+ $path = '/' . $path;
}
- return $this->fakeRoot.$path;
+ return $this->fakeRoot . $path;
}
/**
- * change the root to a fake toor
- * @param string fakeRoot
- * @return bool
- */
+ * change the root to a fake toor
+ *
+ * @param string fakeRoot
+ * @return bool
+ */
public function chroot($fakeRoot) {
- if(!$fakeRoot=='') {
- if($fakeRoot[0]!=='/') {
- $fakeRoot='/'.$fakeRoot;
+ if (!$fakeRoot == '') {
+ if ($fakeRoot[0] !== '/') {
+ $fakeRoot = '/' . $fakeRoot;
}
}
- $this->fakeRoot=$fakeRoot;
+ $this->fakeRoot = $fakeRoot;
}
/**
* get the fake root
+ *
* @return string
*/
public function getRoot() {
@@ -80,10 +69,11 @@ class OC_FilesystemView {
}
/**
- * get the part of the path relative to the mountpoint of the storage it's stored in
- * @param string path
- * @return bool
- */
+ * get the part of the path relative to the mountpoint of the storage it's stored in
+ *
+ * @param string path
+ * @return bool
+ */
public function getInternalPath($path) {
if (!isset($this->internal_path_cache[$path])) {
$this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path));
@@ -93,30 +83,32 @@ class OC_FilesystemView {
/**
* get path relative to the root of the view
+ *
* @param string path
* @return string
*/
public function getRelativePath($path) {
- if($this->fakeRoot=='') {
+ if ($this->fakeRoot == '') {
return $path;
}
- if(strpos($path, $this->fakeRoot)!==0) {
+ if (strpos($path, $this->fakeRoot) !== 0) {
return null;
- }else{
- $path=substr($path, strlen($this->fakeRoot));
- if(strlen($path)===0) {
+ } else {
+ $path = substr($path, strlen($this->fakeRoot));
+ if (strlen($path) === 0) {
return '/';
- }else{
+ } else {
return $path;
}
}
}
/**
- * get the storage object for a path
- * @param string path
- * @return \OC\Files\Storage\Storage
- */
+ * get the storage object for a path
+ *
+ * @param string path
+ * @return \OC\Files\Storage\Storage
+ */
public function getStorage($path) {
if (!isset($this->storage_cache[$path])) {
$this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path));
@@ -125,35 +117,37 @@ class OC_FilesystemView {
}
/**
- * get the mountpoint of the storage object for a 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
- */
+ *
+ * @param string path
+ * @return string
+ */
public function getMountPoint($path) {
return OC_Filesystem::getMountPoint($this->getAbsolutePath($path));
}
/**
- * return the path to a local version of the file
- * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed
- * @param string path
- * @return string
- */
+ * return the path to a local version of the file
+ * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed
+ *
+ * @param string path
+ * @return string
+ */
public function getLocalFile($path) {
- $parent=substr($path, 0, strrpos($path,'/'));
- if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) {
+ $parent = substr($path, 0, strrpos($path, '/'));
+ if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) {
return $storage->getLocalFile($this->getInternalPath($path));
}
}
+
/**
* @param string path
* @return string
*/
public function getLocalFolder($path) {
- $parent=substr($path, 0, strrpos($path,'/'));
- if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) {
+ $parent = substr($path, 0, strrpos($path, '/'));
+ if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) {
return $storage->getLocalFolder($this->getInternalPath($path));
}
}
@@ -166,105 +160,127 @@ class OC_FilesystemView {
public function mkdir($path) {
return $this->basicOperation('mkdir', $path, array('create', 'write'));
}
+
public function rmdir($path) {
return $this->basicOperation('rmdir', $path, array('delete'));
}
+
public function opendir($path) {
return $this->basicOperation('opendir', $path, array('read'));
}
+
public function readdir($handle) {
- $fsLocal= new \OC\Files\Storage\Local( array( 'datadir' => '/' ) );
- return $fsLocal->readdir( $handle );
+ $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/'));
+ return $fsLocal->readdir($handle);
}
+
public function is_dir($path) {
- if($path=='/') {
+ if ($path == '/') {
return true;
}
return $this->basicOperation('is_dir', $path);
}
+
public function is_file($path) {
- if($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');
+ $handle = $this->fopen($path, 'rb');
if ($handle) {
- $chunkSize = 8192;// 8 MB chunks
+ $chunkSize = 8192; // 8 MB chunks
while (!feof($handle)) {
echo fread($handle, $chunkSize);
flush();
}
- $size=$this->filesize($path);
+ $size = $this->filesize($path);
return $size;
}
return false;
}
+
/**
- * @deprecated Replaced by isReadable() as part of CRUDS
- */
+ * @deprecated Replaced by isReadable() as part of CRUDS
+ */
public function is_readable($path) {
- return $this->basicOperation('isReadable',$path);
+ return $this->basicOperation('isReadable', $path);
}
+
/**
- * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS
- */
+ * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS
+ */
public function is_writable($path) {
- return $this->basicOperation('isUpdatable',$path);
+ return $this->basicOperation('isUpdatable', $path);
}
+
public function isCreatable($path) {
return $this->basicOperation('isCreatable', $path);
}
+
public function isReadable($path) {
return $this->basicOperation('isReadable', $path);
}
+
public function isUpdatable($path) {
return $this->basicOperation('isUpdatable', $path);
}
+
public function isDeletable($path) {
return $this->basicOperation('isDeletable', $path);
}
+
public function isSharable($path) {
return $this->basicOperation('isSharable', $path);
}
+
public function file_exists($path) {
- if($path=='/') {
+ if ($path == '/') {
return true;
}
return $this->basicOperation('file_exists', $path);
}
+
public function filectime($path) {
return $this->basicOperation('filectime', $path);
}
+
public function filemtime($path) {
return $this->basicOperation('filemtime', $path);
}
- public function touch($path, $mtime=null) {
+
+ public function touch($path, $mtime = null) {
return $this->basicOperation('touch', $path, array('write'), $mtime);
}
+
public function file_get_contents($path) {
return $this->basicOperation('file_get_contents', $path, array('read'));
}
+
public function file_put_contents($path, $data) {
- if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier
+ if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
$absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path));
if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) {
$path = $this->getRelativePath($absolutePath);
$exists = $this->file_exists($path);
$run = true;
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
- if(!$exists) {
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
+ if (!$exists) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_create,
@@ -283,83 +299,86 @@ class OC_FilesystemView {
)
);
}
- if(!$run) {
+ if (!$run) {
return false;
}
- $target=$this->fopen($path, 'w');
- if($target) {
- $count=OC_Helper::streamCopy($data, $target);
+ $target = $this->fopen($path, 'w');
+ if ($target) {
+ $count = OC_Helper::streamCopy($data, $target);
fclose($target);
fclose($data);
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
- if(!$exists) {
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
+ if (!$exists) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_create,
- array( OC_Filesystem::signal_param_path => $path)
+ array(OC_Filesystem::signal_param_path => $path)
);
}
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_write,
- array( OC_Filesystem::signal_param_path => $path)
+ array(OC_Filesystem::signal_param_path => $path)
);
}
OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count);
return $count > 0;
- }else{
+ } else {
return false;
}
}
- }else{
+ } 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 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)==='/')?'/':'';
+ $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : '';
+ $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : '';
$absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1));
$absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2));
- if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ if (OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
$path1 = $this->getRelativePath($absolutePath1);
$path2 = $this->getRelativePath($absolutePath2);
- if($path1 == null or $path2 == null) {
+ if ($path1 == null or $path2 == null) {
return false;
}
- $run=true;
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
+ $run = true;
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename,
- array(
- OC_Filesystem::signal_param_oldpath => $path1,
- OC_Filesystem::signal_param_newpath => $path2,
- OC_Filesystem::signal_param_run => &$run
- )
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
);
}
- if($run) {
- $mp1 = $this->getMountPoint($path1.$postFix1);
- $mp2 = $this->getMountPoint($path2.$postFix2);
- if($mp1 == $mp2) {
- if($storage = $this->getStorage($path1)) {
- $result = $storage->rename($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2));
+ if ($run) {
+ $mp1 = $this->getMountPoint($path1 . $postFix1);
+ $mp2 = $this->getMountPoint($path2 . $postFix2);
+ if ($mp1 == $mp2) {
+ if ($storage = $this->getStorage($path1)) {
+ $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2));
}
} else {
- $source = $this->fopen($path1.$postFix1, 'r');
- $target = $this->fopen($path2.$postFix2, 'w');
+ $source = $this->fopen($path1 . $postFix1, 'r');
+ $target = $this->fopen($path2 . $postFix2, 'w');
$count = OC_Helper::streamCopy($source, $target);
$storage1 = $this->getStorage($path1);
- $storage1->unlink($this->getInternalPath($path1.$postFix1));
- $result = $count>0;
+ $storage1->unlink($this->getInternalPath($path1 . $postFix1));
+ $result = $count > 0;
}
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_rename,
@@ -373,31 +392,32 @@ class OC_FilesystemView {
}
}
}
+
public function copy($path1, $path2) {
- $postFix1=(substr($path1,-1,1)==='/')?'/':'';
- $postFix2=(substr($path2,-1,1)==='/')?'/':'';
+ $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : '';
+ $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : '';
$absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1));
$absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2));
- if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ if (OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
$path1 = $this->getRelativePath($absolutePath1);
$path2 = $this->getRelativePath($absolutePath2);
- if($path1 == null or $path2 == null) {
+ if ($path1 == null or $path2 == null) {
return false;
}
- $run=true;
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
+ $run = true;
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_copy,
array(
OC_Filesystem::signal_param_oldpath => $path1,
- OC_Filesystem::signal_param_newpath=>$path2,
+ OC_Filesystem::signal_param_newpath => $path2,
OC_Filesystem::signal_param_run => &$run
)
);
- $exists=$this->file_exists($path2);
- if($run and !$exists) {
+ $exists = $this->file_exists($path2);
+ if ($run and !$exists) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_create,
@@ -407,7 +427,7 @@ class OC_FilesystemView {
)
);
}
- if($run) {
+ if ($run) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_write,
@@ -418,28 +438,28 @@ class OC_FilesystemView {
);
}
}
- if($run) {
- $mp1=$this->getMountPoint($path1.$postFix1);
- $mp2=$this->getMountPoint($path2.$postFix2);
- if($mp1 == $mp2) {
- if($storage = $this->getStorage($path1.$postFix1)) {
- $result=$storage->copy($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2));
+ if ($run) {
+ $mp1 = $this->getMountPoint($path1 . $postFix1);
+ $mp2 = $this->getMountPoint($path2 . $postFix2);
+ if ($mp1 == $mp2) {
+ if ($storage = $this->getStorage($path1 . $postFix1)) {
+ $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2));
}
} else {
- $source = $this->fopen($path1.$postFix1, 'r');
- $target = $this->fopen($path2.$postFix2, 'w');
+ $source = $this->fopen($path1 . $postFix1, 'r');
+ $target = $this->fopen($path2 . $postFix2, 'w');
$result = OC_Helper::streamCopy($source, $target);
}
- if( $this->fakeRoot==OC_Filesystem::getRoot() ){
+ if ($this->fakeRoot == OC_Filesystem::getRoot()) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_copy,
array(
OC_Filesystem::signal_param_oldpath => $path1,
- OC_Filesystem::signal_param_newpath=>$path2
+ OC_Filesystem::signal_param_newpath => $path2
)
);
- if(!$exists) {
+ if (!$exists) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_create,
@@ -449,7 +469,7 @@ class OC_FilesystemView {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_post_write,
- array( OC_Filesystem::signal_param_path => $path2)
+ array(OC_Filesystem::signal_param_path => $path2)
);
} else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions
OC_FileCache_Update::update($path2, $this->fakeRoot);
@@ -459,12 +479,13 @@ class OC_FilesystemView {
}
}
}
+
public function fopen($path, $mode) {
- $hooks=array();
- switch($mode) {
+ $hooks = array();
+ switch ($mode) {
case 'r':
case 'rb':
- $hooks[]='read';
+ $hooks[] = 'read';
break;
case 'r+':
case 'rb+':
@@ -474,8 +495,8 @@ class OC_FilesystemView {
case 'xb+':
case 'a+':
case 'ab+':
- $hooks[]='read';
- $hooks[]='write';
+ $hooks[] = 'read';
+ $hooks[] = 'write';
break;
case 'w':
case 'wb':
@@ -483,22 +504,23 @@ class OC_FilesystemView {
case 'xb':
case 'a':
case 'ab':
- $hooks[]='write';
+ $hooks[] = 'write';
break;
default:
- OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR);
+ OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, OC_Log::ERROR);
}
return $this->basicOperation('fopen', $path, $hooks, $mode);
}
+
public function toTmpFile($path) {
- if(OC_Filesystem::isValidPath($path)) {
+ if (OC_Filesystem::isValidPath($path)) {
$source = $this->fopen($path, 'r');
- if($source) {
- $extension='';
- $extOffset=strpos($path, '.');
- if($extOffset !== false) {
- $extension=substr($path, strrpos($path,'.'));
+ if ($source) {
+ $extension = '';
+ $extOffset = strpos($path, '.');
+ if ($extOffset !== false) {
+ $extension = substr($path, strrpos($path, '.'));
}
$tmpFile = OC_Helper::tmpFile($extension);
file_put_contents($tmpFile, $source);
@@ -506,13 +528,14 @@ class OC_FilesystemView {
}
}
}
+
public function fromTmpFile($tmpFile, $path) {
- if(OC_Filesystem::isValidPath($path)) {
- if(!$tmpFile) {
+ if (OC_Filesystem::isValidPath($path)) {
+ if (!$tmpFile) {
debug_print_backtrace();
}
- $source=fopen($tmpFile, 'r');
- if($source) {
+ $source = fopen($tmpFile, 'r');
+ if ($source) {
$this->file_put_contents($path, $source);
unlink($tmpFile);
return true;
@@ -526,8 +549,9 @@ class OC_FilesystemView {
public function getMimeType($path) {
return $this->basicOperation('getMimeType', $path);
}
+
public function hash($type, $path, $raw = false) {
- $postFix=(substr($path,-1,1)==='/')?'/':'';
+ $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path));
if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) {
$path = $this->getRelativePath($absolutePath);
@@ -538,11 +562,11 @@ class OC_FilesystemView {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
OC_Filesystem::signal_read,
- array( OC_Filesystem::signal_param_path => $path)
+ array(OC_Filesystem::signal_param_path => $path)
);
}
- if ($storage = $this->getStorage($path.$postFix)) {
- $result = $storage->hash($type, $this->getInternalPath($path.$postFix), $raw);
+ if ($storage = $this->getStorage($path . $postFix)) {
+ $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw);
$result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result);
return $result;
}
@@ -550,7 +574,7 @@ class OC_FilesystemView {
return null;
}
- public function free_space($path='/') {
+ public function free_space($path = '/') {
return $this->basicOperation('free_space', $path);
}
@@ -566,26 +590,26 @@ class OC_FilesystemView {
* 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)==='/')?'/':'';
+ private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) {
+ $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path));
- if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) {
+ if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) {
$path = $this->getRelativePath($absolutePath);
- if($path == null) {
+ if ($path == null) {
return false;
}
- $internalPath = $this->getInternalPath($path.$postFix);
- $run=$this->runHooks($hooks,$path);
- if($run and $storage = $this->getStorage($path.$postFix)) {
- if(!is_null($extraParam)) {
+ $internalPath = $this->getInternalPath($path . $postFix);
+ $run = $this->runHooks($hooks, $path);
+ if ($run and $storage = $this->getStorage($path . $postFix)) {
+ if (!is_null($extraParam)) {
$result = $storage->$operation($internalPath, $extraParam);
} else {
$result = $storage->$operation($internalPath);
}
$result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
- if($operation!='fopen') {//no post hooks for fopen, the file stream is still open
- $this->runHooks($hooks,$path,true);
+ if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) {
+ if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
+ $this->runHooks($hooks, $path, true);
}
}
return $result;
@@ -594,24 +618,24 @@ class OC_FilesystemView {
return null;
}
- private function runHooks($hooks,$path,$post=false) {
- $prefix=($post)?'post_':'';
- $run=true;
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
- foreach($hooks as $hook) {
- if($hook!='read') {
+ private function runHooks($hooks, $path, $post = false) {
+ $prefix = ($post) ? 'post_' : '';
+ $run = true;
+ if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) {
+ foreach ($hooks as $hook) {
+ if ($hook != 'read') {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
- $prefix.$hook,
+ $prefix . $hook,
array(
OC_Filesystem::signal_param_run => &$run,
OC_Filesystem::signal_param_path => $path
)
);
- } elseif(!$post) {
+ } elseif (!$post) {
OC_Hook::emit(
OC_Filesystem::CLASSNAME,
- $prefix.$hook,
+ $prefix . $hook,
array(
OC_Filesystem::signal_param_path => $path
)
@@ -624,6 +648,7 @@ class OC_FilesystemView {
/**
* check if a file or folder has been updated since $time
+ *
* @param int $time
* @return bool
*/
diff --git a/lib/filesystem.php b/lib/filesystem.php
index b73b52d4203..b1200f95bfa 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -22,566 +22,4 @@
*/
-/**
- * Class for abstraction of filesystem functions
- * This class won't call any filesystem functions for itself but but will pass them to the correct OC_Filestorage object
- * this class should also handle all the file permission related stuff
- *
- * Hooks provided:
- * read(path)
- * write(path, &run)
- * post_write(path)
- * create(path, &run) (when a file is created, both create and write will be emited in that order)
- * post_create(path)
- * delete(path, &run)
- * post_delete(path)
- * rename(oldpath,newpath, &run)
- * post_rename(oldpath,newpath)
- * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order)
- * post_rename(oldpath,newpath)
- *
- * the &run parameter can be set to false to prevent the operation from occuring
- */
-
-class OC_Filesystem{
- static private $storages=array();
- static private $mounts=array();
- public static $loaded=false;
- /**
- * @var \OC\Files\Storage\Storage $defaultInstance
- */
- static private $defaultInstance;
-
-
- /**
- * classname which used for hooks handling
- * used as signalclass in OC_Hooks::emit()
- */
- const CLASSNAME = 'OC_Filesystem';
-
- /**
- * signalname emited before file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_rename = 'rename';
-
- /**
- * signal emited after file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_post_rename = 'post_rename';
-
- /**
- * signal emited before file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_create = 'create';
-
- /**
- * signal emited after file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_post_create = 'post_create';
-
- /**
- * signal emits before file/dir copy
- * @param oldpath
- * @param newpath
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_copy = 'copy';
-
- /**
- * signal emits after file/dir copy
- * @param oldpath
- * @param newpath
- */
- const signal_post_copy = 'post_copy';
-
- /**
- * signal emits before file/dir save
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_write = 'write';
-
- /**
- * signal emits after file/dir save
- * @param path
- */
- const signal_post_write = 'post_write';
-
- /**
- * signal emits when reading file/dir
- * @param path
- */
- const signal_read = 'read';
-
- /**
- * signal emits when removing file/dir
- * @param path
- */
- const signal_delete = 'delete';
-
- /**
- * parameters definitions for signals
- */
- const signal_param_path = 'path';
- const signal_param_oldpath = 'oldpath';
- const signal_param_newpath = 'newpath';
-
- /**
- * run - changing this flag to false in hook handler will cancel event
- */
- const signal_param_run = 'run';
-
- /**
- * get the mountpoint of the storage object for a path
- ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
- *
- * @param string path
- * @return string
- */
- static public function getMountPoint($path) {
- OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path));
- if(!$path) {
- $path='/';
- }
- if($path[0]!=='/') {
- $path='/'.$path;
- }
- $path=str_replace('//', '/',$path);
- $foundMountPoint='';
- $mountPoints=array_keys(OC_Filesystem::$mounts);
- foreach($mountPoints as $mountpoint) {
- if($mountpoint==$path) {
- return $mountpoint;
- }
- if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)) {
- $foundMountPoint=$mountpoint;
- }
- }
- return $foundMountPoint;
- }
-
- /**
- * get the part of the path relative to the mountpoint of the storage it's stored in
- * @param string path
- * @return bool
- */
- static public function getInternalPath($path) {
- $mountPoint=self::getMountPoint($path);
- $internalPath=substr($path,strlen($mountPoint));
- return $internalPath;
- }
- /**
- * get the storage object for a path
- * @param string path
- * @return \OC\Files\Storage\Storage
- */
- static public function getStorage($path) {
- $mountpoint=self::getMountPoint($path);
- if($mountpoint) {
- if(!isset(OC_Filesystem::$storages[$mountpoint])) {
- $mount=OC_Filesystem::$mounts[$mountpoint];
- OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']);
- }
- return OC_Filesystem::$storages[$mountpoint];
- }
- }
-
- /**
- * resolve a path to a storage and internal path
- * @param string $path
- * @return array consisting of the storage and the internal path
- */
- static public function resolvePath($path){
- $mountpoint=self::getMountPoint($path);
- if($mountpoint) {
- if(!isset(OC_Filesystem::$storages[$mountpoint])) {
- $mount=OC_Filesystem::$mounts[$mountpoint];
- OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']);
- }
- $storage = OC_Filesystem::$storages[$mountpoint];
- $internalPath=substr($path,strlen($mountpoint));
- return array($storage, $internalPath);
- }
- }
-
- static public function init($root) {
- if(self::$defaultInstance) {
- return false;
- }
- self::$defaultInstance=new OC_FilesystemView($root);
-
- //load custom mount config
- if(is_file(OC::$SERVERROOT.'/config/mount.php')) {
- $mountConfig=include(OC::$SERVERROOT.'/config/mount.php');
- if(isset($mountConfig['global'])) {
- foreach($mountConfig['global'] as $mountPoint=>$options) {
- self::mount($options['class'],$options['options'],$mountPoint);
- }
- }
-
- if(isset($mountConfig['group'])) {
- foreach($mountConfig['group'] as $group=>$mounts) {
- if(OC_Group::inGroup(OC_User::getUser(),$group)) {
- foreach($mounts as $mountPoint=>$options) {
- $mountPoint=self::setUserVars($mountPoint);
- foreach($options as &$option) {
- $option=self::setUserVars($option);
- }
- self::mount($options['class'],$options['options'],$mountPoint);
- }
- }
- }
- }
-
- if(isset($mountConfig['user'])) {
- foreach($mountConfig['user'] as $user=>$mounts) {
- if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())) {
- foreach($mounts as $mountPoint=>$options) {
- $mountPoint=self::setUserVars($mountPoint);
- foreach($options as &$option) {
- $option=self::setUserVars($option);
- }
- self::mount($options['class'],$options['options'],$mountPoint);
- }
- }
- }
- }
- }
-
- self::$loaded=true;
- }
-
- /**
- * fill in the correct values for $user, and $password placeholders
- * @param string intput
- * @return string
- */
- private static function setUserVars($input) {
- return str_replace('$user',OC_User::getUser(),$input);
- }
-
- /**
- * get the default filesystem view
- * @return OC_FilesystemView
- */
- static public function getView() {
- return self::$defaultInstance;
- }
-
- /**
- * tear down the filesystem, removing all storage providers
- */
- static public function tearDown() {
- self::$storages=array();
- }
-
- /**
- * create a new storage of a specific type
- * @param string type
- * @param array arguments
- * @return \OC\Files\Storage\Storage
- */
- static private function createStorage($class,$arguments) {
- if(class_exists($class)) {
- try {
- return new $class($arguments);
- } catch (Exception $exception) {
- OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR);
- return false;
- }
- }else{
- OC_Log::write('core','storage backend '.$class.' not found',OC_Log::ERROR);
- return false;
- }
- }
-
- /**
- * change the root to a fake root
- * @param string fakeRoot
- * @return bool
- */
- static public function chroot($fakeRoot) {
- return self::$defaultInstance->chroot($fakeRoot);
- }
-
- /**
- * @brief get the relative path of the root data directory for the current user
- * @return string
- *
- * Returns path like /admin/files
- */
- static public function getRoot() {
- return self::$defaultInstance->getRoot();
- }
-
- /**
- * clear all mounts and storage backends
- */
- public static function clearMounts() {
- self::$mounts=array();
- self::$storages=array();
- }
-
- /**
- * mount an \OC\Files\Storage\Storage in our virtual filesystem
- * @param \OC\Files\Storage\Storage storage
- * @param string mountpoint
- */
- static public function mount($class,$arguments,$mountpoint) {
- if($mountpoint[0]!='/') {
- $mountpoint='/'.$mountpoint;
- }
- if(substr($mountpoint,-1)!=='/') {
- $mountpoint=$mountpoint.'/';
- }
- self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments);
- }
-
- /**
- * return the path to a local version of the file
- * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed
- * @param string path
- * @return string
- */
- static public function getLocalFile($path) {
- return self::$defaultInstance->getLocalFile($path);
- }
- /**
- * @param string path
- * @return string
- */
- static public function getLocalFolder($path) {
- return self::$defaultInstance->getLocalFolder($path);
- }
-
- /**
- * return path to file which reflects one visible in browser
- * @param string path
- * @return string
- */
- static public function getLocalPath($path) {
- $datadir = OC_User::getHome(OC_User::getUser()).'/files';
- $newpath = $path;
- if (strncmp($newpath, $datadir, strlen($datadir)) == 0) {
- $newpath = substr($path, strlen($datadir));
- }
- return $newpath;
- }
-
- /**
- * check if the requested path is valid
- * @param string path
- * @return bool
- */
- static public function isValidPath($path) {
- if(!$path || $path[0]!=='/') {
- $path='/'.$path;
- }
- if(strstr($path,'/../') || strrchr($path, '/') === '/..' ) {
- return false;
- }
- return true;
- }
-
- /**
- * checks if a file is blacklisted for storage in the filesystem
- * Listens to write and rename hooks
- * @param array $data from hook
- */
- static public function isBlacklisted($data) {
- $blacklist = array('.htaccess');
- if (isset($data['path'])) {
- $path = $data['path'];
- } else if (isset($data['newpath'])) {
- $path = $data['newpath'];
- }
- if (isset($path)) {
- $filename = strtolower(basename($path));
- if (in_array($filename, $blacklist)) {
- $data['run'] = false;
- }
- }
- }
-
- /**
- * following functions are equivalent to their php builtin equivalents for arguments/return values.
- */
- static public function mkdir($path) {
- return self::$defaultInstance->mkdir($path);
- }
- static public function rmdir($path) {
- return self::$defaultInstance->rmdir($path);
- }
- static public function opendir($path) {
- return self::$defaultInstance->opendir($path);
- }
- static public function readdir($path) {
- return self::$defaultInstance->readdir($path);
- }
- static public function is_dir($path) {
- return self::$defaultInstance->is_dir($path);
- }
- static public function is_file($path) {
- return self::$defaultInstance->is_file($path);
- }
- static public function stat($path) {
- return self::$defaultInstance->stat($path);
- }
- static public function filetype($path) {
- return self::$defaultInstance->filetype($path);
- }
- static public function filesize($path) {
- return self::$defaultInstance->filesize($path);
- }
- static public function readfile($path) {
- return self::$defaultInstance->readfile($path);
- }
- /**
- * @deprecated Replaced by isReadable() as part of CRUDS
- */
- static public function is_readable($path) {
- return self::$defaultInstance->is_readable($path);
- }
- /**
- * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS
- */
- static public function is_writable($path) {
- return self::$defaultInstance->is_writable($path);
- }
- static public function isCreatable($path) {
- return self::$defaultInstance->isCreatable($path);
- }
- static public function isReadable($path) {
- return self::$defaultInstance->isReadable($path);
- }
- static public function isUpdatable($path) {
- return self::$defaultInstance->isUpdatable($path);
- }
- static public function isDeletable($path) {
- return self::$defaultInstance->isDeletable($path);
- }
- static public function isSharable($path) {
- return self::$defaultInstance->isSharable($path);
- }
- static public function file_exists($path) {
- return self::$defaultInstance->file_exists($path);
- }
- static public function filectime($path) {
- return self::$defaultInstance->filectime($path);
- }
- static public function filemtime($path) {
- return self::$defaultInstance->filemtime($path);
- }
- static public function touch($path, $mtime=null) {
- return self::$defaultInstance->touch($path, $mtime);
- }
- static public function file_get_contents($path) {
- return self::$defaultInstance->file_get_contents($path);
- }
- static public function file_put_contents($path,$data) {
- return self::$defaultInstance->file_put_contents($path,$data);
- }
- static public function unlink($path) {
- return self::$defaultInstance->unlink($path);
- }
- static public function rename($path1,$path2) {
- return self::$defaultInstance->rename($path1,$path2);
- }
- static public function copy($path1,$path2) {
- return self::$defaultInstance->copy($path1,$path2);
- }
- static public function fopen($path,$mode) {
- return self::$defaultInstance->fopen($path,$mode);
- }
- static public function toTmpFile($path) {
- return self::$defaultInstance->toTmpFile($path);
- }
- static public function fromTmpFile($tmpFile,$path) {
- return self::$defaultInstance->fromTmpFile($tmpFile,$path);
- }
-
- static public function getMimeType($path) {
- return self::$defaultInstance->getMimeType($path);
- }
- static public function hash($type,$path, $raw = false) {
- return self::$defaultInstance->hash($type,$path, $raw);
- }
-
- static public function free_space($path='/') {
- return self::$defaultInstance->free_space($path);
- }
-
- static public function search($query) {
- return OC_FileCache::search($query);
- }
-
- /**
- * check if a file or folder has been updated since $time
- * @param int $time
- * @return bool
- */
- static public function hasUpdated($path,$time) {
- return self::$defaultInstance->hasUpdated($path,$time);
- }
-
- static public function removeETagHook($params, $root = false) {
- if (isset($params['path'])) {
- $path=$params['path'];
- } else {
- $path=$params['oldpath'];
- }
-
- if ($root) { // reduce path to the required part of it (no 'username/files')
- $fakeRootView = new OC_FilesystemView($root);
- $count = 1;
- $path=str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count);
- }
-
- $path = self::normalizePath($path);
- OC_Connector_Sabre_Node::removeETagPropertyForPath($path);
- }
-
- /**
- * normalize a path
- * @param string path
- * @param bool $stripTrailingSlash
- * @return string
- */
- public static function normalizePath($path,$stripTrailingSlash=true) {
- if($path=='') {
- return '/';
- }
- //no windows style slashes
- $path=str_replace('\\','/',$path);
- //add leading slash
- if($path[0]!=='/') {
- $path='/'.$path;
- }
- //remove trainling slash
- if($stripTrailingSlash and strlen($path)>1 and substr($path,-1,1)==='/') {
- $path=substr($path,0,-1);
- }
- //remove duplicate slashes
- while(strpos($path,'//')!==false) {
- $path=str_replace('//','/',$path);
- }
- //normalize unicode if possible
- if(class_exists('Normalizer')) {
- $path=Normalizer::normalize($path);
- }
- return $path;
- }
-}
-OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook');
-OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook');
-OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook');
-OC_Util::setupFS();