From bd834220959bf7edcc4cce4bfe6c77e0a4649b8b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Sep 2012 18:30:48 +0200 Subject: put filestorages in a namespace --- apps/files_encryption/tests/proxy.php | 2 +- apps/files_external/appinfo/app.php | 16 +- apps/files_external/lib/amazons3.php | 14 +- apps/files_external/lib/config.php | 18 +- apps/files_external/lib/dropbox.php | 18 +- apps/files_external/lib/ftp.php | 6 +- apps/files_external/lib/google.php | 18 +- apps/files_external/lib/smb.php | 4 +- apps/files_external/lib/streamwrapper.php | 5 +- apps/files_external/lib/swift.php | 12 +- apps/files_external/lib/webdav.php | 12 +- apps/files_external/personal.php | 2 +- apps/files_external/tests/amazons3.php | 2 +- apps/files_external/tests/ftp.php | 2 +- apps/files_external/tests/google.php | 2 +- apps/files_external/tests/smb.php | 2 +- apps/files_external/tests/swift.php | 2 +- apps/files_external/tests/webdav.php | 2 +- apps/files_sharing/appinfo/app.php | 4 +- apps/files_sharing/lib/sharedstorage.php | 68 +++---- lib/base.php | 3 + lib/files/storage/common.php | 270 ++++++++++++++++++++++++++++ lib/files/storage/commontest.php | 77 ++++++++ lib/files/storage/local.php | 208 ++++++++++++++++++++++ lib/files/storage/storage.php | 54 ++++++ lib/files/storage/temporary.php | 26 +++ lib/filestorage.php | 66 ------- lib/filestorage/common.php | 282 ------------------------------ lib/filestorage/commontest.php | 75 -------- lib/filestorage/local.php | 199 --------------------- lib/filestorage/temporary.php | 17 -- lib/filesystem.php | 12 +- lib/filesystemview.php | 12 +- lib/util.php | 4 +- tests/lib/cache/file.php | 2 +- tests/lib/filestorage.php | 2 +- tests/lib/filestorage/commontest.php | 2 +- tests/lib/filestorage/local.php | 2 +- tests/lib/filesystem.php | 4 +- 39 files changed, 771 insertions(+), 757 deletions(-) create mode 100644 lib/files/storage/common.php create mode 100644 lib/files/storage/commontest.php create mode 100644 lib/files/storage/local.php create mode 100644 lib/files/storage/storage.php create mode 100644 lib/files/storage/temporary.php delete mode 100644 lib/filestorage.php delete mode 100644 lib/filestorage/common.php delete mode 100644 lib/filestorage/commontest.php delete mode 100644 lib/filestorage/local.php delete mode 100644 lib/filestorage/temporary.php diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 042011a6c87..d600bbc4071 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -30,7 +30,7 @@ class Test_CryptProxy extends UnitTestCase { //set up temporary storage OC_Filesystem::clearMounts(); - OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_Filesystem::init('/'.$user.'/files'); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 837d35c9c63..c58cfcd0f5e 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -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'); diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 41ec3c70b45..a17a70ed38b 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -22,7 +22,9 @@ require_once 'aws-sdk/sdk.class.php'; -class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class AmazonS3 extends \OC\Files\Storage\Common { private $s3; private $bucket; @@ -33,7 +35,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { // 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->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -96,7 +98,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { foreach ($response->body->CommonPrefixes as $object) { $files[] = basename($object->Prefix); } - OC_FakeDirStream::$dirs['amazons3'.$path] = $files; + \OC_FakeDirStream::$dirs['amazons3'.$path] = $files; return opendir('fakedir://amazons3'.$path); } return false; @@ -160,7 +162,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()) { @@ -184,8 +186,8 @@ 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_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index eec31ec2ef9..db09fbdd82b 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -39,14 +39,14 @@ class OC_Mount_Config { */ public static function getBackends() { return array( - 'OC_Filestorage_Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')), - 'OC_Filestorage_AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')), - 'OC_Filestorage_Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('configured' => '#configured','app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), - 'OC_Filestorage_FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_Google' => array('backend' => 'Google Drive', 'configuration' => array('configured' => '#configured', 'token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), - 'OC_Filestorage_SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), - 'OC_Filestorage_DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) + '\OC\Files\Storage\Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')), + '\OC\Files\Storage\AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')), + '\OC\Files\Storage\Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('configured' => '#configured','app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), + '\OC\Files\Storage\FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), + '\OC\Files\Storage\Google' => array('backend' => 'Google Drive', 'configuration' => array('configured' => '#configured', 'token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), + '\OC\Files\Storage\SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), + '\OC\Files\Storage\SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), + '\OC\Files\Storage\DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) ); } @@ -124,7 +124,7 @@ 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; } $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index bb86894e55e..746364668f0 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -22,7 +22,9 @@ require_once 'Dropbox/autoload.php'; -class OC_Filestorage_Dropbox extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class Dropbox extends \OC\Files\Storage\Common { private $dropbox; private $metaData = array(); @@ -31,11 +33,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { public function __construct($params) { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['app_key']) && isset($params['app_secret']) && isset($params['token']) && isset($params['token_secret'])) { - $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'); } else { - throw new Exception('Creating OC_Filestorage_Dropbox storage failed'); + throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed'); } } @@ -95,7 +97,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { foreach ($contents as $file) { $files[] = basename($file['path']); } - OC_FakeDirStream::$dirs['dropbox'.$path] = $files; + \OC_FakeDirStream::$dirs['dropbox'.$path] = $files; return opendir('fakedir://dropbox'.$path); } return false; @@ -177,7 +179,7 @@ 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); @@ -203,8 +205,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_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 261141455cc..140a21ffe13 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -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; @@ -69,7 +71,7 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 9b83dcee537..51c5d219aae 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -22,7 +22,9 @@ require_once 'Google/common.inc.php'; -class OC_Filestorage_Google extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class Google extends \OC\Files\Storage\Common { private $consumer; private $oauth_token; @@ -35,12 +37,12 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['token']) && isset($params['token_secret'])) { $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->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'); } } @@ -96,7 +98,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); } @@ -399,7 +401,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } else { $ext = ''; } - $tmpFile = OC_Helper::tmpFile($ext); + $tmpFile = \OC_Helper::tmpFile($ext); OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); @@ -438,7 +440,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 = ''; diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index e5ba7a17743..d4882ed0249 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -8,7 +8,9 @@ require_once 'smb4php/smb.php'; -class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ +namespace OC\Files\Storage; + +class SMB extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; private $host; diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 7263ef23253..750bdbaf4d4 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -6,8 +6,9 @@ * See the COPYING-README file. */ +namespace OC\Files\Storage; -abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ +abstract class StreamWrapper extends \OC\Files\Storage\Common{ abstract public function constructUrl($path); public function mkdir($path) { @@ -84,6 +85,4 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ return stat($this->constructUrl($path)); } - - } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index c29d28b44c1..c67cf59df6b 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -8,7 +8,9 @@ require_once 'php-cloudfiles/cloudfiles.php'; -class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ +namespace OC\Files\Storage; + +class SWIFT extends \OC\Files\Storage\Common{ private $host; private $root; private $user; @@ -272,10 +274,10 @@ 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); + $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->root)) { $this->rootContainer=$this->createContainer('/'); @@ -341,7 +343,7 @@ 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_FakeDirStream::$dirs[$id]=$files; return opendir('fakedir://'.$id); } @@ -426,7 +428,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_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile,$mode); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 3c18b227fa6..70210b49ee7 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -6,7 +6,9 @@ * 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; @@ -42,7 +44,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ 'password' => $this->password, ); - $this->client = new OC_Connector_Sabre_Client($settings); + $this->client = new \OC_Connector_Sabre_Client($settings); if($caview = \OCP\Files::getStorage('files_external')) { $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; @@ -78,12 +80,12 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ try{ $response=$this->client->propfind($path, array(),1); $id=md5('webdav'.$this->root.$path); - OC_FakeDirStream::$dirs[$id]=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; + \OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); }catch(Exception $e) { @@ -161,7 +163,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index f0d76460f54..a678f345c8e 100755 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -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()); diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index b9b4cf65bd6..ad1c453abb7 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -34,7 +34,7 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r $id = uniqid(); $this->config = include('apps/files_external/tests/config.php'); $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() { diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index 12f3ec3908d..105f7b485bd 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $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() { diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index d2a6358ade4..e96c2263e1c 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -33,7 +33,7 @@ if(!is_array($config) or !isset($config['google']) or !$config['google']['run']) $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $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() { diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index 7de4fddbb34..a0c5d834736 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -19,7 +19,7 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $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() { diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index a6f5eace1c8..3e1485b0f3a 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $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']); } diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 74d980aa3f1..6b1121c9d0c 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']) $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $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() { diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 109f86b2e87..210c78ad174 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -2,8 +2,8 @@ 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"; +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'); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 6dba76955a0..f1539610b02 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -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(); @@ -50,7 +52,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if (isset($this->files[$folder])) { $file = $this->files[$folder]; } else { - $file = OCP\Share::getItemSharedWith('folder', $folder, OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $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)); @@ -58,7 +60,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return $this->files[$target]; } } else { - $file = OCP\Share::getItemSharedWith('file', $target, OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); if ($file) { $this->files[$target] = $file; return $this->files[$target]; @@ -78,7 +80,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $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); + \OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -103,7 +105,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { * @return Source file path with mount point stripped out */ private function getInternalPath($path) { - $mountPoint = OC_Filesystem::getMountPoint($path); + $mountPoint = \OC_Filesystem::getMountPoint($path); $internalPath = substr($path, strlen($mountPoint)); return $internalPath; } @@ -112,7 +114,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } return false; @@ -120,7 +122,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->rmdir($this->getInternalPath($source)); } return false; @@ -128,11 +130,11 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { 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_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->opendir($this->getInternalPath($source)); } return false; @@ -142,7 +144,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } return false; @@ -150,7 +152,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } return false; @@ -163,7 +165,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } return false; @@ -173,7 +175,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); } return false; @@ -183,7 +185,7 @@ 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); + $storage = \OC_Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); } return false; @@ -225,7 +227,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); } return false; @@ -246,7 +248,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); } } @@ -267,7 +269,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); } } @@ -280,8 +282,8 @@ 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); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); + $storage = \OC_Filesystem::getStorage($source); return $storage->file_get_contents($this->getInternalPath($source)); } } @@ -296,8 +298,8 @@ 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); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); + $storage = \OC_Filesystem::getStorage($source); $result = $storage->file_put_contents($this->getInternalPath($source), $data); return $result; } @@ -308,7 +310,7 @@ 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); + $storage = \OC_Filesystem::getStorage($source); return $storage->unlink($this->getInternalPath($source)); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -332,7 +334,7 @@ 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); + $storage = \OC_Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } else { @@ -347,7 +349,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return $this->unlink($path1); } } else { - $storage = OC_Filesystem::getStorage($oldSource); + $storage = \OC_Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } @@ -361,7 +363,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; } @@ -392,8 +394,8 @@ 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); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); + $storage = \OC_Filesystem::getStorage($source); return $storage->fopen($this->getInternalPath($source), $mode); } return false; @@ -404,7 +406,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); } return false; @@ -413,21 +415,21 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source), $mtime); } return false; @@ -435,7 +437,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public static function setup($options) { $user_dir = $options['user_dir']; - OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + \OC_Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** diff --git a/lib/base.php b/lib/base.php index 1c6cc70b0e8..3b2ab8d5ebe 100644 --- a/lib/base.php +++ b/lib/base.php @@ -81,6 +81,9 @@ class OC{ elseif(strpos($className, 'OC_')===0) { $path = strtolower(str_replace('_', '/', substr($className, 3)) . '.php'); } + elseif(strpos($className, 'OC\\')===0) { + $path = strtolower(str_replace('\\', '/', substr($className, 3)) . '.php'); + } elseif(strpos($className, 'OCP\\')===0) { $path = 'public/'.strtolower(str_replace('\\', '/', substr($className, 3)) . '.php'); } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php new file mode 100644 index 00000000000..0a60ff757eb --- /dev/null +++ b/lib/files/storage/common.php @@ -0,0 +1,270 @@ + + * 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\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\Files\Storage\Common methods call functions which are first defined + * in classes which extend it, e.g. $this->stat() . + */ + +abstract class Common extends \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 + }else{ + $stat = $this->stat($path); + return $stat['size']; + } + } + public function isCreatable($path) { + return $this->isUpdatable($path); + } +// 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 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) { + return false; + } + $size=$this->filesize($path); + if($size==0) { + return ''; + } + return fread($handle, $size); + } + 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)) { + 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); + 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 + * + * @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 ); + + } + + 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 ) ) { + + 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 ); + + } 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 true; + } + + } + public function getMimeType($path) { + if(!$this->file_exists($path)) { + return false; + } + if($this->is_dir($path)) { + return 'httpd/unix-directory'; + } + $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); + }else{ + $extension=''; + } + $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); + 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'); + if(!$source) { + return false; + } + if($pos=strrpos($path,'.')) { + $extension=substr($path,$pos); + }else{ + $extension=''; + } + $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); + return $baseDir; + } + 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); + }else{ + $tmp=$this->toTmpFile($path.'/'.$file); + rename($tmp,$target.'/'.$file); + } + } + } + } + } +// abstract public function touch($path, $mtime=null); + + protected function searchInDir($query,$dir='') { + $files=array(); + $dh=$this->opendir($dir); + if($dh) { + while($item=readdir($dh)) { + if ($item == '.' || $item == '..') continue; + if(strstr(strtolower($item),strtolower($query))!==false) { + $files[]=$dir.'/'.$item; + } + if($this->is_dir($dir.'/'.$item)) { + $files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item)); + } + } + } + return $files; + } + + /** + * check if a file or folder has been updated since $time + * @param int $time + * @return bool + */ + public function hasUpdated($path,$time) { + return $this->filemtime($path)>$time; + } +} diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php new file mode 100644 index 00000000000..773bfffcb49 --- /dev/null +++ b/lib/files/storage/commontest.php @@ -0,0 +1,77 @@ +. +* +*/ + +/** + * test implementation for \OC\Files\Storage\Common with \OC\Files\Storage\Local + */ + +namespace OC\Files\Storage; + +class CommonTest extends \OC\Files\Storage\Common{ + /** + * underlying local storage used for missing functions + * @var \OC\Files\Storage\Local + */ + private $storage; + + public function __construct($params) { + $this->storage=new \OC\Files\Storage\Local($params); + } + + public function mkdir($path) { + return $this->storage->mkdir($path); + } + public function rmdir($path) { + return $this->storage->rmdir($path); + } + public function opendir($path) { + return $this->storage->opendir($path); + } + public function stat($path) { + return $this->storage->stat($path); + } + public function filetype($path) { + return $this->storage->filetype($path); + } + public function isReadable($path) { + return $this->storage->isReadable($path); + } + public function isUpdatable($path) { + return $this->storage->isUpdatable($path); + } + public function file_exists($path) { + return $this->storage->file_exists($path); + } + public function unlink($path) { + return $this->storage->unlink($path); + } + public function fopen($path,$mode) { + return $this->storage->fopen($path,$mode); + } + public function free_space($path) { + return $this->storage->free_space($path); + } + public function touch($path, $mtime=null) { + return $this->storage->touch($path,$mtime); + } +} \ No newline at end of file diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php new file mode 100644 index 00000000000..e47441499a1 --- /dev/null +++ b/lib/files/storage/local.php @@ -0,0 +1,208 @@ + + * 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 Local extends \OC\Files\Storage\Common{ + protected $datadir; + public function __construct($arguments) { + $this->datadir=$arguments['datadir']; + if(substr($this->datadir,-1)!=='/') { + $this->datadir.='/'; + } + } + public function mkdir($path) { + return @mkdir($this->datadir.$path); + } + public function rmdir($path) { + return @rmdir($this->datadir.$path); + } + public function opendir($path) { + return opendir($this->datadir.$path); + } + public function is_dir($path) { + if(substr($path,-1)=='/') { + $path=substr($path,0,-1); + } + return is_dir($this->datadir.$path); + } + public function is_file($path) { + return is_file($this->datadir.$path); + } + public function stat($path) { + return stat($this->datadir.$path); + } + public function filetype($path) { + $filetype=filetype($this->datadir.$path); + if($filetype=='link') { + $filetype=filetype(realpath($this->datadir.$path)); + } + return $filetype; + } + public function filesize($path) { + if($this->is_dir($path)) { + return 0; + }else{ + return filesize($this->datadir.$path); + } + } + public function isReadable($path) { + return is_readable($this->datadir.$path); + } + public function isUpdatable($path) { + return is_writable($this->datadir.$path); + } + 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); + } + public function touch($path, $mtime=null) { + // sets the modification time of the file to the given value. + // If mtime is nil the current time is set. + // note that the access time of the file always changes to the current time. + if(!is_null($mtime)) { + $result=touch( $this->datadir.$path, $mtime ); + }else{ + $result=touch( $this->datadir.$path); + } + if( $result ) { + clearstatcache( true, $this->datadir.$path ); + } + + return $result; + } + public function file_get_contents($path) { + return file_get_contents($this->datadir.$path); + } + public function file_put_contents($path,$data) { + return file_put_contents($this->datadir.$path,$data); + } + public function unlink($path) { + return $this->delTree($path); + } + public function rename($path1,$path2) { + if (!$this->isUpdatable($path1)) { + \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); + return false; + } + + if($return=rename($this->datadir.$path1,$this->datadir.$path2)) { + } + return $return; + } + public function copy($path1,$path2) { + if($this->is_dir($path2)) { + if(!$this->file_exists($path2)) { + $this->mkdir($path2); + } + $source=substr($path1,strrpos($path1,'/')+1); + $path2.=$source; + } + return copy($this->datadir.$path1,$this->datadir.$path2); + } + public function fopen($path,$mode) { + if($return=fopen($this->datadir.$path,$mode)) { + switch($mode) { + case 'r': + break; + case 'r+': + case 'w+': + case 'x+': + case 'a+': + break; + case 'w': + case 'x': + case 'a': + break; + } + } + return $return; + } + + public function getMimeType($path) { + if($this->isReadable($path)) { + return \OC_Helper::getMimeType($this->datadir.$path); + }else{ + return false; + } + } + + private function delTree($dir) { + $dirRelative=$dir; + $dir=$this->datadir.$dir; + if (!file_exists($dir)) return true; + if (!is_dir($dir) || is_link($dir)) return unlink($dir); + foreach (scandir($dir) as $item) { + if ($item == '.' || $item == '..') continue; + if(is_file($dir.'/'.$item)) { + if(unlink($dir.'/'.$item)) { + } + }elseif(is_dir($dir.'/'.$item)) { + if (!$this->delTree($dirRelative. "/" . $item)) { + return false; + }; + } + } + if($return=rmdir($dir)) { + } + return $return; + } + + public function hash($path,$type,$raw=false) { + return hash_file($type,$this->datadir.$path,$raw); + } + + public function free_space($path) { + return disk_free_space($this->datadir.$path); + } + + public function search($query) { + return $this->searchInDir($query); + } + public function getLocalFile($path) { + return $this->datadir.$path; + } + public function getLocalFolder($path) { + return $this->datadir.$path; + } + + protected function searchInDir($query,$dir='') { + $files=array(); + foreach (scandir($this->datadir.$dir) as $item) { + if ($item == '.' || $item == '..') continue; + if(strstr(strtolower($item),strtolower($query))!==false) { + $files[]=$dir.'/'.$item; + } + if(is_dir($this->datadir.$dir.'/'.$item)) { + $files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item)); + } + } + return $files; + } + + /** + * check if a file or folder has been updated since $time + * @param int $time + * @return bool + */ + public function hasUpdated($path,$time) { + return $this->filemtime($path)>$time; + } +} diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php new file mode 100644 index 00000000000..a2f6cb7ec34 --- /dev/null +++ b/lib/files/storage/storage.php @@ -0,0 +1,54 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * Provde a common interface to all different storage options + */ +abstract class Storage{ + 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); +} diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php new file mode 100644 index 00000000000..0e69c9112ac --- /dev/null +++ b/lib/files/storage/temporary.php @@ -0,0 +1,26 @@ + + * 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 OC\Files\Storage\Local{ + public function __construct($arguments) { + $this->datadir=\OC_Helper::tmpFolder(); + } + + public function cleanUp() { + \OC_Helper::rmdirr($this->datadir); + } + + public function __destruct() { + $this->cleanUp(); + } +} diff --git a/lib/filestorage.php b/lib/filestorage.php deleted file mode 100644 index 5bfd09253d5..00000000000 --- a/lib/filestorage.php +++ /dev/null @@ -1,66 +0,0 @@ -. -*/ - -/** - * Provde 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); -} diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php deleted file mode 100644 index 351714437c5..00000000000 --- a/lib/filestorage/common.php +++ /dev/null @@ -1,282 +0,0 @@ -. -*/ - -/** - * 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 - * 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 - * in classes which extend it, e.g. $this->stat() . - */ - -abstract class OC_Filestorage_Common extends OC_Filestorage { - - 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 - }else{ - $stat = $this->stat($path); - return $stat['size']; - } - } - public function isCreatable($path) { - return $this->isUpdatable($path); - } -// 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 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) { - return false; - } - $size=$this->filesize($path); - if($size==0) { - return ''; - } - return fread($handle, $size); - } - 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)) { - 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); - 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 - * - * @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 ); - - } - - 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 ) ) { - - 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 ); - - } 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 true; - } - - } - public function getMimeType($path) { - if(!$this->file_exists($path)) { - return false; - } - if($this->is_dir($path)) { - return 'httpd/unix-directory'; - } - $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); - }else{ - $extension=''; - } - $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); - 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'); - if(!$source) { - return false; - } - if($pos=strrpos($path,'.')) { - $extension=substr($path,$pos); - }else{ - $extension=''; - } - $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); - return $baseDir; - } - 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); - }else{ - $tmp=$this->toTmpFile($path.'/'.$file); - rename($tmp,$target.'/'.$file); - } - } - } - } - } -// abstract public function touch($path, $mtime=null); - - protected function searchInDir($query,$dir='') { - $files=array(); - $dh=$this->opendir($dir); - if($dh) { - while($item=readdir($dh)) { - if ($item == '.' || $item == '..') continue; - if(strstr(strtolower($item),strtolower($query))!==false) { - $files[]=$dir.'/'.$item; - } - if($this->is_dir($dir.'/'.$item)) { - $files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item)); - } - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - public function hasUpdated($path,$time) { - return $this->filemtime($path)>$time; - } -} diff --git a/lib/filestorage/commontest.php b/lib/filestorage/commontest.php deleted file mode 100644 index b88bb232c36..00000000000 --- a/lib/filestorage/commontest.php +++ /dev/null @@ -1,75 +0,0 @@ -. -* -*/ - -/** - * test implementation for OC_FileStorage_Common with OC_FileStorage_Local - */ - -class OC_Filestorage_CommonTest extends OC_Filestorage_Common{ - /** - * underlying local storage used for missing functions - * @var OC_FileStorage_Local - */ - private $storage; - - public function __construct($params) { - $this->storage=new OC_Filestorage_Local($params); - } - - public function mkdir($path) { - return $this->storage->mkdir($path); - } - public function rmdir($path) { - return $this->storage->rmdir($path); - } - public function opendir($path) { - return $this->storage->opendir($path); - } - public function stat($path) { - return $this->storage->stat($path); - } - public function filetype($path) { - return $this->storage->filetype($path); - } - public function isReadable($path) { - return $this->storage->isReadable($path); - } - public function isUpdatable($path) { - return $this->storage->isUpdatable($path); - } - public function file_exists($path) { - return $this->storage->file_exists($path); - } - public function unlink($path) { - return $this->storage->unlink($path); - } - public function fopen($path,$mode) { - return $this->storage->fopen($path,$mode); - } - public function free_space($path) { - return $this->storage->free_space($path); - } - public function touch($path, $mtime=null) { - return $this->storage->touch($path,$mtime); - } -} \ No newline at end of file diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php deleted file mode 100644 index e26d3d3ef91..00000000000 --- a/lib/filestorage/local.php +++ /dev/null @@ -1,199 +0,0 @@ -datadir=$arguments['datadir']; - if(substr($this->datadir,-1)!=='/') { - $this->datadir.='/'; - } - } - public function mkdir($path) { - return @mkdir($this->datadir.$path); - } - public function rmdir($path) { - return @rmdir($this->datadir.$path); - } - public function opendir($path) { - return opendir($this->datadir.$path); - } - public function is_dir($path) { - if(substr($path,-1)=='/') { - $path=substr($path,0,-1); - } - return is_dir($this->datadir.$path); - } - public function is_file($path) { - return is_file($this->datadir.$path); - } - public function stat($path) { - return stat($this->datadir.$path); - } - public function filetype($path) { - $filetype=filetype($this->datadir.$path); - if($filetype=='link') { - $filetype=filetype(realpath($this->datadir.$path)); - } - return $filetype; - } - public function filesize($path) { - if($this->is_dir($path)) { - return 0; - }else{ - return filesize($this->datadir.$path); - } - } - public function isReadable($path) { - return is_readable($this->datadir.$path); - } - public function isUpdatable($path) { - return is_writable($this->datadir.$path); - } - 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); - } - public function touch($path, $mtime=null) { - // sets the modification time of the file to the given value. - // If mtime is nil the current time is set. - // note that the access time of the file always changes to the current time. - if(!is_null($mtime)) { - $result=touch( $this->datadir.$path, $mtime ); - }else{ - $result=touch( $this->datadir.$path); - } - if( $result ) { - clearstatcache( true, $this->datadir.$path ); - } - - return $result; - } - public function file_get_contents($path) { - return file_get_contents($this->datadir.$path); - } - public function file_put_contents($path,$data) { - return file_put_contents($this->datadir.$path,$data); - } - public function unlink($path) { - return $this->delTree($path); - } - public function rename($path1,$path2) { - if (!$this->isUpdatable($path1)) { - 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); - return false; - } - - if($return=rename($this->datadir.$path1,$this->datadir.$path2)) { - } - return $return; - } - public function copy($path1,$path2) { - if($this->is_dir($path2)) { - if(!$this->file_exists($path2)) { - $this->mkdir($path2); - } - $source=substr($path1,strrpos($path1,'/')+1); - $path2.=$source; - } - return copy($this->datadir.$path1,$this->datadir.$path2); - } - public function fopen($path,$mode) { - if($return=fopen($this->datadir.$path,$mode)) { - switch($mode) { - case 'r': - break; - case 'r+': - case 'w+': - case 'x+': - case 'a+': - break; - case 'w': - case 'x': - case 'a': - break; - } - } - return $return; - } - - public function getMimeType($path) { - if($this->isReadable($path)) { - return OC_Helper::getMimeType($this->datadir.$path); - }else{ - return false; - } - } - - private function delTree($dir) { - $dirRelative=$dir; - $dir=$this->datadir.$dir; - if (!file_exists($dir)) return true; - if (!is_dir($dir) || is_link($dir)) return unlink($dir); - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') continue; - if(is_file($dir.'/'.$item)) { - if(unlink($dir.'/'.$item)) { - } - }elseif(is_dir($dir.'/'.$item)) { - if (!$this->delTree($dirRelative. "/" . $item)) { - return false; - }; - } - } - if($return=rmdir($dir)) { - } - return $return; - } - - public function hash($path,$type,$raw=false) { - return hash_file($type,$this->datadir.$path,$raw); - } - - public function free_space($path) { - return disk_free_space($this->datadir.$path); - } - - public function search($query) { - return $this->searchInDir($query); - } - public function getLocalFile($path) { - return $this->datadir.$path; - } - public function getLocalFolder($path) { - return $this->datadir.$path; - } - - protected function searchInDir($query,$dir='') { - $files=array(); - foreach (scandir($this->datadir.$dir) as $item) { - if ($item == '.' || $item == '..') continue; - if(strstr(strtolower($item),strtolower($query))!==false) { - $files[]=$dir.'/'.$item; - } - if(is_dir($this->datadir.$dir.'/'.$item)) { - $files=array_merge($files,$this->searchInDir($query,$dir.'/'.$item)); - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - public function hasUpdated($path,$time) { - return $this->filemtime($path)>$time; - } -} diff --git a/lib/filestorage/temporary.php b/lib/filestorage/temporary.php deleted file mode 100644 index 876ba045a63..00000000000 --- a/lib/filestorage/temporary.php +++ /dev/null @@ -1,17 +0,0 @@ -datadir=OC_Helper::tmpFolder(); - } - - public function cleanUp() { - OC_Helper::rmdirr($this->datadir); - } - - public function __destruct() { - $this->cleanUp(); - } -} diff --git a/lib/filesystem.php b/lib/filesystem.php index 92eb4fa4778..9b022d8fef5 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -48,7 +48,7 @@ class OC_Filesystem{ static private $mounts=array(); public static $loaded=false; /** - * @var OC_Filestorage $defaultInstance + * @var \OC\Files\Storage\Storage $defaultInstance */ static private $defaultInstance; @@ -181,7 +181,7 @@ class OC_Filesystem{ /** * get the storage object for a path * @param string path - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ static public function getStorage($path) { $mountpoint=self::getMountPoint($path); @@ -276,7 +276,7 @@ class OC_Filesystem{ * create a new storage of a specific type * @param string type * @param array arguments - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ static private function createStorage($class,$arguments) { if(class_exists($class)) { @@ -320,9 +320,9 @@ class OC_Filesystem{ } /** - * mount an OC_Filestorage in our virtual filesystem - * @param OC_Filestorage storage - * @param string mountpoint + * 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]!='/') { diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 743f9403011..36fef485513 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -35,7 +35,7 @@ * are triggered correctly. * * Filesystem functions are not called directly; they are passed to the correct - * OC_Filestorage object + * \OC\Files\Storage\Storage object */ class OC_FilesystemView { @@ -115,7 +115,7 @@ class OC_FilesystemView { /** * get the storage object for a path * @param string path - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ public function getStorage($path) { if (!isset($this->storage_cache[$path])) { @@ -161,7 +161,7 @@ class OC_FilesystemView { /** * 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_Filestorage via basicOperation(). + * for \OC\Files\Storage\Storage via basicOperation(). */ public function mkdir($path) { return $this->basicOperation('mkdir', $path, array('create', 'write')); @@ -173,7 +173,7 @@ class OC_FilesystemView { return $this->basicOperation('opendir', $path, array('read')); } public function readdir($handle) { - $fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) ); + $fsLocal= new \OC\Files\Storage\Local( array( 'datadir' => '/' ) ); return $fsLocal->readdir( $handle ); } public function is_dir($path) { @@ -540,7 +540,7 @@ class OC_FilesystemView { } /** - * @brief abstraction layer for basic filesystem functions: wrapper for OC_Filestorage + * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation * @param string #path * @param array (optional) hooks @@ -549,7 +549,7 @@ class OC_FilesystemView { * * 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_Filestorage for delegation to a storage backend for execution + * \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)==='/')?'/':''; diff --git a/lib/util.php b/lib/util.php index 5046550d6a2..78976c96606 100755 --- a/lib/util.php +++ b/lib/util.php @@ -34,7 +34,7 @@ class OC_Util { $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage if(!self::$rootMounted) { - OC_Filesystem::mount('OC_Filestorage_Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); self::$rootMounted=true; } @@ -46,7 +46,7 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => $user_root), $user); + OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); OC_Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); OC_FileProxy::register($quotaProxy); diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 00be005d08d..1dd1ff7fa87 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -39,7 +39,7 @@ class Test_Cache_File extends Test_Cache { //set up temporary storage OC_Filesystem::clearMounts(); - OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); diff --git a/tests/lib/filestorage.php b/tests/lib/filestorage.php index 3f7bb7b62dc..bfb40bcd674 100644 --- a/tests/lib/filestorage.php +++ b/tests/lib/filestorage.php @@ -22,7 +22,7 @@ abstract class Test_FileStorage extends UnitTestCase { /** - * @var OC_Filestorage instance + * @var \OC\Files\Storage\Storage instance */ protected $instance; diff --git a/tests/lib/filestorage/commontest.php b/tests/lib/filestorage/commontest.php index 89e83589e5d..0e52e916789 100644 --- a/tests/lib/filestorage/commontest.php +++ b/tests/lib/filestorage/commontest.php @@ -30,7 +30,7 @@ class Test_Filestorage_CommonTest extends Test_FileStorage { if(!file_exists($this->tmpDir)) { mkdir($this->tmpDir); } - $this->instance=new OC_Filestorage_CommonTest(array('datadir'=>$this->tmpDir)); + $this->instance=new \OC\Files\Storage\CommonTest(array('datadir'=>$this->tmpDir)); } public function tearDown() { diff --git a/tests/lib/filestorage/local.php b/tests/lib/filestorage/local.php index f68fb69b97f..7bb27830baa 100644 --- a/tests/lib/filestorage/local.php +++ b/tests/lib/filestorage/local.php @@ -27,7 +27,7 @@ class Test_Filestorage_Local extends Test_FileStorage { private $tmpDir; public function setUp() { $this->tmpDir=OC_Helper::tmpFolder(); - $this->instance=new OC_Filestorage_Local(array('datadir'=>$this->tmpDir)); + $this->instance=new \OC\Files\Storage\Local(array('datadir'=>$this->tmpDir)); } public function tearDown() { diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index 1cfa35e305d..5f5d393ed51 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -46,13 +46,13 @@ class Test_Filesystem extends UnitTestCase{ } public function testMount() { - OC_Filesystem::mount('OC_Filestorage_Local',self::getStorageData(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); $this->assertEqual('/',OC_Filesystem::getMountPoint('/some/folder')); $this->assertEqual('',OC_Filesystem::getInternalPath('/')); $this->assertEqual('some/folder',OC_Filesystem::getInternalPath('/some/folder')); - OC_Filesystem::mount('OC_Filestorage_Local',self::getStorageData(),'/some'); + OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/folder')); $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/')); -- cgit v1.2.3 From e8d3a4768541980fcc391117e5a173875b2f75e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 22:50:10 +0200 Subject: add getId to storage backends --- lib/files/storage/common.php | 1 + lib/files/storage/commontest.php | 3 +++ lib/files/storage/local.php | 3 +++ lib/files/storage/storage.php | 1 + 4 files changed, 8 insertions(+) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 0a60ff757eb..1f8b6204802 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,6 +23,7 @@ namespace OC\Files\Storage; abstract class Common extends \OC\Files\Storage\Storage { public function __construct($parameters) {} +// abstract public function getId(); // abstract public function mkdir($path); // abstract public function rmdir($path); // abstract public function opendir($path); diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php index 773bfffcb49..2b42cfe1156 100644 --- a/lib/files/storage/commontest.php +++ b/lib/files/storage/commontest.php @@ -38,6 +38,9 @@ class CommonTest extends \OC\Files\Storage\Common{ $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); } diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index e47441499a1..78e4877a005 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -19,6 +19,9 @@ class Local extends \OC\Files\Storage\Common{ $this->datadir.='/'; } } + public function getId(){ + return 'local::'.$this->datadir; + } public function mkdir($path) { return @mkdir($this->datadir.$path); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index a2f6cb7ec34..bd4cc4743b6 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -13,6 +13,7 @@ namespace OC\Files\Storage; */ abstract class Storage{ abstract public function __construct($parameters); + abstract public function getId(); abstract public function mkdir($path); abstract public function rmdir($path); abstract public function opendir($path); -- cgit v1.2.3 From 68f65b657c398d44508d20b56ccf9ddbee8e3521 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 22:53:10 +0200 Subject: add OC_Filesystem::resolvePath to get the storage backend and internal path for a file in one go --- lib/filesystem.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/filesystem.php b/lib/filesystem.php index 9b022d8fef5..ef8b3fef5bb 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -194,6 +194,24 @@ class OC_Filesystem{ } } + /** + * 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; -- cgit v1.2.3 From c94fe38d3900acff474c909aaa730d7ab51f914d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 23:25:57 +0200 Subject: add getPermissions to storage backends to get all permission flags in one go --- lib/files/storage/common.php | 19 +++++++++++++++++++ lib/files/storage/storage.php | 1 + 2 files changed, 20 insertions(+) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 1f8b6204802..b2b4ea8eee4 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -54,6 +54,25 @@ abstract class Common extends \OC\Files\Storage\Storage { public function isSharable($path) { return $this->isReadable($path); } + public function getPermissions($path){ + $permissions = 0; + if($this->isCreatable($path)){ + $permissions |= OCP\Share::PERMISSION_CREATE; + } + if($this->isReadable($path)){ + $permissions |= OCP\Share::PERMISSION_READ; + } + if($this->isUpdatable($path)){ + $permissions |= OCP\Share::PERMISSION_UPDATE; + } + if($this->isDeletable($path)){ + $permissions |= OCP\Share::PERMISSION_DELETE; + } + if($this->isSharable($path)){ + $permissions |= OCP\Share::PERMISSION_SHARE; + } + return $permissions; + } // abstract public function file_exists($path); public function filectime($path) { $stat = $this->stat($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bd4cc4743b6..f149c61830c 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -27,6 +27,7 @@ abstract class Storage{ abstract public function isUpdatable($path); abstract public function isDeletable($path); abstract public function isSharable($path); + abstract public function getPermissions($path); abstract public function file_exists($path); abstract public function filectime($path); abstract public function filemtime($path); -- cgit v1.2.3 From 954596c251cb3132878d8d5eafcc37c47b3f520e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 16 Sep 2012 16:52:32 +0200 Subject: rework filecache to work directly on storage backends wip --- lib/files/cache/cache.php | 189 ++++++++++++++++++++++++++++++++++++++++++++ lib/files/cache/scanner.php | 78 ++++++++++++++++++ lib/files/file.php | 61 ++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 lib/files/cache/cache.php create mode 100644 lib/files/cache/scanner.php create mode 100644 lib/files/file.php diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php new file mode 100644 index 00000000000..8fc575948dc --- /dev/null +++ b/lib/files/cache/cache.php @@ -0,0 +1,189 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Cache { + /** + * @var array partial data for the cache + */ + private static $partial = array(); + + /** + * get the stored metadata of a file or folder + * + * @param \OC\Files\File or int $file + * @return array + */ + static public function get($file) { + if ($file instanceof \OC\Files\File) { + $where = 'WHERE `storage` = ? AND `path_hash` = ?'; + $params = array($file->getStorageId(), $file->getInternalPath()); + } else { //file id + $where = 'WHERE `fileid` = ?'; + $params = array($file); + } + $query = \OC_DB::prepare( + 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` ' . $where); + $result=$query->execute($params); + return $result->fetchRow(); + } + + /** + * store meta data for a file or folder + * + * @param \OC\Files\File $file + * @param array $data + * + * @return int file id + */ + static public function put(\OC\Files\File $file, array $data) { + if ($id = self::getId($file) > -1) { + self::update($id, $data); + return $id; + } else { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { //add any saved partial data + $data = array_merge($data, self::$partial[$key]); + unset(self::$partial[$key]); + } + + $requiredFields = array('size', 'mtime', 'mimetype'); + foreach ($requiredFields as $field) { + if (!isset($data[$field])) { //data not complete save as partial and return + self::$partial[$key] = $data; + return -1; + } + } + + $data['path'] = $file->getInternalPath(); + $data['parent'] = self::getParentId($file); + $data['name'] = basename($file->getInternalPath()); + + list($queryParts, $params) = self::buildParts($data); + $queryParts[] = '`storage`'; + $params[] = $file->getStorageId(); + $valuesPlaceholder = array_fill(0, count($queryParts), '?'); + + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query->execute($params); + + return \OC_DB::insertid('*PREFIX*filecache'); + } + } + + /** + * update the metadata in the cache + * + * @param int $id + * @param array $data + */ + static public function update($id, array $data) { + list($queryParts, $params) = self::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 + */ + private static function buildParts(array $data) { + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + + $params = array(); + $queryParts = array(); + foreach ($data as $name => $value) { + if (array_search($name, $fields) !== false) { + $params[] = $value; + $queryParts[] = '`' . $name . '`'; + if ($name === 'path') { + $params[] = md5($value); + $queryParts[] = '`path_hash`'; + } elseif ($name === 'mimetype') { + $params[] = substr($value, 0, strpos($value, '/')); + $queryParts[] = '`mimepart`'; + } + } + } + return array($queryParts, $params); + } + + /** + * get the file id for a file + * + * @param \OC\Files\File $file + * @return int + */ + static public function getId(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + + $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($storageId, $pathHash)); + + if ($row = $result->fetchRow()) { + return $row['id']; + } else { + return -1; + } + } + + /** + * get the id of the parent folder of a file + * + * @param \OC\Files\File $file + * return int + */ + static public function getParentId(\OC\Files\File $file) { + $path = $file->getInternalPath(); + if ($path === '/' or $path === '') { + return -1; + } else { + return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + } + } + + /** + * check if a file is available in the cache + * + * @param \OC\Files\File $file + * @return bool + */ + static public function inCache(\OC\Files\File $file) { + return self::getId($file) != -1; + } + + /** + * remove a file or folder from the cache + * + * @param \OC\Files\File $file + */ + public function remove(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query->execute(array($storageId, $pathHash)); + } + + /** + * remove all entries for files that are stored on $storage form the cache + * + * @param \OC\Files\Storage\Storage $storage + */ + public function removeStorage(\OC\Files\Storage\Storage $storage) { + $storageId = $storage->getId(); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); + $query->execute(array($storageId)); + } +} diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php new file mode 100644 index 00000000000..8f2c5bda5ca --- /dev/null +++ b/lib/files/cache/scanner.php @@ -0,0 +1,78 @@ + + * 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 { + const SCAN_RECURSIVE = true; + const SCAN_SHALLOW = false; + + /** + * get all the metadata of a file or folder + * * + * @param \OC\Files\File $file + * @return array with metadata of the file + */ + public static function getData(\OC\Files\File $file) { + $data = array(); + $storage = $file->getStorage(); + $path = $file->getInternalPath(); + if (!$storage->isReadable($path)) return null; //cant read, nothing we can do + clearstatcache(); + $data['mimetype'] = $storage->getMimeType($path); + $data['mtime'] = $storage->filemtime($path); + if ($data['mimetype'] == 'httpd/unix-directory') { + $data['size'] = -1; //unknown + $data['permissions'] = $storage->getPermissions($path . '/'); + } else { + $data['size'] = $storage->filesize($path); + $data['permissions'] = $storage->getPermissions($path); + } + return $data; + } + + /** + * scan a single file and store it in the cache + * + * @param \OC\Files\File $file + * @return array with metadata of the scanned file + */ + public static function scanFile(\OC\Files\File $file) { + $data = self::getData($file); + Cache::put($file, $data); + return $data; + } + + /** + * scan all the files in a folder and store them in the cache + * + * @param \OC\Files\File $folder + * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @return int the size of the scanned folder or -1 if the size is unknown at this stage + */ + public static function scan(\OC\Files\File $folder, $recursive) { + $size = 0; + $storage = $folder->getStorage(); + $path = $folder->getInternalPath(); + if ($dh = $storage->opendir($path)) { + while ($file = readdir($dh)) { + if ($file !== '.' and $file !== '..') { + $child = new \OC\Files\File($storage, $path . '/' . $file); + $data = self::scanFile($child); + if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { + $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + } + if ($data['size'] >= 0 and $size >= 0) { + $size += $data['size']; + } + } + } + } + return $size; + } +} diff --git a/lib/files/file.php b/lib/files/file.php new file mode 100644 index 00000000000..b6432e63458 --- /dev/null +++ b/lib/files/file.php @@ -0,0 +1,61 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files; + +/** + * representation of the location a file or folder is stored + */ + +class File{ + /** + * @var Storage\Storage $storage + */ + private $storage; + /** + * @var string internalPath + */ + private $internalPath; + + public function __construct(Storage\Storage $storage, $internalPath){ + $this->storage = $storage; + $this->internalPath = $internalPath; + } + + public static function resolve($fullPath){ + $storage = null; + $internalPath = ''; + list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + return new File($storage, $internalPath); + } + + /** + * get the internal path of the file inside the filestorage + * @return string + */ + public function getInternalPath(){ + return $this->internalPath; + } + + /** + * get the storage the file is stored in + * @return \OC\Files\Storage\Storage + */ + public function getStorage(){ + return $this->storage; + } + + /** + * get the id of the storage the file is stored in + * @return string + */ + public function getStorageId(){ + return $this->storage->getId(); + } + +} -- cgit v1.2.3 From 153cd802a9bbc0f5a5f67fe428af7ca78185011f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:40:04 +0200 Subject: add partial file data to the result of Cache::get --- lib/files/cache/cache.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 8fc575948dc..9d90ab041f6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -31,7 +31,13 @@ class Cache { $query = \OC_DB::prepare( 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); - $result=$query->execute($params); + $result = $query->execute($params); + + //merge partial data + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $result=array_merge($result, self::$partial[$key]); + } return $result->fetchRow(); } -- cgit v1.2.3 From 96b798a59f236f4251ced87ecac9da55e82d1685 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:51:15 +0200 Subject: move storage backend test cases to their own namespace --- apps/files_external/tests/amazons3.php | 8 +- apps/files_external/tests/ftp.php | 8 +- apps/files_external/tests/google.php | 6 +- apps/files_external/tests/smb.php | 8 +- apps/files_external/tests/swift.php | 6 +- apps/files_external/tests/webdav.php | 6 +- tests/lib/files/storage/commontest.php | 43 +++++++ tests/lib/files/storage/local.php | 38 ++++++ tests/lib/files/storage/storage.php | 223 +++++++++++++++++++++++++++++++++ tests/lib/filestorage.php | 222 -------------------------------- tests/lib/filestorage/commontest.php | 41 ------ tests/lib/filestorage/local.php | 38 ------ 12 files changed, 331 insertions(+), 316 deletions(-) create mode 100644 tests/lib/files/storage/commontest.php create mode 100644 tests/lib/files/storage/local.php create mode 100644 tests/lib/files/storage/storage.php delete mode 100644 tests/lib/filestorage.php delete mode 100644 tests/lib/filestorage/commontest.php delete mode 100644 tests/lib/filestorage/local.php diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index ad1c453abb7..cf372aecbd7 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -20,12 +20,14 @@ * License along with this library. If not, see . */ +namespace Test\Files\Storage; + $config = include('apps/files_external/tests/config.php'); if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['run']) { - abstract class Test_Filestorage_AmazonS3 extends Test_FileStorage{} + abstract class AmazonS3 extends Storage{} return; } else { - class Test_Filestorage_AmazonS3 extends Test_FileStorage { + class AmazonS3 extends Storage { private $config; private $id; @@ -38,7 +40,7 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r } public function tearDown() { - $s3 = new AmazonS3(array('key' => $this->config['amazons3']['key'], 'secret' => $this->config['amazons3']['secret'])); + $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); } diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index 105f7b485bd..8a0821e25a5 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { - abstract class Test_Filestorage_FTP extends Test_FileStorage{} + abstract class FTP extends Storage{} return; }else{ - class Test_Filestorage_FTP extends Test_FileStorage { + class FTP extends Storage { private $config; public function setUp() { @@ -22,7 +24,7 @@ if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { } public function tearDown() { - OCP\Files::rmdirr($this->instance->constructUrl('')); + \OCP\Files::rmdirr($this->instance->constructUrl('')); } } } diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index e96c2263e1c..fff6461c912 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -20,12 +20,14 @@ * License along with this library. If not, see . */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['google']) or !$config['google']['run']) { - abstract class Test_Filestorage_Google extends Test_FileStorage{} + abstract class Google extends Storage{} return; }else{ - class Test_Filestorage_Google extends Test_FileStorage { + class Google extends Storage { private $config; diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index a0c5d834736..87b110a241c 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -8,11 +8,13 @@ $config=include('apps/files_external/tests/config.php'); +namespace Test\Files\Storage; + if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { - abstract class Test_Filestorage_SMB extends Test_FileStorage{} + abstract class SMB extends Storage{} return; }else{ - class Test_Filestorage_SMB extends Test_FileStorage { + class SMB extends Storage { private $config; public function setUp() { @@ -23,7 +25,7 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { } public function tearDown() { - OCP\Files::rmdirr($this->instance->constructUrl('')); + \OCP\Files::rmdirr($this->instance->constructUrl('')); } } } diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index 3e1485b0f3a..98a97f99b5b 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']) { - abstract class Test_Filestorage_SWIFT extends Test_FileStorage{} + abstract class SWIFT extends Storage{} return; }else{ - class Test_Filestorage_SWIFT extends Test_FileStorage { + class SWIFT extends Storage { private $config; public function setUp() { diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 6b1121c9d0c..cddd0d513ed 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']) { - abstract class Test_Filestorage_DAV extends Test_FileStorage{} + abstract class DAV extends Storage{} return; }else{ - class Test_Filestorage_DAV extends Test_FileStorage { + class DAV extends Storage { private $config; public function setUp() { diff --git a/tests/lib/files/storage/commontest.php b/tests/lib/files/storage/commontest.php new file mode 100644 index 00000000000..2e3808e2d92 --- /dev/null +++ b/tests/lib/files/storage/commontest.php @@ -0,0 +1,43 @@ +. +* +*/ + +namespace Test\Files\Storage; + +class CommonTest extends Storage { + /** + * @var string tmpDir + */ + private $tmpDir; + public function setUp() { + $this->tmpDir=get_temp_dir().'/filestoragecommon'; + if(!file_exists($this->tmpDir)) { + mkdir($this->tmpDir); + } + $this->instance=new \OC\Files\Storage\CommonTest(array('datadir'=>$this->tmpDir)); + } + + public function tearDown() { + \OC_Helper::rmdirr($this->tmpDir); + } +} + +?> diff --git a/tests/lib/files/storage/local.php b/tests/lib/files/storage/local.php new file mode 100644 index 00000000000..6672368e676 --- /dev/null +++ b/tests/lib/files/storage/local.php @@ -0,0 +1,38 @@ +. +* +*/ + +namespace Test\Files\Storage; + +class Local extends Storage { + /** + * @var string tmpDir + */ + private $tmpDir; + public function setUp() { + $this->tmpDir=\OC_Helper::tmpFolder(); + $this->instance=new \OC\Files\Storage\Local(array('datadir'=>$this->tmpDir)); + } + + public function tearDown() { + \OC_Helper::rmdirr($this->tmpDir); + } +} diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php new file mode 100644 index 00000000000..9c8581b259a --- /dev/null +++ b/tests/lib/files/storage/storage.php @@ -0,0 +1,223 @@ +. +* +*/ + +namespace Test\Files\Storage; + +abstract class Storage extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Storage instance + */ + protected $instance; + + /** + * the root folder of the storage should always exist, be readable and be recognized as a directory + */ + public function testRoot() { + $this->assertTrue($this->instance->file_exists('/'),'Root folder does not exist'); + $this->assertTrue($this->instance->isReadable('/'),'Root folder is not readable'); + $this->assertTrue($this->instance->is_dir('/'),'Root folder is not a directory'); + $this->assertFalse($this->instance->is_file('/'),'Root folder is a file'); + $this->assertEqual('dir',$this->instance->filetype('/')); + + //without this, any further testing would be useless, not an acutal requirement for filestorage though + $this->assertTrue($this->instance->isUpdatable('/'),'Root folder is not writable'); + } + + public function testDirectories() { + $this->assertFalse($this->instance->file_exists('/folder')); + + $this->assertTrue($this->instance->mkdir('/folder')); + + $this->assertTrue($this->instance->file_exists('/folder')); + $this->assertTrue($this->instance->is_dir('/folder')); + $this->assertFalse($this->instance->is_file('/folder')); + $this->assertEqual('dir',$this->instance->filetype('/folder')); + $this->assertEqual(0,$this->instance->filesize('/folder')); + $this->assertTrue($this->instance->isReadable('/folder')); + $this->assertTrue($this->instance->isUpdatable('/folder')); + + $dh=$this->instance->opendir('/'); + $content=array(); + while($file=readdir($dh)) { + if($file!='.' and $file!='..') { + $content[]=$file; + } + } + $this->assertEqual(array('folder'),$content); + + $this->assertFalse($this->instance->mkdir('/folder'));//cant create existing folders + $this->assertTrue($this->instance->rmdir('/folder')); + + $this->assertFalse($this->instance->file_exists('/folder')); + + $this->assertFalse($this->instance->rmdir('/folder'));//cant remove non existing folders + + $dh=$this->instance->opendir('/'); + $content=array(); + while($file=readdir($dh)) { + if($file!='.' and $file!='..') { + $content[]=$file; + } + } + $this->assertEqual(array(),$content); + } + + /** + * test the various uses of file_get_contents and file_put_contents + */ + public function testGetPutContents() { + $sourceFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $sourceText=file_get_contents($sourceFile); + + //fill a file with string data + $this->instance->file_put_contents('/lorem.txt',$sourceText); + $this->assertFalse($this->instance->is_dir('/lorem.txt')); + $this->assertEqual($sourceText,$this->instance->file_get_contents('/lorem.txt'),'data returned from file_get_contents is not equal to the source data'); + + //empty the file + $this->instance->file_put_contents('/lorem.txt',''); + $this->assertEqual('',$this->instance->file_get_contents('/lorem.txt'),'file not emptied'); + } + + /** + * test various known mimetypes + */ + public function testMimeType() { + $this->assertEqual('httpd/unix-directory',$this->instance->getMimeType('/')); + $this->assertEqual(false,$this->instance->getMimeType('/non/existing/file')); + + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); + $this->assertEqual('text/plain',$this->instance->getMimeType('/lorem.txt')); + + $pngFile=\OC::$SERVERROOT.'/tests/data/logo-wide.png'; + $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); + $this->assertEqual('image/png',$this->instance->getMimeType('/logo-wide.png')); + + $svgFile=\OC::$SERVERROOT.'/tests/data/logo-wide.svg'; + $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); + $this->assertEqual('image/svg+xml',$this->instance->getMimeType('/logo-wide.svg')); + } + + public function testCopyAndMove() { + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $this->instance->file_put_contents('/source.txt',file_get_contents($textFile)); + $this->instance->copy('/source.txt','/target.txt'); + $this->assertTrue($this->instance->file_exists('/target.txt')); + $this->assertEqual($this->instance->file_get_contents('/source.txt'),$this->instance->file_get_contents('/target.txt')); + + $this->instance->rename('/source.txt','/target2.txt'); + $this->assertTrue($this->instance->file_exists('/target2.txt')); + $this->assertFalse($this->instance->file_exists('/source.txt')); + $this->assertEqual(file_get_contents($textFile),$this->instance->file_get_contents('/target.txt')); + } + + public function testLocal() { + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); + $localFile=$this->instance->getLocalFile('/lorem.txt'); + $this->assertTrue(file_exists($localFile)); + $this->assertEqual(file_get_contents($localFile),file_get_contents($textFile)); + + $this->instance->mkdir('/folder'); + $this->instance->file_put_contents('/folder/lorem.txt',file_get_contents($textFile)); + $this->instance->file_put_contents('/folder/bar.txt','asd'); + $this->instance->mkdir('/folder/recursive'); + $this->instance->file_put_contents('/folder/recursive/file.txt','foo'); + $localFolder=$this->instance->getLocalFolder('/folder'); + + $this->assertTrue(is_dir($localFolder)); + $this->assertTrue(file_exists($localFolder.'/lorem.txt')); + $this->assertEqual(file_get_contents($localFolder.'/lorem.txt'),file_get_contents($textFile)); + $this->assertEqual(file_get_contents($localFolder.'/bar.txt'),'asd'); + $this->assertEqual(file_get_contents($localFolder.'/recursive/file.txt'),'foo'); + } + + public function testStat() { + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $ctimeStart=time(); + $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); + $this->assertTrue($this->instance->isReadable('/lorem.txt')); + $ctimeEnd=time(); + $cTime=$this->instance->filectime('/lorem.txt'); + $mTime=$this->instance->filemtime('/lorem.txt'); + if($cTime!=-1) {//not everything can support ctime + $this->assertTrue(($ctimeStart-1)<=$cTime); + $this->assertTrue($cTime<=($ctimeEnd+1)); + } + $this->assertTrue($this->instance->hasUpdated('/lorem.txt',$ctimeStart-1)); + $this->assertTrue($this->instance->hasUpdated('/',$ctimeStart-1)); + + $this->assertTrue(($ctimeStart-1)<=$mTime); + $this->assertTrue($mTime<=($ctimeEnd+1)); + $this->assertEqual(filesize($textFile),$this->instance->filesize('/lorem.txt')); + + $stat=$this->instance->stat('/lorem.txt'); + //only size, mtime and ctime are requered in the result + $this->assertEqual($stat['size'],$this->instance->filesize('/lorem.txt')); + $this->assertEqual($stat['mtime'],$mTime); + $this->assertEqual($stat['ctime'],$cTime); + + $mtimeStart=time(); + $this->instance->touch('/lorem.txt'); + $mtimeEnd=time(); + $originalCTime=$cTime; + $cTime=$this->instance->filectime('/lorem.txt'); + $mTime=$this->instance->filemtime('/lorem.txt'); + $this->assertTrue(($mtimeStart-1)<=$mTime); + $this->assertTrue($mTime<=($mtimeEnd+1)); + $this->assertEqual($cTime,$originalCTime); + + $this->assertTrue($this->instance->hasUpdated('/lorem.txt',$mtimeStart-1)); + + if($this->instance->touch('/lorem.txt',100)!==false) { + $mTime=$this->instance->filemtime('/lorem.txt'); + $this->assertEqual($mTime,100); + } + + $mtimeStart=time(); + $fh=$this->instance->fopen('/lorem.txt','a'); + fwrite($fh,' '); + fclose($fh); + clearstatcache(); + $mtimeEnd=time(); + $mTime=$this->instance->filemtime('/lorem.txt'); + $this->assertTrue(($mtimeStart-1)<=$mTime); + $this->assertTrue($mTime<=($mtimeEnd+1)); + + $this->instance->unlink('/lorem.txt'); + $this->assertTrue($this->instance->hasUpdated('/',$mtimeStart-1)); + } + + public function testSearch() { + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; + $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); + $pngFile=\OC::$SERVERROOT.'/tests/data/logo-wide.png'; + $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); + $svgFile=\OC::$SERVERROOT.'/tests/data/logo-wide.svg'; + $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); + $result=$this->instance->search('logo'); + $this->assertEqual(2,count($result)); + $this->assertNotIdentical(false,array_search('/logo-wide.svg',$result)); + $this->assertNotIdentical(false,array_search('/logo-wide.png',$result)); + } +} diff --git a/tests/lib/filestorage.php b/tests/lib/filestorage.php deleted file mode 100644 index bfb40bcd674..00000000000 --- a/tests/lib/filestorage.php +++ /dev/null @@ -1,222 +0,0 @@ -. -* -*/ - -abstract class Test_FileStorage extends UnitTestCase { - /** - * @var \OC\Files\Storage\Storage instance - */ - protected $instance; - - /** - * the root folder of the storage should always exist, be readable and be recognized as a directory - */ - public function testRoot() { - $this->assertTrue($this->instance->file_exists('/'),'Root folder does not exist'); - $this->assertTrue($this->instance->isReadable('/'),'Root folder is not readable'); - $this->assertTrue($this->instance->is_dir('/'),'Root folder is not a directory'); - $this->assertFalse($this->instance->is_file('/'),'Root folder is a file'); - $this->assertEqual('dir',$this->instance->filetype('/')); - - //without this, any further testing would be useless, not an acutal requirement for filestorage though - $this->assertTrue($this->instance->isUpdatable('/'),'Root folder is not writable'); - } - - public function testDirectories() { - $this->assertFalse($this->instance->file_exists('/folder')); - - $this->assertTrue($this->instance->mkdir('/folder')); - - $this->assertTrue($this->instance->file_exists('/folder')); - $this->assertTrue($this->instance->is_dir('/folder')); - $this->assertFalse($this->instance->is_file('/folder')); - $this->assertEqual('dir',$this->instance->filetype('/folder')); - $this->assertEqual(0,$this->instance->filesize('/folder')); - $this->assertTrue($this->instance->isReadable('/folder')); - $this->assertTrue($this->instance->isUpdatable('/folder')); - - $dh=$this->instance->opendir('/'); - $content=array(); - while($file=readdir($dh)) { - if($file!='.' and $file!='..') { - $content[]=$file; - } - } - $this->assertEqual(array('folder'),$content); - - $this->assertFalse($this->instance->mkdir('/folder'));//cant create existing folders - $this->assertTrue($this->instance->rmdir('/folder')); - - $this->assertFalse($this->instance->file_exists('/folder')); - - $this->assertFalse($this->instance->rmdir('/folder'));//cant remove non existing folders - - $dh=$this->instance->opendir('/'); - $content=array(); - while($file=readdir($dh)) { - if($file!='.' and $file!='..') { - $content[]=$file; - } - } - $this->assertEqual(array(),$content); - } - - /** - * test the various uses of file_get_contents and file_put_contents - */ - public function testGetPutContents() { - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $sourceText=file_get_contents($sourceFile); - - //fill a file with string data - $this->instance->file_put_contents('/lorem.txt',$sourceText); - $this->assertFalse($this->instance->is_dir('/lorem.txt')); - $this->assertEqual($sourceText,$this->instance->file_get_contents('/lorem.txt'),'data returned from file_get_contents is not equal to the source data'); - - //empty the file - $this->instance->file_put_contents('/lorem.txt',''); - $this->assertEqual('',$this->instance->file_get_contents('/lorem.txt'),'file not emptied'); - } - - /** - * test various known mimetypes - */ - public function testMimeType() { - $this->assertEqual('httpd/unix-directory',$this->instance->getMimeType('/')); - $this->assertEqual(false,$this->instance->getMimeType('/non/existing/file')); - - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); - $this->assertEqual('text/plain',$this->instance->getMimeType('/lorem.txt')); - - $pngFile=OC::$SERVERROOT.'/tests/data/logo-wide.png'; - $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); - $this->assertEqual('image/png',$this->instance->getMimeType('/logo-wide.png')); - - $svgFile=OC::$SERVERROOT.'/tests/data/logo-wide.svg'; - $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); - $this->assertEqual('image/svg+xml',$this->instance->getMimeType('/logo-wide.svg')); - } - - public function testCopyAndMove() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $this->instance->file_put_contents('/source.txt',file_get_contents($textFile)); - $this->instance->copy('/source.txt','/target.txt'); - $this->assertTrue($this->instance->file_exists('/target.txt')); - $this->assertEqual($this->instance->file_get_contents('/source.txt'),$this->instance->file_get_contents('/target.txt')); - - $this->instance->rename('/source.txt','/target2.txt'); - $this->assertTrue($this->instance->file_exists('/target2.txt')); - $this->assertFalse($this->instance->file_exists('/source.txt')); - $this->assertEqual(file_get_contents($textFile),$this->instance->file_get_contents('/target.txt')); - } - - public function testLocal() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); - $localFile=$this->instance->getLocalFile('/lorem.txt'); - $this->assertTrue(file_exists($localFile)); - $this->assertEqual(file_get_contents($localFile),file_get_contents($textFile)); - - $this->instance->mkdir('/folder'); - $this->instance->file_put_contents('/folder/lorem.txt',file_get_contents($textFile)); - $this->instance->file_put_contents('/folder/bar.txt','asd'); - $this->instance->mkdir('/folder/recursive'); - $this->instance->file_put_contents('/folder/recursive/file.txt','foo'); - $localFolder=$this->instance->getLocalFolder('/folder'); - - $this->assertTrue(is_dir($localFolder)); - $this->assertTrue(file_exists($localFolder.'/lorem.txt')); - $this->assertEqual(file_get_contents($localFolder.'/lorem.txt'),file_get_contents($textFile)); - $this->assertEqual(file_get_contents($localFolder.'/bar.txt'),'asd'); - $this->assertEqual(file_get_contents($localFolder.'/recursive/file.txt'),'foo'); - } - - public function testStat() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $ctimeStart=time(); - $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); - $this->assertTrue($this->instance->isReadable('/lorem.txt')); - $ctimeEnd=time(); - $cTime=$this->instance->filectime('/lorem.txt'); - $mTime=$this->instance->filemtime('/lorem.txt'); - if($cTime!=-1) {//not everything can support ctime - $this->assertTrue(($ctimeStart-1)<=$cTime); - $this->assertTrue($cTime<=($ctimeEnd+1)); - } - $this->assertTrue($this->instance->hasUpdated('/lorem.txt',$ctimeStart-1)); - $this->assertTrue($this->instance->hasUpdated('/',$ctimeStart-1)); - - $this->assertTrue(($ctimeStart-1)<=$mTime); - $this->assertTrue($mTime<=($ctimeEnd+1)); - $this->assertEqual(filesize($textFile),$this->instance->filesize('/lorem.txt')); - - $stat=$this->instance->stat('/lorem.txt'); - //only size, mtime and ctime are requered in the result - $this->assertEqual($stat['size'],$this->instance->filesize('/lorem.txt')); - $this->assertEqual($stat['mtime'],$mTime); - $this->assertEqual($stat['ctime'],$cTime); - - $mtimeStart=time(); - $this->instance->touch('/lorem.txt'); - $mtimeEnd=time(); - $originalCTime=$cTime; - $cTime=$this->instance->filectime('/lorem.txt'); - $mTime=$this->instance->filemtime('/lorem.txt'); - $this->assertTrue(($mtimeStart-1)<=$mTime); - $this->assertTrue($mTime<=($mtimeEnd+1)); - $this->assertEqual($cTime,$originalCTime); - - $this->assertTrue($this->instance->hasUpdated('/lorem.txt',$mtimeStart-1)); - - if($this->instance->touch('/lorem.txt',100)!==false) { - $mTime=$this->instance->filemtime('/lorem.txt'); - $this->assertEqual($mTime,100); - } - - $mtimeStart=time(); - $fh=$this->instance->fopen('/lorem.txt','a'); - fwrite($fh,' '); - fclose($fh); - clearstatcache(); - $mtimeEnd=time(); - $originalCTime=$cTime; - $mTime=$this->instance->filemtime('/lorem.txt'); - $this->assertTrue(($mtimeStart-1)<=$mTime); - $this->assertTrue($mTime<=($mtimeEnd+1)); - - $this->instance->unlink('/lorem.txt'); - $this->assertTrue($this->instance->hasUpdated('/',$mtimeStart-1)); - } - - public function testSearch() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); - $pngFile=OC::$SERVERROOT.'/tests/data/logo-wide.png'; - $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); - $svgFile=OC::$SERVERROOT.'/tests/data/logo-wide.svg'; - $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); - $result=$this->instance->search('logo'); - $this->assertEqual(2,count($result)); - $this->assertNotIdentical(false,array_search('/logo-wide.svg',$result)); - $this->assertNotIdentical(false,array_search('/logo-wide.png',$result)); - } -} diff --git a/tests/lib/filestorage/commontest.php b/tests/lib/filestorage/commontest.php deleted file mode 100644 index 0e52e916789..00000000000 --- a/tests/lib/filestorage/commontest.php +++ /dev/null @@ -1,41 +0,0 @@ -. -* -*/ - -class Test_Filestorage_CommonTest extends Test_FileStorage { - /** - * @var string tmpDir - */ - private $tmpDir; - public function setUp() { - $this->tmpDir=get_temp_dir().'/filestoragecommon'; - if(!file_exists($this->tmpDir)) { - mkdir($this->tmpDir); - } - $this->instance=new \OC\Files\Storage\CommonTest(array('datadir'=>$this->tmpDir)); - } - - public function tearDown() { - OC_Helper::rmdirr($this->tmpDir); - } -} - -?> \ No newline at end of file diff --git a/tests/lib/filestorage/local.php b/tests/lib/filestorage/local.php deleted file mode 100644 index 7bb27830baa..00000000000 --- a/tests/lib/filestorage/local.php +++ /dev/null @@ -1,38 +0,0 @@ -. -* -*/ - -class Test_Filestorage_Local extends Test_FileStorage { - /** - * @var string tmpDir - */ - private $tmpDir; - public function setUp() { - $this->tmpDir=OC_Helper::tmpFolder(); - $this->instance=new \OC\Files\Storage\Local(array('datadir'=>$this->tmpDir)); - } - - public function tearDown() { - OC_Helper::rmdirr($this->tmpDir); - } -} - -?> \ No newline at end of file -- cgit v1.2.3 From b206d16b104f0474cfd41944b857a3981948b94d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:51:34 +0200 Subject: add support for loading namespaced test cases --- lib/base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/base.php b/lib/base.php index 7a09946b9db..38568e27490 100644 --- a/lib/base.php +++ b/lib/base.php @@ -95,6 +95,9 @@ class OC{ } 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; } -- cgit v1.2.3 From 46896be0d482f5dcec85ec32b232dd8a205f3e41 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:03:17 +0200 Subject: fix namespace error in temporary storage backend --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index 0e69c9112ac..ffc55e27507 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -11,7 +11,7 @@ namespace OC\Files\Storage; /** * local storage backnd in temporary folder for testing purpores */ -class Temporary extends OC\Files\Storage\Local{ +class Temporary extends Local{ public function __construct($arguments) { $this->datadir=\OC_Helper::tmpFolder(); } -- cgit v1.2.3 From 73eedd8fc8326616a356c8b8c40826d9dba92f31 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:43:10 +0200 Subject: some simple test cases for the new filecache --- tests/lib/files/cache/cache.php | 88 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/lib/files/cache/cache.php diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php new file mode 100644 index 00000000000..168489a7213 --- /dev/null +++ b/tests/lib/files/cache/cache.php @@ -0,0 +1,88 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +use \OC\Files\Cache\Cache as FileCache; + +class Cache extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Temporary $storage; + */ + private $storage; + + private function createPath($path) { + return new \OC\Files\File($this->storage, $path); + } + + public function testSimple() { + $file1 = $this->createPath('foo'); + $file2 = $this->createPath('foo/bar'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + + $this->assertFalse(FileCache::inCache($file1)); + $this->assertEqual(FileCache::get($file1), null); + + $id1 = FileCache::put($file1, $data1); + $this->assertTrue(FileCache::inCache($file1)); + $cacheData1 = FileCache::get($file1); + foreach ($data1 as $key => $value) { + $this->assertEqual($value, $cacheData1[$key]); + } + $this->assertEqual($cacheData1['fileid'], $id1); + $this->assertEqual($id1, FileCache::getId($file1)); + + $this->assertFalse(FileCache::inCache($file2)); + $id2 = FileCache::put($file2, $data2); + $this->assertTrue(FileCache::inCache($file2)); + $cacheData2 = FileCache::get($file2); + foreach ($data2 as $key => $value) { + $this->assertEqual($value, $cacheData2[$key]); + } + $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); + $this->assertEqual($cacheData2['fileid'], $id2); + $this->assertEqual($id2, FileCache::getId($file2)); + $this->assertEqual($id1, FileCache::getParentId($file2)); + + $newSize = 1050; + $newId2 = FileCache::put($file2, array('size' => $newSize)); + $cacheData2 = FileCache::get($file2); + $this->assertEqual($newId2, $id2); + $this->assertEqual($cacheData2['size'], $newSize); + $this->assertEqual($cacheData1, FileCache::get($file1)); + + FileCache::remove($file2); + $this->assertFalse(FileCache::inCache($file2)); + $this->assertEqual(FileCache::get($file2), null); + $this->assertTrue(FileCache::inCache($file1)); + + $this->assertEqual($cacheData1, FileCache::get($id1)); + } + + public function testPartial() { + $file1 = $this->createPath('foo'); + + FileCache::put($file1, array('size' => 10)); + $this->assertEqual(array('size' => 10), FileCache::get($file1)); + + FileCache::put($file1, array('mtime' => 15)); + $this->assertEqual(array('size' => 10, 'mtime' => 15), FileCache::get($file1)); + + FileCache::put($file1, array('size' => 12)); + $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); + } + + public function tearDown() { + FileCache::removeStorage($this->storage); + } + + public function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + } +} -- cgit v1.2.3 From 97b0eabc850f64949282b471288c93d7148c72ff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:43:48 +0200 Subject: fix several problems in the new filecache in order to complete the tests --- lib/files/cache/cache.php | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d90ab041f6..5d4cb9dd2b6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -23,22 +23,25 @@ class Cache { static public function get($file) { if ($file instanceof \OC\Files\File) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), $file->getInternalPath()); + $params = array($file->getStorageId(), md5($file->getInternalPath())); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); + $data = $result->fetchRow(); //merge partial data - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $result=array_merge($result, self::$partial[$key]); + if (!$data and $file instanceof \OC\Files\File) { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $data = self::$partial[$key]; + } } - return $result->fetchRow(); + return $data; } /** @@ -50,13 +53,13 @@ class Cache { * @return int file id */ static public function put(\OC\Files\File $file, array $data) { - if ($id = self::getId($file) > -1) { + if (($id = self::getId($file)) > -1) { self::update($id, $data); return $id; } else { $key = $file->getStorageId() . '::' . $file->getInternalPath(); if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge($data, self::$partial[$key]); + $data = array_merge(self::$partial[$key], $data); unset(self::$partial[$key]); } @@ -77,7 +80,7 @@ class Cache { $params[] = $file->getStorageId(); $valuesPlaceholder = array_fill(0, count($queryParts), '?'); - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); return \OC_DB::insertid('*PREFIX*filecache'); @@ -135,11 +138,11 @@ class Cache { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); - $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($storageId, $pathHash)); if ($row = $result->fetchRow()) { - return $row['id']; + return $row['fileid']; } else { return -1; } @@ -175,7 +178,7 @@ class Cache { * * @param \OC\Files\File $file */ - public function remove(\OC\Files\File $file) { + static public function remove(\OC\Files\File $file) { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); @@ -187,7 +190,7 @@ class Cache { * * @param \OC\Files\Storage\Storage $storage */ - public function removeStorage(\OC\Files\Storage\Storage $storage) { + static public function removeStorage(\OC\Files\Storage\Storage $storage) { $storageId = $storage->getId(); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $query->execute(array($storageId)); -- cgit v1.2.3 From 6fafd5d4e9d23cd98738a3b00ce0053d6b6e3dff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:48:39 +0200 Subject: this should be done elsewhere if needed --- lib/files/cache/cache.php | 2 +- lib/files/cache/scanner.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5d4cb9dd2b6..0c1d6788ec6 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -152,7 +152,7 @@ class Cache { * get the id of the parent folder of a file * * @param \OC\Files\File $file - * return int + * @return int */ static public function getParentId(\OC\Files\File $file) { $path = $file->getInternalPath(); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 8f2c5bda5ca..e8e9c71c4e5 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -23,7 +23,6 @@ class Scanner { $storage = $file->getStorage(); $path = $file->getInternalPath(); if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - clearstatcache(); $data['mimetype'] = $storage->getMimeType($path); $data['mtime'] = $storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { -- cgit v1.2.3 From f360d7c736b08f48f1abcea1e0b93dc890178c94 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 23 Sep 2012 01:51:00 +0200 Subject: add getId to shared storage backend --- apps/files_sharing/lib/sharedstorage.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index f1539610b02..876e719956f 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -91,7 +91,7 @@ class Shared extends \OC\Files\Storage\Common { * @param string Shared target file path * @return Returns CRUDS permissions granted or false if not found */ - private function getPermissions($target) { + public function getPermissions($target) { $file = $this->getFile($target); if (isset($file['permissions'])) { return $file['permissions']; @@ -449,4 +449,8 @@ class Shared extends \OC\Files\Storage\Common { //TODO return false; } + + public function getId(){ + return 'shared::' . $this->sharedFolder; + } } -- cgit v1.2.3 From dcf995fff3ecc2780d3187744397461d1a14c041 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 23 Sep 2012 15:25:03 +0200 Subject: add Cache::getFolderContent --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 0c1d6788ec6..f8808ad0b4d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,6 +44,25 @@ class Cache { return $data; } + /** + * get the metadata of all files stored in $folder + * + * @param \OC\Files\File $folder + * @return array + */ + static public function getFolderContents($folder) { + $fileId = self::getId($folder); + if ($fileId > -1) { + $query = \OC_DB::prepare( + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` WHERE parent = ?'); + $result = $query->execute(array($fileId)); + return $result->fetchAll(); + } else { + return array(); + } + } + /** * store meta data for a file or folder * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 168489a7213..9f35cd889ac 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -78,6 +78,29 @@ class Cache extends \UnitTestCase { $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); } + public function testFolder() { + $file1 = $this->createPath('folder'); + $file2 = $this->createPath('folder/bar'); + $file3 = $this->createPath('folder/foo'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + FileCache::put($file1, $data1); + FileCache::put($file2, $fileData['bar']); + FileCache::put($file3, $fileData['foo']); + + $content = FileCache::getFolderContents($file1); + $this->assertEqual(count($content), 2); + foreach ($content as $cachedData) { + $data = $fileData[$cachedData['name']]; + foreach ($data as $name => $value) { + $this->assertEqual($value, $cachedData[$name]); + } + } + } + public function tearDown() { FileCache::removeStorage($this->storage); } -- cgit v1.2.3 From 522d7df860fb47d3cc56e315850dda2797569ac5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 26 Sep 2012 17:52:02 +0200 Subject: convert Cache to a non-static class that handles the cache for a single storage backend --- lib/files/cache/cache.php | 121 ++++++++++++++++++++++------------------ lib/files/cache/scanner.php | 1 + tests/lib/files/cache/cache.php | 82 ++++++++++++++------------- 3 files changed, 110 insertions(+), 94 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index f8808ad0b4d..167cc5d13f9 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,21 +9,36 @@ namespace OC\Files\Cache; class Cache { + /** + * @var \OC\Files\Storage\Storage + */ + private $storage; + /** * @var array partial data for the cache */ - private static $partial = array(); + private $partial = array(); + + private $storageId; + + /** + * @param \OC\Files\Storage\Storage $storage + */ + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->storageId = $storage->getId(); + } /** * get the stored metadata of a file or folder * - * @param \OC\Files\File or int $file + * @param string/int $file * @return array */ - static public function get($file) { - if ($file instanceof \OC\Files\File) { + public function get($file) { + if (is_string($file)) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), md5($file->getInternalPath())); + $params = array($this->storageId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -35,23 +50,28 @@ class Cache { $data = $result->fetchRow(); //merge partial data - if (!$data and $file instanceof \OC\Files\File) { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $data = self::$partial[$key]; + 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']; } + return $data; } /** * get the metadata of all files stored in $folder * - * @param \OC\Files\File $folder + * @param string $folder * @return array */ - static public function getFolderContents($folder) { - $fileId = self::getId($folder); + 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` @@ -66,43 +86,42 @@ class Cache { /** * store meta data for a file or folder * - * @param \OC\Files\File $file + * @param string $file * @param array $data * * @return int file id */ - static public function put(\OC\Files\File $file, array $data) { - if (($id = self::getId($file)) > -1) { - self::update($id, $data); + public function put($file, array $data) { + if (($id = $this->getId($file)) > -1) { + $this->update($id, $data); return $id; } else { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge(self::$partial[$key], $data); - unset(self::$partial[$key]); + 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 - self::$partial[$key] = $data; + $this->partial[$file] = $data; return -1; } } - $data['path'] = $file->getInternalPath(); - $data['parent'] = self::getParentId($file); - $data['name'] = basename($file->getInternalPath()); + $data['path'] = $file; + $data['parent'] = $this->getParentId($file); + $data['name'] = basename($file); - list($queryParts, $params) = self::buildParts($data); + list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $file->getStorageId(); + $params[] = $this->storageId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return \OC_DB::insertid('*PREFIX*filecache'); + return (int) \OC_DB::insertid('*PREFIX*filecache'); } } @@ -112,8 +131,8 @@ class Cache { * @param int $id * @param array $data */ - static public function update($id, array $data) { - list($queryParts, $params) = self::buildParts($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 = ?'); @@ -126,7 +145,7 @@ class Cache { * @param array $data * @return array */ - private static function buildParts(array $data) { + static function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); $params = array(); @@ -150,15 +169,14 @@ class Cache { /** * get the file id for a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getId(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + 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($storageId, $pathHash)); + $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -170,48 +188,43 @@ class Cache { /** * get the id of the parent folder of a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getParentId(\OC\Files\File $file) { - $path = $file->getInternalPath(); - if ($path === '/' or $path === '') { + public function getParentId($file) { + if ($file === '/' or $file === '') { return -1; } else { - return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + return $this->getId(dirname($file)); } } /** * check if a file is available in the cache * - * @param \OC\Files\File $file + * @param string $file * @return bool */ - static public function inCache(\OC\Files\File $file) { - return self::getId($file) != -1; + public function inCache($file) { + return $this->getId($file) != -1; } /** * remove a file or folder from the cache * - * @param \OC\Files\File $file + * @param string $file */ - static public function remove(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + public function remove($file) { + $pathHash = md5($file); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($storageId, $pathHash)); + $query->execute(array($this->storageId, $pathHash)); } /** - * remove all entries for files that are stored on $storage form the cache - * - * @param \OC\Files\Storage\Storage $storage + * remove all entries for files that are stored on the storage from the cache */ - static public function removeStorage(\OC\Files\Storage\Storage $storage) { - $storageId = $storage->getId(); + public function clear() { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); - $query->execute(array($storageId)); + $query->execute(array($this->storageId)); } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8e9c71c4e5..17fc0fb2e8e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -15,6 +15,7 @@ class Scanner { /** * get all the metadata of a file or folder * * + * * @param \OC\Files\File $file * @return array with metadata of the file */ diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9f35cd889ac..24dd38fa736 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -16,82 +16,83 @@ class Cache extends \UnitTestCase { */ private $storage; - private function createPath($path) { - return new \OC\Files\File($this->storage, $path); - } + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; public function testSimple() { - $file1 = $this->createPath('foo'); - $file2 = $this->createPath('foo/bar'); + $file1 = 'foo'; + $file2 = 'foo/bar'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); - $this->assertFalse(FileCache::inCache($file1)); - $this->assertEqual(FileCache::get($file1), null); + $this->assertFalse($this->cache->inCache($file1)); + $this->assertEqual($this->cache->get($file1), null); - $id1 = FileCache::put($file1, $data1); - $this->assertTrue(FileCache::inCache($file1)); - $cacheData1 = FileCache::get($file1); + $id1 = $this->cache->put($file1, $data1); + $this->assertTrue($this->cache->inCache($file1)); + $cacheData1 = $this->cache->get($file1); foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } $this->assertEqual($cacheData1['fileid'], $id1); - $this->assertEqual($id1, FileCache::getId($file1)); + $this->assertEqual($id1, $this->cache->getId($file1)); - $this->assertFalse(FileCache::inCache($file2)); - $id2 = FileCache::put($file2, $data2); - $this->assertTrue(FileCache::inCache($file2)); - $cacheData2 = FileCache::get($file2); + $this->assertFalse($this->cache->inCache($file2)); + $id2 = $this->cache->put($file2, $data2); + $this->assertTrue($this->cache->inCache($file2)); + $cacheData2 = $this->cache->get($file2); foreach ($data2 as $key => $value) { $this->assertEqual($value, $cacheData2[$key]); } $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); $this->assertEqual($cacheData2['fileid'], $id2); - $this->assertEqual($id2, FileCache::getId($file2)); - $this->assertEqual($id1, FileCache::getParentId($file2)); + $this->assertEqual($id2, $this->cache->getId($file2)); + $this->assertEqual($id1, $this->cache->getParentId($file2)); $newSize = 1050; - $newId2 = FileCache::put($file2, array('size' => $newSize)); - $cacheData2 = FileCache::get($file2); + $newId2 = $this->cache->put($file2, array('size' => $newSize)); + $cacheData2 = $this->cache->get($file2); $this->assertEqual($newId2, $id2); $this->assertEqual($cacheData2['size'], $newSize); - $this->assertEqual($cacheData1, FileCache::get($file1)); + $this->assertEqual($cacheData1, $this->cache->get($file1)); - FileCache::remove($file2); - $this->assertFalse(FileCache::inCache($file2)); - $this->assertEqual(FileCache::get($file2), null); - $this->assertTrue(FileCache::inCache($file1)); + $this->cache->remove($file2); + $this->assertFalse($this->cache->inCache($file2)); + $this->assertEqual($this->cache->get($file2), null); + $this->assertTrue($this->cache->inCache($file1)); - $this->assertEqual($cacheData1, FileCache::get($id1)); + $this->assertEqual($cacheData1, $this->cache->get($id1)); } public function testPartial() { - $file1 = $this->createPath('foo'); + $file1 = 'foo'; - FileCache::put($file1, array('size' => 10)); - $this->assertEqual(array('size' => 10), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 10)); + $this->assertEqual(array('size' => 10), $this->cache->get($file1)); - FileCache::put($file1, array('mtime' => 15)); - $this->assertEqual(array('size' => 10, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('mtime' => 15)); + $this->assertEqual(array('size' => 10, 'mtime' => 15), $this->cache->get($file1)); - FileCache::put($file1, array('size' => 12)); - $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 12)); + $this->assertEqual(array('size' => 12, 'mtime' => 15), $this->cache->get($file1)); } public function testFolder() { - $file1 = $this->createPath('folder'); - $file2 = $this->createPath('folder/bar'); - $file3 = $this->createPath('folder/foo'); + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); - FileCache::put($file1, $data1); - FileCache::put($file2, $fileData['bar']); - FileCache::put($file3, $fileData['foo']); + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['bar']); + $this->cache->put($file3, $fileData['foo']); - $content = FileCache::getFolderContents($file1); + $content = $this->cache->getFolderContents($file1); $this->assertEqual(count($content), 2); foreach ($content as $cachedData) { $data = $fileData[$cachedData['name']]; @@ -102,10 +103,11 @@ class Cache extends \UnitTestCase { } public function tearDown() { - FileCache::removeStorage($this->storage); + $this->cache->clear(); } public function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->cache = new \OC\Files\Cache\Cache($this->storage); } } -- cgit v1.2.3 From 92555eff711ff391f3af5ef6fb6f6414bfe012cf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:34:45 +0200 Subject: add encrypted column to the new filecache --- lib/files/cache/cache.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 167cc5d13f9..9d8275e5e03 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,7 +44,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -59,6 +59,7 @@ class Cache { $data['fileid'] = (int)$data['fileid']; $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; + $data['encrypted'] = (bool)$data['encrypted']; } return $data; @@ -74,7 +75,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ?'); $result = $query->execute(array($fileId)); return $result->fetchAll(); @@ -112,6 +113,7 @@ class Cache { $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`'; @@ -121,7 +123,7 @@ class Cache { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return (int) \OC_DB::insertid('*PREFIX*filecache'); + return (int)\OC_DB::insertid('*PREFIX*filecache'); } } @@ -146,7 +148,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); -- cgit v1.2.3 From 1ed89760be5e1c5cf5b3fa7d40d845750b2840ab Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:35:51 +0200 Subject: dont need this anymore --- tests/lib/files/cache/cache.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 24dd38fa736..48cdc1c8c8c 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -8,8 +8,6 @@ namespace Test\Files\Cache; -use \OC\Files\Cache\Cache as FileCache; - class Cache extends \UnitTestCase { /** * @var \OC\Files\Storage\Temporary $storage; -- cgit v1.2.3 From 6134e554f2306c5309a793d4d3149a0f9b05ea5f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:46:35 +0200 Subject: new filecache table --- db_structure.xml | 92 ++++++++++++++++++-------------------------------------- lib/util.php | 2 +- 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 99a30cb6137..8bbc6e5cc6b 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -53,19 +53,27 @@ - *dbprefix*fscache + *dbprefix*filecache - id - 1 + fileid integer 0 true + 1 4 + + storage + text + + true + 64 + + path text @@ -85,49 +93,17 @@ parent integer - 0 - true - 8 - - - - name - text true - 300 + 4 - user + name text true - 64 - - - - size - integer - 0 - true - 8 - - - - ctime - integer - 0 - true - 8 - - - - mtime - integer - 0 - true - 8 + 250 @@ -135,7 +111,7 @@ text true - 96 + 64 @@ -147,55 +123,45 @@ - encrypted + size integer - 0 + true - 1 + 4 - versioned + mtime integer - 0 + true - 1 + 4 - writable + encrypted integer 0 true - 1 + 4 - fscache_path_hash_index - - path_hash - ascending - - - - - parent_index + storage_path_hash + true - parent + storage ascending - - - - name_index - name + path_hash ascending - parent_name_index + parent_name_hash + true parent ascending diff --git a/lib/util.php b/lib/util.php index 31dd376b9cc..264d61319dd 100755 --- a/lib/util.php +++ b/lib/util.php @@ -81,7 +81,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.9.0. This is not visible to the user - return array(4,86,11); + return array(4,86,12); } /** -- cgit v1.2.3 From 636c75ce061492751d0fb001e0bf7219df379f09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:23:33 +0200 Subject: better parent path bahaviour for the filecache --- lib/files/cache/cache.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d8275e5e03..79673771e5e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -194,10 +194,14 @@ class Cache { * @return int */ public function getParentId($file) { - if ($file === '/' or $file === '') { + if ($file === '') { return -1; } else { - return $this->getId(dirname($file)); + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + return $this->getId($parent); } } -- cgit v1.2.3 From 96d7cd59978cc416bc0d9c5ac487af23692ef1d8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:10 +0200 Subject: correct namespace usage in common filestorage backend --- lib/files/storage/common.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index b2b4ea8eee4..3886a041829 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common extends \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\Share::PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= OCP\Share::PERMISSION_READ; + $permissions |= \OCP\Share::PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\Share::PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\Share::PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\Share::PERMISSION_SHARE; } return $permissions; } -- cgit v1.2.3 From e415e90c6d8a2e8bb129be7c63a7077c56ab3da8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:49 +0200 Subject: make filestorage scanner non-static and add a simple test case --- lib/files/cache/scanner.php | 64 +++++++++++++++++++++++++-------------- tests/lib/files/cache/cache.php | 1 + tests/lib/files/cache/scanner.php | 47 ++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 tests/lib/files/cache/scanner.php diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 17fc0fb2e8e..721d0d825ec 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -9,29 +9,42 @@ namespace OC\Files\Cache; class Scanner { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @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->cache = new Cache($storage); + } + /** * get all the metadata of a file or folder * * * - * @param \OC\Files\File $file + * @param string $path * @return array with metadata of the file */ - public static function getData(\OC\Files\File $file) { + public function getData($path) { $data = array(); - $storage = $file->getStorage(); - $path = $file->getInternalPath(); - if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - $data['mimetype'] = $storage->getMimeType($path); - $data['mtime'] = $storage->filemtime($path); + 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 - $data['permissions'] = $storage->getPermissions($path . '/'); + $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { - $data['size'] = $storage->filesize($path); - $data['permissions'] = $storage->getPermissions($path); + $data['size'] = $this->storage->filesize($path); + $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -39,33 +52,40 @@ class Scanner { /** * scan a single file and store it in the cache * - * @param \OC\Files\File $file + * @param string $file * @return array with metadata of the scanned file */ - public static function scanFile(\OC\Files\File $file) { - $data = self::getData($file); - Cache::put($file, $data); + public function scanFile($file) { + $data = $this->getData($file); + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } + } + $this->cache->put($file, $data); return $data; } /** * scan all the files in a folder and store them in the cache * - * @param \OC\Files\File $folder + * @param string $path * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public static function scan(\OC\Files\File $folder, $recursive) { + public function scan($path, $recursive) { $size = 0; - $storage = $folder->getStorage(); - $path = $folder->getInternalPath(); - if ($dh = $storage->opendir($path)) { + if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = new \OC\Files\File($storage, $path . '/' . $file); - $data = self::scanFile($child); + $child = $path . '/' . $file; + $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); } if ($data['size'] >= 0 and $size >= 0) { $size += $data['size']; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 48cdc1c8c8c..8cedadbf19a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -34,6 +34,7 @@ class Cache extends \UnitTestCase { foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } + $this->assertEqual($cacheData1['mimepart'], 'foo'); $this->assertEqual($cacheData1['fileid'], $id1); $this->assertEqual($id1, $this->cache->getId($file1)); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php new file mode 100644 index 00000000000..3d1c1546ab0 --- /dev/null +++ b/tests/lib/files/cache/scanner.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Scanner extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + function testFile() { + $data = "dummy file data\n"; + $this->storage->file_put_contents('foo.txt', $data); + $this->scanner->scanFile('foo.txt'); + + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'text/plain'); + } + + function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->scanner = new \OC\Files\Cache\Scanner($this->storage); + $this->cache = new \OC\Files\Cache\Cache($this->storage); + } + + function tearDown() { +// $this->cache->clear(); + } +} -- cgit v1.2.3 From 3c8e5ea3581cbbfc5acd3c229080bc63548d2827 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:31:13 +0200 Subject: this index cant be unique due to collisions of the root of different storages --- db_structure.xml | 1 - lib/util.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 8bbc6e5cc6b..e0b9dc11e94 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -161,7 +161,6 @@ parent_name_hash - true parent ascending diff --git a/lib/util.php b/lib/util.php index 264d61319dd..be9d1f4fb5f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -81,7 +81,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.9.0. This is not visible to the user - return array(4,86,12); + return array(4,86,13); } /** -- cgit v1.2.3 From 85be00be6595a3af168f6df963ffdeac8c3c6d5e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:40:09 +0200 Subject: add some more test cases for the scanner --- lib/files/cache/scanner.php | 6 ++++-- tests/lib/files/cache/scanner.php | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 721d0d825ec..7d449204e81 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -77,12 +77,14 @@ class Scanner { * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public function scan($path, $recursive) { + public function scan($path, $recursive = self::SCAN_RECURSIVE) { + $this->scanFile($path); + $size = 0; if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = $path . '/' . $file; + $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 3d1c1546ab0..7ee28dfc3fd 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -33,6 +33,27 @@ class Scanner extends \UnitTestCase { $cachedData = $this->cache->get('foo.txt'); $this->assertEqual($cachedData['size'], strlen($data)); $this->assertEqual($cachedData['mimetype'], 'text/plain'); + $this->assertNotEqual($cachedData['parent'], -1); //parent folders should be scanned automatically + + $data = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.png', $data); + $this->scanner->scanFile('foo.png'); + + $this->assertEqual($this->cache->inCache('foo.png'), true); + $cachedData = $this->cache->get('foo.png'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'image/png'); + } + + function testFolder() { + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + + $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); } function setUp() { @@ -42,6 +63,6 @@ class Scanner extends \UnitTestCase { } function tearDown() { -// $this->cache->clear(); + $this->cache->clear(); } } -- cgit v1.2.3 From b9b9fd9dbaae47b3a15aed9694c18b95404550b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 13:07:19 +0200 Subject: more tests and fixes for the filesystem scanner --- lib/files/cache/scanner.php | 15 ++++++++++++--- tests/lib/files/cache/scanner.php | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7d449204e81..e8f54c34be7 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -86,15 +86,24 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } } - if ($data['size'] >= 0 and $size >= 0) { + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { $size += $data['size']; } } } } + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } return $size; } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 7ee28dfc3fd..41286e69d3e 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -45,15 +45,52 @@ class Scanner extends \UnitTestCase { $this->assertEqual($cachedData['mimetype'], 'image/png'); } - function testFolder() { + private function fillTestFolders() { $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); $this->storage->file_put_contents('foo.txt', $textData); $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + } + + function testFolder() { + $this->fillTestFolders(); $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache(''), true); $this->assertEqual($this->cache->inCache('foo.txt'), true); $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), true); + + $cachedDataText = $this->cache->get('foo.txt'); + $cachedDataText2 = $this->cache->get('foo.txt'); + $cachedDataImage = $this->cache->get('foo.png'); + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataImage['parent'], $cachedDataText['parent']); + $this->assertEqual($cachedDataFolder['fileid'], $cachedDataImage['parent']); + $this->assertEqual($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); + $this->assertEqual($cachedDataFolder2['size'], $cachedDataText2['size']); + } + + function testShallow() { + $this->fillTestFolders(); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertEqual($this->cache->inCache(''), true); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), false); + + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataFolder['size'], -1); + $this->assertEqual($cachedDataFolder2['size'], -1); } function setUp() { -- cgit v1.2.3 From c815fd5a5c8cba52b24327584e689498cb03fb3e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 8 Oct 2012 14:31:13 +0200 Subject: fix files_external test cases --- apps/files_external/tests/dropbox.php | 8 +++++--- apps/files_external/tests/smb.php | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/files_external/tests/dropbox.php b/apps/files_external/tests/dropbox.php index 64eb2556c92..e77e0767c91 100644 --- a/apps/files_external/tests/dropbox.php +++ b/apps/files_external/tests/dropbox.php @@ -6,19 +6,21 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('files_external/tests/config.php'); if(!is_array($config) or !isset($config['dropbox']) or !$config['dropbox']['run']) { - abstract class Test_Filestorage_Dropbox extends Test_FileStorage{} + abstract class Dropbox extends Storage{} return; }else{ - class Test_Filestorage_Dropbox extends Test_FileStorage { + class Dropbox extends Storage { private $config; public function setUp() { $id=uniqid(); $this->config=include('files_external/tests/config.php'); $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() { diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index 87b110a241c..24728dc2370 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -6,9 +6,10 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); -namespace Test\Files\Storage; if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { abstract class SMB extends Storage{} -- cgit v1.2.3 From 13515effc99bfad7e776d00476e897fa396a8c6c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 8 Oct 2012 14:58:21 +0200 Subject: add Cache::getStatus --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 10 ++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 79673771e5e..5ef49246ea5 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,6 +9,11 @@ namespace OC\Files\Cache; 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 \OC\Files\Storage\Storage */ @@ -233,4 +238,28 @@ class Cache { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $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 * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($this->storageId, $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; + } + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 8cedadbf19a..177cf1c045d 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -101,6 +101,16 @@ class Cache extends \UnitTestCase { } } + function testStatus() { + $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1)); + $this->assertEquals(\OC\Files\Cache\Cache::PARTIAL, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1, 'mtime' => 20, 'mimetype' => 'foo/file')); + $this->assertEquals(\OC\Files\Cache\Cache::SHALLOW, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => 10)); + $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From d717a5e55ca54c6ddbaf2f35f0f19b707dcfe1c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 11:51:14 +0200 Subject: remove old filecache --- lib/filecache.php | 511 ----------------------------------------------- lib/filecache/cached.php | 81 -------- lib/filecache/update.php | 217 -------------------- lib/filesystem.php | 12 +- lib/util.php | 7 - 5 files changed, 2 insertions(+), 826 deletions(-) delete mode 100644 lib/filecache.php delete mode 100644 lib/filecache/cached.php delete mode 100644 lib/filecache/update.php diff --git a/lib/filecache.php b/lib/filecache.php deleted file mode 100644 index 8fcb6fd9404..00000000000 --- a/lib/filecache.php +++ /dev/null @@ -1,511 +0,0 @@ -. -* -*/ - -/** - * provide caching for filesystem info in the database - * - * not used by OC_Filesystem for reading filesystem info, - * instread 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 - */ -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) - * - * $data is an assiciative 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=$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; - - $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) { - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `name` LIKE ? AND `user`=?'); - }else{ - $query=OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `name` LIKE ? AND `user`=?'); - } - $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; - $id=self::getId($path,$root); - 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)); - $id=self::getParentId($path); - $path=dirname($path); - } - } - - /** - * recursively scan the filesystem and fill the cache - * @param string $path - * @param OC_EventSource $enventSource (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`="httpd/unix-directory"'); - $query->execute(array($user)); - }else{ - $query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 AND `mimetype`="httpd/unix-directory"'); - $query->execute(); - } - } -} - -//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'); diff --git a/lib/filecache/cached.php b/lib/filecache/cached.php deleted file mode 100644 index 9b1eb4f7803..00000000000 --- a/lib/filecache/cached.php +++ /dev/null @@ -1,81 +0,0 @@ - - * 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 `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; - } - } -} \ No newline at end of file diff --git a/lib/filecache/update.php b/lib/filecache/update.php deleted file mode 100644 index 1b81f70d77b..00000000000 --- a/lib/filecache/update.php +++ /dev/null @@ -1,217 +0,0 @@ - - * 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); - } - 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); - } -} diff --git a/lib/filesystem.php b/lib/filesystem.php index 0d24b7203bc..b73b52d4203 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -254,13 +254,6 @@ class OC_Filesystem{ } } } - - $mtime=filemtime(OC::$SERVERROOT.'/config/mount.php'); - $previousMTime=OC_Appconfig::getValue('files','mountconfigmtime',0); - if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated - OC_FileCache::triggerUpdate(); - OC_Appconfig::setValue('files','mountconfigmtime',$mtime); - } } self::$loaded=true; @@ -399,7 +392,7 @@ class OC_Filesystem{ } /** - * checks if a file is blacklsited for storage in the filesystem + * checks if a file is blacklisted for storage in the filesystem * Listens to write and rename hooks * @param array $data from hook */ @@ -419,7 +412,7 @@ class OC_Filesystem{ } /** - * following functions are equivilent to their php buildin equivilents for arguments/return values. + * following functions are equivalent to their php builtin equivalents for arguments/return values. */ static public function mkdir($path) { return self::$defaultInstance->mkdir($path); @@ -592,4 +585,3 @@ OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook') OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); OC_Util::setupFS(); -require_once 'filecache.php'; diff --git a/lib/util.php b/lib/util.php index b21580cb017..557f731522e 100755 --- a/lib/util.php +++ b/lib/util.php @@ -58,13 +58,6 @@ class OC_Util { OC_Filesystem::mount($options['class'], $options['options'], $mountPoint); } } - - $mtime=filemtime($user_root.'/mount.php'); - $previousMTime=OC_Preferences::getValue($user,'files','mountconfigmtime',0); - if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated - OC_FileCache::triggerUpdate($user); - OC_Preferences::setValue($user,'files','mountconfigmtime',$mtime); - } } OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); } -- cgit v1.2.3 From 9df60d27bd9dad6a37a0d763b808a5b1c5ade5c5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 11:54:44 +0200 Subject: move some code around --- lib/files/filesystem.php | 629 ++++++++++++++++++++++++++++++++++++++++++++ lib/files/view.php | 658 +++++++++++++++++++++++++++++++++++++++++++++++ lib/filesystem.php | 562 ---------------------------------------- lib/filesystemview.php | 633 --------------------------------------------- 4 files changed, 1287 insertions(+), 1195 deletions(-) create mode 100644 lib/files/filesystem.php create mode 100644 lib/files/view.php delete mode 100644 lib/filesystemview.php 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 @@ + + * 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/files/view.php b/lib/files/view.php new file mode 100644 index 00000000000..8c3f288f445 --- /dev/null +++ b/lib/files/view.php @@ -0,0 +1,658 @@ + + * 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 toor + * + * @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 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)); + } + return $this->internal_path_cache[$path]; + } + + /** + * 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 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)); + } + return $this->storage_cache[$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 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 + */ + public function getLocalFile($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)) { + return $storage->getLocalFolder($this->getInternalPath($path)); + } + } + + /** + * 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 \OC\Files\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; + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + public function is_readable($path) { + return $this->basicOperation('isReadable', $path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + public function is_writable($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 == '/') { + 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) { + 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 = 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) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + if (!$run) { + return false; + } + $target = $this->fopen($path, 'w'); + if ($target) { + $count = OC_Helper::streamCopy($data, $target); + fclose($target); + fclose($data); + 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) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array(OC_Filesystem::signal_param_path => $path) + ); + } + OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); + return $count > 0; + } 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 = 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)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + + if ($path1 == null or $path2 == null) { + return false; + } + $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 + ) + ); + } + 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'); + $count = OC_Helper::streamCopy($source, $target); + $storage1 = $this->getStorage($path1); + $storage1->unlink($this->getInternalPath($path1 . $postFix1)); + $result = $count > 0; + } + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_rename, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2 + ) + ); + } + return $result; + } + } + } + + public function copy($path1, $path2) { + $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)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + + if ($path1 == null or $path2 == null) { + return false; + } + $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_run => &$run + ) + ); + $exists = $this->file_exists($path2); + if ($run and !$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + if ($run) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + } + } + 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'); + $result = OC_Helper::streamCopy($source, $target); + } + 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 + ) + ); + if (!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_create, + array(OC_Filesystem::signal_param_path => $path2) + ); + } + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array(OC_Filesystem::signal_param_path => $path2) + ); + } 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); + OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); + } + return $result; + } + } + } + + 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 (OC_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; + } + } + } + + public function fromTmpFile($tmpFile, $path) { + if (OC_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 { + } + } 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); + if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + if ($path == null) { + return false; + } + if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_read, + array(OC_Filesystem::signal_param_path => $path) + ); + } + if ($storage = $this->getStorage($path . $postFix)) { + $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $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 (optional) hooks + * @param mixed (optional) $extraParam + * @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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); + if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + 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)) { + $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); + } + } + return $result; + } + } + 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') { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix . $hook, + array( + OC_Filesystem::signal_param_run => &$run, + OC_Filesystem::signal_param_path => $path + ) + ); + } elseif (!$post) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix . $hook, + array( + OC_Filesystem::signal_param_path => $path + ) + ); + } + } + } + return $run; + } + + /** + * check if a file or folder has been updated since $time + * + * @param int $time + * @return bool + */ + public function hasUpdated($path, $time) { + return $this->basicOperation('hasUpdated', $path, array(), $time); + } +} 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(); diff --git a/lib/filesystemview.php b/lib/filesystemview.php deleted file mode 100644 index 071fc781f12..00000000000 --- a/lib/filesystemview.php +++ /dev/null @@ -1,633 +0,0 @@ -. - */ - - -/** - * 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 - */ - -class OC_FilesystemView { - 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 toor - * @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 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)); - } - return $this->internal_path_cache[$path]; - } - - /** - * 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 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)); - } - return $this->storage_cache[$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 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 - */ - public function getLocalFile($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)) { - return $storage->getLocalFolder($this->getInternalPath($path)); - } - } - - /** - * 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 \OC\Files\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; - } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - public function is_readable($path) { - return $this->basicOperation('isReadable',$path); - } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - public function is_writable($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=='/') { - 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) { - 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 = 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) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, - array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, - array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - if(!$run) { - return false; - } - $target=$this->fopen($path, 'w'); - if($target) { - $count=OC_Helper::streamCopy($data, $target); - fclose($target); - fclose($data); - 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) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path) - ); - } - OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); - return $count > 0; - }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 = 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)) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if($path1 == null or $path2 == null) { - return false; - } - $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 - ) - ); - } - 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'); - $count = OC_Helper::streamCopy($source, $target); - $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1.$postFix1)); - $result = $count>0; - } - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_rename, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 - ) - ); - } - return $result; - } - } - } - public function copy($path1, $path2) { - $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)) { - $path1 = $this->getRelativePath($absolutePath1); - $path2 = $this->getRelativePath($absolutePath2); - - if($path1 == null or $path2 == null) { - return false; - } - $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_run => &$run - ) - ); - $exists=$this->file_exists($path2); - if($run and !$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, - array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - if($run) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, - array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run - ) - ); - } - } - 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'); - $result = OC_Helper::streamCopy($source, $target); - } - 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 - ) - ); - if(!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path2) - ); - } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path2) - ); - } 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); - OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); - } - return $result; - } - } - } - 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(OC_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; - } - } - } - public function fromTmpFile($tmpFile, $path) { - if(OC_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 { - } - } 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - if ($path == null) { - return false; - } - if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_read, - array( OC_Filesystem::signal_param_path => $path) - ); - } - if ($storage = $this->getStorage($path.$postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path.$postFix), $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 (optional) hooks - * @param mixed (optional) $extraParam - * @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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { - $path = $this->getRelativePath($absolutePath); - 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)) { - $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); - } - } - return $result; - } - } - 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') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $prefix.$hook, - array( - OC_Filesystem::signal_param_run => &$run, - OC_Filesystem::signal_param_path => $path - ) - ); - } elseif(!$post) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $prefix.$hook, - array( - OC_Filesystem::signal_param_path => $path - ) - ); - } - } - } - return $run; - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - return $this->basicOperation('hasUpdated', $path, array(), $time); - } -} -- cgit v1.2.3 From 07c53841899262fdd34304302ffaaf2704800c38 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:25:46 +0200 Subject: fix namespaces in filesystem and filesystemview --- lib/app.php | 6 +- lib/files/filesystem.php | 153 +++++++++++++++------------- lib/files/view.php | 260 ++++++++++++++++++++++++++--------------------- 3 files changed, 225 insertions(+), 194 deletions(-) diff --git a/lib/app.php b/lib/app.php index 395230156f6..4d7353e99dc 100755 --- a/lib/app.php +++ b/lib/app.php @@ -714,16 +714,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, user not logged in', OC_Log::ERROR); return false; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d0a96b59a0e..f23f3a79e98 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -15,16 +15,16 @@ * 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) + * 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 emited in that order) + * 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 occuring + * the &run parameter can be set to false to prevent the operation from occurring */ namespace OC\Files; @@ -34,7 +34,7 @@ class Filesystem { static private $mounts = array(); public static $loaded = false; /** - * @var \OC\Files\Storage\Storage $defaultInstance + * @var \OC\Files\View $defaultInstance */ static private $defaultInstance; @@ -46,80 +46,80 @@ class Filesystem { const CLASSNAME = 'OC_Filesystem'; /** - * signalname emited before file renaming + * signalname emitted before file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_rename = 'rename'; /** - * signal emited after file renaming + * signal emitted after file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_post_rename = 'post_rename'; /** - * signal emited before file/dir creation + * signal emitted before file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @param string $path + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_create = 'create'; /** - * signal emited after file/dir creation + * signal emitted after file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @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 oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event + * @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 oldpath - * @param newpath + * @param string $oldpath + * @param string $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 + * @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 path + * @param string $path */ const signal_post_write = 'post_write'; /** * signal emits when reading file/dir * - * @param path + * @param string $path */ const signal_read = 'read'; /** * signal emits when removing file/dir * - * @param path + * @param string $path */ const signal_delete = 'delete'; @@ -139,11 +139,11 @@ class Filesystem { * 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 + * @param string $path * @return string */ static public function getMountPoint($path) { - OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); if (!$path) { $path = '/'; } @@ -152,7 +152,7 @@ class Filesystem { } $path = str_replace('//', '/', $path); $foundMountPoint = ''; - $mountPoints = array_keys(OC_Filesystem::$mounts); + $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { if ($mountpoint == $path) { return $mountpoint; @@ -167,7 +167,7 @@ class Filesystem { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @param string $path * @return bool */ static public function getInternalPath($path) { @@ -179,17 +179,19 @@ class Filesystem { /** * get the storage object for a path * - * @param string 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']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - return OC_Filesystem::$storages[$mountpoint]; + return self::$storages[$mountpoint]; + }else{ + return null; } } @@ -202,13 +204,15 @@ class Filesystem { 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']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - $storage = OC_Filesystem::$storages[$mountpoint]; + $storage = self::$storages[$mountpoint]; $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); + }else{ + return array(null, null); } } @@ -216,11 +220,11 @@ class Filesystem { if (self::$defaultInstance) { return false; } - self::$defaultInstance = new OC_FilesystemView($root); + self::$defaultInstance = new View($root); -//load custom mount config - if (is_file(OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = include(OC::$SERVERROOT . '/config/mount.php'); + //load custom mount config + 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); @@ -229,7 +233,7 @@ class Filesystem { if (isset($mountConfig['group'])) { foreach ($mountConfig['group'] as $group => $mounts) { - if (OC_Group::inGroup(OC_User::getUser(), $group)) { + if (\OC_Group::inGroup(\OC_User::getUser(), $group)) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -243,7 +247,7 @@ class Filesystem { if (isset($mountConfig['user'])) { foreach ($mountConfig['user'] as $user => $mounts) { - if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) { + if ($user === 'all' or strtolower($user) === strtolower(\OC_User::getUser())) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -257,22 +261,24 @@ class Filesystem { } self::$loaded = true; + + return true; } /** * fill in the correct values for $user, and $password placeholders * - * @param string intput + * @param string $input * @return string */ private static function setUserVars($input) { - return str_replace('$user', OC_User::getUser(), $input); + return str_replace('$user', \OC_User::getUser(), $input); } /** * get the default filesystem view * - * @return OC_FilesystemView + * @return View */ static public function getView() { return self::$defaultInstance; @@ -288,20 +294,20 @@ class Filesystem { /** * create a new storage of a specific type * - * @param string type - * @param array arguments + * @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); + } 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); + \OC_Log::write('core', 'storage backend ' . $class . ' not found', \OC_Log::ERROR); return false; } } @@ -309,7 +315,7 @@ class Filesystem { /** * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ static public function chroot($fakeRoot) { @@ -337,8 +343,9 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage storage - * @param string mountpoint + * @param \OC\Files\Storage\Storage $storage + * @param array $arguments + * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { if ($mountpoint[0] != '/') { @@ -354,7 +361,7 @@ class Filesystem { * 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 + * @param string $path * @return string */ static public function getLocalFile($path) { @@ -362,7 +369,7 @@ class Filesystem { } /** - * @param string path + * @param string $path * @return string */ static public function getLocalFolder($path) { @@ -372,11 +379,11 @@ class Filesystem { /** * return path to file which reflects one visible in browser * - * @param string path + * @param string $path * @return string */ static public function getLocalPath($path) { - $datadir = OC_User::getHome(OC_User::getUser()) . '/files'; + $datadir = \OC_User::getHome(\OC_User::getUser()) . '/files'; $newpath = $path; if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { $newpath = substr($path, strlen($datadir)); @@ -387,7 +394,7 @@ class Filesystem { /** * check if the requested path is valid * - * @param string path + * @param string $path * @return bool */ static public function isValidPath($path) { @@ -468,7 +475,7 @@ class Filesystem { * @deprecated Replaced by isReadable() as part of CRUDS */ static public function is_readable($path) { - return self::$defaultInstance->is_readable($path); + return self::$defaultInstance->isReadable($path); } /** @@ -559,7 +566,7 @@ class Filesystem { } static public function search($query) { - return OC_FileCache::search($query); + return Cache\Cache::search($query); } /** @@ -580,19 +587,19 @@ class Filesystem { } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); - OC_Connector_Sabre_Node::removeETagPropertyForPath($path); + \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); } /** * normalize a path * - * @param string path + * @param string $path * @param bool $stripTrailingSlash * @return string */ @@ -606,7 +613,7 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trainling slash +//remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } @@ -616,14 +623,14 @@ class Filesystem { } //normalize unicode if possible if (class_exists('Normalizer')) { - $path = Normalizer::normalize($path); + $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_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(); +\OC_Util::setupFS(); diff --git a/lib/files/view.php b/lib/files/view.php index 8c3f288f445..230455479cf 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -45,9 +45,9 @@ class View { } /** - * change the root to a fake toor + * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ public function chroot($fakeRoot) { @@ -71,12 +71,12 @@ class View { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @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)); + $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); } return $this->internal_path_cache[$path]; } @@ -84,7 +84,7 @@ class View { /** * get path relative to the root of the view * - * @param string path + * @param string $path * @return string */ public function getRelativePath($path) { @@ -106,12 +106,12 @@ class View { /** * get the storage object for a path * - * @param string 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)); + $this->storage_cache[$path] = Filesystem::getStorage($this->getAbsolutePath($path)); } return $this->storage_cache[$path]; } @@ -120,35 +120,39 @@ class View { * 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 + * @param string $path * @return string */ public function getMountPoint($path) { - return OC_Filesystem::getMountPoint($this->getAbsolutePath($path)); + return 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 + * @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)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFile($this->getInternalPath($path)); + } else { + return null; } } /** - * @param string 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)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFolder($this->getInternalPath($path)); + } else { + return null; } } @@ -274,28 +278,28 @@ class View { 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 = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { + $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 == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } @@ -304,28 +308,30 @@ class View { } $target = $this->fopen($path, 'w'); if ($target) { - $count = OC_Helper::streamCopy($data, $target); + $count = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_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); + \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); @@ -343,9 +349,9 @@ class View { public function rename($path1, $path2) { $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)) { + $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); @@ -353,13 +359,13 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, Filesystem::signal_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -369,36 +375,42 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1)) { $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $count = OC_Helper::streamCopy($source, $target); + $count = \OC_Helper::streamCopy($source, $target); $storage1 = $this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1 . $postFix1)); $result = $count > 0; } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + 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 = 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)) { + $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); @@ -406,34 +418,34 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_copy, + $exists = $this->file_exists($path2); + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); - $exists = $this->file_exists($path2); if ($run and !$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } if ($run) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -444,39 +456,45 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1 . $postFix1)) { $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $result = OC_Helper::streamCopy($source, $target); + $result = \OC_Helper::streamCopy($source, $target); } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_copy, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2 ) ); if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path2) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + array(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); - OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); +// OC_FileCache_Update::update($path2, $this->fakeRoot); + Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; + } else { + return false; } + } else { + return false; } } @@ -507,14 +525,14 @@ class View { $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 (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); if ($source) { $extension = ''; @@ -522,15 +540,19 @@ class View { if ($extOffset !== false) { $extension = substr($path, strrpos($path, '.')); } - $tmpFile = OC_Helper::tmpFile($extension); + $tmpFile = \OC_Helper::tmpFile($extension); file_put_contents($tmpFile, $source); return $tmpFile; + } else { + return false; } + } else { + return false; } } public function fromTmpFile($tmpFile, $path) { - if (OC_Filesystem::isValidPath($path)) { + if (Filesystem::isValidPath($path)) { if (!$tmpFile) { debug_print_backtrace(); } @@ -540,6 +562,7 @@ class View { unlink($tmpFile); return true; } else { + return false; } } else { return false; @@ -552,22 +575,22 @@ class View { public function hash($type, $path, $raw = false) { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $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 (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_read, - array(OC_Filesystem::signal_param_path => $path) + if (Filesystem::$loaded && $this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_read, + array(Filesystem::signal_param_path => $path) ); } if ($storage = $this->getStorage($path . $postFix)) { $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); - $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); + $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } } @@ -581,9 +604,9 @@ class View { /** * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation - * @param string #path - * @param array (optional) hooks - * @param mixed (optional) $extraParam + * @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 @@ -592,8 +615,8 @@ class View { */ 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)) { + $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; @@ -606,8 +629,8 @@ class View { } else { $result = $storage->$operation($internalPath); } - $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + $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); } @@ -621,23 +644,23 @@ class View { private function runHooks($hooks, $path, $post = false) { $prefix = ($post) ? 'post_' : ''; $run = true; - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { foreach ($hooks as $hook) { if ($hook != 'read') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_run => &$run, - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_run => &$run, + Filesystem::signal_param_path => $path ) ); } elseif (!$post) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_path => $path ) ); } @@ -649,6 +672,7 @@ class View { /** * check if a file or folder has been updated since $time * + * @param string $path * @param int $time * @return bool */ -- cgit v1.2.3 From 4b9fbf46e554f8bb368e6cf5a8f75ca5c56e8228 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:50:57 +0200 Subject: add depricated OC_Filessystem for compatibility --- lib/filesystem.php | 479 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 460 insertions(+), 19 deletions(-) diff --git a/lib/filesystem.php b/lib/filesystem.php index b1200f95bfa..4189fe36c2b 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -1,25 +1,466 @@ . -* -*/ + * Copyright (c) 2012 Robin Appelman + * 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 + */ + +/** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ +class OC_Filesystem { + /** + * 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 + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getMountPoint($path) { + return \OC\Files\Filesystem::getMountPoint($path); + } + + /** + * get the part of the path relative to the mountpoint of the storage it's stored in + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return bool + */ + static public function getInternalPath($path) { + return \OC\Files\Filesystem::getInternalPath($path); + } + + /** + * get the storage object for a path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return \OC\Files\Storage\Storage + */ + static public function getStorage($path) { + return \OC\Files\Filesystem::getStorage($path); + } + + /** + * resolve a path to a storage and internal path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return array consisting of the storage and the internal path + */ + static public function resolvePath($path) { + return \OC\Files\Filesystem::resolvePath($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function init($root) { + return \OC\Files\Filesystem::init($root); + } + + /** + * get the default filesystem view + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @return \OC\Files\View + */ + static public function getView() { + return \OC\Files\Filesystem::getView(); + } + + /** + * tear down the filesystem, removing all storage providers + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function tearDown() { + \OC\Files\Filesystem::tearDown(); + } + + /** + * change the root to a fake root + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $fakeRoot + * @return bool + */ + static public function chroot($fakeRoot) { + return \OC\Files\Filesystem::chroot($fakeRoot); + } + + /** + * @brief get the relative path of the root data directory for the current user + * @return string + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * Returns path like /admin/files + */ + static public function getRoot() { + return \OC\Files\Filesystem::getRoot(); + } + + /** + * clear all mounts and storage backends + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + public static function clearMounts() { + \OC\Files\Filesystem::clearMounts(); + } + + /** + * mount an \OC\Files\Storage\Storage in our virtual filesystem + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param \OC\Files\Storage\Storage $class + * @param array $arguments + * @param string $mountpoint + */ + static public function mount($class, $arguments, $mountpoint) { + \OC\Files\Filesystem::mount($class, $arguments, $mountpoint); + } + + /** + * 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 + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalFile($path) { + return \OC\Files\Filesystem::getLocalFile($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalFolder($path) { + return \OC\Files\Filesystem::getLocalFolder($path); + } + + /** + * return path to file which reflects one visible in browser + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalPath($path) { + return \OC\Files\Filesystem::getLocalPath($path); + } + + /** + * check if the requested path is valid + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return bool + */ + static public function isValidPath($path) { + return \OC\Files\Filesystem::isValidPath($path); + } + + /** + * checks if a file is blacklisted for storage in the filesystem + * Listens to write and rename hooks + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param array $data from hook + */ + static public function isBlacklisted($data) { + \OC\Files\Filesystem::isBlacklisted($data); + } + + /** + * following functions are equivalent to their php builtin equivalents for arguments/return values. + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function mkdir($path) { + return \OC\Files\Filesystem::mkdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function rmdir($path) { + return \OC\Files\Filesystem::rmdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function opendir($path) { + return \OC\Files\Filesystem::opendir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function readdir($path) { + return \OC\Files\Filesystem::readdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function is_dir($path) { + return \OC\Files\Filesystem::is_dir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function is_file($path) { + return \OC\Files\Filesystem::is_file($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function stat($path) { + return \OC\Files\Filesystem::stat($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filetype($path) { + return \OC\Files\Filesystem::filetype($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filesize($path) { + return \OC\Files\Filesystem::filesize($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function readfile($path) { + return \OC\Files\Filesystem::readfile($path); + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + static public function is_readable($path) { + return \OC\Files\Filesystem::isReadable($path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + static public function is_writable($path) { + return \OC\Files\Filesystem::is_writable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isCreatable($path) { + return \OC\Files\Filesystem::isCreatable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isReadable($path) { + return \OC\Files\Filesystem::isReadable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isUpdatable($path) { + return \OC\Files\Filesystem::isUpdatable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isDeletable($path) { + return \OC\Files\Filesystem::isDeletable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isSharable($path) { + return \OC\Files\Filesystem::isSharable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_exists($path) { + return \OC\Files\Filesystem::file_exists($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filectime($path) { + return \OC\Files\Filesystem::filectime($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filemtime($path) { + return \OC\Files\Filesystem::filemtime($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function touch($path, $mtime = null) { + return \OC\Files\Filesystem::touch($path, $mtime); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_get_contents($path) { + return \OC\Files\Filesystem::file_get_contents($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_put_contents($path, $data) { + return \OC\Files\Filesystem::file_put_contents($path, $data); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function unlink($path) { + return \OC\Files\Filesystem::unlink($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function rename($path1, $path2) { + return \OC\Files\Filesystem::rename($path1, $path2); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function copy($path1, $path2) { + return \OC\Files\Filesystem::copy($path1, $path2); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function fopen($path, $mode) { + return \OC\Files\Filesystem::fopen($path, $mode); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function toTmpFile($path) { + return \OC\Files\Filesystem::toTmpFile($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function fromTmpFile($tmpFile, $path) { + return \OC\Files\Filesystem::fromTmpFile($tmpFile, $path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function getMimeType($path) { + return \OC\Files\Filesystem::getMimeType($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function hash($type, $path, $raw = false) { + return \OC\Files\Filesystem::hash($type, $path, $raw); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function free_space($path = '/') { + return \OC\Files\Filesystem::free_space($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function search($query) { + return \OC\Files\Filesystem::search($query); + } + + /** + * check if a file or folder has been updated since $time + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @param int $time + * @return bool + */ + static public function hasUpdated($path, $time) { + return \OC\Files\Filesystem::hasUpdated($path, $time); + } + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function removeETagHook($params, $root = false) { + \OC\Files\Filesystem::removeETagHook($params, $root); + } + /** + * normalize a path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @param bool $stripTrailingSlash + * @return string + */ + public static function normalizePath($path, $stripTrailingSlash = true) { + return \OC\Files\Filesystem::normalizePath($path, $stripTrailingSlash); + } +} -- cgit v1.2.3 From c88c54bbb054fe2d79b3a93604989d527b5dd444 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:51:15 +0200 Subject: make sure we can do our tests again --- lib/cache/file.php | 4 ++-- tests/lib/cache/file.php | 2 +- tests/lib/filesystem.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/cache/file.php b/lib/cache/file.php index 27d8b19f36e..f9ecf41dcac 100644 --- a/lib/cache/file.php +++ b/lib/cache/file.php @@ -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); diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 1dd1ff7fa87..3e8fd8c1bb1 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -51,7 +51,7 @@ class Test_Cache_File extends Test_Cache { OC_User::setUserId('test'); //set up the users dir - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/test'); $this->instance=new OC_Cache_File(); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index 8fc3ce641da..b402b86af1f 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -84,7 +84,7 @@ class Test_Filesystem extends UnitTestCase { OC_Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); -- cgit v1.2.3 From aaa1b733642c41821a53bc6d04fab246bfe7f1e6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 13:18:36 +0200 Subject: don't use depricated OC_Filesystem --- apps/files/ajax/autocomplete.php | 6 +-- apps/files/ajax/newfile.php | 6 +-- apps/files/ajax/upload.php | 4 +- apps/files/appinfo/filesync.php | 4 +- apps/files/download.php | 8 +-- apps/files/index.php | 14 +++--- apps/files_encryption/lib/crypt.php | 6 +-- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 6 +-- apps/files_encryption/tests/proxy.php | 30 +++++------ apps/files_external/ajax/addRootCertificate.php | 12 ++--- apps/files_external/lib/config.php | 12 ++--- apps/files_sharing/lib/sharedstorage.php | 66 ++++++++++++------------- apps/files_sharing/public.php | 8 +-- apps/files_versions/lib/hooks.php | 4 +- apps/files_versions/lib/versions.php | 16 +++--- lib/connector/sabre/directory.php | 10 ++-- lib/connector/sabre/file.php | 10 ++-- lib/connector/sabre/node.php | 8 +-- lib/filechunking.php | 38 +++++++------- lib/fileproxy/quota.php | 2 +- lib/files.php | 54 ++++++++++---------- lib/files/file.php | 2 +- lib/helper.php | 2 +- lib/image.php | 2 +- lib/ocs.php | 4 +- lib/public/files.php | 2 +- lib/public/share.php | 6 +-- lib/util.php | 10 ++-- settings/personal.php | 2 +- tests/lib/cache/file.php | 4 +- tests/lib/filesystem.php | 56 +++++++++++---------- 32 files changed, 209 insertions(+), 207 deletions(-) diff --git a/apps/files/ajax/autocomplete.php b/apps/files/ajax/autocomplete.php index fae38368a85..d0dab9c2bd7 100644 --- a/apps/files/ajax/autocomplete.php +++ b/apps/files/ajax/autocomplete.php @@ -33,8 +33,8 @@ $query=strtolower($query); $files=array(); -if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { - $dh = OC_Filesystem::opendir($base); +if(\OC\Files\Filesystem::file_exists($base) and \OC\Files\Filesystem::is_dir($base)) { + $dh = \OC\Files\Filesystem::opendir($base); if($dh) { if(substr($base, -1, 1)!='/') { $base=$base.'/'; @@ -43,7 +43,7 @@ if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { if ($file != "." && $file != "..") { if(substr(strtolower($file), 0, $queryLen)==$query) { $item=$base.$file; - if((!$dirOnly or OC_Filesystem::is_dir($item))) { + if((!$dirOnly or \OC\Files\Filesystem::is_dir($item))) { $files[]=(object)array('id'=>$item,'label'=>$item,'name'=>$item); } } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 77d866979c3..4d73970b68d 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -63,12 +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) { $meta = OC_FileCache::get($target); $mime=$meta['mimetype']; $id = OC_FileCache::getId($target); - $eventSource->send('success', array('mime'=>$mime, 'size'=>OC_Filesystem::filesize($target), 'id' => $id)); + $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); } else { $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); } @@ -76,7 +76,7 @@ if($source) { exit(); } else { if($content) { - if(OC_Filesystem::file_put_contents($dir.'/'.$filename, $content)) { + if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { $meta = OC_FileCache::get($dir.'/'.$filename); $id = OC_FileCache::getId($dir.'/'.$filename); OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index a4dcd80a2e2..8bf7f10e18b 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -38,7 +38,7 @@ $totalSize=0; foreach($files['size'] as $size) { $totalSize+=$size; } -if($totalSize>OC_Filesystem::free_space('/')) { +if($totalSize>\OC\Files\Filesystem::free_space('/')) { OCP\JSON::error(array("data" => array( "message" => "Not enough space available" ))); exit(); } @@ -48,7 +48,7 @@ if(strpos($dir, '..') === false) { $fileCount=count($files['name']); for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); - if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { + if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { $meta = OC_FileCache::get($target); $id = OC_FileCache::getId($target); $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); diff --git a/apps/files/appinfo/filesync.php b/apps/files/appinfo/filesync.php index c1fe444cec7..e755771de64 100644 --- a/apps/files/appinfo/filesync.php +++ b/apps/files/appinfo/filesync.php @@ -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), ); diff --git a/apps/files/download.php b/apps/files/download.php index ff6aefbbe0f..b00a50a0452 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -29,7 +29,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); @@ -37,12 +37,12 @@ if(!OC_Filesystem::file_exists($filename)) { exit; } -$ftype=OC_Filesystem::getMimeType( $filename ); +$ftype=\OC\Files\Filesystem::getMimeType( $filename ); header('Content-Type:'.$ftype); header('Content-Disposition: attachment; filename="'.basename($filename).'"'); OCP\Response::disableCaching(); -header('Content-Length: '.OC_Filesystem::filesize($filename)); +header('Content-Length: '.\OC\Files\Filesystem::filesize($filename)); @ob_end_clean(); -OC_Filesystem::readfile( $filename ); +\OC\Files\Filesystem::readfile( $filename ); diff --git a/apps/files/index.php b/apps/files/index.php index 493087d26f1..b02aaf81c0f 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -38,7 +38,7 @@ 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(); } @@ -85,26 +85,26 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace=OC_Filesystem::free_space('/'); +$freeSpace=\OC\Files\Filesystem::free_space('/'); $freeSpace=max($freeSpace,0); $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $permissions = OCP\Share::PERMISSION_READ; -if (OC_Filesystem::isUpdatable($dir.'/')) { +if (\OC\Files\Filesystem::isUpdatable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_UPDATE; } -if (OC_Filesystem::isDeletable($dir.'/')) { +if (\OC\Files\Filesystem::isDeletable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_DELETE; } -if (OC_Filesystem::isSharable($dir.'/')) { +if (\OC\Files\Filesystem::isSharable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_SHARE; } $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( '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); diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 38d8edf28c3..6bee8accf71 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -44,7 +44,7 @@ class OC_Crypt { } public static function init($login,$password) { - $view=new OC_FilesystemView('/'); + $view=new \OC\Files\View('/'); if(!$view->file_exists('/'.$login)) { $view->mkdir('/'.$login); } @@ -90,7 +90,7 @@ class OC_Crypt { // Write the file $proxyEnabled=OC_FileProxy::$enabled; OC_FileProxy::$enabled=false; - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); $view->file_put_contents('/encryption.key',$enckey); OC_FileProxy::$enabled=$proxyEnabled; } @@ -98,7 +98,7 @@ class OC_Crypt { public static function changekeypasscode($oldPassword, $newPassword) { if(OCP\User::isLoggedIn()) { $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); // read old key $key=$view->file_get_contents('/encryption.key'); diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index 721a1b955df..89a071327ad 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -38,7 +38,7 @@ class OC_CryptStream{ public function stream_open($path, $mode, $options, &$opened_path) { if(!self::$rootView) { - self::$rootView=new OC_FilesystemView(''); + self::$rootView=new \OC\Files\View(''); } $path=str_replace('crypt://','',$path); if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])) { diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index f61cd1e3773..27abe3bb19e 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -90,13 +90,13 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ fclose($result); $result=fopen('crypt://'.$path,$meta['mode']); }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb') { - if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0) { + if(\OC\Files\Filesystem::file_exists($path) and \OC\Files\Filesystem::filesize($path)>0) { //first encrypt the target file so we don't end up with a half encrypted file OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing',OCP\Util::DEBUG); - $tmp=fopen('php://temp'); + $tmp=fopen('php://temp', 'w+'); OCP\Files::streamCopy($result,$tmp); fclose($result); - OC_Filesystem::file_put_contents($path,$tmp); + \OC\Files\Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index d600bbc4071..c04e0e5c4fc 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -29,13 +29,13 @@ class Test_CryptProxy extends UnitTestCase { OC_FileProxy::register(new OC_FileProxy_Encryption()); //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); - OC_Filesystem::init('/'.$user.'/files'); + \OC\Files\Filesystem::init('/'.$user.'/files'); //set up the users home folder in the temp storage - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); } @@ -51,13 +51,13 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -68,8 +68,8 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - $rootView=new OC_FilesystemView(''); - $view=new OC_FilesystemView('/'.OC_User::getUser()); + $rootView=new \OC\Files\View(''); + $view=new \OC\Files\View('/'.OC_User::getUser()); $userDir='/'.OC_User::getUser().'/files'; $rootView->file_put_contents($userDir.'/file',$original); @@ -90,13 +90,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/binary'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -104,13 +104,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/zeros'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); } diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php index e0a0239c954..6fef9aac1ed 100644 --- a/apps/files_external/ajax/addRootCertificate.php +++ b/apps/files_external/ajax/addRootCertificate.php @@ -3,23 +3,23 @@ OCP\JSON::checkAppEnabled('files_external'); if ( !($filename = $_FILES['rootcert_import']['name']) ) { - header("Location: settings/personal.php"); + header("Location: settings/personal.php"); exit; } -$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); -$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); +$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); +$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'); + +$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files_external/uploads'); if (!$view->file_exists('')) $view->mkdir(''); $isValid = openssl_pkey_get_public($data); //maybe it was just the wrong file format, try to convert it... if ($isValid == false) { - $data = chunk_split(base64_encode($data), 64, "\n"); + $data = chunk_split(base64_encode($data), 64, "\n"); $data = "-----BEGIN CERTIFICATE-----\n".$data."-----END CERTIFICATE-----\n"; $isValid = openssl_pkey_get_public($data); } diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index cb32fed2032..7be23360199 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -109,10 +109,10 @@ 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 + /** + * 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 = ''; @@ -142,11 +142,11 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } - $view = new OC_FilesystemView('/'.OCP\User::getUser().'/files'); + $view = new \OC\Files\View('/'.OCP\User::getUser().'/files'); self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { - $view = new OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); switch ($mountType) { case 'user': if ($applicable == "all") { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 876e719956f..e17c4b6e043 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -80,7 +80,7 @@ class Shared extends \OC\Files\Storage\Common { $file = $this->getFile($target); if (isset($file['path'])) { $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - \OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); + \\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -105,7 +105,7 @@ class Shared extends \OC\Files\Storage\Common { * @return Source file path with mount point stripped out */ private function getInternalPath($path) { - $mountPoint = \OC_Filesystem::getMountPoint($path); + $mountPoint = \OC\Files\Filesystem::getMountPoint($path); $internalPath = substr($path, strlen($mountPoint)); return $internalPath; } @@ -114,7 +114,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } return false; @@ -122,7 +122,7 @@ class Shared extends \OC\Files\Storage\Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->rmdir($this->getInternalPath($source)); } return false; @@ -130,11 +130,11 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { - $files = OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); + $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->opendir($this->getInternalPath($source)); } return false; @@ -144,7 +144,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } return false; @@ -152,7 +152,7 @@ class Shared extends \OC\Files\Storage\Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } return false; @@ -165,7 +165,7 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } return false; @@ -175,7 +175,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); } return false; @@ -185,7 +185,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); } return false; @@ -195,7 +195,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_CREATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_CREATE); } public function isReadable($path) { @@ -206,28 +206,28 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_UPDATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_UPDATE); } public function isDeletable($path) { if ($path == '') { return true; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_DELETE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_DELETE); } public function isSharable($path) { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_SHARE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_SHARE); } public function file_exists($path) { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); } return false; @@ -248,7 +248,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); } } @@ -269,7 +269,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); } } @@ -282,8 +282,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_get_contents($this->getInternalPath($source)); } } @@ -298,8 +298,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); $result = $storage->file_put_contents($this->getInternalPath($source), $data); return $result; } @@ -310,7 +310,7 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->unlink($this->getInternalPath($source)); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -319,7 +319,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $itemType = 'file'; } - return OCP\Share::unshareFromSelf($itemType, $path); + return \OCP\Share::unshareFromSelf($itemType, $path); } } return false; @@ -334,7 +334,7 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } else { @@ -349,7 +349,7 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } @@ -394,8 +394,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, 'mode' => $mode, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->fopen($this->getInternalPath($source), $mode); } return false; @@ -406,7 +406,7 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); } return false; @@ -415,21 +415,21 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source), $mtime); } return false; @@ -437,7 +437,7 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { $user_dir = $options['user_dir']; - \OC_Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 34340102a9e..c5f4b39d704 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -73,7 +73,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { if (isset($_GET['path'])) { $path .= $_GET['path']; $dir .= $_GET['path']; - if (!OC_Filesystem::file_exists($path)) { + if (!\OC\Files\Filesystem::file_exists($path)) { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -101,7 +101,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('owner', $uidOwner); // 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'); @@ -157,7 +157,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', basename($dir)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($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']; @@ -170,7 +170,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', dirname($path)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); if ($type == 'file') { $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.$_GET['file'].'&download'); } else { diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php index 9ec0b01a7f9..7cb3170df23 100644 --- a/apps/files_versions/lib/hooks.php +++ b/apps/files_versions/lib/hooks.php @@ -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 ); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 7d12e58f941..7f7837a7425 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -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('/'.$uid.'/files'); + $users_view = new \OC\Files\View('/'.$uid); //check if source file already exist as version to avoid recursions. // todo does this check work? @@ -94,7 +94,7 @@ class Storage { // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $matches=glob($versionsFolderName.'/'.$filename.'.v*'); sort($matches); @@ -127,7 +127,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); // rollback if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) { @@ -150,7 +150,7 @@ class Storage { public static function isversioned($filename) { 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('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); @@ -178,7 +178,7 @@ class Storage { 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('/'.$uid.'/files_versions'); $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $versions = array(); @@ -190,7 +190,7 @@ class Storage { $i = 0; - $files_view = new \OC_FilesystemView('/'.$uid.'/files'); + $files_view = new \OC\Files\View('/'.$uid.'/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { @@ -245,7 +245,7 @@ class Storage { public static function expire($filename) { 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('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 413efef73b7..4fff3ba51b8 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -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); } @@ -154,7 +154,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); } @@ -167,7 +167,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); } } @@ -181,7 +181,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $rootInfo=OC_FileCache_Cached::get(''); return array( $rootInfo['size'], - OC_Filesystem::free_space() + \OC\Files\Filesystem::free_space() ); } diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 5bd38240d44..1770b491280 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -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); } @@ -107,7 +107,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @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 \OC\Files\Filesystem::hash('md5', $path); } /** @@ -122,7 +122,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); } } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 72de9723774..e7e83507ea2 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -80,7 +80,7 @@ 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; @@ -99,9 +99,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::get($this->path)) { } else { - $fileinfo_cache = OC_Filesystem::stat($this->path); + $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } $this->fileinfo_cache = $fileinfo_cache; @@ -130,7 +130,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); } /** diff --git a/lib/filechunking.php b/lib/filechunking.php index 5ab33c77ad7..e616e3b12d8 100644 --- a/lib/filechunking.php +++ b/lib/filechunking.php @@ -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; diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 5a0dbdb6fe2..bc5ef9c8df4 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -88,7 +88,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ public function preCopy($path1,$path2) { if(!self::$rootView){ - self::$rootView = new OC_FilesystemView(''); + self::$rootView = new \OC\Files\View(''); } return (self::$rootView->filesize($path1)<$this->getFreeSpace() or $this->getFreeSpace()==0); } diff --git a/lib/files.php b/lib/files.php index 2b2b8b42dc4..29322cf2d06 100644 --- a/lib/files.php +++ b/lib/files.php @@ -46,10 +46,10 @@ class OC_Files { if ($path == '/Shared') { list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); }else{ - $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['size'] = \OC\Files\Filesystem::filesize($path); + $info['mtime'] = \OC\Files\Filesystem::filemtime($path); + $info['ctime'] = \OC\Files\Filesystem::filectime($path); + $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); $info['encrypted'] = false; $info['versioned'] = false; } @@ -64,7 +64,7 @@ class OC_Files { * @param dir $directory path under datadirectory */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=OC_Filesystem::normalizePath($directory); + $directory=\OC\Files\Filesystem::normalizePath($directory); if($directory=='/') { $directory=''; } @@ -151,17 +151,17 @@ class OC_Files { } foreach($files as $file) { $file=$dir.'/'.$file; - if(OC_Filesystem::is_file($file)) { - $tmpFile=OC_Filesystem::toTmpFile($file); + if(\OC\Files\Filesystem::is_file($file)) { + $tmpFile=OC_F\OC\Files\Filesystemilesystem::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(); 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); @@ -179,7 +179,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or OC_Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::is_readable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); @@ -188,9 +188,9 @@ class OC_Files { header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); }else{ - header('Content-Type: '.OC_Filesystem::getMimeType($filename)); + header('Content-Type: '.\OC\Files\Filesystem::getMimeType($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); @@ -201,7 +201,7 @@ class OC_Files { } if($only_header) { if(!$zip) - header("Content-Length: ".OC_Filesystem::filesize($filename)); + header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); return ; } if($zip) { @@ -215,7 +215,7 @@ 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)) { @@ -232,11 +232,11 @@ 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); } } @@ -253,7 +253,7 @@ class OC_Files { if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { $targetFile=self::normalizePath($targetDir.'/'.$target); $sourceFile=self::normalizePath($sourceDir.'/'.$source); - return OC_Filesystem::rename($sourceFile,$targetFile); + return \OC\Files\Filesystem::rename($sourceFile,$targetFile); } else { return false; } @@ -271,7 +271,7 @@ class OC_Files { if(OC_User::isLoggedIn()) { $targetFile=$targetDir.'/'.$target; $sourceFile=$sourceDir.'/'.$source; - return OC_Filesystem::copy($sourceFile,$targetFile); + return \OC\Files\Filesystem::copy($sourceFile,$targetFile); } } @@ -286,9 +286,9 @@ class OC_Files { if(OC_User::isLoggedIn()) { $file=$dir.'/'.$name; if($type=='dir') { - return OC_Filesystem::mkdir($file); + return \OC\Files\Filesystem::mkdir($file); }elseif($type=='file') { - $fileHandle=OC_Filesystem::fopen($file, 'w'); + $fileHandle=\OC\Files\Filesystem::fopen($file, 'w'); if($fileHandle) { fclose($fileHandle); return true; @@ -308,7 +308,7 @@ class OC_Files { public static function delete($dir,$file) { if(OC_User::isLoggedIn() && ($dir!= '' || $file != 'Shared')) { $file=$dir.'/'.$file; - return OC_Filesystem::unlink($file); + return \OC\Files\Filesystem::unlink($file); } } @@ -339,10 +339,10 @@ class OC_Files { $totalsize = 0; if(is_array($files)) { foreach($files as $file) { - $totalsize += OC_Filesystem::filesize($dir.'/'.$file); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$file); } }else{ - $totalsize += OC_Filesystem::filesize($dir.'/'.$files); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$files); } if($totalsize > $zipLimit) { $l = OC_L10N::get('lib'); @@ -368,7 +368,7 @@ class OC_Files { * @return string guessed mime type */ static function getMimeType($path) { - return OC_Filesystem::getMimeType($path); + return \OC\Files\Filesystem::getMimeType($path); } /** @@ -378,7 +378,7 @@ class OC_Files { * @return array */ static function getTree($path) { - return OC_Filesystem::getTree($path); + return \OC\Files\Filesystem::getTree($path); } /** @@ -402,7 +402,7 @@ class OC_Files { $httpCode=$info['http_code']; curl_close($ch); if($httpCode==200 or $httpCode==0) { - OC_Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); + \OC\Files\Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); return true; }else{ return false; diff --git a/lib/files/file.php b/lib/files/file.php index b6432e63458..0d33cea7ee7 100644 --- a/lib/files/file.php +++ b/lib/files/file.php @@ -30,7 +30,7 @@ class File{ public static function resolve($fullPath){ $storage = null; $internalPath = ''; - list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); return new File($storage, $internalPath); } diff --git a/lib/helper.php b/lib/helper.php index 908a61b5a2d..48e16cebd00 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -560,7 +560,7 @@ class OC_Helper { $newpath = $path . '/' . $filename; $counter = 2; - while (OC_Filesystem::file_exists($newpath)) { + while (\OC\Files\Filesystem::file_exists($newpath)) { $newname = $name . ' (' . $counter . ')' . $ext; $newpath = $path . '/' . $newname; $counter++; diff --git a/lib/image.php b/lib/image.php index 861353e039d..94fe3ce827a 100644 --- a/lib/image.php +++ b/lib/image.php @@ -470,7 +470,7 @@ class OC_Image { default: // this is mostly file created from encrypted file - $this->resource = imagecreatefromstring(\OC_Filesystem::file_get_contents(\OC_Filesystem::getLocalPath($imagepath))); + $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagepath))); $itype = IMAGETYPE_PNG; OC_Log::write('core','OC_Image->loadFromFile, Default', OC_Log::DEBUG); break; diff --git a/lib/ocs.php b/lib/ocs.php index 7350c3c8821..645380ddba8 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -589,11 +589,11 @@ class OC_OCS { if(OC_User::userExists($user)) { // calculate the disc space $user_dir = '/'.$user.'/files'; - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::init($user_dir); $rootInfo=OC_FileCache::get(''); $sharedInfo=OC_FileCache::get('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; - $free=OC_Filesystem::free_space(); + $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/lib/public/files.php b/lib/public/files.php index 90889c59ad8..2d6775e01f1 100644 --- a/lib/public/files.php +++ b/lib/public/files.php @@ -98,7 +98,7 @@ class Files { /** * @param string appid * @param $app app - * @return OC_FilesystemView + * @return \OC\Files\View */ public static function getStorage( $app ) { return \OC_App::getStorage( $app ); diff --git a/lib/public/share.php b/lib/public/share.php index 1db3a0b2c1d..7c4ede5e882 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -515,7 +515,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -602,7 +602,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } @@ -751,7 +751,7 @@ class Share { } else { $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { diff --git a/lib/util.php b/lib/util.php index 557f731522e..5cf76574574 100755 --- a/lib/util.php +++ b/lib/util.php @@ -34,7 +34,7 @@ class OC_Util { $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage if(!self::$rootMounted) { - OC_Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); self::$rootMounted=true; } @@ -46,8 +46,8 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); + \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); OC_FileProxy::register($quotaProxy); // Load personal mount config @@ -55,7 +55,7 @@ class OC_Util { $mountConfig = include($user_root.'/mount.php'); if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - OC_Filesystem::mount($options['class'], $options['options'], $mountPoint); + \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); } } } @@ -64,7 +64,7 @@ class OC_Util { } public static function tearDownFS() { - OC_Filesystem::tearDown(); + \OC\Files\Filesystem::tearDown(); self::$fsSetup=false; } diff --git a/settings/personal.php b/settings/personal.php index 9297f5d91cc..54002d87c59 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -25,7 +25,7 @@ if (!isset($sharedInfo['size'])) { } $used=$rootInfo['size']-$sharedSize; if($used<0) $used=0; -$free=OC_Filesystem::free_space(); +$free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 3e8fd8c1bb1..5dcd3268804 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -38,8 +38,8 @@ class Test_Cache_File extends Test_Cache { } //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index b402b86af1f..af3620f5707 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -20,6 +20,8 @@ * */ +use \OC\Files\Filesystem as Filesystem; + class Test_Filesystem extends UnitTestCase { /** * @var array tmpDirs @@ -42,64 +44,64 @@ class Test_Filesystem extends UnitTestCase { } public function setUp() { - OC_Filesystem::clearMounts(); + Filesystem::clearMounts(); } public function testMount() { - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',OC_Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('',Filesystem::getInternalPath('/')); + $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some')); + $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); } public function testNormalize() { - $this->assertEqual('/path', OC_Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', OC_Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', OC_Filesystem::normalizePath('path')); - $this->assertEqual('/path', OC_Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo////bar')); + $this->assertEqual('/path', Filesystem::normalizePath('/path/')); + $this->assertEqual('/path/', Filesystem::normalizePath('/path/', false)); + $this->assertEqual('/path', Filesystem::normalizePath('path')); + $this->assertEqual('/path', Filesystem::normalizePath('\path')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo//bar/')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo////bar')); if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", OC_Filesystem::normalizePath("/foo/baru\xCC\x88")); + $this->assertEqual("/foo/bar\xC3\xBC", Filesystem::normalizePath("/foo/baru\xCC\x88")); } } public function testHooks() { - if(OC_Filesystem::getView()){ + if(Filesystem::getView()){ $user = OC_User::getUser(); }else{ $user=uniqid(); - OC_Filesystem::init('/'.$user.'/files'); + Filesystem::init('/'.$user.'/files'); } OC_Hook::clear('OC_Filesystem'); OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); - OC_Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); + Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); - OC_Filesystem::file_put_contents('/foo', 'foo'); - OC_Filesystem::mkdir('/bar'); - OC_Filesystem::file_put_contents('/bar//foo', 'foo'); + Filesystem::file_put_contents('/foo', 'foo'); + Filesystem::mkdir('/bar'); + Filesystem::file_put_contents('/bar//foo', 'foo'); $tmpFile = OC_Helper::tmpFile(); file_put_contents($tmpFile, 'foo'); $fh = fopen($tmpFile, 'r'); - OC_Filesystem::file_put_contents('/bar//foo', $fh); + Filesystem::file_put_contents('/bar//foo', $fh); } public function dummyHook($arguments) { $path = $arguments['path']; - $this->assertEqual($path, OC_Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + $this->assertEqual($path, Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } } -- cgit v1.2.3 From 08bb5dbe3a9b2bf502e5c6e0c944867015c3795b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 18:19:45 +0200 Subject: few more test cases for scanning folders --- tests/lib/files/cache/scanner.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 41286e69d3e..1f11b9d01d1 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -91,6 +91,13 @@ class Scanner extends \UnitTestCase { $this->assertEqual($cachedDataFolder['size'], -1); $this->assertEqual($cachedDataFolder2['size'], -1); + + $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertNotEqual($cachedDataFolder['size'], -1); } function setUp() { -- cgit v1.2.3 From a2785f57d2335d06f3fa9900298343c1d7f9253a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 17:45:47 +0200 Subject: fix cache scanner test case --- tests/lib/files/cache/scanner.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 1f11b9d01d1..e3f47047f54 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -94,10 +94,9 @@ class Scanner extends \UnitTestCase { $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); - $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertNotEqual($cachedDataFolder['size'], -1); + $this->assertNotEqual($cachedDataFolder2['size'], -1); } function setUp() { -- cgit v1.2.3 From 5c6e9518edde10e0c23d0d734d2cc6d161fc15c0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 17:46:29 +0200 Subject: drop Filesystem::getInternalPath and Filesystem::getStorage in favor of Filesystem::resolvePath --- apps/files_sharing/lib/sharedstorage.php | 86 ++++++++++++++++---------------- lib/files/filesystem.php | 31 ------------ lib/files/view.php | 61 ++++++++-------------- lib/filesystem.php | 22 -------- tests/lib/filesystem.php | 9 ++-- 5 files changed, 71 insertions(+), 138 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e17c4b6e043..e12027a4f2b 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -114,16 +114,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\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\Files\Filesystem::getStorage($source); - return $storage->rmdir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->rmdir($internalPath); } return false; } @@ -134,8 +134,8 @@ class Shared extends \OC\Files\Storage\Common { \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->opendir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->opendir($internalPath); } return false; } @@ -144,16 +144,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\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\Files\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; } @@ -165,8 +165,8 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->stat($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->stat($internalPath); } return false; } @@ -175,8 +175,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filetype($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filetype($internalPath); } return false; } @@ -185,8 +185,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filesize($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filesize($internalPath); } return false; } @@ -227,8 +227,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\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; } @@ -248,8 +248,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filectime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filectime($internalPath); } } } @@ -269,8 +269,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filemtime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filemtime($internalPath); } } } @@ -283,8 +283,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->file_get_contents($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->file_get_contents($internalPath); } } @@ -299,8 +299,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - $result = $storage->file_put_contents($this->getInternalPath($source), $data); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + $result = $storage->file_put_contents($internalPath, $data); return $result; } return false; @@ -310,8 +310,8 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC\Files\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)) { @@ -334,8 +334,9 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC\Files\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 @@ -349,8 +350,9 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC\Files\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); } } } @@ -395,8 +397,8 @@ class Shared extends \OC\Files\Storage\Common { 'mode' => $mode, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->fopen($this->getInternalPath($source), $mode); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->fopen($internalPath, $mode); } return false; } @@ -406,8 +408,8 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->getMimeType($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->getMimeType($internalPath); } return false; } @@ -415,22 +417,22 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\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\Files\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\Files\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; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index f23f3a79e98..841f30c7679 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,37 +164,6 @@ class Filesystem { 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(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); - } - return self::$storages[$mountpoint]; - }else{ - return null; - } - } - /** * resolve a path to a storage and internal path * diff --git a/lib/files/view.php b/lib/files/view.php index 230455479cf..bffeb434f28 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -68,19 +68,6 @@ class View { return $this->fakeRoot; } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @param string $path - * @return bool - */ - public function getInternalPath($path) { - if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); - } - return $this->internal_path_cache[$path]; - } - /** * get path relative to the root of the view * @@ -103,19 +90,6 @@ class View { } } - /** - * 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] = Filesystem::getStorage($this->getAbsolutePath($path)); - } - return $this->storage_cache[$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 @@ -136,8 +110,9 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFile($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFile($internalPath); } else { return null; } @@ -149,8 +124,9 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFolder($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFolder($internalPath); } else { return null; } @@ -373,8 +349,10 @@ class View { $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)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->rename($internalPath1, $internalPath2); } else { $result = false; } @@ -382,8 +360,8 @@ class View { $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)); + list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + $storage1->unlink($internalPath1); $result = $count > 0; } if ($this->fakeRoot == Filesystem::getRoot()) { @@ -454,8 +432,10 @@ class View { $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)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->copy($internalPath1, $internalPath2); } else { $result = false; } @@ -588,8 +568,9 @@ class View { array(Filesystem::signal_param_path => $path) ); } - if ($storage = $this->getStorage($path . $postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($storage) { + $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } @@ -621,9 +602,9 @@ class View { if ($path == null) { return false; } - $internalPath = $this->getInternalPath($path . $postFix); $run = $this->runHooks($hooks, $path); - if ($run and $storage = $this->getStorage($path . $postFix)) { + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 4189fe36c2b..587eb50d9e0 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -44,28 +44,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::getMountPoint($path); } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return bool - */ - static public function getInternalPath($path) { - return \OC\Files\Filesystem::getInternalPath($path); - } - - /** - * get the storage object for a path - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - return \OC\Files\Filesystem::getStorage($path); - } - /** * resolve a path to a storage and internal path * diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index af3620f5707..6e7b4fb781f 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -51,15 +51,18 @@ class Test_Filesystem extends UnitTestCase { Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); + $this->assertEqual('',$internalPath); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('some/folder',$internalPath); Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); $this->assertEqual('/',Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('folder',$internalPath); } public function testNormalize() { -- cgit v1.2.3 From 542869114ad67295d61450e637b15a1f4d3ae209 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 11 Oct 2012 23:06:57 +0200 Subject: implement getId for the external storage providers --- apps/files_external/lib/amazons3.php | 6 ++++++ apps/files_external/lib/dropbox.php | 6 ++++++ apps/files_external/lib/ftp.php | 4 ++++ apps/files_external/lib/google.php | 7 ++++++- apps/files_external/lib/smb.php | 4 ++++ apps/files_external/lib/swift.php | 7 +++++++ apps/files_external/lib/webdav.php | 4 ++++ 7 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index a17a70ed38b..2f7c8b35bec 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -29,12 +29,14 @@ 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->id = 'amazon::'.$params['key'] . md5($params['secret']); $this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -59,6 +61,10 @@ class AmazonS3 extends \OC\Files\Storage\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) != '/') { diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 86dbdab9caa..351a2840d90 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -28,12 +28,14 @@ class Dropbox extends \OC\Files\Storage\Common { private $dropbox; private $root; + private $id; private $metaData = array(); private static $tempFiles = array(); public function __construct($params) { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['app_key']) && isset($params['app_secret']) && 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->setToken($params['token'], $params['token_secret']); @@ -81,6 +83,10 @@ class Dropbox extends \OC\Files\Storage\Common { } } + public function getId(){ + return $this->id; + } + public function mkdir($path) { $path = $this->root.$path; try { diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 140a21ffe13..731581dacc6 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -32,6 +32,10 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ } } + public function getId(){ + return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root; + } + /** * construct the ftp url * @param string path diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 51c5d219aae..e4be4de5a09 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -30,6 +30,7 @@ class Google extends \OC\Files\Storage\Common { private $oauth_token; private $sig_method; private $entries; + private $id; private static $tempFiles = array(); @@ -37,6 +38,7 @@ class Google extends \OC\Files\Storage\Common { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['token']) && isset($params['token_secret'])) { $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; + $this->id = 'google::' . $consumer_key . $consumer_secret; $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(); @@ -177,6 +179,9 @@ class Google extends \OC\Files\Storage\Common { } } + public function getId(){ + return $this->id; + } public function mkdir($path) { $collection = dirname($path); @@ -539,4 +544,4 @@ class Google extends \OC\Files\Storage\Common { } -} \ No newline at end of file +} diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 8fcdd1f722f..71c7a91ec93 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -42,6 +42,10 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } } + public function getId(){ + return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root; + } + public function constructUrl($path) { if(substr($path,-1)=='/') { $path=substr($path,0,-1); diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 8d402b25212..61f58766e8e 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -11,6 +11,7 @@ require_once 'php-cloudfiles/cloudfiles.php'; namespace OC\Files\Storage; class SWIFT extends \OC\Files\Storage\Common{ + private $id; private $host; private $root; private $user; @@ -274,6 +275,8 @@ class SWIFT extends \OC\Files\Storage\Common{ $this->user=$params['user']; $this->root=isset($params['root'])?$params['root']:'/'; $this->secure=isset($params['secure'])?(bool)$params['secure']:true; + + $this->id = 'swift::' . $this->user . '@' . $this->host . '/' . $this->root; if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } @@ -289,6 +292,10 @@ class SWIFT extends \OC\Files\Storage\Common{ } } + public function getId(){ + return $this->id; + } + public function mkdir($path) { if($this->containerExists($path)) { diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 7c61d06a018..6ed93e9035b 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -56,6 +56,10 @@ class DAV extends \OC\Files\Storage\Common{ $this->mkdir(''); } + public function getId(){ + return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root; + } + private function createBaseUri() { $baseUri='http'; if($this->secure) { -- cgit v1.2.3 From 141ff806c6cfbd349ffa232502a89a620882c409 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 11 Oct 2012 23:17:59 +0200 Subject: fix namespace problems for external storage backends --- apps/files_external/lib/amazons3.php | 4 +-- apps/files_external/lib/dropbox.php | 4 +-- apps/files_external/lib/ftp.php | 7 ++-- apps/files_external/lib/google.php | 12 +++---- apps/files_external/lib/smb.php | 5 +-- apps/files_external/lib/swift.php | 69 ++++++++++++++++++------------------ apps/files_external/lib/webdav.php | 32 +++++++---------- apps/files_external/tests/config.php | 2 +- 8 files changed, 65 insertions(+), 70 deletions(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 2f7c8b35bec..832127d3e79 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'aws-sdk/sdk.class.php'; - namespace OC\Files\Storage; +require_once 'aws-sdk/sdk.class.php'; + class AmazonS3 extends \OC\Files\Storage\Common { private $s3; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 351a2840d90..0f7593162e4 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'Dropbox/autoload.php'; - namespace OC\Files\Storage; +require_once 'Dropbox/autoload.php'; + class Dropbox extends \OC\Files\Storage\Common { private $dropbox; diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 731581dacc6..dea44728f3c 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -26,7 +26,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - //create the root folder if necesary + //create the root folder if necessary if (!$this->is_dir('')) { $this->mkdir(''); } @@ -38,7 +38,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ /** * construct the ftp url - * @param string path + * @param string $path * @return string */ public function constructUrl($path) { @@ -74,7 +74,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ }else{ $ext=''; } - $tmpFile=OCP\Files::tmpFile($ext); + $tmpFile=\OCP\Files::tmpFile($ext); \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); @@ -82,6 +82,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile,$mode); } + return false; } public function writeBack($tmpFile) { diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index e4be4de5a09..141fc619e35 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'Google/common.inc.php'; - namespace OC\Files\Storage; +require_once 'Google/common.inc.php'; + class Google extends \OC\Files\Storage\Common { private $consumer; @@ -62,7 +62,7 @@ class Google extends \OC\Files\Storage\Common { $tempStr .= '&' . urlencode($key) . '=' . urlencode($value); } $uri = preg_replace('/&/', '?', $tempStr, 1); - $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $httpMethod, $uri, $params); + $request = \OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $httpMethod, $uri, $params); $request->sign_request($this->sig_method, $this->consumer, $this->oauth_token); $auth_header = $request->to_header(); $headers = array($auth_header, 'GData-Version: 3.0'); @@ -129,7 +129,7 @@ class Google extends \OC\Files\Storage\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; } @@ -248,7 +248,7 @@ class Google extends \OC\Files\Storage\Common { $this->entries[$name] = $entry; } } - OC_FakeDirStream::$dirs['google'.$path] = $files; + \OC_FakeDirStream::$dirs['google'.$path] = $files; return opendir('fakedir://google'.$path); } @@ -407,7 +407,7 @@ class Google extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 71c7a91ec93..dfba3105ecb 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -6,10 +6,10 @@ * See the COPYING-README file. */ -require_once 'smb4php/smb.php'; - namespace OC\Files\Storage; +require_once 'smb4php/smb.php'; + class SMB extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; @@ -70,6 +70,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ /** * check if a file or folder has been updated since $time + * @param string $path * @param int $time * @return bool */ diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 61f58766e8e..4b3f38166dc 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -6,10 +6,10 @@ * See the COPYING-README file. */ -require_once 'php-cloudfiles/cloudfiles.php'; - namespace OC\Files\Storage; +require_once 'php-cloudfiles/cloudfiles.php'; + class SWIFT extends \OC\Files\Storage\Common{ private $id; private $host; @@ -18,15 +18,15 @@ class SWIFT extends \OC\Files\Storage\Common{ private $token; private $secure; /** - * @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; @@ -38,7 +38,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * translate directory path to container name - * @param string path + * @param string $path * @return string */ private function getContainerName($path) { @@ -48,8 +48,8 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * get container by path - * @param string path - * @return CF_Container + * @param string $path + * @return \CF_Container */ private function getContainer($path) { if($path=='' or $path=='/') { @@ -62,15 +62,15 @@ class SWIFT extends \OC\Files\Storage\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=='.') { @@ -92,8 +92,8 @@ class SWIFT extends \OC\Files\Storage\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])) { @@ -110,7 +110,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $obj=$container->get_object(basename($path)); $this->objects[$path]=$obj; return $obj; - }catch(NoSuchObjectException $e) { + }catch(\NoSuchObjectException $e) { return null; } } @@ -135,8 +135,8 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * create object - * @param string path - * @return CF_Object + * @param string $path + * @return \CF_Object */ private function createObject($path) { $container=$this->getContainer(dirname($path)); @@ -157,7 +157,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * check if container for path exists - * @param string path + * @param string $path * @return bool */ private function containerExists($path) { @@ -166,15 +166,15 @@ class SWIFT extends \OC\Files\Storage\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); @@ -188,15 +188,15 @@ class SWIFT extends \OC\Files\Storage\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); @@ -211,8 +211,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $fh=fopen($tmpFile,'a'); fwrite($fh,$name."\n"); } - }catch(Exception $e) { - $containers=array(); + }catch(\Exception $e) { file_put_contents($tmpFile,$name."\n"); } @@ -223,20 +222,20 @@ class SWIFT extends \OC\Files\Storage\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) { @@ -258,13 +257,13 @@ class SWIFT extends \OC\Files\Storage\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{ return $container->get_object(self::SUBCONTAINER_FILE); - }catch(NoSuchObjectException $e) { + }catch(\NoSuchObjectException $e) { return $container->create_object(self::SUBCONTAINER_FILE); } } @@ -526,11 +525,11 @@ class SWIFT extends \OC\Files\Storage\Common{ private function getTmpFile($path) { $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(); } } @@ -545,7 +544,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * remove custom mtime metadata - * @param CF_Object obj + * @param \CF_Object $obj */ private function resetMTime($obj) { if(isset($obj->metadata['Mtime'])) { diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 6ed93e9035b..73231b6ad81 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -15,7 +15,7 @@ class DAV extends \OC\Files\Storage\Common{ private $secure; private $root; /** - * @var Sabre_DAV_Client + * @var \Sabre_DAV_Client */ private $client; @@ -92,7 +92,7 @@ class DAV extends \OC\Files\Storage\Common{ \OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -103,7 +103,7 @@ class DAV extends \OC\Files\Storage\Common{ $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; @@ -123,7 +123,7 @@ class DAV extends \OC\Files\Storage\Common{ try{ $this->client->propfind($path, array('{DAV:}resourcetype')); return true;//no 404 exception - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -169,7 +169,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ $ext=''; } - $tmpFile=OCP\Files::tmpFile($ext); + $tmpFile=\OCP\Files::tmpFile($ext); \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); @@ -195,7 +195,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ return 0; } - }catch(Exception $e) { + }catch(\Exception $e) { return 0; } } @@ -231,12 +231,9 @@ class DAV extends \OC\Files\Storage\Common{ $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ - $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); + $this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e) { - echo $e; - echo 'fail'; - var_dump($response); + }catch(\Exception $e) { return false; } } @@ -245,12 +242,9 @@ class DAV extends \OC\Files\Storage\Common{ $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ - $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2)); + $this->client->request('COPY',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e) { - echo $e; - echo 'fail'; - var_dump($response); + }catch(\Exception $e) { return false; } } @@ -264,7 +258,7 @@ class DAV extends \OC\Files\Storage\Common{ 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, 'ctime'=>-1, ); - }catch(Exception $e) { + }catch(\Exception $e) { return array(); } } @@ -282,7 +276,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ return false; } - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -300,7 +294,7 @@ class DAV extends \OC\Files\Storage\Common{ try{ $response=$this->client->request($method,$path,$body); return $response['statusCode']==$expected; - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index ff16b1c1d8a..5af317675cb 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -8,7 +8,7 @@ return array( 'root'=>'/test', ), 'webdav'=>array( - 'run'=>false, + 'run'=>true, 'host'=>'localhost', 'user'=>'test', 'password'=>'test', -- cgit v1.2.3 From cfa036eaa916c1adf38fb161a16c50cd050c0a3b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 20 Oct 2012 23:54:37 +0200 Subject: drop filectime from the filesystem api's --- apps/files_external/lib/amazons3.php | 2 -- apps/files_external/lib/dropbox.php | 1 - apps/files_external/lib/google.php | 2 -- apps/files_external/lib/swift.php | 2 -- apps/files_external/lib/webdav.php | 1 - apps/files_sharing/lib/sharedstorage.php | 22 ---------------------- lib/files.php | 3 +-- lib/files/filesystem.php | 4 ---- lib/files/storage/common.php | 4 ---- lib/files/storage/local.php | 3 --- lib/files/storage/storage.php | 1 - lib/files/view.php | 4 ---- lib/filesystem.php | 7 ------- 13 files changed, 1 insertion(+), 55 deletions(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 832127d3e79..c3fa4651f64 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -115,12 +115,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { $stat['size'] = $this->s3->get_bucket_filesize($this->bucket); $stat['atime'] = time(); $stat['mtime'] = $stat['atime']; - $stat['ctime'] = $stat['atime']; } else if ($object = $this->getObject($path)) { $stat['size'] = $object['Size']; $stat['atime'] = time(); $stat['mtime'] = strtotime($object['LastModified']); - $stat['ctime'] = $stat['mtime']; } if (isset($stat)) { return $stat; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 0f7593162e4..0e82f80668f 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -119,7 +119,6 @@ class Dropbox extends \OC\Files\Storage\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; diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 141fc619e35..7ee5b97f8be 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -257,14 +257,12 @@ class Google extends \OC\Files\Storage\Common { $stat['size'] = $this->free_space($path); $stat['atime'] = time(); $stat['mtime'] = time(); - $stat['ctime'] = time(); } else if ($entry = $this->getResource($path)) { // NOTE: Native resources don't have a file size $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; // if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) // $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)) { return $stat; diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 4b3f38166dc..c3578b0c23e 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -500,7 +500,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>-1, 'size'=>$container->bytes_used, - 'ctime'=>-1 ); } @@ -518,7 +517,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>$mtime, 'size'=>$obj->content_length, - 'ctime'=>-1, ); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 73231b6ad81..c9785f3eb11 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -256,7 +256,6 @@ class DAV extends \OC\Files\Storage\Common{ return array( 'mtime'=>strtotime($response['{DAV:}getlastmodified']), 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, - 'ctime'=>-1, ); }catch(\Exception $e) { return array(); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e12027a4f2b..521dfb69f2a 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -162,7 +162,6 @@ class Shared extends \OC\Files\Storage\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)) { list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); @@ -233,27 +232,6 @@ class Shared extends \OC\Files\Storage\Common { 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) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); - return $storage->filectime($internalPath); - } - } - } - public function filemtime($path) { if ($path == '' || $path == '/') { $mtime = 0; diff --git a/lib/files.php b/lib/files.php index 29322cf2d06..28c8d0b449f 100644 --- a/lib/files.php +++ b/lib/files.php @@ -30,13 +30,12 @@ class OC_Files { /** * get the filesystem info - * @param string path + * @param string $path * @return array * * returns an associative array with the following keys: * - size * - mtime - * - ctime * - mimetype * - encrypted * - versioned diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index e4c269257c2..94e8a562564 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -478,10 +478,6 @@ class Filesystem { 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); } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3886a041829..17405845554 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -74,10 +74,6 @@ abstract class Common extends \OC\Files\Storage\Storage { return $permissions; } // abstract public function file_exists($path); - public function filectime($path) { - $stat = $this->stat($path); - return $stat['ctime']; - } public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index 66ae5542e36..ccd69e3971c 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -66,9 +66,6 @@ class Local extends \OC\Files\Storage\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); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index f149c61830c..941bc3b0779 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -29,7 +29,6 @@ abstract class Storage{ abstract public function isSharable($path); abstract public function getPermissions($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); diff --git a/lib/files/view.php b/lib/files/view.php index bffeb434f28..58e3ee6f051 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -236,10 +236,6 @@ class View { return $this->basicOperation('file_exists', $path); } - public function filectime($path) { - return $this->basicOperation('filectime', $path); - } - public function filemtime($path) { return $this->basicOperation('filemtime', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 587eb50d9e0..9ce75aaf8ce 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -306,13 +306,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::file_exists($path); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filectime($path) { - return \OC\Files\Filesystem::filectime($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ -- cgit v1.2.3 From 1901ac8b17c99eef3ccd99edf877fd0a86737d17 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:13:16 +0200 Subject: drop depricated is_readable and is_writable --- lib/files.php | 2 +- lib/files/filesystem.php | 14 -------------- lib/files/view.php | 14 -------------- lib/filesystem.php | 7 ------- 4 files changed, 1 insertion(+), 36 deletions(-) diff --git a/lib/files.php b/lib/files.php index 28c8d0b449f..ba111bee967 100644 --- a/lib/files.php +++ b/lib/files.php @@ -178,7 +178,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or \OC\Files\Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::isReadable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 94e8a562564..0dae774febe 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -440,20 +440,6 @@ class Filesystem { return self::$defaultInstance->readfile($path); } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return self::$defaultInstance->isReadable($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); } diff --git a/lib/files/view.php b/lib/files/view.php index 58e3ee6f051..a59ad8105d6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -195,20 +195,6 @@ class View { return false; } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - public function is_readable($path) { - return $this->basicOperation('isReadable', $path); - } - - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - public function is_writable($path) { - return $this->basicOperation('isUpdatable', $path); - } - public function isCreatable($path) { return $this->basicOperation('isCreatable', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 9ce75aaf8ce..ea0a289c8d2 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -257,13 +257,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::isReadable($path); } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return \OC\Files\Filesystem::is_writable($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ -- cgit v1.2.3 From 6f1fbf97f7678f7a9a8b2e92d1cdd24fc5710d17 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:27:55 +0200 Subject: some namespaces fixed for the shared backend --- apps/files_sharing/lib/sharedstorage.php | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 521dfb69f2a..e354314cc39 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -37,7 +37,7 @@ class Shared extends \OC\Files\Storage\Common { /** * @brief Get the source file path and the permissions granted 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 array with the keys path and permissions or false if not found */ private function getFile($target) { $target = '/'.$target; @@ -52,7 +52,7 @@ class Shared extends \OC\Files\Storage\Common { if (isset($this->files[$folder])) { $file = $this->files[$folder]; } else { - $file = OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $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)); @@ -60,13 +60,13 @@ class Shared extends \OC\Files\Storage\Common { return $this->files[$target]; } } else { - $file = OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = \OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); if ($file) { $this->files[$target] = $file; return $this->files[$target]; } } - OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, OCP\Util::ERROR); + \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); return false; } } @@ -74,13 +74,13 @@ class Shared extends \OC\Files\Storage\Common { /** * @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\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -89,7 +89,7 @@ class Shared extends \OC\Files\Storage\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 */ public function getPermissions($target) { $file = $this->getFile($target); @@ -99,17 +99,6 @@ class Shared extends \OC\Files\Storage\Common { 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\Files\Filesystem::getMountPoint($path); - $internalPath = substr($path, strlen($mountPoint)); - return $internalPath; - } - public function mkdir($path) { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; -- cgit v1.2.3 From 3ff0772a05c70592360c7b11b280cc4cf45a385e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:31:32 +0200 Subject: add getCache and getScanner to storage api in order to allow storage backends to overwride caching behaviour --- lib/files/storage/common.php | 50 ++++++++----------------------- lib/files/storage/storage.php | 70 ++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 72 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 17405845554..de02c0d5d81 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -20,7 +20,7 @@ namespace OC\Files\Storage; * in classes which extend it, e.g. $this->stat() . */ -abstract class Common extends \OC\Files\Storage\Storage { +abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} // abstract public function getId(); @@ -123,64 +123,30 @@ abstract class Common extends \OC\Files\Storage\Storage { * 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 ) ) { - 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 ); - } 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; } @@ -209,7 +175,7 @@ abstract class Common extends \OC\Files\Storage\Storage { return $mime; } public function hash($type,$path,$raw = false) { - $tmpFile=$this->getLocalFile(); + $tmpFile=$this->getLocalFile($path); $hash=hash($type,$tmpFile,$raw); unlink($tmpFile); return $hash; @@ -283,4 +249,12 @@ abstract class Common extends \OC\Files\Storage\Storage { public function hasUpdated($path,$time) { return $this->filemtime($path)>$time; } + + public function getCache(){ + return new \OC\Files\Cache\Cache($this); + } + + public function getScanner(){ + return new \OC\Files\Cache\Scanner($this); + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 941bc3b0779..b1ec0bdb500 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -9,40 +9,40 @@ namespace OC\Files\Storage; /** - * Provde a common interface to all different storage options + * Provide a common interface to all different storage options */ -abstract class Storage{ - abstract public function __construct($parameters); - abstract public function getId(); - 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 getPermissions($path); - abstract public function file_exists($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 +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 @@ -51,5 +51,7 @@ abstract class Storage{ * 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); + public function hasUpdated($path,$time); + public function getCache(); + public function getScanner(); } -- cgit v1.2.3 From 01594b8610ce4f08e28010994d9cbecda4c52e35 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:54:34 +0200 Subject: remove chroot from filesystem api --- lib/files/filesystem.php | 10 ---------- lib/filesystem.php | 11 ----------- 2 files changed, 21 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 0dae774febe..05dd698ab4b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,16 +281,6 @@ class Filesystem { } } - /** - * 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 diff --git a/lib/filesystem.php b/lib/filesystem.php index ea0a289c8d2..20b5ab27909 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -81,17 +81,6 @@ class OC_Filesystem { \OC\Files\Filesystem::tearDown(); } - /** - * change the root to a fake root - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return \OC\Files\Filesystem::chroot($fakeRoot); - } - /** * @brief get the relative path of the root data directory for the current user * @return string -- cgit v1.2.3 From 2522c25af726a8487ac13855e8a035b990cd69a4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 02:12:58 +0200 Subject: use OC_Files::getFileInfo and OC_Files::getDirectoryContent as high level api for the filecache most apps would want to use this api instead of using the cache directly --- lib/files.php | 108 +++++++++++++++++++++--------------------- lib/files/filesystem.php | 73 +++++++++++++++++++++------- lib/files/storage/storage.php | 7 +++ tests/lib/files.php | 87 ++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 71 deletions(-) create mode 100644 tests/lib/files.php diff --git a/lib/files.php b/lib/files.php index ba111bee967..8d402c0001d 100644 --- a/lib/files.php +++ b/lib/files.php @@ -41,69 +41,67 @@ class OC_Files { * - versioned */ public static function getFileInfo($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['size'] = \OC\Files\Filesystem::filesize($path); - $info['mtime'] = \OC\Files\Filesystem::filemtime($path); - $info['ctime'] = \OC\Files\Filesystem::filectime($path); - $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); - $info['encrypted'] = false; - $info['versioned'] = false; + $path=\OC\Files\Filesystem::normalizePath($path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $data = $cache->get($internalPath); + + if($data['mimetype'] === 'httpd/unix-directory'){ + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; } - } else { - $info = OC_FileCache::get($path); } - return $info; + + return $data; } /** * get the content of a directory - * @param dir $directory path under datadirectory + * @param string $directory path under datadirectory + * @return array */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=\OC\Files\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\Share::PERMISSION_READ; - // NOTE: Remove check when new encryption is merged - if (!$file['encrypted']) { - $permissions |= OCP\Share::PERMISSION_SHARE; - } - if ($file['type'] == 'dir' && $file['writable']) { - $permissions |= OCP\Share::PERMISSION_CREATE; - } - if ($file['writable']) { - $permissions |= OCP\Share::PERMISSION_UPDATE | OCP\Share::PERMISSION_DELETE; + $path=\OC\Files\Filesystem::normalizePath($directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $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']; + } } - $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)); + }else{ //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $files[] = $rootEntry; } } + usort($files, "fileCmp");//TODO: remove this once ajax is merged return $files; } @@ -145,7 +143,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } foreach($files as $file) { @@ -166,7 +164,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } $file=$dir.'/'.$files; @@ -446,7 +444,7 @@ class OC_Files { $setting = 'php_value '.$key.' '.$size; $hasReplaced = 0; $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); - if($content !== NULL) { + if($content !== null) { $htaccess = $content; } if($hasReplaced == 0) { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 05dd698ab4b..b7f8483fbf9 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,6 +164,43 @@ class Filesystem { return $foundMountPoint; } + /** + * get a list of all mount points in a directory + * + * @param string $path + * @return string[] + */ + static public function getMountPoints($path) { + $path = self::normalizePath($path); + if (strlen($path) > 1) { + $path .= '/'; + } + $pathLength = strlen($path); + + $mountPoints = array_keys(self::$mounts); + $result = array(); + foreach ($mountPoints as $mountPoint) { + if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { + $result[] = $mountPoint; + } + } + return $result; + } + + /** + * get the storage mounted at $mountPoint + * + * @param string $mountPoint + * @return \OC\Files\Storage\Storage + */ + public static function getStorage($mountPoint) { + if (!isset(self::$storages[$mountPoint])) { + $mount = self::$mounts[$mountPoint]; + self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); + } + return self::$storages[$mountPoint]; + } + /** * resolve a path to a storage and internal path * @@ -173,14 +210,14 @@ class Filesystem { static public function resolvePath($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); + $storage = self::getStorage($mountpoint); + if ($mountpoint === $path) { + $internalPath = ''; + } else { + $internalPath = substr($path, strlen($mountpoint)); } - $storage = self::$storages[$mountpoint]; - $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); - }else{ + } else { return array(null, null); } } @@ -302,18 +339,22 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $class * @param array $arguments * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - if ($mountpoint[0] != '/') { - $mountpoint = '/' . $mountpoint; + $mountpoint = self::normalizePath($mountpoint); + if (strlen($mountpoint) > 1) { + $mountpoint .= '/'; } - if (substr($mountpoint, -1) !== '/') { - $mountpoint = $mountpoint . '/'; + + if ($class instanceof \OC\Files\Storage\Storage) { + self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); + self::$storages[$mountpoint] = $class; + } else { + self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } - self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } /** @@ -522,15 +563,15 @@ class Filesystem { static public function removeETagHook($params, $root = false) { if (isset($params['path'])) { - $path=$params['path']; + $path = $params['path']; } else { - $path=$params['oldpath']; + $path = $params['oldpath']; } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b1ec0bdb500..853e8ba5198 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -52,6 +52,13 @@ interface Storage{ * returning true for other changes in the folder is optional */ public function hasUpdated($path,$time); + + /** + * @return \OC\Files\Cache\Cache + */ public function getCache(); + /** + * @return \OC\Files\Cache\Scanner + */ public function getScanner(); } diff --git a/tests/lib/files.php b/tests/lib/files.php new file mode 100644 index 00000000000..9cb52768458 --- /dev/null +++ b/tests/lib/files.php @@ -0,0 +1,87 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +use \OC\Files\Filesystem as Filesystem; + +class Test_Files extends PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $cache->clear(); + } + } + + public function testCacheAPI() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $cachedData = OC_Files::getFileInfo('/foo.txt'); + $this->assertEquals($textSize, $cachedData['size']); + $this->assertEquals('text/plain', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/'); + $this->assertEquals($storageSize * 3, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/folder'); + $this->assertEquals($storageSize + $textSize, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $folderData = OC_Files::getDirectoryContent('/'); + /** + * expected entries: + * folder + * foo.png + * foo.txt + * substorage + */ + $this->assertEquals(4, count($folderData)); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('substorage', $folderData[3]['name']); + + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($storageSize, $folderData[3]['size']); + } + + /** + * @return OC\Files\Storage\Storage + */ + private function getTestStorage() { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + + $scanner = $storage->getScanner(); + $scanner->scan(''); + $this->storages[] = $storage; + return $storage; + } +} -- cgit v1.2.3 From 33cabcf590401763609570a86f7bc7540dbf1fc5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 22:04:45 +0200 Subject: postpone the cost of setting up some of the external storage backends untill we actually need it --- apps/files_external/lib/ftp.php | 2 ++ apps/files_external/lib/smb.php | 7 ++----- apps/files_external/lib/streamwrapper.php | 26 ++++++++++++++++++++++++++ apps/files_external/lib/swift.php | 29 +++++++++++++++++++++++++++-- apps/files_external/lib/webdav.php | 23 +++++++++++++++++++++++ apps/files_external/tests/config.php | 2 +- 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index dea44728f3c..e76eca0be38 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -50,6 +50,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ return $url; } public function fopen($path,$mode) { + $this->init(); switch($mode) { case 'r': case 'rb': @@ -86,6 +87,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ } public function writeBack($tmpFile) { + $this->init(); if(isset(self::$tempFiles[$tmpFile])) { $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]); unlink($tmpFile); diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index dfba3105ecb..4382f630031 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -35,11 +35,6 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ 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(){ @@ -54,6 +49,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } public function stat($path) { + $this->init(); if(!$path and $this->root=='/') {//mtime doesn't work for shares $mtime=$this->shareMTime(); $stat=stat($this->constructUrl($path)); @@ -75,6 +71,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ * @return bool */ 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; diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 750bdbaf4d4..bc1c95c5e8f 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -9,13 +9,29 @@ 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 public function constructUrl($path); public function mkdir($path) { + $this->init(); return mkdir($this->constructUrl($path)); } public function rmdir($path) { + $this->init(); if($this->file_exists($path)) { $succes=rmdir($this->constructUrl($path)); clearstatcache(); @@ -26,10 +42,12 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function opendir($path) { + $this->init(); return opendir($this->constructUrl($path)); } public function filetype($path) { + $this->init(); return filetype($this->constructUrl($path)); } @@ -42,16 +60,19 @@ abstract class StreamWrapper extends \OC\Files\Storage\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) { + $this->init(); return fopen($this->constructUrl($path),$mode); } @@ -60,6 +81,7 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); if(is_null($mtime)) { $fh=$this->fopen($path,'a'); fwrite($fh,''); @@ -70,18 +92,22 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function getFile($path,$target) { + $this->init(); return copy($this->constructUrl($path),$target); } public function uploadFile($path,$target) { + $this->init(); return copy($path,$this->constructUrl($target)); } 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)); } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index c3578b0c23e..55c2c3e0ac9 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -17,6 +17,7 @@ class SWIFT extends \OC\Files\Storage\Common{ private $user; private $token; private $secure; + private $ready = false; /** * @var \CF_Authentication auth */ @@ -188,7 +189,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * add an emulated sub container - * @param CF_Container $container + * @param \CF_Container $container * @param string $name * @return bool */ @@ -222,7 +223,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * remove an emulated sub container - * @param CF_Container $container + * @param \CF_Container $container * @param string $name * @return bool */ @@ -279,6 +280,15 @@ class SWIFT extends \OC\Files\Storage\Common{ if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } + + } + + 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(); @@ -297,6 +307,7 @@ class SWIFT extends \OC\Files\Storage\Common{ public function mkdir($path) { + $this->init(); if($this->containerExists($path)) { return false; }else{ @@ -306,6 +317,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function rmdir($path) { + $this->init(); if(!$this->containerExists($path)) { return false; }else{ @@ -343,6 +355,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function opendir($path) { + $this->init(); $container=$this->getContainer($path); $files=$this->getObjects($container); $i=array_search(self::SUBCONTAINER_FILE,$files); @@ -357,6 +370,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function filetype($path) { + $this->init(); if($this->containerExists($path)) { return 'dir'; }else{ @@ -373,6 +387,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function file_exists($path) { + $this->init(); if($this->is_dir($path)) { return true; }else{ @@ -381,6 +396,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function file_get_contents($path) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { return false; @@ -389,6 +405,7 @@ class SWIFT extends \OC\Files\Storage\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 +419,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function unlink($path) { + $this->init(); if($this->containerExists($path)) { return $this->rmdir($path); } @@ -415,6 +433,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function fopen($path,$mode) { + $this->init(); switch($mode) { case 'r': case 'rb': @@ -458,6 +477,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { return false; @@ -472,6 +492,7 @@ class SWIFT extends \OC\Files\Storage\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 +505,7 @@ class SWIFT extends \OC\Files\Storage\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 +517,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function stat($path) { + $this->init(); $container=$this->getContainer($path); if (!is_null($container)) { return array( @@ -521,6 +544,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } private function getTmpFile($path) { + $this->init(); $obj=$this->getObject($path); if(!is_null($obj)) { $tmpFile=\OCP\Files::tmpFile(); @@ -532,6 +556,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } private function fromTmpFile($tmpFile,$path) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { $obj=$this->createObject($path); diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index c9785f3eb11..470a80f8cf3 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -14,6 +14,7 @@ class DAV extends \OC\Files\Storage\Common{ private $host; private $secure; private $root; + private $ready; /** * @var \Sabre_DAV_Client */ @@ -37,6 +38,13 @@ class DAV extends \OC\Files\Storage\Common{ if(substr($this->root,-1,1)!='/') { $this->root.='/'; } + } + + private function init(){ + if($this->ready){ + return; + } + $this->ready = true; $settings = array( 'baseUri' => $this->createBaseUri(), @@ -70,16 +78,19 @@ class DAV extends \OC\Files\Storage\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); @@ -98,6 +109,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function filetype($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}resourcetype')); @@ -119,6 +131,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function file_exists($path) { + $this->init(); $path=$this->cleanPath($path); try{ $this->client->propfind($path, array('{DAV:}resourcetype')); @@ -129,10 +142,12 @@ class DAV extends \OC\Files\Storage\Common{ } public function unlink($path) { + $this->init(); return $this->simpleResponse('DELETE',$path,null,204); } public function fopen($path,$mode) { + $this->init(); $path=$this->cleanPath($path); switch($mode) { case 'r': @@ -187,6 +202,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function free_space($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes')); @@ -201,6 +217,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); if(is_null($mtime)) { $mtime=time(); } @@ -209,11 +226,13 @@ class DAV extends \OC\Files\Storage\Common{ } public function getFile($path,$target) { + $this->init(); $source=$this->fopen($path,'r'); file_put_contents($target,$source); } public function uploadFile($path,$target) { + $this->init(); $source=fopen($path,'r'); $curl = curl_init(); @@ -228,6 +247,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function rename($path1,$path2) { + $this->init(); $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ @@ -239,6 +259,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function copy($path1,$path2) { + $this->init(); $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ @@ -250,6 +271,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function stat($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength')); @@ -263,6 +285,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function getMimeType($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype')); diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index 5af317675cb..65127175ad7 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -30,7 +30,7 @@ return array( 'root'=>'/', ), 'smb'=>array( - 'run'=>false, + 'run'=>true, 'user'=>'test', 'password'=>'test', 'host'=>'localhost', -- cgit v1.2.3 From 707bd68bb4e77b4184b578699d508750653e2d42 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 22:05:29 +0200 Subject: automatically scan files when needed --- lib/files.php | 463 +++++++++++++++++++++++++++------------------------- tests/lib/files.php | 27 ++- 2 files changed, 265 insertions(+), 225 deletions(-) diff --git a/lib/files.php b/lib/files.php index 8d402c0001d..a5eec1f2a63 100644 --- a/lib/files.php +++ b/lib/files.php @@ -1,35 +1,36 @@ . -* -*/ + * 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 . + * + */ /** * Class for fileserver access * */ class OC_Files { - static $tmpFiles=array(); + static $tmpFiles = array(); /** * get the filesystem info + * * @param string $path * @return array * @@ -41,19 +42,25 @@ class OC_Files { * - versioned */ public static function getFileInfo($path) { - $path=\OC\Files\Filesystem::normalizePath($path); + $path = \OC\Files\Filesystem::normalizePath($path); /** * @var \OC\Files\Storage\Storage $storage * @var string $path */ - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); - $cache=$storage->getCache(); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + $data = $cache->get($internalPath); - if($data['mimetype'] === 'httpd/unix-directory'){ + if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = \OC\Files\Filesystem::getMountPoints($path); - foreach($mountPoints as $mountPoint){ + foreach ($mountPoints as $mountPoint) { $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -66,43 +73,50 @@ class OC_Files { } /** - * get the content of a directory - * @param string $directory path under datadirectory - * @return array - */ + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $path=\OC\Files\Filesystem::normalizePath($directory); + $path = \OC\Files\Filesystem::normalizePath($directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $path */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache=$storage->getCache(); - $files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); $dirLength = strlen($path); - foreach($mountPoints as $mountPoint){ + foreach ($mountPoints as $mountPoint) { $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); $relativePath = trim(substr($mountPoint, $dirLength), '/'); - if($pos = strpos($relativePath, '/')){ //mountpoint inside subfolder add size to the correct folder + 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){ + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { $entry['size'] += $rootEntry['size']; } } - }else{ //mountpoint in this folder, add an entry for it + } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; $files[] = $rootEntry; } } - usort($files, "fileCmp");//TODO: remove this once ajax is merged + usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } @@ -113,12 +127,11 @@ class OC_Files { // get next subdir to check $dir = array_pop($dirs_to_check); $dir_content = self::getDirectoryContent($dir, $mimetype_filter); - foreach($dir_content as $file) { + foreach ($dir_content as $file) { if ($file['type'] == 'file') { - $files[] = $dir.'/'.$file['name']; - } - else { - $dirs_to_check[] = $dir.'/'.$file['name']; + $files[] = $dir . '/' . $file['name']; + } else { + $dirs_to_check[] = $dir . '/' . $file['name']; } } } @@ -126,170 +139,171 @@ class OC_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) { - if(strpos($files,';')) { - $files=explode(';',$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) { + if (strpos($files, ';')) { + $files = explode(';', $files); } - if(is_array($files)) { - self::validateZipDownload($dir,$files); + if (is_array($files)) { + self::validateZipDownload($dir, $files); $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) { exit("cannot open <$filename>\n"); } - foreach($files as $file) { - $file=$dir.'/'.$file; - if(\OC\Files\Filesystem::is_file($file)) { - $tmpFile=OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); - self::$tmpFiles[]=$tmpFile; - $zip->addFile($tmpFile,basename($file)); - }elseif(\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file,$zip); + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (\OC\Files\Filesystem::is_file($file)) { + $tmpFile = OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); + self::$tmpFiles[] = $tmpFile; + $zip->addFile($tmpFile, basename($file)); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip); } } $zip->close(); set_time_limit($executionTime); - }elseif(\OC\Files\Filesystem::is_dir($dir.'/'.$files)) { - self::validateZipDownload($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); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) { exit("cannot open <$filename>\n"); } - $file=$dir.'/'.$files; - self::zipAddDir($file,$zip); + $file = $dir . '/' . $files; + self::zipAddDir($file, $zip); $zip->close(); set_time_limit($executionTime); - }else{ - $zip=false; - $filename=$dir.'/'.$files; + } else { + $zip = false; + $filename = $dir . '/' . $files; } @ob_end_clean(); - if($zip or \OC\Files\Filesystem::isReadable($filename)) { - header('Content-Disposition: attachment; filename="'.basename($filename).'"'); + if ($zip or \OC\Files\Filesystem::isReadable($filename)) { + header('Content-Disposition: attachment; filename="' . basename($filename) . '"'); 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)); - }else{ - header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); + } else { + header('Content-Type: ' . \OC\Files\Filesystem::getMimeType($filename)); } - }elseif($zip or !\OC\Files\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', $filename); $tmpl->printPage(); - }else{ + } else { header("HTTP/1.0 403 Forbidden"); die('403 Forbidden'); } - if($only_header) { - if(!$zip) - header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); - return ; + if ($only_header) { + if (!$zip) + header("Content-Length: " . \OC\Files\Filesystem::filesize($filename)); + 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(); } } unlink($filename); - }else{ + } else { \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); } } } - public static function zipAddDir($dir,$zip,$internalDir='') { - $dirname=basename($dir); - $zip->addEmptyDir($internalDir.$dirname); - $internalDir.=$dirname.='/'; - $files=OC_Files::getdirectorycontent($dir); - foreach($files as $file) { - $filename=$file['name']; - $file=$dir.'/'.$filename; - if(\OC\Files\Filesystem::is_file($file)) { - $tmpFile=\OC\Files\Filesystem::toTmpFile($file); - OC_Files::$tmpFiles[]=$tmpFile; - $zip->addFile($tmpFile,$internalDir.$filename); - }elseif(\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file,$zip,$internalDir); + public static function zipAddDir($dir, $zip, $internalDir = '') { + $dirname = basename($dir); + $zip->addEmptyDir($internalDir . $dirname); + $internalDir .= $dirname .= '/'; + $files = OC_Files::getdirectorycontent($dir); + foreach ($files as $file) { + $filename = $file['name']; + $file = $dir . '/' . $filename; + if (\OC\Files\Filesystem::is_file($file)) { + $tmpFile = \OC\Files\Filesystem::toTmpFile($file); + OC_Files::$tmpFiles[] = $tmpFile; + $zip->addFile($tmpFile, $internalDir . $filename); + } 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\Files\Filesystem::rename($sourceFile,$targetFile); + * 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\Files\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\Files\Filesystem::copy($sourceFile,$targetFile); + * 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\Files\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') { + * 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\Files\Filesystem::mkdir($file); - }elseif($type=='file') { - $fileHandle=\OC\Files\Filesystem::fopen($file, 'w'); - if($fileHandle) { + } elseif ($type == 'file') { + $fileHandle = \OC\Files\Filesystem::fopen($file, 'w'); + if ($fileHandle) { fclose($fileHandle); return true; - }else{ + } else { return false; } } @@ -297,29 +311,29 @@ class OC_Files { } /** - * 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; + * 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\Files\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.'), @@ -332,19 +346,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\Files\Filesystem::filesize($dir.'/'.$file); + if (is_array($files)) { + foreach ($files as $file) { + $totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $file); } - }else{ - $totalsize += \OC\Files\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.'), @@ -359,78 +373,80 @@ class OC_Files { } /** - * try to detect the mime type of a file - * - * @param string path - * @return string guessed mime type - */ + * try to detect the mime type of a file + * + * @param string path + * @return string guessed mime type + */ static function getMimeType($path) { return \OC\Files\Filesystem::getMimeType($path); } /** - * get a file tree - * - * @param string path - * @return array - */ + * get a file tree + * + * @param string path + * @return array + */ static function getTree($path) { return \OC\Files\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); + * 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']; + $info = curl_getinfo($ch); + $httpCode = $info['http_code']; curl_close($ch); - if($httpCode==200 or $httpCode==0) { - \OC\Files\Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); + if ($httpCode == 200 or $httpCode == 0) { + \OC\Files\Filesystem::fromTmpFile($tmpfile, $dir . '/' . $file); return true; - }else{ + } 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; } @@ -439,50 +455,53 @@ 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); } + } else { + 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); + $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') { +function fileCmp($a, $b) { + if ($a['type'] == 'dir' and $b['type'] != 'dir') { return -1; - }elseif($a['type']!='dir' and $b['type']=='dir') { + } elseif ($a['type'] != 'dir' and $b['type'] == 'dir') { return 1; - }else{ - return strnatcasecmp($a['name'],$b['name']); + } else { + return strnatcasecmp($a['name'], $b['name']); } } diff --git a/tests/lib/files.php b/tests/lib/files.php index 9cb52768458..d978ac3fd13 100644 --- a/tests/lib/files.php +++ b/tests/lib/files.php @@ -67,10 +67,29 @@ class Test_Files extends PHPUnit_Framework_TestCase { $this->assertEquals($storageSize, $folderData[3]['size']); } + public function testAutoScan() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(false); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $cachedData = \OC_Files::getFileInfo('/'); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + $this->assertEquals(-1, $cachedData['size']); + + $folderData = \OC_Files::getDirectoryContent('/substorage/folder'); + $this->assertEquals('text/plain', $folderData[0]['mimetype']); + $this->assertEquals($textSize, $folderData[0]['size']); + } + /** + * @param bool $scan * @return OC\Files\Storage\Storage */ - private function getTestStorage() { + private function getTestStorage($scan = true) { $storage = new \OC\Files\Storage\Temporary(array()); $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -79,8 +98,10 @@ class Test_Files extends PHPUnit_Framework_TestCase { $storage->file_put_contents('foo.png', $imgData); $storage->file_put_contents('folder/bar.txt', $textData); - $scanner = $storage->getScanner(); - $scanner->scan(''); + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } $this->storages[] = $storage; return $storage; } -- cgit v1.2.3 From 56c7ee799cb13f7a4db60663f60b76cdf223614b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 23 Oct 2012 16:34:58 +0200 Subject: use strtotime on non-nummeric times in oc_filesystem::touch --- lib/files/view.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index a59ad8105d6..18d9193035e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -227,6 +227,9 @@ class View { } 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); } @@ -331,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -342,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -414,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -550,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -585,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); -- cgit v1.2.3 From 5a3d6805a2613c4f55daa971e112cc77f17b060f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 24 Oct 2012 15:52:30 +0200 Subject: cleanup OC_Files a bit --- apps/files/ajax/delete.php | 23 ++++--- apps/files/ajax/move.php | 13 ++-- apps/files/ajax/newfile.php | 2 +- apps/files/ajax/newfolder.php | 2 +- apps/files/ajax/rename.php | 14 +++-- lib/files.php | 136 ------------------------------------------ 6 files changed, 34 insertions(+), 156 deletions(-) diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index 57c8c15c197..ae6158a05aa 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -12,17 +12,22 @@ $files = isset($_POST["file"]) ? stripslashes($_POST["file"]) : stripslashes($_P $files = explode(';', $files); $filesWithError = ''; -$success = true; -//Now delete -foreach($files as $file) { - if( !OC_Files::delete( $dir, $file )) { - $filesWithError .= $file . "\n"; - $success = false; +if (OC_User::isLoggedIn()) { + $success = true; + + //Now delete + foreach ($files as $file) { + if ($dir != '' || $file != 'Shared' && !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { + $filesWithError .= $file . "\n"; + $success = false; + } } +} else { + $success = false; } -if($success) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $files ))); +if ($success) { + OCP\JSON::success(array("data" => array("dir" => $dir, "files" => $files))); } else { - OCP\JSON::error(array("data" => array( "message" => "Could not delete:\n" . $filesWithError ))); + OCP\JSON::error(array("data" => array("message" => "Could not delete:\n" . $filesWithError))); } diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php index 8b3149ef14e..f8727831228 100644 --- a/apps/files/ajax/move.php +++ b/apps/files/ajax/move.php @@ -11,9 +11,14 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $target = stripslashes($_GET["target"]); - -if(OC_Files::move($dir, $file, $target, $file)) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file ))); -} else { +if (OC_User::isLoggedIn() && ($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" ))); } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 4d73970b68d..f94d984d5ba 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -82,7 +82,7 @@ if($source) { OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } - }elseif(OC_Files::newFile($dir, $filename, 'file')) { + }elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) { $meta = OC_FileCache::get($dir.'/'.$filename); $id = OC_FileCache::getId($dir.'/'.$filename); OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index 0f1f2f14eb0..c36c2084551 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -19,7 +19,7 @@ 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 { diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php index 45448279fa1..a2b9b8de257 100644 --- a/apps/files/ajax/rename.php +++ b/apps/files/ajax/rename.php @@ -11,10 +11,14 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $newname = stripslashes($_GET["newname"]); -// Delete -if( OC_Files::move( $dir, $file, $dir, $newname )) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname ))); -} -else{ +if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { + $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); + $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); + 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" ))); } diff --git a/lib/files.php b/lib/files.php index ff9befa89e5..7ab7c89201a 100644 --- a/lib/files.php +++ b/lib/files.php @@ -252,77 +252,6 @@ class OC_Files { } } - /** - * 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\Files\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\Files\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\Files\Filesystem::mkdir($file); - } elseif ($type == 'file') { - $fileHandle = \OC\Files\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\Files\Filesystem::unlink($file); - } - } - /** * checks if the selected files are within the size constraint. If not, outputs an error page. * @@ -372,55 +301,6 @@ 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\Files\Filesystem::getMimeType($path); - } - - /** - * get a file tree - * - * @param string path - * @return array - */ - static function getTree($path) { - return \OC\Files\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\Files\Filesystem::fromTmpFile($tmpfile, $dir . '/' . $file); - return true; - } else { - return false; - } - } - /** * set the maximum upload size limit for apache hosts using .htaccess * @@ -478,22 +358,6 @@ class OC_Files { 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) { -- cgit v1.2.3 From 39adadd3e3e50dcf3bf577a22870aaec52f63052 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:30:25 +0200 Subject: move the cache api from OC_Files to filesystem(view) --- lib/files.php | 92 ------------------------------------- lib/files/cache/cache.php | 5 ++ lib/files/filesystem.php | 27 +++++++++++ lib/files/view.php | 92 +++++++++++++++++++++++++++++++++++++ tests/lib/files.php | 108 -------------------------------------------- tests/lib/files/view.php | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+), 200 deletions(-) delete mode 100644 tests/lib/files.php create mode 100644 tests/lib/files/view.php diff --git a/lib/files.php b/lib/files.php index 7ab7c89201a..422e7f4ffe7 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,98 +28,6 @@ class OC_Files { static $tmpFiles = array(); - /** - * 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) { - $path = \OC\Files\Filesystem::normalizePath($path); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $data = $cache->get($internalPath); - - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; - } - } - - return $data; - } - - /** - * get the content of a directory - * - * @param string $directory path under datadirectory - * @return array - */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($directory); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); - $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $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; - $files[] = $rootEntry; - } - } - - usort($files, "fileCmp"); //TODO: remove this once ajax is merged - return $files; - } - public static function searchByMime($mimetype_filter) { $files = array(); $dirs_to_check = array(''); diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5ef49246ea5..9b55666f959 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -8,6 +8,11 @@ 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 diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b7f8483fbf9..d735cf8626a 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -609,6 +609,33 @@ class Filesystem { } 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); + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public static function getDirectoryContent($directory, $mimetype_filter = '') { + return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); + } } \OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); diff --git a/lib/files/view.php b/lib/files/view.php index 18d9193035e..aaca1618acb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -645,4 +645,96 @@ class View { 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) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $data = $cache->get($internalPath); + + if ($data['mimetype'] === 'httpd/unix-directory') { + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } + } + + return $data; + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public function getDirectoryContent($directory, $mimetype_filter = '') { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $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; + $files[] = $rootEntry; + } + } + + usort($files, "fileCmp"); //TODO: remove this once ajax is merged + return $files; + } } diff --git a/tests/lib/files.php b/tests/lib/files.php deleted file mode 100644 index d978ac3fd13..00000000000 --- a/tests/lib/files.php +++ /dev/null @@ -1,108 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. */ - -use \OC\Files\Filesystem as Filesystem; - -class Test_Files extends PHPUnit_Framework_TestCase { - /** - * @var \OC\Files\Storage\Storage[] $storages; - */ - private $storages = array(); - - public function setUp() { - Filesystem::clearMounts(); - } - - public function tearDown() { - foreach ($this->storages as $storage) { - $cache = $storage->getCache(); - $cache->clear(); - } - } - - public function testCacheAPI() { - $storage1 = $this->getTestStorage(); - $storage2 = $this->getTestStorage(); - $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); - $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $storageSize = $textSize * 2 + $imageSize; - - $cachedData = OC_Files::getFileInfo('/foo.txt'); - $this->assertEquals($textSize, $cachedData['size']); - $this->assertEquals('text/plain', $cachedData['mimetype']); - - $cachedData = OC_Files::getFileInfo('/'); - $this->assertEquals($storageSize * 3, $cachedData['size']); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - - $cachedData = OC_Files::getFileInfo('/folder'); - $this->assertEquals($storageSize + $textSize, $cachedData['size']); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - - $folderData = OC_Files::getDirectoryContent('/'); - /** - * expected entries: - * folder - * foo.png - * foo.txt - * substorage - */ - $this->assertEquals(4, count($folderData)); - $this->assertEquals('folder', $folderData[0]['name']); - $this->assertEquals('foo.png', $folderData[1]['name']); - $this->assertEquals('foo.txt', $folderData[2]['name']); - $this->assertEquals('substorage', $folderData[3]['name']); - - $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); - $this->assertEquals($imageSize, $folderData[1]['size']); - $this->assertEquals($textSize, $folderData[2]['size']); - $this->assertEquals($storageSize, $folderData[3]['size']); - } - - public function testAutoScan() { - $storage1 = $this->getTestStorage(false); - $storage2 = $this->getTestStorage(false); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $storageSize = $textSize * 2 + $imageSize; - - $cachedData = \OC_Files::getFileInfo('/'); - $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - $this->assertEquals(-1, $cachedData['size']); - - $folderData = \OC_Files::getDirectoryContent('/substorage/folder'); - $this->assertEquals('text/plain', $folderData[0]['mimetype']); - $this->assertEquals($textSize, $folderData[0]['size']); - } - - /** - * @param bool $scan - * @return OC\Files\Storage\Storage - */ - private function getTestStorage($scan = true) { - $storage = new \OC\Files\Storage\Temporary(array()); - $textData = "dummy file data\n"; - $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); - $storage->mkdir('folder'); - $storage->file_put_contents('foo.txt', $textData); - $storage->file_put_contents('foo.png', $imgData); - $storage->file_put_contents('folder/bar.txt', $textData); - - if ($scan) { - $scanner = $storage->getScanner(); - $scanner->scan(''); - } - $this->storages[] = $storage; - return $storage; - } -} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php new file mode 100644 index 00000000000..6e7608f596b --- /dev/null +++ b/tests/lib/files/view.php @@ -0,0 +1,113 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +namespace Test\Files; + +use \OC\Files\Filesystem as Filesystem; + +class View extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $cache->clear(); + } + } + + public function testCacheAPI() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertEquals($textSize, $cachedData['size']); + $this->assertEquals('text/plain', $cachedData['mimetype']); + + $cachedData = $rootView->getFileInfo('/'); + $this->assertEquals($storageSize * 3, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $cachedData = $rootView->getFileInfo('/folder'); + $this->assertEquals($storageSize + $textSize, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $folderData = $rootView->getDirectoryContent('/'); + /** + * expected entries: + * folder + * foo.png + * foo.txt + * substorage + */ + $this->assertEquals(4, count($folderData)); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('substorage', $folderData[3]['name']); + + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($storageSize, $folderData[3]['size']); + } + + public function testAutoScan() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(false); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/'); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + $this->assertEquals(-1, $cachedData['size']); + + $folderData = $rootView->getDirectoryContent('/substorage/folder'); + $this->assertEquals('text/plain', $folderData[0]['mimetype']); + $this->assertEquals($textSize, $folderData[0]['size']); + } + + /** + * @param bool $scan + * @return \OC\Files\Storage\Storage + */ + private function getTestStorage($scan = true) { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } + $this->storages[] = $storage; + return $storage; + } +} -- cgit v1.2.3 From e63e246c4894aa7f72feb550d98747890838af0b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:37:49 +0200 Subject: fix problem with normalizePath when there was a double leading slash --- lib/files/filesystem.php | 8 ++++---- tests/lib/files/view.php | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d735cf8626a..2b51131b20b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -595,14 +595,14 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trailing 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); } +//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); diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6e7608f596b..adbed5a18b6 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -69,6 +69,9 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($imageSize, $folderData[1]['size']); $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + + $folderView = new \OC\Files\View('/folder'); + $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); } public function testAutoScan() { -- cgit v1.2.3 From 7ef0ffe8ad8f95b023f95f80e7b91c2a3ee50c67 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:43:23 +0200 Subject: add View->putFileInfo to the filecache api --- lib/files/view.php | 30 ++++++++++++++++++++++++++++-- tests/lib/files/view.php | 7 +++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index aaca1618acb..094a7d92a4d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -663,7 +663,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -700,7 +700,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -737,4 +737,30 @@ class View { usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } + + /** + * change file metadata + * + * @param string $path + * @param array $data + * @return int + * + * returns the fileid of the updated file + */ + public function putFileInfo($path, $data) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + return $cache->put($internalPath, $data); + } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index adbed5a18b6..051ae251627 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -72,6 +72,13 @@ class View extends \PHPUnit_Framework_TestCase { $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertFalse($cachedData['encrypted']); + $id = $rootView->putFileInfo('/foo.txt', array('encrypted' => true)); + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertTrue($cachedData['encrypted']); + $this->assertEquals($cachedData['fileid'], $id); } public function testAutoScan() { -- cgit v1.2.3 From 8bce661e4ddedb611d5873c578203dfda631ce7e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 13:23:15 +0200 Subject: add search to the filecache api --- lib/files/cache/cache.php | 21 ++++++++++- lib/files/filesystem.php | 2 +- lib/files/view.php | 84 ++++++++++++++++++++++++++++++----------- tests/lib/files/cache/cache.php | 20 ++++++++++ tests/lib/files/view.php | 45 +++++++++++++++++++++- 5 files changed, 146 insertions(+), 26 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9b55666f959..7e0c5cb21f9 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -251,7 +251,7 @@ class Cache { */ public function getStatus($file) { $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { @@ -267,4 +267,23 @@ class Cache { } } } + + /** + * 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` + FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' + ); + $result = $query->execute(array($pattern, $this->storageId)); + $files = array(); + while ($row = $result->fetchRow()) { + $files[] = $row; + } + return $files; + } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 2b51131b20b..4031c0c5b80 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -548,7 +548,7 @@ class Filesystem { } static public function search($query) { - return Cache\Cache::search($query); + return self::$defaultInstance->search($query); } /** diff --git a/lib/files/view.php b/lib/files/view.php index 094a7d92a4d..ee95cce0c1d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -150,7 +150,7 @@ class View { } public function readdir($handle) { - $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/')); + $fsLocal = new Storage\Local(array('datadir' => '/')); return $fsLocal->readdir($handle); } @@ -334,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -553,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -588,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -660,26 +660,26 @@ class View { * - versioned */ public function getFileInfo($path) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $data = $cache->get($internalPath); if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -697,26 +697,26 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($directory); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -748,19 +748,57 @@ class View { * returns the fileid of the updated file */ public function putFileInfo($path, $data) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } return $cache->put($internalPath, $data); } + + /** + * search for files with the name matching $query + * + * @param string $query + * @return array + */ + public function search($query) { + $files = array(); + $rootLength = strlen($this->fakeRoot); + + $mountPoint = Filesystem::getMountPoint($this->fakeRoot); + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $results = $cache->search('%' . $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); + $cache = $storage->getCache(); + + $relativeMountPoint = substr($mountPoint, $rootLength); + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } + + return $files; + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 177cf1c045d..839e06e93fc 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -111,6 +111,26 @@ class Cache extends \UnitTestCase { $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); } + function testSearch() { + $file1 = 'folder'; + $file2 = 'folder/foobar'; + $file3 = 'folder/foo'; + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['foobar']); + $this->cache->put($file3, $fileData['foo']); + + $this->assertEquals(2, count($this->cache->search('%foo%'))); + $this->assertEquals(1, count($this->cache->search('foo'))); + $this->assertEquals(1, count($this->cache->search('%folder%'))); + $this->assertEquals(1, count($this->cache->search('folder%'))); + $this->assertEquals(3, count($this->cache->search('%'))); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 051ae251627..fc872ea5e27 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -87,7 +87,6 @@ class View extends \PHPUnit_Framework_TestCase { Filesystem::mount($storage1, array(), '/'); Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $rootView = new \OC\Files\View(''); @@ -100,6 +99,50 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($textSize, $folderData[0]['size']); } + function testSearch() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $results = $rootView->search('foo'); + $this->assertEquals(6, count($results)); + $paths = array(); + foreach ($results as $result) { + $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $paths[] = $result['path']; + } + $this->assertContains('/foo.txt', $paths); + $this->assertContains('/foo.png', $paths); + $this->assertContains('/substorage/foo.txt', $paths); + $this->assertContains('/substorage/foo.png', $paths); + $this->assertContains('/folder/anotherstorage/foo.txt', $paths); + $this->assertContains('/folder/anotherstorage/foo.png', $paths); + + $folderView = new \OC\Files\View('/folder'); + $results = $folderView->search('bar'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/folder/bar.txt', $paths); + $this->assertContains('/bar.txt', $paths); + + $results = $folderView->search('foo'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/foo.txt', $paths); + $this->assertContains('/anotherstorage/foo.png', $paths); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From 7ad8bf3156a794e47ee223efd2e1cf9191cc8a97 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 18:07:01 +0200 Subject: move filesystem test case --- tests/lib/files/filesystem.php | 110 +++++++++++++++++++++++++++++++++++++++++ tests/lib/files/view.php | 22 ++++----- tests/lib/filesystem.php | 110 ----------------------------------------- 3 files changed, 120 insertions(+), 122 deletions(-) create mode 100644 tests/lib/files/filesystem.php delete mode 100644 tests/lib/filesystem.php diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php new file mode 100644 index 00000000000..363426511bd --- /dev/null +++ b/tests/lib/files/filesystem.php @@ -0,0 +1,110 @@ +. + * + */ + +namespace Test\Files; + +class Filesystem extends \PHPUnit_Framework_TestCase { + /** + * @var array tmpDirs + */ + private $tmpDirs=array(); + + /** + * @return array + */ + private function getStorageData() { + $dir = \OC_Helper::tmpFolder(); + $this->tmpDirs[] = $dir; + return array('datadir' => $dir); + } + + public function tearDown() { + foreach ($this->tmpDirs as $dir) { + \OC_Helper::rmdirr($dir); + } + } + + public function setUp() { + \OC\Files\Filesystem::clearMounts(); + } + + public function testMount() { + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); + $this->assertEquals('',$internalPath); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEquals('some/folder',$internalPath); + + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/folder')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/')); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEquals('folder',$internalPath); + } + + public function testNormalize() { + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('/path/')); + $this->assertEquals('/path/', \OC\Files\Filesystem::normalizePath('/path/', false)); + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('path')); + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('\path')); + $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo//bar/')); + $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo////bar')); + if (class_exists('Normalizer')) { + $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("/foo/baru\xCC\x88")); + } + } + + public function testHooks() { + if(\OC\Files\Filesystem::getView()){ + $user = \OC_User::getUser(); + }else{ + $user=uniqid(); + \OC\Files\Filesystem::init('/'.$user.'/files'); + } + \OC_Hook::clear('OC_Filesystem'); + \OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); + + \OC\Files\Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); + + $rootView=new \OC\Files\View(''); + $rootView->mkdir('/'.$user); + $rootView->mkdir('/'.$user.'/files'); + + \OC\Files\Filesystem::file_put_contents('/foo', 'foo'); + \OC\Files\Filesystem::mkdir('/bar'); + \OC\Files\Filesystem::file_put_contents('/bar//foo', 'foo'); + + $tmpFile = \OC_Helper::tmpFile(); + file_put_contents($tmpFile, 'foo'); + $fh = fopen($tmpFile, 'r'); + \OC\Files\Filesystem::file_put_contents('/bar//foo', $fh); + } + + public function dummyHook($arguments) { + $path = $arguments['path']; + $this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + } +} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index fc872ea5e27..980c5298fb4 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -7,8 +7,6 @@ namespace Test\Files; -use \OC\Files\Filesystem as Filesystem; - class View extends \PHPUnit_Framework_TestCase { /** * @var \OC\Files\Storage\Storage[] $storages; @@ -16,7 +14,7 @@ class View extends \PHPUnit_Framework_TestCase { private $storages = array(); public function setUp() { - Filesystem::clearMounts(); + \OC\Files\Filesystem::clearMounts(); } public function tearDown() { @@ -30,9 +28,9 @@ class View extends \PHPUnit_Framework_TestCase { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $storageSize = $textSize * 2 + $imageSize; @@ -84,8 +82,8 @@ class View extends \PHPUnit_Framework_TestCase { public function testAutoScan() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(false); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); $rootView = new \OC\Files\View(''); @@ -103,9 +101,9 @@ class View extends \PHPUnit_Framework_TestCase { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); $rootView = new \OC\Files\View(''); @@ -113,7 +111,7 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(6, count($results)); $paths = array(); foreach ($results as $result) { - $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $this->assertEquals($result['path'], \OC\Files\Filesystem::normalizePath($result['path'])); $paths[] = $result['path']; } $this->assertContains('/foo.txt', $paths); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php deleted file mode 100644 index 6e7b4fb781f..00000000000 --- a/tests/lib/filesystem.php +++ /dev/null @@ -1,110 +0,0 @@ -. - * - */ - -use \OC\Files\Filesystem as Filesystem; - -class Test_Filesystem extends UnitTestCase { - /** - * @var array tmpDirs - */ - private $tmpDirs=array(); - - /** - * @return array - */ - private function getStorageData() { - $dir = OC_Helper::tmpFolder(); - $this->tmpDirs[] = $dir; - return array('datadir' => $dir); - } - - public function tearDown() { - foreach ($this->tmpDirs as $dir) { - OC_Helper::rmdirr($dir); - } - } - - public function setUp() { - Filesystem::clearMounts(); - } - - public function testMount() { - Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); - $this->assertEqual('/',Filesystem::getMountPoint('/')); - $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); - $this->assertEqual('',$internalPath); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); - $this->assertEqual('some/folder',$internalPath); - - Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); - $this->assertEqual('/',Filesystem::getMountPoint('/')); - $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); - $this->assertEqual('/',Filesystem::getMountPoint('/some')); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); - $this->assertEqual('folder',$internalPath); - } - - public function testNormalize() { - $this->assertEqual('/path', Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', Filesystem::normalizePath('path')); - $this->assertEqual('/path', Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo////bar')); - if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", Filesystem::normalizePath("/foo/baru\xCC\x88")); - } - } - - public function testHooks() { - if(Filesystem::getView()){ - $user = OC_User::getUser(); - }else{ - $user=uniqid(); - Filesystem::init('/'.$user.'/files'); - } - OC_Hook::clear('OC_Filesystem'); - OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); - - Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); - - $rootView=new \OC\Files\View(''); - $rootView->mkdir('/'.$user); - $rootView->mkdir('/'.$user.'/files'); - - Filesystem::file_put_contents('/foo', 'foo'); - Filesystem::mkdir('/bar'); - Filesystem::file_put_contents('/bar//foo', 'foo'); - - $tmpFile = OC_Helper::tmpFile(); - file_put_contents($tmpFile, 'foo'); - $fh = fopen($tmpFile, 'r'); - Filesystem::file_put_contents('/bar//foo', $fh); - } - - public function dummyHook($arguments) { - $path = $arguments['path']; - $this->assertEqual($path, Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized - } -} -- cgit v1.2.3 From c22a723785f80671548b89c543e9163c2fff9264 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 19:07:29 +0200 Subject: add file permissions cache --- db_structure.xml | 47 +++++++++++++++++++ lib/files/cache/permissions.php | 85 +++++++++++++++++++++++++++++++++++ lib/util.php | 2 +- tests/lib/files/cache/permissions.php | 47 +++++++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 lib/files/cache/permissions.php create mode 100644 tests/lib/files/cache/permissions.php diff --git a/db_structure.xml b/db_structure.xml index e0b9dc11e94..e420a9f0e44 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -175,6 +175,53 @@
+ + + *dbprefix*permissions + + + + + fileid + integer + 0 + true + 4 + + + + user + text + + true + 64 + + + + permissions + integer + 0 + true + 4 + + + + id_user_index + true + + fileid + ascending + + + user + ascending + + + + + +
+ *dbprefix*group_user diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php new file mode 100644 index 00000000000..e3fa63c464a --- /dev/null +++ b/lib/files/cache/permissions.php @@ -0,0 +1,85 @@ + + * 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 { + /** + * get the permissions for a single file + * + * @param int $fileId + * @param string $user + * @return int (-1 if file no permissions set) + */ + static 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 + */ + static 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[] + */ + static public function getMultiple($fileIds, $user) { + $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 + */ + static public function remove($fileId, $user) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + $query->execute(array($fileId, $user)); + } + + static public function removeMultiple($fileIds, $user) { + $params = $fileIds; + $params[] = $user; + $inPart = implode(', ', array_fill(0, count($fileIds), '?')); + + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + $query->execute($params); + } +} diff --git a/lib/util.php b/lib/util.php index 137766d0129..a2e0422c97f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -86,7 +86,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,00); + return array(4,91,01); } /** diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php new file mode 100644 index 00000000000..4d47929a3ee --- /dev/null +++ b/tests/lib/files/cache/permissions.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Permissions extends \PHPUnit_Framework_TestCase { + function testSimple() { + $ids = range(1, 10); + $user = uniqid(); + + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::set(1, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + + \OC\Files\Cache\Permissions::set(1, $user, 2); + $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + + \OC\Files\Cache\Permissions::set(2, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + \OC\Files\Cache\Permissions::remove(1, $user); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::remove(1, $user . '2'); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + $expected = array(); + foreach ($ids as $id) { + \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $expected[$id] = 10 + $id; + } + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + unset($expected[9]); + unset($expected[10]); + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + } +} -- cgit v1.2.3 From 6db81afab9d68ccd50c1e164622252e47ae76c2f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:05:02 +0200 Subject: move some stuff to the new api --- apps/files/ajax/list.php | 2 +- apps/files/ajax/newfile.php | 12 ++++++------ apps/files/ajax/newfolder.php | 3 ++- apps/files/ajax/rawlist.php | 2 +- apps/files/ajax/upload.php | 2 +- apps/files/index.php | 2 +- apps/files/settings.php | 2 +- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 10 +++++----- apps/files_sharing/appinfo/update.php | 3 ++- lib/connector/sabre/directory.php | 6 +++--- lib/connector/sabre/node.php | 4 ++-- lib/fileproxy/quota.php | 12 ++++-------- lib/files.php | 2 +- lib/files/filesystem.php | 13 +++++++++++++ lib/files/view.php | 1 - lib/ocs.php | 4 ++-- lib/public/share.php | 15 +++++++++------ lib/search/provider/file.php | 2 +- settings/personal.php | 4 ++-- 20 files changed, 58 insertions(+), 45 deletions(-) diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 568fe754c02..92091f42135 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -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; } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 5f3f3d88f27..38714f34a63 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -65,9 +65,9 @@ if($source) { $target=$dir.'/'.$filename; $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); if($result) { - $meta = OC_FileCache::get($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $mime=$meta['mimetype']; - $id = OC_FileCache::getId($target); + $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,14 +77,14 @@ if($source) { } else { if($content) { if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } }elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index c36c2084551..e26e1238bc6 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -25,7 +25,8 @@ if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($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(); } diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index e0aa0bdac52..1cd2944483c 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -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; diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index b6b8c7f7b46..2a784d61691 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -49,7 +49,7 @@ if(strpos($dir, '..') === false) { for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { - $meta = \OC_Files::getFileInfo($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $id = $meta['fileid']; $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); } diff --git a/apps/files/index.php b/apps/files/index.php index 192cd2696f2..4676ebc6021 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -44,7 +44,7 @@ if(!\OC\Files\Filesystem::is_dir($dir.'/')) { } $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i['date'] = OCP\Util::formatDate($i['mtime'] ); if($i['type']=='file') { $fileinfo=pathinfo($i['name']); diff --git a/apps/files/settings.php b/apps/files/settings.php index 52ec9fd0fe3..30463210f71 100644 --- a/apps/files/settings.php +++ b/apps/files/settings.php @@ -36,7 +36,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; } diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index e98013e1f42..c4298382646 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -167,7 +167,7 @@ class OC_CryptStream{ public function stream_close() { $this->flush(); if($this->meta['mode']!='r' and $this->meta['mode']!='rb') { - OC_FileCache::put($this->path, array('encrypted'=>true,'size'=>$this->size),''); + \OC\Files\Filesystem::putFileInfo($this->path, array('encrypted'=>true,'size'=>$this->size),''); } return fclose($this->source); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7b7bafe73eb..49fb30ac291 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -59,7 +59,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ * @return bool */ private static function isEncrypted($path) { - $metadata=OC_FileCache_Cached::get($path,''); + $metadata=\OC\Files\Filesystem::getFileInfo($path,''); return isset($metadata['encrypted']) and (bool)$metadata['encrypted']; } @@ -68,14 +68,14 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ if (!is_resource($data)) {//stream put contents should have been converter to fopen $size=strlen($data); $data=OC_Crypt::blockEncrypt($data); - OC_FileCache::put($path, array('encrypted'=>true,'size'=>$size),''); + \OC\Files\Filesystem::putFileInfo($path, array('encrypted'=>true,'size'=>$size),''); } } } public function postFile_get_contents($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data=OC_Crypt::blockDecrypt($data,'',$cached['size']); } return $data; @@ -113,7 +113,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postStat($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data['size']=$cached['size']; } return $data; @@ -121,7 +121,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postFileSize($path,$size) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); return $cached['size']; }else{ return $size; diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index e75c538b150..51048bd178c 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -10,6 +10,7 @@ if (version_compare($installedVersion, '0.3', '<')) { OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); while ($row = $result->fetchRow()) { + $meta = \OC\Files\Filesystem::getId($path, ''); $itemSource = OC_FileCache::getId($row['source'], ''); if ($itemSource != -1) { $file = OC_FileCache::get($row['source'], ''); @@ -70,4 +71,4 @@ if (version_compare($installedVersion, '0.3.3', '<')) { foreach ($users as $user) { OC_FileCache::delete('Shared', '/'.$user.'/files/'); } -} \ No newline at end of file +} diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 3df85b2bbbe..d4f58527d21 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -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) { @@ -117,7 +117,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ 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']; @@ -178,7 +178,7 @@ 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\Files\Filesystem::free_space() diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index e7e83507ea2..2095c956e5f 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -95,11 +95,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * Make sure the fileinfo cache is filled. Uses OC_FileCache or a direct stat + * Make sure the fileinfo cache is filled. Uses the file cache or a direct stat */ protected function getFileinfoCache() { if (!isset($this->fileinfo_cache)) { - if ($fileinfo_cache = \OC\Files\Filesystem::get($this->path)) { + if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) { } else { $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index d120f309998..cd9a2f4a192 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -57,7 +57,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ * @return int */ private function getFreeSpace($path) { - $storage=OC_Filesystem::getStorage($path); + list($storage,)=\OC\Files\Filesystem::resolvePath($path); $owner=$storage->getOwner($path); $totalSpace=$this->getQuota($owner); @@ -65,13 +65,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ return 0; } - $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; diff --git a/lib/files.php b/lib/files.php index 422e7f4ffe7..6a063f216d5 100644 --- a/lib/files.php +++ b/lib/files.php @@ -146,7 +146,7 @@ class OC_Files { $dirname = basename($dir); $zip->addEmptyDir($internalDir . $dirname); $internalDir .= $dirname .= '/'; - $files = OC_Files::getdirectorycontent($dir); + $files = \OC\Files\Filesystem::getDirectoryContent($dir); foreach ($files as $file) { $filename = $file['name']; $file = $dir . '/' . $filename; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4031c0c5b80..b3c92f38558 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -627,6 +627,19 @@ class Filesystem { 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 * diff --git a/lib/files/view.php b/lib/files/view.php index ee95cce0c1d..e9b583f8ae6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -451,7 +451,6 @@ class View { array(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); Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; diff --git a/lib/ocs.php b/lib/ocs.php index 645380ddba8..c6bcd2c06e1 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -590,8 +590,8 @@ class OC_OCS { // calculate the disc space $user_dir = '/'.$user.'/files'; \OC\Files\Filesystem::init($user_dir); - $rootInfo=OC_FileCache::get(''); - $sharedInfo=OC_FileCache::get('/Shared'); + $rootInfo=\OC\Files\Filesystem::getFileInfo(''); + $sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; diff --git a/lib/public/share.php b/lib/public/share.php index 7a9a087d1bd..dd6c841c99d 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -285,10 +285,10 @@ class Share { // If the item is a folder, scan through the folder looking for equivalent item types if ($itemType == 'folder') { $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); - if ($parentFolder && $files = \OC_Files::getDirectoryContent($itemSource)) { + if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { for ($i = 0; $i < count($files); $i++) { $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC_Files::getDirectoryContent($name, '/')) { + if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/')) { // Continue scanning into child folders array_push($files, $children); } else { @@ -768,9 +768,10 @@ class Share { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { - $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); + $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); + $childItem['file_source'] = $meta['fileid']; } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { @@ -881,7 +882,8 @@ class Share { if ($itemType == 'file' || $itemType == 'folder') { $fileSource = $itemSource; } else { - $fileSource = \OC_FileCache::getId($filePath); + $meta = \OC\Files\Filesystem::getFileInfo($filePath); + $fileSource = $meta['fileid']; } if ($fileSource == -1) { $message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache'; @@ -1063,7 +1065,8 @@ class Share { } if ($item['uid_owner'] == $uidOwner) { if ($itemType == 'file' || $itemType == 'folder') { - if ($item['file_source'] == \OC_FileCache::getId($itemSource)) { + $meta = \OC\Files\Filesystem::getFileInfo($itemSource); + if ($item['file_source'] == $meta['fileid']) { return $target; } } else if ($item['item_source'] == $itemSource) { diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php index 0d4b332b792..456e12b5ec2 100644 --- a/lib/search/provider/file.php +++ b/lib/search/provider/file.php @@ -2,7 +2,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{ function search($query) { - $files=OC_FileCache::search($query, true); + $files=\OC\Files\Filesystem::search($query, true); $results=array(); $l=OC_L10N::get('lib'); foreach($files as $fileData) { diff --git a/settings/personal.php b/settings/personal.php index c73a3dd3701..5a267ec2844 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -16,8 +16,8 @@ OC_Util::addStyle( '3rdparty', 'chosen' ); OC_App::setActiveNavigationEntry( 'personal' ); // calculate the disc space -$rootInfo=OC_FileCache::get(''); -$sharedInfo=OC_FileCache::get('/Shared'); +$rootInfo=\OC\Files\Filesystem::getFileInfo(''); +$sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']; if($used<0) $used=0; $free=\OC\Files\Filesystem::free_space(); -- cgit v1.2.3 From 7d6da68d532fe1b1299f3a724e70b8ec3960ec8d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:25:52 +0200 Subject: prove some compatibility with the old cache api --- lib/files/view.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index e9b583f8ae6..04b7dca8afc 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -712,7 +712,7 @@ class View { $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($path); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); @@ -733,6 +733,10 @@ class View { } } + foreach($files as $i => $file){ + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + } + usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } -- cgit v1.2.3 From 99534271977ef5a4fd35ce119d6627bbcde45096 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:26:12 +0200 Subject: also use new cache api here --- lib/fileproxy/fileoperations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fileproxy/fileoperations.php b/lib/fileproxy/fileoperations.php index 23fb63fcfb1..47ccd8f8c26 100644 --- a/lib/fileproxy/fileoperations.php +++ b/lib/fileproxy/fileoperations.php @@ -29,9 +29,9 @@ class OC_FileProxy_FileOperations extends OC_FileProxy{ public function premkdir($path) { if(!self::$rootView){ - self::$rootView = new OC_FilesystemView(''); + self::$rootView = new \OC\Files\View(''); } return !self::$rootView->file_exists($path); } -} \ No newline at end of file +} -- cgit v1.2.3 From 695405dfeb4da3733df1b1be239a97100f2ce66f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:01:20 +0200 Subject: add permissions data to the results of the cache api --- lib/files/cache/cache.php | 15 +++++++++++++++ lib/files/cache/scanner.php | 3 ++- lib/files/view.php | 12 +++++++++++- tests/lib/files/cache/scanner.php | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7e0c5cb21f9..5efc7d67c4a 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -286,4 +286,19 @@ class Cache { } return $files; } + + /** + * 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->storageId)); + $ids = array(); + while ($row = $result->fetchRow()) { + $ids[] = $row['fileid']; + } + return $ids; + } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8f54c34be7..0adde1d354d 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -66,7 +66,8 @@ class Scanner { $this->scanFile($parent); } } - $this->cache->put($file, $data); + $id = $this->cache->put($file, $data); + Permissions::set($id, \OC_User::getUser(), $data['permissions']); return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 04b7dca8afc..82455d582eb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -686,6 +686,8 @@ class View { } } + $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + return $data; } @@ -733,8 +735,16 @@ class View { } } - foreach($files as $i => $file){ + $ids = array(); + + foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + + $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; } usort($files, "fileCmp"); //TODO: remove this once ajax is merged diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index e3f47047f54..34fefc784d4 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -106,6 +106,8 @@ class Scanner extends \UnitTestCase { } function tearDown() { + $ids = $this->cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } -- cgit v1.2.3 From fcc92a9f43e75ecdb15adb0e948d45eac119306f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:34:25 +0200 Subject: add searchByMime to new cache api --- lib/files/cache/cache.php | 21 +++++++++++++++++++++ lib/files/filesystem.php | 4 ++++ lib/files/view.php | 25 ++++++++++++++++++++++--- tests/lib/files/cache/cache.php | 3 +++ tests/lib/files/view.php | 3 +++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5efc7d67c4a..6604525477b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -287,6 +287,27 @@ class Cache { return $files; } + /** + * 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` = ?'; + } + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' + ); + $result = $query->execute(array($mimetype, $this->storageId)); + return $result->fetchAll(); + } + /** * get all file ids on the files on the storage * diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b3c92f38558..96660a8ce30 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -551,6 +551,10 @@ class Filesystem { 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 * diff --git a/lib/files/view.php b/lib/files/view.php index 82455d582eb..0a5a6436c27 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -747,7 +747,7 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); //TODO: remove this once ajax is merged + usort($files, "fileCmp"); return $files; } @@ -784,6 +784,25 @@ class View { * @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); @@ -791,7 +810,7 @@ class View { $storage = Filesystem::getStorage($mountPoint); $cache = $storage->getCache(); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { $result['path'] = substr($mountPoint . $result['path'], $rootLength); @@ -805,7 +824,7 @@ class View { $cache = $storage->getCache(); $relativeMountPoint = substr($mountPoint, $rootLength); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { $result['path'] = $relativeMountPoint . $result['path']; $files[] = $result; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 839e06e93fc..5a8d79b902c 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -129,6 +129,9 @@ class Cache extends \UnitTestCase { $this->assertEquals(1, count($this->cache->search('%folder%'))); $this->assertEquals(1, count($this->cache->search('folder%'))); $this->assertEquals(3, count($this->cache->search('%'))); + + $this->assertEquals(3, count($this->cache->searchByMime('foo'))); + $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } public function tearDown() { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 980c5298fb4..5144fb1caad 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -139,6 +139,9 @@ class View extends \PHPUnit_Framework_TestCase { } $this->assertContains('/anotherstorage/foo.txt', $paths); $this->assertContains('/anotherstorage/foo.png', $paths); + + $this->assertEquals(6, count($rootView->searchByMime('text'))); + $this->assertEquals(3, count($folderView->searchByMime('text'))); } /** -- cgit v1.2.3 From 3437071cf1776288d9239a89b1a6ceb9c5ddbce1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:40:27 +0200 Subject: remove old searchByMime --- lib/files.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/lib/files.php b/lib/files.php index 6a063f216d5..28df2255809 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,24 +28,6 @@ class OC_Files { static $tmpFiles = array(); - 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 * -- cgit v1.2.3 From 5bfff6c56e8d4d911c7a5265bb5462c7122ca495 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:17:35 +0200 Subject: use absolute paths when resolving mount points --- lib/files.php | 10 ---------- lib/files/cache/permissions.php | 3 +++ lib/files/view.php | 35 ++++++++++++++++++++++++++--------- lib/public/share.php | 4 ++-- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/files.php b/lib/files.php index 28df2255809..e6b324f062b 100644 --- a/lib/files.php +++ b/lib/files.php @@ -249,13 +249,3 @@ class OC_Files { return false; } } - -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']); - } -} diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index e3fa63c464a..dd7233abc70 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -50,6 +50,9 @@ class Permissions { * @return int[] */ static public function getMultiple($fileIds, $user) { + if (count($fileIds) === 0) { + return array(); + } $params = $fileIds; $params[] = $user; $inPart = implode(', ', array_fill(0, count($fileIds), '?')); diff --git a/lib/files/view.php b/lib/files/view.php index 0a5a6436c27..0f9a5feb5dd 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,6 +110,7 @@ class View { */ 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); @@ -124,6 +125,7 @@ class View { */ 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); @@ -334,8 +336,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +347,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +419,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -552,7 +554,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -587,7 +589,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -747,8 +749,23 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); - return $files; + 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; } /** diff --git a/lib/public/share.php b/lib/public/share.php index 060f67c9e91..707d5abe440 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -534,7 +534,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -621,7 +621,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } -- cgit v1.2.3 From dea0d20a9ad0270896e57a7459d6276798658d7c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:18:01 +0200 Subject: fix delete and sort files --- apps/files/ajax/delete.php | 19 ++++++++----------- apps/files/ajax/scan.php | 2 ++ apps/files/index.php | 12 ++++++++++++ apps/files_sharing/public.php | 4 ++-- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index ae6158a05aa..fdd0c0c491d 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -12,18 +12,15 @@ $files = isset($_POST["file"]) ? stripslashes($_POST["file"]) : stripslashes($_P $files = explode(';', $files); $filesWithError = ''; -if (OC_User::isLoggedIn()) { - $success = true; - - //Now delete - foreach ($files as $file) { - if ($dir != '' || $file != 'Shared' && !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { - $filesWithError .= $file . "\n"; - $success = false; - } + +$success = true; + +//Now delete +foreach ($files as $file) { + if (($dir === '' && $file === 'Shared') || !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { + $filesWithError .= $file . "\n"; + $success = false; } -} else { - $success = false; } if ($success) { diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 5cd9572d7f9..91b20fa8362 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -1,5 +1,7 @@ assign('uidOwner', $uidOwner); $tmpl->assign('dir', basename($dir)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($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']; @@ -200,7 +200,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', dirname($path)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($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 { -- cgit v1.2.3 From 86be7e88721ada34e7b230a0e5dfb4df546bc38a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:23:13 +0200 Subject: remove last uses of depricated OC_Filesystem --- apps/files_sharing/public.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 143edd23c49..35e7734e2d0 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -24,7 +24,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]; @@ -33,7 +33,9 @@ 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; @@ -102,7 +104,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { if (isset($_GET['path'])) { $path .= $_GET['path']; $dir .= $_GET['path']; - if (!OC_Filesystem::file_exists($path)) { + if (!\OC\Files\Filesystem::file_exists($path)) { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -130,7 +132,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('owner', $uidOwner); // 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'); -- cgit v1.2.3 From 0fb707d2c90846c1231cdefac79e9b58c8351c81 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 14:25:15 +0200 Subject: some more porting of the sharing --- apps/files_sharing/appinfo/update.php | 9 +++++---- apps/files_sharing/public.php | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index 51048bd178c..69c526eae0f 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -9,11 +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()) { - $meta = \OC\Files\Filesystem::getId($path, ''); - $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 { @@ -69,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/'); } } diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 35e7734e2d0..1fe73110024 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -10,7 +10,8 @@ if (isset($_GET['token'])) { $qry = \OC_DB::prepare('SELECT `source` FROM `*PREFIX*sharing` WHERE `target` = ? LIMIT 1'); $filepath = $qry->execute(array($_GET['token']))->fetchOne(); if(isset($filepath)) { - $info = OC_FileCache_Cached::get($filepath, ''); + $rootView = new \OC\Files\View(''); + $info = $rootView->getFileInfo($filepath, ''); if(strtolower($info['mimetype']) == 'httpd/unix-directory') { $_GET['dir'] = $filepath; } else { -- cgit v1.2.3 From 7891add28655c7f39b388ac0a889b246b23ad934 Mon Sep 17 00:00:00 2001 From: Björn Schießle Date: Sat, 27 Oct 2012 15:26:28 +0200 Subject: don't call $('#found_versions').chosen(); after opening the history drop-down since no version is selected at the beginning --- apps/files_versions/js/versions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 426d521df82..b9c54689813 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -73,7 +73,6 @@ function createVersionsDropdown(filename, files) { $.each( versions, function(index, row ) { addVersion( row ); }); - $('#found_versions').chosen(); } else { $('#found_versions').hide(); $('#makelink').hide(); -- cgit v1.2.3 From 72aebe3aa3ce51ef47ef6005b528c4d296e208c6 Mon Sep 17 00:00:00 2001 From: Björn Schießle Date: Sat, 27 Oct 2012 15:24:01 +0200 Subject: fix broken paths in versions app --- apps/files_versions/lib/versions.php | 41 +++++++++++++++++------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 47e514d9d7e..e83310172af 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -58,10 +58,8 @@ class Storage { public function store($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - - $userHome = \OC_User::getHome($uid); - $files_view = new \OC\Files\View($userHome.'/files'); - $users_view = new \OC\Files\View($userHome); + $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? @@ -96,11 +94,12 @@ class Storage { // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { - $versions_fileview = new \OC\Files\View($userHome.'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); - $matches=glob($versionsFolderName.'/'.$filename.'.v*'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); + $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath(''); + $matches=glob($versionsName.'.v*'); sort($matches); - $parts=explode('.v', end($matches)); + $parts=explode('.v',end($matches)); if((end($parts)+Storage::DEFAULTMININTERVAL)>time()) { return false; } @@ -110,7 +109,7 @@ class Storage { // create all parent folders $info=pathinfo($filename); if(!file_exists($versionsFolderName.'/'.$info['dirname'])) { - mkdir($versionsFolderName.'/'.$info['dirname'],0750, true); + mkdir($versionsFolderName.'/'.$info['dirname'],0750,true); } // store a new version of a file @@ -129,7 +128,7 @@ class Storage { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $users_view = new \OC\Files\View(\OC_User::getHome($uid)); + $users_view = new \OC\Files\View('/'.\OCP\User::getUser()); // rollback if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) { @@ -152,12 +151,12 @@ class Storage { public static function isversioned($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC\Files\View(\OC_User::getHome($uid).'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); // check for old versions - $matches=glob($versionsFolderName.$filename.'.v*'); + $matches=glob($versionsName.'.v*'); if(count($matches)>0) { return true; }else{ @@ -177,22 +176,20 @@ class Storage { * @returns array */ 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\Files\View(\OC_User::getHome($uid).'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); - $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); $versions = array(); - // fetch for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); + $matches = glob( $versionsName.'.v*' ); sort( $matches ); $i = 0; - $files_view = new \OC\Files\View(\OC_User::getHome($uid).'/files'); + $files_view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { @@ -249,10 +246,10 @@ class Storage { list($uid, $filename) = self::getUidAndFilename($filename); $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); // check for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); + $matches = glob( $versionsName.'.v*' ); if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) { @@ -263,7 +260,7 @@ class Storage { foreach( $deleteItems as $de ) { - unlink( $versionsFolderName.'/'.$filename.'.v'.$de ); + unlink( $versionsName.'.v'.$de ); } } -- cgit v1.2.3 From 0d3f68cc7a425410e498e9946ab9847348dcdc55 Mon Sep 17 00:00:00 2001 From: Björn Schießle Date: Sat, 27 Oct 2012 15:23:35 +0200 Subject: fix function documentation --- lib/user.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/user.php b/lib/user.php index 064fcbad96f..869984a16eb 100644 --- a/lib/user.php +++ b/lib/user.php @@ -369,8 +369,7 @@ class OC_User { * @param $password The password * @returns string * - * Check if the password is correct without logging in the user - * returns the user id or false + * returns the path to the users home directory */ public static function getHome($uid) { foreach(self::$_usedBackends as $backend) { -- cgit v1.2.3 From 2dc1b778b47c7a765b1c4b56aa928c74f7116946 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 27 Oct 2012 16:24:24 +0200 Subject: Include copy of Symfony routing component, and don't use composer --- .gitignore | 4 - 3rdparty/bin/composer | Bin 631359 -> 0 bytes .../Symfony/Component/Routing/Annotation/Route.php | 103 +++++++ .../Symfony/Component/Routing/CompiledRoute.php | 134 +++++++++ .../Routing/Exception/ExceptionInterface.php | 23 ++ .../Exception/InvalidParameterException.php | 23 ++ .../Exception/MethodNotAllowedException.php | 38 +++ .../MissingMandatoryParametersException.php | 24 ++ .../Exception/ResourceNotFoundException.php | 25 ++ .../Routing/Exception/RouteNotFoundException.php | 23 ++ .../Routing/Generator/Dumper/GeneratorDumper.php | 39 +++ .../Generator/Dumper/GeneratorDumperInterface.php | 45 +++ .../Generator/Dumper/PhpGeneratorDumper.php | 150 ++++++++++ .../Component/Routing/Generator/UrlGenerator.php | 176 ++++++++++++ .../Routing/Generator/UrlGeneratorInterface.php | 37 +++ .../routing/Symfony/Component/Routing/LICENSE | 19 ++ .../Routing/Loader/AnnotationClassLoader.php | 213 ++++++++++++++ .../Routing/Loader/AnnotationDirectoryLoader.php | 77 +++++ .../Routing/Loader/AnnotationFileLoader.php | 125 +++++++++ .../Component/Routing/Loader/ClosureLoader.php | 54 ++++ .../Component/Routing/Loader/PhpFileLoader.php | 64 +++++ .../Component/Routing/Loader/XmlFileLoader.php | 224 +++++++++++++++ .../Component/Routing/Loader/YamlFileLoader.php | 142 ++++++++++ .../Routing/Loader/schema/routing/routing-1.0.xsd | 38 +++ .../Component/Routing/Matcher/ApacheUrlMatcher.php | 76 +++++ .../Routing/Matcher/Dumper/ApacheMatcherDumper.php | 155 ++++++++++ .../Routing/Matcher/Dumper/MatcherDumper.php | 44 +++ .../Matcher/Dumper/MatcherDumperInterface.php | 41 +++ .../Routing/Matcher/Dumper/PhpMatcherDumper.php | 293 +++++++++++++++++++ .../Routing/Matcher/RedirectableUrlMatcher.php | 53 ++++ .../Matcher/RedirectableUrlMatcherInterface.php | 35 +++ .../Component/Routing/Matcher/UrlMatcher.php | 151 ++++++++++ .../Routing/Matcher/UrlMatcherInterface.php | 38 +++ .../routing/Symfony/Component/Routing/README.md | 32 +++ .../Symfony/Component/Routing/RequestContext.php | 250 +++++++++++++++++ .../Routing/RequestContextAwareInterface.php | 27 ++ .../routing/Symfony/Component/Routing/Route.php | 312 +++++++++++++++++++++ .../Symfony/Component/Routing/RouteCollection.php | 259 +++++++++++++++++ .../Symfony/Component/Routing/RouteCompiler.php | 128 +++++++++ .../Component/Routing/RouteCompilerInterface.php | 29 ++ .../routing/Symfony/Component/Routing/Router.php | 263 +++++++++++++++++ .../Symfony/Component/Routing/RouterInterface.php | 26 ++ .../Symfony/Component/Routing/composer.json | 29 ++ composer.json | 18 -- 44 files changed, 4037 insertions(+), 22 deletions(-) delete mode 100755 3rdparty/bin/composer create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/README.md create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Route.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Router.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/composer.json delete mode 100644 composer.json diff --git a/.gitignore b/.gitignore index 4ae39ed7fac..4749dea19dc 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,3 @@ nbproject # WebFinger .well-known /.buildpath -3rdparty/autoload.php -3rdparty/composer/ -3rdparty/symfony/ -composer.lock diff --git a/3rdparty/bin/composer b/3rdparty/bin/composer deleted file mode 100755 index 7999bd4ff68..00000000000 Binary files a/3rdparty/bin/composer and /dev/null differ diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php new file mode 100644 index 00000000000..f60af463f2c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Annotation; + +/** + * Annotation class for @Route(). + * + * @Annotation + * + * @author Fabien Potencier + */ +class Route +{ + private $pattern; + private $name; + private $requirements; + private $options; + private $defaults; + + /** + * Constructor. + * + * @param array $data An array of key/value parameters. + */ + public function __construct(array $data) + { + $this->requirements = array(); + $this->options = array(); + $this->defaults = array(); + + if (isset($data['value'])) { + $data['pattern'] = $data['value']; + unset($data['value']); + } + + foreach ($data as $key => $value) { + $method = 'set'.$key; + if (!method_exists($this, $method)) { + throw new \BadMethodCallException(sprintf("Unknown property '%s' on annotation '%s'.", $key, get_class($this))); + } + $this->$method($value); + } + } + + public function setPattern($pattern) + { + $this->pattern = $pattern; + } + + public function getPattern() + { + return $this->pattern; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getName() + { + return $this->name; + } + + public function setRequirements($requirements) + { + $this->requirements = $requirements; + } + + public function getRequirements() + { + return $this->requirements; + } + + public function setOptions($options) + { + $this->options = $options; + } + + public function getOptions() + { + return $this->options; + } + + public function setDefaults($defaults) + { + $this->defaults = $defaults; + } + + public function getDefaults() + { + return $this->defaults; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php b/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php new file mode 100644 index 00000000000..c86c9eca5b2 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * CompiledRoutes are returned by the RouteCompiler class. + * + * @author Fabien Potencier + */ +class CompiledRoute +{ + private $route; + private $variables; + private $tokens; + private $staticPrefix; + private $regex; + + /** + * Constructor. + * + * @param Route $route A original Route instance + * @param string $staticPrefix The static prefix of the compiled route + * @param string $regex The regular expression to use to match this route + * @param array $tokens An array of tokens to use to generate URL for this route + * @param array $variables An array of variables + */ + public function __construct(Route $route, $staticPrefix, $regex, array $tokens, array $variables) + { + $this->route = $route; + $this->staticPrefix = $staticPrefix; + $this->regex = $regex; + $this->tokens = $tokens; + $this->variables = $variables; + } + + /** + * Returns the Route instance. + * + * @return Route A Route instance + */ + public function getRoute() + { + return $this->route; + } + + /** + * Returns the static prefix. + * + * @return string The static prefix + */ + public function getStaticPrefix() + { + return $this->staticPrefix; + } + + /** + * Returns the regex. + * + * @return string The regex + */ + public function getRegex() + { + return $this->regex; + } + + /** + * Returns the tokens. + * + * @return array The tokens + */ + public function getTokens() + { + return $this->tokens; + } + + /** + * Returns the variables. + * + * @return array The variables + */ + public function getVariables() + { + return $this->variables; + } + + /** + * Returns the pattern. + * + * @return string The pattern + */ + public function getPattern() + { + return $this->route->getPattern(); + } + + /** + * Returns the options. + * + * @return array The options + */ + public function getOptions() + { + return $this->route->getOptions(); + } + + /** + * Returns the defaults. + * + * @return array The defaults + */ + public function getDefaults() + { + return $this->route->getDefaults(); + } + + /** + * Returns the requirements. + * + * @return array The requirements + */ + public function getRequirements() + { + return $this->route->getRequirements(); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php new file mode 100644 index 00000000000..5289f525fcd --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * ExceptionInterface + * + * @author Alexandre Salomé + * + * @api + */ +interface ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php new file mode 100644 index 00000000000..4f12469529d --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a parameter is not valid + * + * @author Alexandre Salomé + * + * @api + */ +class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php new file mode 100644 index 00000000000..470ce52216e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * The resource was found but the request method is not allowed. + * + * This exception should trigger an HTTP 405 response in your application code. + * + * @author Kris Wallsmith + * + * @api + */ +class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface +{ + protected $allowedMethods; + + public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null) + { + $this->allowedMethods = array_map('strtoupper', $allowedMethods); + + parent::__construct($message, $code, $previous); + } + + public function getAllowedMethods() + { + return $this->allowedMethods; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php new file mode 100644 index 00000000000..5a523fa5590 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a route cannot be generated because of missing + * mandatory parameters. + * + * @author Alexandre Salomé + * + * @api + */ +class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php new file mode 100644 index 00000000000..362a0d61f36 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * The resource was not found. + * + * This exception should trigger an HTTP 404 response in your application code. + * + * @author Kris Wallsmith + * + * @api + */ +class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php new file mode 100644 index 00000000000..4d5f288e7ed --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a route does not exists + * + * @author Alexandre Salomé + * + * @api + */ +class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php new file mode 100644 index 00000000000..1291bd12d0e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * GeneratorDumper is the base class for all built-in generator dumpers. + * + * @author Fabien Potencier + */ +abstract class GeneratorDumper implements GeneratorDumperInterface +{ + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes The RouteCollection to dump + */ + public function __construct(RouteCollection $routes) + { + $this->routes = $routes; + } + + public function getRoutes() + { + return $this->routes; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php new file mode 100644 index 00000000000..6f5353caf26 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * GeneratorDumperInterface is the interface that all generator dumper classes must implement. + * + * @author Fabien Potencier + * + * @api + */ +interface GeneratorDumperInterface +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the generator class + */ + public function dump(array $options = array()); + + /** + * Gets the routes to dump. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes(); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php new file mode 100644 index 00000000000..080dd3a2539 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\Route; + +/** + * PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class PhpGeneratorDumper extends GeneratorDumper +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the generator class + * + * @api + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'class' => 'ProjectUrlGenerator', + 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + ), $options); + + return + $this->startClass($options['class'], $options['base_class']). + $this->addConstructor(). + $this->addGenerator(). + $this->endClass() + ; + } + + private function addGenerator() + { + $methods = array(); + foreach ($this->getRoutes()->all() as $name => $route) { + $compiledRoute = $route->compile(); + + $variables = str_replace("\n", '', var_export($compiledRoute->getVariables(), true)); + $defaults = str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)); + $requirements = str_replace("\n", '', var_export($compiledRoute->getRequirements(), true)); + $tokens = str_replace("\n", '', var_export($compiledRoute->getTokens(), true)); + + $escapedName = str_replace('.', '__', $name); + + $methods[] = <<{'get'.\$escapedName.'RouteInfo'}(); + + return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute); + } + +$methods +EOF; + } + + private function startClass($class, $baseClass) + { + $routes = array(); + foreach ($this->getRoutes()->all() as $name => $route) { + $routes[] = " '$name' => true,"; + } + $routes = implode("\n", $routes); + + return <<context = \$context; + } + +EOF; + } + + private function endClass() + { + return << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Exception\InvalidParameterException; +use Symfony\Component\Routing\Exception\RouteNotFoundException; +use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; + +/** + * UrlGenerator generates URL based on a set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class UrlGenerator implements UrlGeneratorInterface +{ + protected $context; + protected $decodedChars = array( + // %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitly allowed it) + '%2F' => '/', + ); + + protected $routes; + protected $cache; + + /** + * Constructor. + * + * @param RouteCollection $routes A RouteCollection instance + * @param RequestContext $context The context + * + * @api + */ + public function __construct(RouteCollection $routes, RequestContext $context) + { + $this->routes = $routes; + $this->context = $context; + $this->cache = array(); + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + * + * @throws Symfony\Component\Routing\Exception\RouteNotFoundException When route doesn't exist + * + * @api + */ + public function generate($name, $parameters = array(), $absolute = false) + { + if (null === $route = $this->routes->get($name)) { + throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); + } + + if (!isset($this->cache[$name])) { + $this->cache[$name] = $route->compile(); + } + + return $this->doGenerate($this->cache[$name]->getVariables(), $route->getDefaults(), $route->getRequirements(), $this->cache[$name]->getTokens(), $parameters, $name, $absolute); + } + + /** + * @throws Symfony\Component\Routing\Exception\MissingMandatoryParametersException When route has some missing mandatory parameters + * @throws Symfony\Component\Routing\Exception\InvalidParameterException When a parameter value is not correct + */ + protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) + { + $variables = array_flip($variables); + + $originParameters = $parameters; + $parameters = array_replace($this->context->getParameters(), $parameters); + $tparams = array_replace($defaults, $parameters); + + // all params must be given + if ($diff = array_diff_key($variables, $tparams)) { + throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff)))); + } + + $url = ''; + $optional = true; + foreach ($tokens as $token) { + if ('variable' === $token[0]) { + if (false === $optional || !array_key_exists($token[3], $defaults) || (isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]])) { + if (!$isEmpty = in_array($tparams[$token[3]], array(null, '', false), true)) { + // check requirement + if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) { + throw new InvalidParameterException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]])); + } + } + + if (!$isEmpty || !$optional) { + $url = $token[1].strtr(rawurlencode($tparams[$token[3]]), $this->decodedChars).$url; + } + + $optional = false; + } + } elseif ('text' === $token[0]) { + $url = $token[1].$url; + $optional = false; + } + } + + if (!$url) { + $url = '/'; + } + + // add a query string if needed + $extra = array_diff_key($originParameters, $variables, $defaults); + if ($extra && $query = http_build_query($extra, '', '&')) { + $url .= '?'.$query; + } + + $url = $this->context->getBaseUrl().$url; + + if ($this->context->getHost()) { + $scheme = $this->context->getScheme(); + if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { + $absolute = true; + $scheme = $req; + } + + if ($absolute) { + $port = ''; + if ('http' === $scheme && 80 != $this->context->getHttpPort()) { + $port = ':'.$this->context->getHttpPort(); + } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { + $port = ':'.$this->context->getHttpsPort(); + } + + $url = $scheme.'://'.$this->context->getHost().$port.$url; + } + } + + return $url; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php new file mode 100644 index 00000000000..6f2800c27c1 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator; + +use Symfony\Component\Routing\RequestContextAwareInterface; + +/** + * UrlGeneratorInterface is the interface that all URL generator classes must implements. + * + * @author Fabien Potencier + * + * @api + */ +interface UrlGeneratorInterface extends RequestContextAwareInterface +{ + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + * + * @api + */ + public function generate($name, $parameters = array(), $absolute = false); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE b/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE new file mode 100644 index 00000000000..cdffe7aebc0 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php new file mode 100644 index 00000000000..5f292d4589e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Doctrine\Common\Annotations\Reader; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Config\Loader\LoaderResolver; + +/** + * AnnotationClassLoader loads routing information from a PHP class and its methods. + * + * You need to define an implementation for the getRouteDefaults() method. Most of the + * time, this method should define some PHP callable to be called for the route + * (a controller in MVC speak). + * + * The @Route annotation can be set on the class (for global parameters), + * and on each method. + * + * The @Route annotation main value is the route pattern. The annotation also + * recognizes three parameters: requirements, options, and name. The name parameter + * is mandatory. Here is an example of how you should be able to use it: + * + * /** + * * @Route("/Blog") + * * / + * class Blog + * { + * /** + * * @Route("/", name="blog_index") + * * / + * public function index() + * { + * } + * + * /** + * * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"}) + * * / + * public function show() + * { + * } + * } + * + * @author Fabien Potencier + */ +abstract class AnnotationClassLoader implements LoaderInterface +{ + protected $reader; + protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route'; + protected $defaultRouteIndex; + + /** + * Constructor. + * + * @param Reader $reader + */ + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + /** + * Sets the annotation class to read route properties from. + * + * @param string $class A fully-qualified class name + */ + public function setRouteAnnotationClass($class) + { + $this->routeAnnotationClass = $class; + } + + /** + * Loads from annotations from a class. + * + * @param string $class A class name + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When route can't be parsed + */ + public function load($class, $type = null) + { + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + $globals = array( + 'pattern' => '', + 'requirements' => array(), + 'options' => array(), + 'defaults' => array(), + ); + + $class = new \ReflectionClass($class); + if ($class->isAbstract()) { + throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class)); + } + + if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { + if (null !== $annot->getPattern()) { + $globals['pattern'] = $annot->getPattern(); + } + + if (null !== $annot->getRequirements()) { + $globals['requirements'] = $annot->getRequirements(); + } + + if (null !== $annot->getOptions()) { + $globals['options'] = $annot->getOptions(); + } + + if (null !== $annot->getDefaults()) { + $globals['defaults'] = $annot->getDefaults(); + } + } + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($class->getFileName())); + + foreach ($class->getMethods() as $method) { + $this->defaultRouteIndex = 0; + foreach ($this->reader->getMethodAnnotations($method) as $annot) { + if ($annot instanceof $this->routeAnnotationClass) { + $this->addRoute($collection, $annot, $globals, $class, $method); + } + } + } + + return $collection; + } + + protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method) + { + $name = $annot->getName(); + if (null === $name) { + $name = $this->getDefaultRouteName($class, $method); + } + + $defaults = array_merge($globals['defaults'], $annot->getDefaults()); + $requirements = array_merge($globals['requirements'], $annot->getRequirements()); + $options = array_merge($globals['options'], $annot->getOptions()); + + $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options); + + $this->configureRoute($route, $class, $method, $annot); + + $collection->add($name, $route); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type); + } + + /** + * Sets the loader resolver. + * + * @param LoaderResolver $resolver A LoaderResolver instance + */ + public function setResolver(LoaderResolver $resolver) + { + } + + /** + * Gets the loader resolver. + * + * @return LoaderResolver A LoaderResolver instance + */ + public function getResolver() + { + } + + /** + * Gets the default route name for a class method. + * + * @param \ReflectionClass $class + * @param \ReflectionMethod $method + * + * @return string + */ + protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method) + { + $name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name); + if ($this->defaultRouteIndex > 0) { + $name .= '_'.$this->defaultRouteIndex; + } + $this->defaultRouteIndex++; + + return $name; + } + + abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php new file mode 100644 index 00000000000..8097cd67f96 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Resource\DirectoryResource; + +/** + * AnnotationDirectoryLoader loads routing information from annotations set + * on PHP classes and methods. + * + * @author Fabien Potencier + */ +class AnnotationDirectoryLoader extends AnnotationFileLoader +{ + /** + * Loads from annotations from a directory. + * + * @param string $path A directory path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed + */ + public function load($path, $type = null) + { + $dir = $this->locator->locate($path); + + $collection = new RouteCollection(); + $collection->addResource(new DirectoryResource($dir, '/\.php$/')); + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) { + continue; + } + + if ($class = $this->findClass($file)) { + $refl = new \ReflectionClass($class); + if ($refl->isAbstract()) { + continue; + } + + $collection->addCollection($this->loader->load($class, $type)); + } + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + try { + $path = $this->locator->locate($resource); + } catch (\Exception $e) { + return false; + } + + return is_string($resource) && is_dir($path) && (!$type || 'annotation' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php new file mode 100644 index 00000000000..49e1cb2f775 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\FileLocator; + +/** + * AnnotationFileLoader loads routing information from annotations set + * on a PHP class and its methods. + * + * @author Fabien Potencier + */ +class AnnotationFileLoader extends FileLoader +{ + protected $loader; + + /** + * Constructor. + * + * @param FileLocator $locator A FileLocator instance + * @param AnnotationClassLoader $loader An AnnotationClassLoader instance + * @param string|array $paths A path or an array of paths where to look for resources + */ + public function __construct(FileLocator $locator, AnnotationClassLoader $loader, $paths = array()) + { + if (!function_exists('token_get_all')) { + throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.'); + } + + parent::__construct($locator, $paths); + + $this->loader = $loader; + } + + /** + * Loads from annotations from a file. + * + * @param string $file A PHP file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $collection = new RouteCollection(); + if ($class = $this->findClass($path)) { + $collection->addResource(new FileResource($path)); + $collection->addCollection($this->loader->load($class, $type)); + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type); + } + + /** + * Returns the full class name for the first class in the file. + * + * @param string $file A PHP file path + * + * @return string|false Full class name if found, false otherwise + */ + protected function findClass($file) + { + $class = false; + $namespace = false; + $tokens = token_get_all(file_get_contents($file)); + for ($i = 0, $count = count($tokens); $i < $count; $i++) { + $token = $tokens[$i]; + + if (!is_array($token)) { + continue; + } + + if (true === $class && T_STRING === $token[0]) { + return $namespace.'\\'.$token[1]; + } + + if (true === $namespace && T_STRING === $token[0]) { + $namespace = ''; + do { + $namespace .= $token[1]; + $token = $tokens[++$i]; + } while ($i < $count && is_array($token) && in_array($token[0], array(T_NS_SEPARATOR, T_STRING))); + } + + if (T_CLASS === $token[0]) { + $class = true; + } + + if (T_NAMESPACE === $token[0]) { + $namespace = true; + } + } + + return false; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php new file mode 100644 index 00000000000..ca49c8fa35a --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Config\Loader\Loader; + +/** + * ClosureLoader loads routes from a PHP closure. + * + * The Closure must return a RouteCollection instance. + * + * @author Fabien Potencier + * + * @api + */ +class ClosureLoader extends Loader +{ + /** + * Loads a Closure. + * + * @param \Closure $closure A Closure + * @param string $type The resource type + * + * @api + */ + public function load($closure, $type = null) + { + return call_user_func($closure); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return $resource instanceof \Closure && (!$type || 'closure' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php new file mode 100644 index 00000000000..ffd31f94442 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * PhpFileLoader loads routes from a PHP file. + * + * The file must return a RouteCollection instance. + * + * @author Fabien Potencier + * + * @api + */ +class PhpFileLoader extends FileLoader +{ + /** + * Loads a PHP file. + * + * @param mixed $file A PHP file path + * @param string $type The resource type + * + * @api + */ + public function load($file, $type = null) + { + // the loader variable is exposed to the included file below + $loader = $this; + + $path = $this->locator->locate($file); + $this->setCurrentDir(dirname($path)); + + $collection = include $path; + $collection->addResource(new FileResource($path)); + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php new file mode 100644 index 00000000000..5dad9db3fae --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -0,0 +1,224 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\Route; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * XmlFileLoader loads XML routing files. + * + * @author Fabien Potencier + * + * @api + */ +class XmlFileLoader extends FileLoader +{ + /** + * Loads an XML file. + * + * @param string $file An XML file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When a tag can't be parsed + * + * @api + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $xml = $this->loadFile($path); + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($path)); + + // process routes and imports + foreach ($xml->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement) { + continue; + } + + $this->parseNode($collection, $node, $path, $file); + } + + return $collection; + } + + /** + * Parses a node from a loaded XML file. + * + * @param RouteCollection $collection the collection to associate with the node + * @param DOMElement $node the node to parse + * @param string $path the path of the XML file being processed + * @param string $file + */ + protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file) + { + switch ($node->tagName) { + case 'route': + $this->parseRoute($collection, $node, $path); + break; + case 'import': + $resource = (string) $node->getAttribute('resource'); + $type = (string) $node->getAttribute('type'); + $prefix = (string) $node->getAttribute('prefix'); + $this->setCurrentDir(dirname($path)); + $collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix); + break; + default: + throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); + } + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type); + } + + /** + * Parses a route and adds it to the RouteCollection. + * + * @param RouteCollection $collection A RouteCollection instance + * @param \DOMElement $definition Route definition + * @param string $file An XML file path + * + * @throws \InvalidArgumentException When the definition cannot be parsed + */ + protected function parseRoute(RouteCollection $collection, \DOMElement $definition, $file) + { + $defaults = array(); + $requirements = array(); + $options = array(); + + foreach ($definition->childNodes as $node) { + if (!$node instanceof \DOMElement) { + continue; + } + + switch ($node->tagName) { + case 'default': + $defaults[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + case 'option': + $options[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + case 'requirement': + $requirements[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + default: + throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); + } + } + + $route = new Route((string) $definition->getAttribute('pattern'), $defaults, $requirements, $options); + + $collection->add((string) $definition->getAttribute('id'), $route); + } + + /** + * Loads an XML file. + * + * @param string $file An XML file path + * + * @return \DOMDocument + * + * @throws \InvalidArgumentException When loading of XML file returns error + */ + protected function loadFile($file) + { + $internalErrors = libxml_use_internal_errors(true); + $disableEntities = libxml_disable_entity_loader(true); + libxml_clear_errors(); + + $dom = new \DOMDocument(); + $dom->validateOnParse = true; + if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { + libxml_disable_entity_loader($disableEntities); + + throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); + } + $dom->normalizeDocument(); + + libxml_use_internal_errors($internalErrors); + libxml_disable_entity_loader($disableEntities); + + foreach ($dom->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + throw new \InvalidArgumentException('Document types are not allowed.'); + } + } + + $this->validate($dom); + + return $dom; + } + + /** + * Validates a loaded XML file. + * + * @param \DOMDocument $dom A loaded XML file + * + * @throws \InvalidArgumentException When XML doesn't validate its XSD schema + */ + protected function validate(\DOMDocument $dom) + { + $location = __DIR__.'/schema/routing/routing-1.0.xsd'; + + $current = libxml_use_internal_errors(true); + libxml_clear_errors(); + + if (!$dom->schemaValidate($location)) { + throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($current))); + } + libxml_use_internal_errors($current); + } + + /** + * Retrieves libxml errors and clears them. + * + * @return array An array of libxml error strings + */ + private function getXmlErrors($internalErrors) + { + $errors = array(); + foreach (libxml_get_errors() as $error) { + $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', + LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', + $error->code, + trim($error->message), + $error->file ? $error->file : 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + return $errors; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php new file mode 100644 index 00000000000..ee723834355 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\Route; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * YamlFileLoader loads Yaml routing files. + * + * @author Fabien Potencier + * + * @api + */ +class YamlFileLoader extends FileLoader +{ + private static $availableKeys = array( + 'type', 'resource', 'prefix', 'pattern', 'options', 'defaults', 'requirements' + ); + + /** + * Loads a Yaml file. + * + * @param string $file A Yaml file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When route can't be parsed + * + * @api + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $config = Yaml::parse($path); + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($path)); + + // empty file + if (null === $config) { + $config = array(); + } + + // not an array + if (!is_array($config)) { + throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file)); + } + + foreach ($config as $name => $config) { + $config = $this->normalizeRouteConfig($config); + + if (isset($config['resource'])) { + $type = isset($config['type']) ? $config['type'] : null; + $prefix = isset($config['prefix']) ? $config['prefix'] : null; + $this->setCurrentDir(dirname($path)); + $collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix); + } else { + $this->parseRoute($collection, $name, $config, $path); + } + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type); + } + + /** + * Parses a route and adds it to the RouteCollection. + * + * @param RouteCollection $collection A RouteCollection instance + * @param string $name Route name + * @param array $config Route definition + * @param string $file A Yaml file path + * + * @throws \InvalidArgumentException When config pattern is not defined for the given route + */ + protected function parseRoute(RouteCollection $collection, $name, $config, $file) + { + $defaults = isset($config['defaults']) ? $config['defaults'] : array(); + $requirements = isset($config['requirements']) ? $config['requirements'] : array(); + $options = isset($config['options']) ? $config['options'] : array(); + + if (!isset($config['pattern'])) { + throw new \InvalidArgumentException(sprintf('You must define a "pattern" for the "%s" route.', $name)); + } + + $route = new Route($config['pattern'], $defaults, $requirements, $options); + + $collection->add($name, $route); + } + + /** + * Normalize route configuration. + * + * @param array $config A resource config + * + * @return array + * + * @throws InvalidArgumentException if one of the provided config keys is not supported + */ + private function normalizeRouteConfig(array $config) + { + foreach ($config as $key => $value) { + if (!in_array($key, self::$availableKeys)) { + throw new \InvalidArgumentException(sprintf( + 'Yaml routing loader does not support given key: "%s". Expected one of the (%s).', + $key, implode(', ', self::$availableKeys) + )); + } + } + + return $config; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd new file mode 100644 index 00000000000..a9554e64df3 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php new file mode 100644 index 00000000000..3003dfdebb0 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\MethodNotAllowedException; + +/** + * ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper). + * + * @author Fabien Potencier + */ +class ApacheUrlMatcher extends UrlMatcher +{ + /** + * Tries to match a URL based on Apache mod_rewrite matching. + * + * Returns false if no route matches the URL. + * + * @param string $pathinfo The pathinfo to be parsed + * + * @return array An array of parameters + * + * @throws MethodNotAllowedException If the current method is not allowed + */ + public function match($pathinfo) + { + $parameters = array(); + $defaults = array(); + $allow = array(); + $match = false; + + foreach ($_SERVER as $key => $value) { + $name = $key; + + if (0 === strpos($name, 'REDIRECT_')) { + $name = substr($name, 9); + } + + if (0 === strpos($name, '_ROUTING_DEFAULTS_')) { + $name = substr($name, 18); + $defaults[$name] = $value; + } elseif (0 === strpos($name, '_ROUTING_')) { + $name = substr($name, 9); + if ('_route' == $name) { + $match = true; + $parameters[$name] = $value; + } elseif (0 === strpos($name, '_allow_')) { + $allow[] = substr($name, 7); + } else { + $parameters[$name] = $value; + } + } else { + continue; + } + + unset($_SERVER[$key]); + } + + if ($match) { + return $this->mergeDefaults($parameters, $defaults); + } elseif (0 < count($allow)) { + throw new MethodNotAllowedException($allow); + } else { + return parent::match($pathinfo); + } + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php new file mode 100644 index 00000000000..4f03b8d393b --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +/** + * Dumps a set of Apache mod_rewrite rules. + * + * @author Fabien Potencier + * @author Kris Wallsmith + */ +class ApacheMatcherDumper extends MatcherDumper +{ + /** + * Dumps a set of Apache mod_rewrite rules. + * + * Available options: + * + * * script_name: The script name (app.php by default) + * * base_uri: The base URI ("" by default) + * + * @param array $options An array of options + * + * @return string A string to be used as Apache rewrite rules + * + * @throws \LogicException When the route regex is invalid + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'script_name' => 'app.php', + 'base_uri' => '', + ), $options); + + $options['script_name'] = self::escape($options['script_name'], ' ', '\\'); + + $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); + $methodVars = array(); + + foreach ($this->getRoutes()->all() as $name => $route) { + $compiledRoute = $route->compile(); + + // prepare the apache regex + $regex = $compiledRoute->getRegex(); + $delimiter = $regex[0]; + $regexPatternEnd = strrpos($regex, $delimiter); + if (strlen($regex) < 2 || 0 === $regexPatternEnd) { + throw new \LogicException('The "%s" route regex "%s" is invalid', $name, $regex); + } + $regex = preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1)); + $regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\'); + + $hasTrailingSlash = '/$' == substr($regex, -2) && '^/$' != $regex; + + $variables = array('E=_ROUTING__route:'.$name); + foreach ($compiledRoute->getVariables() as $i => $variable) { + $variables[] = 'E=_ROUTING_'.$variable.':%'.($i + 1); + } + foreach ($route->getDefaults() as $key => $value) { + $variables[] = 'E=_ROUTING_DEFAULTS_'.$key.':'.strtr($value, array( + ':' => '\\:', + '=' => '\\=', + '\\' => '\\\\', + ' ' => '\\ ', + )); + } + $variables = implode(',', $variables); + + $rule = array("# $name"); + + // method mismatch + if ($req = $route->getRequirement('_method')) { + $methods = explode('|', strtoupper($req)); + // GET and HEAD are equivalent + if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { + $methods[] = 'HEAD'; + } + $allow = array(); + foreach ($methods as $method) { + $methodVars[] = $method; + $allow[] = 'E=_ROUTING__allow_'.$method.':1'; + } + + $rule[] = "RewriteCond %{REQUEST_URI} $regex"; + $rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods)); + $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); + } + + // redirect with trailing slash appended + if ($hasTrailingSlash) { + $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; + $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; + } + + // the main rule + $rule[] = "RewriteCond %{REQUEST_URI} $regex"; + $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]"; + + $rules[] = implode("\n", $rule); + } + + if (0 < count($methodVars)) { + $rule = array('# 405 Method Not Allowed'); + $methodVars = array_values(array_unique($methodVars)); + foreach ($methodVars as $i => $methodVar) { + $rule[] = sprintf('RewriteCond %%{_ROUTING__allow_%s} !-z%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); + } + $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); + + $rules[] = implode("\n", $rule); + } + + return implode("\n\n", $rules)."\n"; + } + + /** + * Escapes a string. + * + * @param string $string The string to be escaped + * @param string $char The character to be escaped + * @param string $with The character to be used for escaping + * + * @return string The escaped string + */ + private static function escape($string, $char, $with) + { + $escaped = false; + $output = ''; + foreach (str_split($string) as $symbol) { + if ($escaped) { + $output .= $symbol; + $escaped = false; + continue; + } + if ($symbol === $char) { + $output .= $with.$char; + continue; + } + if ($symbol === $with) { + $escaped = true; + } + $output .= $symbol; + } + + return $output; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php new file mode 100644 index 00000000000..423368b57ed --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * MatcherDumper is the abstract class for all built-in matcher dumpers. + * + * @author Fabien Potencier + */ +abstract class MatcherDumper implements MatcherDumperInterface +{ + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes The RouteCollection to dump + */ + public function __construct(RouteCollection $routes) + { + $this->routes = $routes; + } + + /** + * Gets the routes to dump. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes() + { + return $this->routes; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php new file mode 100644 index 00000000000..fe09e067d7c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +/** + * MatcherDumperInterface is the interface that all matcher dumper classes must implement. + * + * @author Fabien Potencier + */ +interface MatcherDumperInterface +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the matcher class + */ + public function dump(array $options = array()); + + /** + * Gets the routes to match. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes(); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php new file mode 100644 index 00000000000..fdaad513a19 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -0,0 +1,293 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +/** + * PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes. + * + * @author Fabien Potencier + */ +class PhpMatcherDumper extends MatcherDumper +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the matcher class + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'class' => 'ProjectUrlMatcher', + 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + ), $options); + + // trailing slash support is only enabled if we know how to redirect the user + $interfaces = class_implements($options['base_class']); + $supportsRedirections = isset($interfaces['Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface']); + + return + $this->startClass($options['class'], $options['base_class']). + $this->addConstructor(). + $this->addMatcher($supportsRedirections). + $this->endClass() + ; + } + + private function addMatcher($supportsRedirections) + { + // we need to deep clone the routes as we will modify the structure to optimize the dump + $code = implode("\n", $this->compileRoutes(clone $this->getRoutes(), $supportsRedirections)); + + return <<getIterator(); + $keys = array_keys($routeIterator->getArrayCopy()); + $keysCount = count($keys); + + $i = 0; + foreach ($routeIterator as $name => $route) { + $i++; + + if ($route instanceof RouteCollection) { + $prefix = $route->getPrefix(); + $optimizable = $prefix && count($route->all()) > 1 && false === strpos($route->getPrefix(), '{'); + $indent = ''; + if ($optimizable) { + for ($j = $i; $j < $keysCount; $j++) { + if ($keys[$j] === null) { + continue; + } + + $testRoute = $routeIterator->offsetGet($keys[$j]); + $isCollection = ($testRoute instanceof RouteCollection); + + $testPrefix = $isCollection ? $testRoute->getPrefix() : $testRoute->getPattern(); + + if (0 === strpos($testPrefix, $prefix)) { + $routeIterator->offsetUnset($keys[$j]); + + if ($isCollection) { + $route->addCollection($testRoute); + } else { + $route->add($keys[$j], $testRoute); + } + + $i++; + $keys[$j] = null; + } + } + + if ($prefix !== $parentPrefix) { + $code[] = sprintf(" if (0 === strpos(\$pathinfo, %s)) {", var_export($prefix, true)); + $indent = ' '; + } + } + + foreach ($this->compileRoutes($route, $supportsRedirections, $prefix) as $line) { + foreach (explode("\n", $line) as $l) { + if ($l) { + $code[] = $indent.$l; + } else { + $code[] = $l; + } + } + } + + if ($optimizable && $prefix !== $parentPrefix) { + $code[] = " }\n"; + } + } else { + foreach ($this->compileRoute($route, $name, $supportsRedirections, $parentPrefix) as $line) { + $code[] = $line; + } + } + } + + return $code; + } + + private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null) + { + $code = array(); + $compiledRoute = $route->compile(); + $conditions = array(); + $hasTrailingSlash = false; + $matches = false; + if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#', $compiledRoute->getRegex(), $m)) { + if ($supportsRedirections && substr($m['url'], -1) === '/') { + $conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true)); + $hasTrailingSlash = true; + } else { + $conditions[] = sprintf("\$pathinfo === %s", var_export(str_replace('\\', '', $m['url']), true)); + } + } else { + if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() != $parentPrefix) { + $conditions[] = sprintf("0 === strpos(\$pathinfo, %s)", var_export($compiledRoute->getStaticPrefix(), true)); + } + + $regex = $compiledRoute->getRegex(); + if ($supportsRedirections && $pos = strpos($regex, '/$')) { + $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); + $hasTrailingSlash = true; + } + $conditions[] = sprintf("preg_match(%s, \$pathinfo, \$matches)", var_export($regex, true)); + + $matches = true; + } + + $conditions = implode(' && ', $conditions); + + $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); + + $code[] = <<getRequirement('_method')) { + $methods = explode('|', strtoupper($req)); + // GET and HEAD are equivalent + if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { + $methods[] = 'HEAD'; + } + if (1 === count($methods)) { + $code[] = <<context->getMethod() != '$methods[0]') { + \$allow[] = '$methods[0]'; + goto $gotoname; + } +EOF; + } else { + $methods = implode('\', \'', $methods); + $code[] = <<context->getMethod(), array('$methods'))) { + \$allow = array_merge(\$allow, array('$methods')); + goto $gotoname; + } +EOF; + } + } + + if ($hasTrailingSlash) { + $code[] = sprintf(<<redirect(\$pathinfo.'/', '%s'); + } +EOF + , $name); + } + + if ($scheme = $route->getRequirement('_scheme')) { + if (!$supportsRedirections) { + throw new \LogicException('The "_scheme" requirement is only supported for route dumper that implements RedirectableUrlMatcherInterface.'); + } + + $code[] = sprintf(<<context->getScheme() !== '$scheme') { + return \$this->redirect(\$pathinfo, '%s', '$scheme'); + } +EOF + , $name); + } + + // optimize parameters array + if (true === $matches && $compiledRoute->getDefaults()) { + $code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));" + , str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name); + } elseif (true === $matches) { + $code[] = sprintf(" \$matches['_route'] = '%s';", $name); + $code[] = sprintf(" return \$matches;", $name); + } elseif ($compiledRoute->getDefaults()) { + $code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true))); + } else { + $code[] = sprintf(" return array('_route' => '%s');", $name); + } + $code[] = " }"; + + if ($req) { + $code[] = " $gotoname:"; + } + + $code[] = ''; + + return $code; + } + + private function startClass($class, $baseClass) + { + return <<context = \$context; + } + +EOF; + } + + private function endClass() + { + return << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\ResourceNotFoundException; + +/** + * @author Fabien Potencier + * + * @api + */ +abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + private $trailingSlashTest = false; + + /** + * @see UrlMatcher::match() + * + * @api + */ + public function match($pathinfo) + { + try { + $parameters = parent::match($pathinfo); + } catch (ResourceNotFoundException $e) { + if ('/' === substr($pathinfo, -1)) { + throw $e; + } + + // try with a / at the end + $this->trailingSlashTest = true; + + return $this->match($pathinfo.'/'); + } + + if ($this->trailingSlashTest) { + $this->trailingSlashTest = false; + + return $this->redirect($pathinfo, null); + } + + return $parameters; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php new file mode 100644 index 00000000000..929ae9cc78f --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +/** + * RedirectableUrlMatcherInterface knows how to redirect the user. + * + * @author Fabien Potencier + * + * @api + */ +interface RedirectableUrlMatcherInterface +{ + /** + * Redirects the user to another URL. + * + * @param string $path The path info to redirect to. + * @param string $route The route that matched + * @param string $scheme The URL scheme (null to keep the current one) + * + * @return array An array of parameters + * + * @api + */ + public function redirect($path, $route, $scheme = null); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php new file mode 100644 index 00000000000..5ff8070ea0c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; + +/** + * UrlMatcher matches URL based on a set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class UrlMatcher implements UrlMatcherInterface +{ + protected $context; + protected $allow; + + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes A RouteCollection instance + * @param RequestContext $context The context + * + * @api + */ + public function __construct(RouteCollection $routes, RequestContext $context) + { + $this->routes = $routes; + $this->context = $context; + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Tries to match a URL with a set of routes. + * + * @param string $pathinfo The path info to be parsed + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + * + * @api + */ + public function match($pathinfo) + { + $this->allow = array(); + + if ($ret = $this->matchCollection($pathinfo, $this->routes)) { + return $ret; + } + + throw 0 < count($this->allow) + ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) + : new ResourceNotFoundException(); + } + + protected function matchCollection($pathinfo, RouteCollection $routes) + { + $pathinfo = urldecode($pathinfo); + + foreach ($routes as $name => $route) { + if ($route instanceof RouteCollection) { + if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) { + continue; + } + + if (!$ret = $this->matchCollection($pathinfo, $route)) { + continue; + } + + return $ret; + } + + $compiledRoute = $route->compile(); + + // check the static prefix of the URL first. Only use the more expensive preg_match when it matches + if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { + continue; + } + + if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { + continue; + } + + // check HTTP method requirement + if ($req = $route->getRequirement('_method')) { + // HEAD and GET are equivalent as per RFC + if ('HEAD' === $method = $this->context->getMethod()) { + $method = 'GET'; + } + + if (!in_array($method, $req = explode('|', strtoupper($req)))) { + $this->allow = array_merge($this->allow, $req); + + continue; + } + } + + return array_merge($this->mergeDefaults($matches, $route->getDefaults()), array('_route' => $name)); + } + } + + protected function mergeDefaults($params, $defaults) + { + $parameters = $defaults; + foreach ($params as $key => $value) { + if (!is_int($key)) { + $parameters[$key] = rawurldecode($value); + } + } + + return $parameters; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php new file mode 100644 index 00000000000..5823d3201bc --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\RequestContextAwareInterface; + +/** + * UrlMatcherInterface is the interface that all URL matcher classes must implement. + * + * @author Fabien Potencier + * + * @api + */ +interface UrlMatcherInterface extends RequestContextAwareInterface +{ + /** + * Tries to match a URL with a set of routes. + * + * @param string $pathinfo The path info to be parsed + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + * + * @api + */ + public function match($pathinfo); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/README.md b/3rdparty/symfony/routing/Symfony/Component/Routing/README.md new file mode 100644 index 00000000000..eb72334d2ea --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/README.md @@ -0,0 +1,32 @@ +Routing Component +================= + +Routing associates a request with the code that will convert it to a response. + +The example below demonstrates how you can set up a fully working routing +system: + + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Routing\Matcher\UrlMatcher; + use Symfony\Component\Routing\RequestContext; + use Symfony\Component\Routing\RouteCollection; + use Symfony\Component\Routing\Route; + + $routes = new RouteCollection(); + $routes->add('hello', new Route('/hello', array('controller' => 'foo'))); + + $context = new RequestContext(); + + // this is optional and can be done without a Request instance + $context->fromRequest(Request::createFromGlobals()); + + $matcher = new UrlMatcher($routes, $context); + + $parameters = $matcher->match('/hello'); + +Resources +--------- + +Unit tests: + +https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/Routing diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php new file mode 100644 index 00000000000..fef85b6bb34 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php @@ -0,0 +1,250 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * Holds information about the current request. + * + * @author Fabien Potencier + * + * @api + */ +class RequestContext +{ + private $baseUrl; + private $method; + private $host; + private $scheme; + private $httpPort; + private $httpsPort; + private $parameters; + + /** + * Constructor. + * + * @param string $baseUrl The base URL + * @param string $method The HTTP method + * @param string $host The HTTP host name + * @param string $scheme The HTTP scheme + * @param integer $httpPort The HTTP port + * @param integer $httpsPort The HTTPS port + * + * @api + */ + public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443) + { + $this->baseUrl = $baseUrl; + $this->method = strtoupper($method); + $this->host = $host; + $this->scheme = strtolower($scheme); + $this->httpPort = $httpPort; + $this->httpsPort = $httpsPort; + $this->parameters = array(); + } + + /** + * Gets the base URL. + * + * @return string The base URL + */ + public function getBaseUrl() + { + return $this->baseUrl; + } + + /** + * Sets the base URL. + * + * @param string $baseUrl The base URL + * + * @api + */ + public function setBaseUrl($baseUrl) + { + $this->baseUrl = $baseUrl; + } + + /** + * Gets the HTTP method. + * + * The method is always an uppercased string. + * + * @return string The HTTP method + */ + public function getMethod() + { + return $this->method; + } + + /** + * Sets the HTTP method. + * + * @param string $method The HTTP method + * + * @api + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + /** + * Gets the HTTP host. + * + * @return string The HTTP host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the HTTP host. + * + * @param string $host The HTTP host + * + * @api + */ + public function setHost($host) + { + $this->host = $host; + } + + /** + * Gets the HTTP scheme. + * + * @return string The HTTP scheme + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Sets the HTTP scheme. + * + * @param string $scheme The HTTP scheme + * + * @api + */ + public function setScheme($scheme) + { + $this->scheme = strtolower($scheme); + } + + /** + * Gets the HTTP port. + * + * @return string The HTTP port + */ + public function getHttpPort() + { + return $this->httpPort; + } + + /** + * Sets the HTTP port. + * + * @param string $httpPort The HTTP port + * + * @api + */ + public function setHttpPort($httpPort) + { + $this->httpPort = $httpPort; + } + + /** + * Gets the HTTPS port. + * + * @return string The HTTPS port + */ + public function getHttpsPort() + { + return $this->httpsPort; + } + + /** + * Sets the HTTPS port. + * + * @param string $httpsPort The HTTPS port + * + * @api + */ + public function setHttpsPort($httpsPort) + { + $this->httpsPort = $httpsPort; + } + + /** + * Returns the parameters. + * + * @return array The parameters + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Sets the parameters. + * + * This method implements a fluent interface. + * + * @param array $parameters The parameters + * + * @return Route The current Route instance + */ + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + + return $this; + } + + /** + * Gets a parameter value. + * + * @param string $name A parameter name + * + * @return mixed The parameter value + */ + public function getParameter($name) + { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + /** + * Checks if a parameter value is set for the given parameter. + * + * @param string $name A parameter name + * + * @return Boolean true if the parameter value is set, false otherwise + */ + public function hasParameter($name) + { + return array_key_exists($name, $this->parameters); + } + + /** + * Sets a parameter value. + * + * @param string $name A parameter name + * @param mixed $parameter The parameter value + * + * @api + */ + public function setParameter($name, $parameter) + { + $this->parameters[$name] = $parameter; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php new file mode 100644 index 00000000000..38443a88b7c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * @api + */ +interface RequestContextAwareInterface +{ + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php new file mode 100644 index 00000000000..548568334d1 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * A Route describes a route and its parameters. + * + * @author Fabien Potencier + * + * @api + */ +class Route +{ + private $pattern; + private $defaults; + private $requirements; + private $options; + private $compiled; + + private static $compilers = array(); + + /** + * Constructor. + * + * Available options: + * + * * compiler_class: A class name able to compile this route instance (RouteCompiler by default) + * + * @param string $pattern The pattern to match + * @param array $defaults An array of default parameter values + * @param array $requirements An array of requirements for parameters (regexes) + * @param array $options An array of options + * + * @api + */ + public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array()) + { + $this->setPattern($pattern); + $this->setDefaults($defaults); + $this->setRequirements($requirements); + $this->setOptions($options); + } + + public function __clone() + { + $this->compiled = null; + } + + /** + * Returns the pattern. + * + * @return string The pattern + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * Sets the pattern. + * + * This method implements a fluent interface. + * + * @param string $pattern The pattern + * + * @return Route The current Route instance + */ + public function setPattern($pattern) + { + $this->pattern = trim($pattern); + + // a route must start with a slash + if (empty($this->pattern) || '/' !== $this->pattern[0]) { + $this->pattern = '/'.$this->pattern; + } + + return $this; + } + + /** + * Returns the options. + * + * @return array The options + */ + public function getOptions() + { + return $this->options; + } + + /** + * Sets the options. + * + * This method implements a fluent interface. + * + * @param array $options The options + * + * @return Route The current Route instance + */ + public function setOptions(array $options) + { + $this->options = array_merge(array( + 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', + ), $options); + + return $this; + } + + /** + * Sets an option value. + * + * This method implements a fluent interface. + * + * @param string $name An option name + * @param mixed $value The option value + * + * @return Route The current Route instance + * + * @api + */ + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + /** + * Get an option value. + * + * @param string $name An option name + * + * @return mixed The option value + */ + public function getOption($name) + { + return isset($this->options[$name]) ? $this->options[$name] : null; + } + + /** + * Returns the defaults. + * + * @return array The defaults + */ + public function getDefaults() + { + return $this->defaults; + } + + /** + * Sets the defaults. + * + * This method implements a fluent interface. + * + * @param array $defaults The defaults + * + * @return Route The current Route instance + */ + public function setDefaults(array $defaults) + { + $this->defaults = array(); + foreach ($defaults as $name => $default) { + $this->defaults[(string) $name] = $default; + } + + return $this; + } + + /** + * Gets a default value. + * + * @param string $name A variable name + * + * @return mixed The default value + */ + public function getDefault($name) + { + return isset($this->defaults[$name]) ? $this->defaults[$name] : null; + } + + /** + * Checks if a default value is set for the given variable. + * + * @param string $name A variable name + * + * @return Boolean true if the default value is set, false otherwise + */ + public function hasDefault($name) + { + return array_key_exists($name, $this->defaults); + } + + /** + * Sets a default value. + * + * @param string $name A variable name + * @param mixed $default The default value + * + * @return Route The current Route instance + * + * @api + */ + public function setDefault($name, $default) + { + $this->defaults[(string) $name] = $default; + + return $this; + } + + /** + * Returns the requirements. + * + * @return array The requirements + */ + public function getRequirements() + { + return $this->requirements; + } + + /** + * Sets the requirements. + * + * This method implements a fluent interface. + * + * @param array $requirements The requirements + * + * @return Route The current Route instance + */ + public function setRequirements(array $requirements) + { + $this->requirements = array(); + foreach ($requirements as $key => $regex) { + $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); + } + + return $this; + } + + /** + * Returns the requirement for the given key. + * + * @param string $key The key + * + * @return string The regex + */ + public function getRequirement($key) + { + return isset($this->requirements[$key]) ? $this->requirements[$key] : null; + } + + /** + * Sets a requirement for the given key. + * + * @param string $key The key + * @param string $regex The regex + * + * @return Route The current Route instance + * + * @api + */ + public function setRequirement($key, $regex) + { + $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); + + return $this; + } + + /** + * Compiles the route. + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile() + { + if (null !== $this->compiled) { + return $this->compiled; + } + + $class = $this->getOption('compiler_class'); + + if (!isset(self::$compilers[$class])) { + self::$compilers[$class] = new $class; + } + + return $this->compiled = self::$compilers[$class]->compile($this); + } + + private function sanitizeRequirement($key, $regex) + { + if (is_array($regex)) { + throw new \InvalidArgumentException(sprintf('Routing requirements must be a string, array given for "%s"', $key)); + } + + if ('^' == $regex[0]) { + $regex = substr($regex, 1); + } + + if ('$' == substr($regex, -1)) { + $regex = substr($regex, 0, -1); + } + + return $regex; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php new file mode 100644 index 00000000000..b3289d337c4 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * A RouteCollection represents a set of Route instances. + * + * When adding a route, it overrides existing routes with the + * same name defined in the instance or its children and parents. + * + * @author Fabien Potencier + * + * @api + */ +class RouteCollection implements \IteratorAggregate +{ + private $routes; + private $resources; + private $prefix; + private $parent; + + /** + * Constructor. + * + * @api + */ + public function __construct() + { + $this->routes = array(); + $this->resources = array(); + $this->prefix = ''; + } + + public function __clone() + { + foreach ($this->routes as $name => $route) { + $this->routes[$name] = clone $route; + if ($route instanceof RouteCollection) { + $this->routes[$name]->setParent($this); + } + } + } + + /** + * Gets the parent RouteCollection. + * + * @return RouteCollection The parent RouteCollection + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the parent RouteCollection. + * + * @param RouteCollection $parent The parent RouteCollection + */ + public function setParent(RouteCollection $parent) + { + $this->parent = $parent; + } + + /** + * Gets the current RouteCollection as an Iterator. + * + * @return \ArrayIterator An \ArrayIterator interface + */ + public function getIterator() + { + return new \ArrayIterator($this->routes); + } + + /** + * Adds a route. + * + * @param string $name The route name + * @param Route $route A Route instance + * + * @throws \InvalidArgumentException When route name contains non valid characters + * + * @api + */ + public function add($name, Route $route) + { + if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) { + throw new \InvalidArgumentException(sprintf('The provided route name "%s" contains non valid characters. A route name must only contain digits (0-9), letters (a-z and A-Z), underscores (_) and dots (.).', $name)); + } + + $parent = $this; + while ($parent->getParent()) { + $parent = $parent->getParent(); + } + + if ($parent) { + $parent->remove($name); + } + + $this->routes[$name] = $route; + } + + /** + * Returns the array of routes. + * + * @return array An array of routes + */ + public function all() + { + $routes = array(); + foreach ($this->routes as $name => $route) { + if ($route instanceof RouteCollection) { + $routes = array_merge($routes, $route->all()); + } else { + $routes[$name] = $route; + } + } + + return $routes; + } + + /** + * Gets a route by name. + * + * @param string $name The route name + * + * @return Route $route A Route instance + */ + public function get($name) + { + // get the latest defined route + foreach (array_reverse($this->routes) as $routes) { + if (!$routes instanceof RouteCollection) { + continue; + } + + if (null !== $route = $routes->get($name)) { + return $route; + } + } + + if (isset($this->routes[$name])) { + return $this->routes[$name]; + } + } + + /** + * Removes a route by name. + * + * @param string $name The route name + */ + public function remove($name) + { + if (isset($this->routes[$name])) { + unset($this->routes[$name]); + } + + foreach ($this->routes as $routes) { + if ($routes instanceof RouteCollection) { + $routes->remove($name); + } + } + } + + /** + * Adds a route collection to the current set of routes (at the end of the current set). + * + * @param RouteCollection $collection A RouteCollection instance + * @param string $prefix An optional prefix to add before each pattern of the route collection + * + * @api + */ + public function addCollection(RouteCollection $collection, $prefix = '') + { + $collection->setParent($this); + $collection->addPrefix($prefix); + + // remove all routes with the same name in all existing collections + foreach (array_keys($collection->all()) as $name) { + $this->remove($name); + } + + $this->routes[] = $collection; + } + + /** + * Adds a prefix to all routes in the current set. + * + * @param string $prefix An optional prefix to add before each pattern of the route collection + * + * @api + */ + public function addPrefix($prefix) + { + // a prefix must not end with a slash + $prefix = rtrim($prefix, '/'); + + if (!$prefix) { + return; + } + + // a prefix must start with a slash + if ('/' !== $prefix[0]) { + $prefix = '/'.$prefix; + } + + $this->prefix = $prefix.$this->prefix; + + foreach ($this->routes as $name => $route) { + if ($route instanceof RouteCollection) { + $route->addPrefix($prefix); + } else { + $route->setPattern($prefix.$route->getPattern()); + } + } + } + + public function getPrefix() + { + return $this->prefix; + } + + /** + * Returns an array of resources loaded to build this collection. + * + * @return ResourceInterface[] An array of resources + */ + public function getResources() + { + $resources = $this->resources; + foreach ($this as $routes) { + if ($routes instanceof RouteCollection) { + $resources = array_merge($resources, $routes->getResources()); + } + } + + return array_unique($resources); + } + + /** + * Adds a resource for this collection. + * + * @param ResourceInterface $resource A resource instance + */ + public function addResource(ResourceInterface $resource) + { + $this->resources[] = $resource; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php new file mode 100644 index 00000000000..72ececc5caa --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * RouteCompiler compiles Route instances to CompiledRoute instances. + * + * @author Fabien Potencier + */ +class RouteCompiler implements RouteCompilerInterface +{ + /** + * Compiles the current route instance. + * + * @param Route $route A Route instance + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile(Route $route) + { + $pattern = $route->getPattern(); + $len = strlen($pattern); + $tokens = array(); + $variables = array(); + $pos = 0; + preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + foreach ($matches as $match) { + if ($text = substr($pattern, $pos, $match[0][1] - $pos)) { + $tokens[] = array('text', $text); + } + $seps = array($pattern[$pos]); + $pos = $match[0][1] + strlen($match[0][0]); + $var = $match[1][0]; + + if ($req = $route->getRequirement($var)) { + $regexp = $req; + } else { + if ($pos !== $len) { + $seps[] = $pattern[$pos]; + } + $regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), '#')); + } + + $tokens[] = array('variable', $match[0][0][0], $regexp, $var); + + if (in_array($var, $variables)) { + throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var)); + } + + $variables[] = $var; + } + + if ($pos < $len) { + $tokens[] = array('text', substr($pattern, $pos)); + } + + // find the first optional token + $firstOptional = INF; + for ($i = count($tokens) - 1; $i >= 0; $i--) { + $token = $tokens[$i]; + if ('variable' === $token[0] && $route->hasDefault($token[3])) { + $firstOptional = $i; + } else { + break; + } + } + + // compute the matching regexp + $regexp = ''; + for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) { + $regexp .= $this->computeRegexp($tokens, $i, $firstOptional); + } + + return new CompiledRoute( + $route, + 'text' === $tokens[0][0] ? $tokens[0][1] : '', + sprintf("#^%s$#s", $regexp), + array_reverse($tokens), + $variables + ); + } + + /** + * Computes the regexp used to match the token. + * + * @param array $tokens The route tokens + * @param integer $index The index of the current token + * @param integer $firstOptional The index of the first optional token + * + * @return string The regexp + */ + private function computeRegexp(array $tokens, $index, $firstOptional) + { + $token = $tokens[$index]; + if ('text' === $token[0]) { + // Text tokens + return preg_quote($token[1], '#'); + } else { + // Variable tokens + if (0 === $index && 0 === $firstOptional && 1 == count($tokens)) { + // When the only token is an optional variable token, the separator is required + return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], '#'), $token[3], $token[2]); + } else { + $nbTokens = count($tokens); + $regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], '#'), $token[3], $token[2]); + if ($index >= $firstOptional) { + // Enclose each optional tokens in a subpattern to make it optional + $regexp = "(?:$regexp"; + if ($nbTokens - 1 == $index) { + // Close the optional subpatterns + $regexp .= str_repeat(")?", $nbTokens - $firstOptional); + } + } + + return $regexp; + } + } + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php new file mode 100644 index 00000000000..5c988adafba --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * RouteCompilerInterface is the interface that all RouteCompiler classes must implements. + * + * @author Fabien Potencier + */ +interface RouteCompilerInterface +{ + /** + * Compiles the current route instance. + * + * @param Route $route A Route instance + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile(Route $route); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php new file mode 100644 index 00000000000..eadb2231e11 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php @@ -0,0 +1,263 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Config\ConfigCache; + +/** + * The Router class is an example of the integration of all pieces of the + * routing system for easier use. + * + * @author Fabien Potencier + */ +class Router implements RouterInterface +{ + protected $matcher; + protected $generator; + protected $defaults; + protected $context; + protected $loader; + protected $collection; + protected $resource; + protected $options; + + /** + * Constructor. + * + * @param LoaderInterface $loader A LoaderInterface instance + * @param mixed $resource The main resource to load + * @param array $options An array of options + * @param RequestContext $context The context + * @param array $defaults The default values + */ + public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array()) + { + $this->loader = $loader; + $this->resource = $resource; + $this->context = null === $context ? new RequestContext() : $context; + $this->defaults = $defaults; + $this->setOptions($options); + } + + /** + * Sets options. + * + * Available options: + * + * * cache_dir: The cache directory (or null to disable caching) + * * debug: Whether to enable debugging or not (false by default) + * * resource_type: Type hint for the main resource (optional) + * + * @param array $options An array of options + * + * @throws \InvalidArgumentException When unsupported option is provided + */ + public function setOptions(array $options) + { + $this->options = array( + 'cache_dir' => null, + 'debug' => false, + 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper', + 'generator_cache_class' => 'ProjectUrlGenerator', + 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper', + 'matcher_cache_class' => 'ProjectUrlMatcher', + 'resource_type' => null, + ); + + // check option names and live merge, if errors are encountered Exception will be thrown + $invalid = array(); + $isInvalid = false; + foreach ($options as $key => $value) { + if (array_key_exists($key, $this->options)) { + $this->options[$key] = $value; + } else { + $isInvalid = true; + $invalid[] = $key; + } + } + + if ($isInvalid) { + throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('\', \'', $invalid))); + } + } + + /** + * Sets an option. + * + * @param string $key The key + * @param mixed $value The value + * + * @throws \InvalidArgumentException + */ + public function setOption($key, $value) + { + if (!array_key_exists($key, $this->options)) { + throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); + } + + $this->options[$key] = $value; + } + + /** + * Gets an option value. + * + * @param string $key The key + * + * @return mixed The value + * + * @throws \InvalidArgumentException + */ + public function getOption($key) + { + if (!array_key_exists($key, $this->options)) { + throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); + } + + return $this->options[$key]; + } + + /** + * Gets the RouteCollection instance associated with this Router. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRouteCollection() + { + if (null === $this->collection) { + $this->collection = $this->loader->load($this->resource, $this->options['resource_type']); + } + + return $this->collection; + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + + $this->getMatcher()->setContext($context); + $this->getGenerator()->setContext($context); + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + */ + public function generate($name, $parameters = array(), $absolute = false) + { + return $this->getGenerator()->generate($name, $parameters, $absolute); + } + + /** + * Tries to match a URL with a set of routes. + * + * Returns false if no route matches the URL. + * + * @param string $url URL to be parsed + * + * @return array|false An array of parameters or false if no route matches + */ + public function match($url) + { + return $this->getMatcher()->match($url); + } + + /** + * Gets the UrlMatcher instance associated with this Router. + * + * @return UrlMatcherInterface A UrlMatcherInterface instance + */ + public function getMatcher() + { + if (null !== $this->matcher) { + return $this->matcher; + } + + if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) { + return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context, $this->defaults); + } + + $class = $this->options['matcher_cache_class']; + $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); + if (!$cache->isFresh($class)) { + $dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection()); + + $options = array( + 'class' => $class, + 'base_class' => $this->options['matcher_base_class'], + ); + + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + } + + require_once $cache; + + return $this->matcher = new $class($this->context, $this->defaults); + } + + /** + * Gets the UrlGenerator instance associated with this Router. + * + * @return UrlGeneratorInterface A UrlGeneratorInterface instance + */ + public function getGenerator() + { + if (null !== $this->generator) { + return $this->generator; + } + + if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { + return $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->defaults); + } + + $class = $this->options['generator_cache_class']; + $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); + if (!$cache->isFresh($class)) { + $dumper = new $this->options['generator_dumper_class']($this->getRouteCollection()); + + $options = array( + 'class' => $class, + 'base_class' => $this->options['generator_base_class'], + ); + + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + } + + require_once $cache; + + return $this->generator = new $class($this->context, $this->defaults); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php new file mode 100644 index 00000000000..961342bf09c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\Matcher\UrlMatcherInterface; + +/** + * RouterInterface is the interface that all Router classes must implements. + * + * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface. + * + * @author Fabien Potencier + */ +interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json b/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json new file mode 100644 index 00000000000..8d29398b243 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json @@ -0,0 +1,29 @@ +{ + "name": "symfony/routing", + "type": "library", + "description": "Symfony Routing Component", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.2" + }, + "suggest": { + "symfony/config": "self.version", + "symfony/yaml": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Routing": "" } + }, + "target-dir": "Symfony/Component/Routing" +} diff --git a/composer.json b/composer.json deleted file mode 100644 index 7916b15cb9f..00000000000 --- a/composer.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "description": "ownCloud gives you universal access to your files/contacts/calendar through a web interface or WebDAV.", - "homepage": "http://owncloud.org", - "license": "AGPL-3.0+", - "support": { - "email": "owncloud@kde.org", - "irc": "irc://irc.freenode.org/owncloud", - "forum": "http://forum.owncloud.org/", - "issues": "https://github.com/owncloud/core/issues" - }, - "require": { - "php": ">=5.3.2", - "symfony/routing": "2.0.*" - }, - "config": { - "vendor-dir": "3rdparty" - } -} -- cgit v1.2.3 From 56e9ce44c3ac18d6183a8959c690c6e3269bc79e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 17:02:05 +0200 Subject: add a way to recalucale the size of a folder in the cache --- lib/files/cache/cache.php | 25 +++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 11 +++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6604525477b..734890329ae 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -308,6 +308,31 @@ class Cache { return $result->fetchAll(); } + /** + * 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); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); + $result = $query->execute(array($id, $this->storageId)); + $totalSize = 0; + while ($row = $result->fetchRow()) { + $size = (int)$row['size']; + if ($size === -1) { + $totalSize = -1; + break; + } else { + $totalSize += $size; + } + } + + $this->update($id, array('size' => $totalSize)); + return $totalSize; + } + /** * get all file ids on the files on the storage * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 5a8d79b902c..57a154d295c 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -99,6 +99,17 @@ class Cache extends \UnitTestCase { $this->assertEqual($value, $cachedData[$name]); } } + + $file4 = 'folder/unkownSize'; + $fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(-1, $this->cache->calculateFolderSize($file1)); + + $fileData['unkownSize'] = array('size' => 5, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); } function testStatus() { -- cgit v1.2.3 From 79d0ac21ccc65d12b6643ab525d45977644873e8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 18:05:40 +0200 Subject: delete child entries when a folder gets removed from cache --- lib/files/cache/cache.php | 12 +++++++++--- lib/files/cache/scanner.php | 16 ++++++++++++++++ tests/lib/files/cache/cache.php | 6 +++++- tests/lib/files/cache/scanner.php | 9 +++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 734890329ae..cba48e4dbea 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -231,9 +231,15 @@ class Cache { * @param string $file */ public function remove($file) { - $pathHash = md5($file); - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($this->storageId, $pathHash)); + $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'])); } /** diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354d..7062888d74a 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,4 +107,20 @@ class Scanner { } return $size; } + + /** + * update the folder size and the size of all parent folders + * + * @param $path + */ + public function correctFolderSize($path) { + $this->cache->calculateFolderSize($path); + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.') { + $parent = ''; + } + $this->correctFolderSize($parent); + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 57a154d295c..4f22e9bd1d9 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -82,7 +82,7 @@ class Cache extends \UnitTestCase { $file1 = 'folder'; $file2 = 'folder/bar'; $file3 = 'folder/foo'; - $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); @@ -110,6 +110,10 @@ class Cache extends \UnitTestCase { $this->cache->put($file4, $fileData['unkownSize']); $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); + + $this->cache->remove('folder'); + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/bar')); } function testStatus() { diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34fefc784d4..34d38c42736 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -89,14 +89,19 @@ class Scanner extends \UnitTestCase { $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertEqual($cachedDataFolder['size'], -1); - $this->assertEqual($cachedDataFolder2['size'], -1); + $this->assertEqual(-1, $cachedDataFolder['size']); + $this->assertEqual(-1, $cachedDataFolder2['size']); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertNotEqual($cachedDataFolder2['size'], -1); + + $this->scanner->correctFolderSize('folder'); + + $cachedDataFolder = $this->cache->get(''); + $this->assertNotEqual($cachedDataFolder['size'], -1); } function setUp() { -- cgit v1.2.3 From fba7be1194fd31da2cb71c56d0cd8e6ab1c1ff49 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:26:31 +0100 Subject: add filesystem watcher to detect updates --- lib/files/cache/cache.php | 8 +++- lib/files/cache/watcher.php | 70 +++++++++++++++++++++++++++++++ tests/lib/files/cache/watcher.php | 86 +++++++++++++++++++++++++++++++++++++++ tests/lib/files/view.php | 2 + 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 lib/files/cache/watcher.php create mode 100644 tests/lib/files/cache/watcher.php diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index cba48e4dbea..138a5e6e63e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -234,7 +234,7 @@ class Cache { $entry = $this->get($file); if ($entry['mimetype'] === 'httpd/unix-directory') { $children = $this->getFolderContents($file); - foreach($children as $child){ + foreach ($children as $child) { $this->remove($child['path']); } } @@ -325,7 +325,9 @@ class Cache { $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); $result = $query->execute(array($id, $this->storageId)); $totalSize = 0; + $hasChilds = 0; while ($row = $result->fetchRow()) { + $hasChilds = true; $size = (int)$row['size']; if ($size === -1) { $totalSize = -1; @@ -335,7 +337,9 @@ class Cache { } } - $this->update($id, array('size' => $totalSize)); + if ($hasChilds) { + $this->update($id, array('size' => $totalSize)); + } return $totalSize; } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php new file mode 100644 index 00000000000..f04ca9b4656 --- /dev/null +++ b/lib/files/cache/watcher.php @@ -0,0 +1,70 @@ + + * 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 ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->scanner->scan($path, Scanner::SCAN_SHALLOW); + $this->cleanFolder($path); + } else { + $this->scanner->scanFile($path); + } + $this->scanner->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']); + } + } + } +} diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php new file mode 100644 index 00000000000..a7076d9b0b5 --- /dev/null +++ b/tests/lib/files/cache/watcher.php @@ -0,0 +1,86 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Watcher extends \PHPUnit_Framework_TestCase { + + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + \OC\Files\Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $cache->clear(); + } + } + + function testWatcher() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertTrue($cache->inCache('folder/bar2.txt')); + + $this->assertFalse($cache->inCache('bar.test')); + $storage->file_put_contents('bar.test', 'foo'); + $updater->checkUpdate(''); + $this->assertTrue($cache->inCache('bar.test')); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(3, $cachedData['size']); + + $cache->put('bar.test', array('mtime' => 10)); + $storage->file_put_contents('bar.test', 'test data'); + + $updater->checkUpdate('bar.test'); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(9, $cachedData['size']); + + $cache->put('folder', array('mtime' => 10)); + + $storage->unlink('folder/bar2.txt'); + $updater->checkUpdate('folder'); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertFalse($cache->inCache('folder/bar2.txt')); + } + + /** + * @param bool $scan + * @return \OC\Files\Storage\Storage + */ + private function getTestStorage($scan = true) { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + $storage->file_put_contents('folder/bar2.txt', $textData); + + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } + $this->storages[] = $storage; + return $storage; + } +} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 5144fb1caad..8ff03963e40 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -20,6 +20,8 @@ class View extends \PHPUnit_Framework_TestCase { public function tearDown() { foreach ($this->storages as $storage) { $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } -- cgit v1.2.3 From b07672821bcdc1ce31e169d691cf9a94ad5fad21 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:43:45 +0100 Subject: check for changes when using the cache api --- lib/files/view.php | 6 ++++++ tests/lib/files/view.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 0f9a5feb5dd..c5e470b438e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -672,6 +672,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $data = $cache->get($internalPath); @@ -711,6 +714,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 8ff03963e40..fa562cb15cd 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -146,6 +146,23 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, count($folderView->searchByMime('text'))); } + function testWatcher() { + $storage1 = $this->getTestStorage(); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(16, $cachedData['size']); + + $rootView->putFileInfo('foo.txt', array('mtime' => 10)); + $storage1->file_put_contents('foo.txt', 'foo'); + clearstatcache(); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From 8a6bb7965d96b1c4297da8f5dbc9644fec7aeb0f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 2 Nov 2012 22:25:33 +0100 Subject: add Cache::move --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++-- tests/lib/files/cache/cache.php | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 138a5e6e63e..9d13b56104d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -242,6 +242,32 @@ class Cache { $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 */ @@ -296,8 +322,7 @@ class Cache { /** * search for files by mimetype * - * @param string $part1 - * @param string $part2 + * @param string $mimetype * @return array */ public function searchByMime($mimetype) { diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 4f22e9bd1d9..9c469aa9374 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -149,6 +149,32 @@ class Cache extends \UnitTestCase { $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } + function testMove() { + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; + $file4 = 'folder/foo/1'; + $file5 = 'folder/foo/2'; + $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $this->cache->put($file4, $data); + $this->cache->put($file5, $data); + + $this->cache->move('folder/foo', 'folder/foobar'); + + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/foo/1')); + $this->assertFalse($this->cache->inCache('folder/foo/2')); + + $this->assertTrue($this->cache->inCache('folder/bar')); + $this->assertTrue($this->cache->inCache('folder/foobar')); + $this->assertTrue($this->cache->inCache('folder/foobar/1')); + $this->assertTrue($this->cache->inCache('folder/foobar/2')); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 72c38686449a8887d8441377a11f0bfc910bc31f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:42:26 +0100 Subject: add resolvePath to filesystem view api --- lib/files/view.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 709e374d863..e3f9b762f7a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -101,6 +101,16 @@ class View { 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 -- cgit v1.2.3 From 706bb3ccd654f76c0a6c5b7874fcc1e288b13f54 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:47:00 +0100 Subject: move ETag generation to storage backends --- lib/connector/sabre/node.php | 16 +--------------- lib/files/filesystem.php | 10 ++++++++++ lib/files/storage/common.php | 16 ++++++++++++++++ lib/files/storage/storage.php | 8 ++++++++ lib/files/view.php | 15 +++++++++++++++ 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ebc9e539625..d0ab0c24988 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -210,27 +210,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return $props; } - /** - * 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); - } - } - /** * 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); + $tag = \OC\Files\Filesystem::getETag($path); if (empty($tag)) { return null; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 76a188e4120..ed2814211f4 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -654,6 +654,16 @@ class Filesystem { public static function getDirectoryContent($directory, $mimetype_filter = '') { return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); } + + /** + * 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_Filesystem', 'removeETagHook'); diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e22264d0da9..f471752d1ff 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -267,4 +267,20 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getOwner($path) { 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('', true); + } + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 1f5c9356294..bb1ba16984d 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -63,4 +63,12 @@ interface Storage{ public function getScanner(); public function getOwner($path); + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path); } diff --git a/lib/files/view.php b/lib/files/view.php index e3f9b762f7a..a54c3ee3564 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -866,4 +866,19 @@ class View { 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); + return $storage->getETag($internalPath); + } } -- cgit v1.2.3 From e7bed5ddabea5a3841d4a08082badaec025ed242 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:59:08 +0100 Subject: allow creating Cache objects with only the storage id instead of the whole storage object --- lib/files/cache/cache.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d13b56104d..dba026a611e 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -19,24 +19,25 @@ class Cache { const SHALLOW = 2; //folder in cache, but not all child files are completely scanned const COMPLETE = 3; - /** - * @var \OC\Files\Storage\Storage - */ - private $storage; - /** * @var array partial data for the cache */ private $partial = array(); + /** + * @var string + */ private $storageId; /** - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $storage */ - public function __construct(\OC\Files\Storage\Storage $storage) { - $this->storage = $storage; - $this->storageId = $storage->getId(); + public function __construct($storage) { + if($storage instanceof \OC\Files\Storage\Storage){ + $this->storageId = $storage->getId(); + }else{ + $this->storageId = $storage; + } } /** -- cgit v1.2.3 From 3f644fe70c8451ab1ab877c4dd97f34366548b70 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:07:30 +0100 Subject: fix calculateFolderSize for non existing files --- lib/files/cache/cache.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index dba026a611e..83d3585bb5f 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -348,6 +348,9 @@ class Cache { */ 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->storageId)); $totalSize = 0; -- cgit v1.2.3 From 15b8a3f98757f220db190c1e9489d5888b2b1015 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:10:54 +0100 Subject: move correctFolderSize from Scanner to Cache --- lib/files/cache/cache.php | 16 ++++++++++++++++ lib/files/cache/scanner.php | 16 ---------------- lib/files/cache/watcher.php | 2 +- tests/lib/files/cache/scanner.php | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 83d3585bb5f..7c6bba4fadb 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -340,6 +340,22 @@ class Cache { 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 * diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7062888d74a..0adde1d354d 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,20 +107,4 @@ class Scanner { } return $size; } - - /** - * update the folder size and the size of all parent folders - * - * @param $path - */ - public function correctFolderSize($path) { - $this->cache->calculateFolderSize($path); - if ($path !== '') { - $parent = dirname($path); - if ($parent === '.') { - $parent = ''; - } - $this->correctFolderSize($parent); - } - } } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index f04ca9b4656..d6039d9945c 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -50,7 +50,7 @@ class Watcher { } else { $this->scanner->scanFile($path); } - $this->scanner->correctFolderSize($path); + $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34d38c42736..f784a82dada 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -98,7 +98,7 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder2['size'], -1); - $this->scanner->correctFolderSize('folder'); + $this->cache->correctFolderSize('folder'); $cachedDataFolder = $this->cache->get(''); $this->assertNotEqual($cachedDataFolder['size'], -1); -- cgit v1.2.3 From 5a173b901f90dba3465847cde4477be9994a1341 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 20:47:40 +0100 Subject: fix Scanner->scan setting the filesize to 0 for files --- lib/files/cache/scanner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354d..eb947a2d53e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -101,9 +101,9 @@ class Scanner { } } } - } - if ($size !== -1) { - $this->cache->put($path, array('size' => $size)); + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } } return $size; } -- cgit v1.2.3 From fedff3eafe73a3eafbc1bc7af364297e8135d086 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:12:40 +0100 Subject: add cache updater --- lib/files/cache/updater.php | 71 +++++++++++++++++++++++ tests/lib/files/cache/updater.php | 116 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 lib/files/cache/updater.php create mode 100644 tests/lib/files/cache/updater.php diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php new file mode 100644 index 00000000000..fb9783023e8 --- /dev/null +++ b/lib/files/cache/updater.php @@ -0,0 +1,71 @@ + + * 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); + $cache = new Cache($storage); + $scanner = new Scanner($storage); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } + + static public function deleteUpdate($path) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($path); + $cache = new Cache($storage); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } + + /** + * @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']); + } +} diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php new file mode 100644 index 00000000000..8059418dc16 --- /dev/null +++ b/tests/lib/files/cache/updater.php @@ -0,0 +1,116 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +use \OC\Files\Filesystem as Filesystem; + +class Updater extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + private static $user; + + public function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + $this->storage->file_put_contents('folder/bar2.txt', $textData); + + $this->scanner = $this->storage->getScanner(); + $this->scanner->scan(''); + $this->cache = $this->storage->getCache(); + + if (!self::$user) { + if (!\OC\Files\Filesystem::getView()) { + self::$user = uniqid(); + \OC\Files\Filesystem::init('/' . self::$user . '/files'); + } else { + self::$user = \OC_User::getUser(); + } + } + + Filesystem::clearMounts(); + Filesystem::mount($this->storage, array(), '/' . self::$user . '/files'); + + \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'); + + } + + public function tearDown() { + $this->cache->clear(); + Filesystem::tearDown(); + } + + public function testWrite() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + Filesystem::file_put_contents('foo.txt', 'asd'); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::file_put_contents('bar.txt', 'asd'); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('bar.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + } + + public function testDelete() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + Filesystem::unlink('foo.txt', 'asd'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + } + + public function testRename() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::rename('foo.txt', 'bar.txt'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + } +} -- cgit v1.2.3 From d4858527c2fae4b58c5a9bc1c3aae9ada0ee7b24 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:35:30 +0100 Subject: fix rename parameter order --- apps/files/ajax/rename.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php index a2b9b8de257..470ee635a2a 100644 --- a/apps/files/ajax/rename.php +++ b/apps/files/ajax/rename.php @@ -11,9 +11,9 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $newname = stripslashes($_GET["newname"]); -if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { - $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); - $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); +if (($dir != '' || $file != 'Shared')) { + $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 { -- cgit v1.2.3 From 46071fed80c7375edf4788578776a6b313b6dca3 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:35:40 +0100 Subject: fix quota proxy --- lib/fileproxy/quota.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index b359b9ae023..a8219191bf3 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -22,7 +22,7 @@ */ /** - * user quota managment + * user quota management */ class OC_FileProxy_Quota extends OC_FileProxy{ @@ -39,10 +39,8 @@ class OC_FileProxy_Quota extends OC_FileProxy{ return $this->userQuota[$user]; } $userQuota=OC_Preferences::getValue($user, 'files', 'quota', 'default'); - $userQuota=OC_Preferences::getValue($user,'files','quota','default'); if($userQuota=='default') { $userQuota=OC_AppConfig::getValue('files', 'default_quota', 'none'); - $userQuota=OC_AppConfig::getValue('files','default_quota','none'); } if($userQuota=='none') { $this->userQuota[$user]=0; @@ -59,8 +57,12 @@ 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); $totalSpace=$this->getQuota($owner); if($totalSpace==0) { -- cgit v1.2.3 From 41a61bc637c3d60efc5abe81c39fc726fd78cd1d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:36:13 +0100 Subject: fix undefined index when loading files app --- apps/files/index.php | 4 +--- apps/files/templates/part.list.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index cdb88ab83f2..4e5f4cd93a8 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -66,9 +66,7 @@ foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i['extension']=''; } } - if($i['directory']=='/') { - $i['directory']=''; - } + $i['directory'] = $dir; $files[] = $i; } diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index 4b5ac325672..9c9d9926e55 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -18,7 +18,7 @@ $name = str_replace('%2F', '/', $name); $directory = str_replace('+', '%20', urlencode($file['directory'])); $directory = str_replace('%2F', '/', $directory); ?> - ' data-permissions=''> + ' data-permissions=''>
-- cgit v1.2.3 From cbcd9ba84ada830d91a6f1d7bee0ac59762835ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 00:57:30 +0100 Subject: allow storage backends to implement custom permission management --- lib/files/cache/permissions.php | 36 +++++++++++++++++++--------- lib/files/storage/common.php | 14 +++++++---- lib/files/storage/storage.php | 5 ++++ lib/files/view.php | 6 +++-- tests/lib/files/cache/permissions.php | 45 +++++++++++++++++++++-------------- tests/lib/files/cache/scanner.php | 3 ++- tests/lib/files/cache/watcher.php | 3 ++- tests/lib/files/view.php | 3 ++- 8 files changed, 76 insertions(+), 39 deletions(-) diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index dd7233abc70..d0968337f02 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -9,6 +9,22 @@ 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 * @@ -16,7 +32,7 @@ class Permissions { * @param string $user * @return int (-1 if file no permissions set) */ - static public function get($fileId, $user) { + 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()) { @@ -33,7 +49,7 @@ class Permissions { * @param string $user * @param int $permissions */ - static public function set($fileId, $user, $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 { @@ -49,7 +65,7 @@ class Permissions { * @param string $user * @return int[] */ - static public function getMultiple($fileIds, $user) { + public function getMultiple($fileIds, $user) { if (count($fileIds) === 0) { return array(); } @@ -72,17 +88,15 @@ class Permissions { * @param int $fileId * @param string $user */ - static public function remove($fileId, $user) { + public function remove($fileId, $user) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); $query->execute(array($fileId, $user)); } - static public function removeMultiple($fileIds, $user) { - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); - $query->execute($params); + 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)); + } } } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index f471752d1ff..cf6fe64a4f2 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= \OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= \OCP\Share::PERMISSION_READ; + $permissions |= \OCP\PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= \OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= \OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= \OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\PERMISSION_SHARE; } return $permissions; } @@ -259,6 +259,10 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Scanner($this); } + public function getPermissionsCache(){ + return new \OC\Files\Cache\Permissions($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bb1ba16984d..73dcb8fe36b 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -64,6 +64,11 @@ interface Storage{ public function getOwner($path); + /** + * @return \OC\Files\Cache\Permissions + */ + public function getPermissionsCache(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index a54c3ee3564..e516a4fed6a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -701,7 +701,8 @@ class View { } } - $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); return $data; } @@ -759,8 +760,9 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } + $permissionsCache = $storage->getPermissionsCache(); - $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { $files[$i]['permissions'] = $permissions[$file['fileid']]; } diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php index 4d47929a3ee..56dbbc4518e 100644 --- a/tests/lib/files/cache/permissions.php +++ b/tests/lib/files/cache/permissions.php @@ -9,39 +9,48 @@ namespace Test\Files\Cache; class Permissions extends \PHPUnit_Framework_TestCase { + /*** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + + function setUp(){ + $this->permissionsCache=new \OC\Files\Cache\Permissions('dummy'); + } + function testSimple() { $ids = range(1, 10); $user = uniqid(); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::set(1, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->set(1, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(1, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(2, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user . '2')); - \OC\Files\Cache\Permissions::set(1, $user, 2); - $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + $this->permissionsCache->set(1, $user, 2); + $this->assertEquals(2, $this->permissionsCache->get(1, $user)); - \OC\Files\Cache\Permissions::set(2, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->set(2, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); - \OC\Files\Cache\Permissions::remove(1, $user); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::remove(1, $user . '2'); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->remove(1, $user); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->remove(1, $user . '2'); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); $expected = array(); foreach ($ids as $id) { - \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $this->permissionsCache->set($id, $user, 10 + $id); $expected[$id] = 10 + $id; } - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + $this->permissionsCache->removeMultiple(array(10, 9), $user); unset($expected[9]); unset($expected[10]); - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + $this->permissionsCache->removeMultiple($ids, $user); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index f784a82dada..c53da92727c 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -112,7 +112,8 @@ class Scanner extends \UnitTestCase { function tearDown() { $ids = $this->cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $this->storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index a7076d9b0b5..0125dd843b9 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -23,7 +23,8 @@ class Watcher extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index fa562cb15cd..a173094b1cc 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -21,7 +21,8 @@ class View extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } -- cgit v1.2.3 From 5569f07e8d68716f01267c9f41e5f0be299cc67a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 22:04:48 +0100 Subject: add OC_FilesystemView alias for compatibility --- lib/filesystemview.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/filesystemview.php diff --git a/lib/filesystemview.php b/lib/filesystemview.php new file mode 100644 index 00000000000..37e2a737e04 --- /dev/null +++ b/lib/filesystemview.php @@ -0,0 +1,8 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +class OC_FilesystemView extends \OC\Files\View {} -- cgit v1.2.3 From 288ecf318cbb742b2c6a40d6c6afedfafb3cafd4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 22:08:08 +0100 Subject: add getFileInfo and getDirectoryContent to OC_Files for compatibility --- lib/files.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/files.php b/lib/files.php index e6b324f062b..3abc8c4aaf2 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,6 +28,14 @@ class OC_Files { static $tmpFiles = array(); + public function getFileInfo($path){ + return \OC\Files\Filesystem::getFileInfo($path); + } + + public function getDirectoryContent($path){ + return \OC\Files\Filesystem::getDirectoryContent($path); + } + /** * return the content of a file or return a zip file containning multiply files * -- cgit v1.2.3 From 54240140b10f2d718753445b656c9607967d7c64 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 16 Nov 2012 12:14:29 +0100 Subject: fix incorectly merged smb.php --- apps/files_external/lib/smb.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index bf0d780d27b..a4b2338e3b2 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -35,6 +35,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ if(substr($this->share, -1, 1)=='/') { $this->share = substr($this->share,0,-1); } + } public function getId(){ return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root; -- cgit v1.2.3 From 3358bface5c20aeb4ad41dc1edffb895bc24af71 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 16 Nov 2012 12:24:28 +0100 Subject: fix incorectly merged versions.php --- apps/files_versions/lib/versions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index b365f456792..7fe3d5549e9 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -189,7 +189,7 @@ class Storage { $i = 0; - $files_view = new \OC\Files\View('/' \OCP\User::getUser() . '/files'); + $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { -- cgit v1.2.3 From 40fae0acbf2e84782c273a82eb10a2ed9fdf8162 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 18 Nov 2012 14:10:28 +0100 Subject: fix outdated permissions cache use in scanner --- lib/files/cache/scanner.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index eb947a2d53e..404029ee2ef 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -19,12 +19,18 @@ class Scanner { */ private $cache; + /** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; - $this->cache = new Cache($storage); + $this->cache = $storage->getCache(); + $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -67,7 +73,7 @@ class Scanner { } } $id = $this->cache->put($file, $data); - Permissions::set($id, \OC_User::getUser(), $data['permissions']); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } -- cgit v1.2.3 From 77fdb16b7cb97f4e68949baf6796ef0e290b03f5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 22 Nov 2012 00:22:27 -0500 Subject: Remove incorrect extra parameter for init() call --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index 89fbcd05cda..c79afe19572 100755 --- a/lib/util.php +++ b/lib/util.php @@ -52,7 +52,7 @@ class OC_Util { } //jail the user into his "home" directory \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); - \OC\Files\Filesystem::init($user_dir, $user); + \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); $fileOperationProxy = new OC_FileProxy_FileOperations(); -- cgit v1.2.3 From b76d1afe193fae3bf94aed9a95e270b452e62eb8 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 22 Nov 2012 00:44:48 -0500 Subject: Create public function initMountPoints() for initializing a specified user's mount points --- lib/files/filesystem.php | 53 +++++++++++++++++++++++++++++++++--------------- lib/util.php | 16 --------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index ed2814211f4..cee3cd883b3 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -229,35 +229,50 @@ class Filesystem { self::$defaultInstance = new View($root); //load custom mount config - if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + 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(\OC_User::getUser(), $group)) { + if (\OC_Group::inGroup($user, $group)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $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 ($mountConfig['user'] as $mountUser => $mounts) { + if ($user === 'all' or strtolower($mountUser) === strtolower($user)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } @@ -265,10 +280,16 @@ class Filesystem { } } } - - self::$loaded = true; - - return true; + // Load personal mount points + $root = OC_User::getHome($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); + } + } + } } /** @@ -277,8 +298,8 @@ class Filesystem { * @param string $input * @return string */ - private static function setUserVars($input) { - return str_replace('$user', \OC_User::getUser(), $input); + private static function setUserVars($user, $input) { + return str_replace('$user', $user, $input); } /** diff --git a/lib/util.php b/lib/util.php index c79afe19572..25fdcef1aea 100755 --- a/lib/util.php +++ b/lib/util.php @@ -58,8 +58,6 @@ class OC_Util { $fileOperationProxy = new OC_FileProxy_FileOperations(); OC_FileProxy::register($quotaProxy); OC_FileProxy::register($fileOperationProxy); - // Load personal mount config - self::loadUserMountPoints($user); OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); } @@ -71,20 +69,6 @@ class OC_Util { self::$fsSetup=false; } - public static function loadUserMountPoints($user) { - $user_dir = '/'.$user.'/files'; - $user_root = OC_User::getHome($user); - $userdirectory = $user_root . '/files'; - if (is_file($user_root.'/mount.php')) { - $mountConfig = include $user_root.'/mount.php'; - if (isset($mountConfig['user'][$user])) { - foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); - } - } - } - } - /** * get the current installed version of ownCloud * @return array -- cgit v1.2.3 From 208c6fd966dd5f9f387cdd1b4f030a2723144347 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 22 Nov 2012 10:21:48 +0100 Subject: fixing namespace --- lib/files/filesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index cee3cd883b3..9e8ce3ec184 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,7 +281,7 @@ class Filesystem { } } // Load personal mount points - $root = OC_User::getHome($user); + $root = \OC_User::getHome($user); if (is_file($root.'/mount.php')) { $mountConfig = include $root.'/mount.php'; if (isset($mountConfig['user'][$user])) { -- cgit v1.2.3 From e6cf082fe07e4e33c883bd5f9aaa0cc72b082741 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 22:44:43 +0100 Subject: emit a hooks during the filesystem scan --- lib/files/cache/scanner.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 404029ee2ef..e650a220f56 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -14,6 +14,11 @@ class Scanner { */ private $storage; + /** + * @var string $storageId + */ + private $storageId; + /** * @var \OC\Files\Cache\Cache $cache */ @@ -29,6 +34,7 @@ class Scanner { public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; + $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); $this->permissionsCache = $storage->getPermissionsCache(); } @@ -62,6 +68,7 @@ class Scanner { * @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 ($file !== '') { $parent = dirname($file); @@ -85,6 +92,7 @@ class Scanner { * @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) { + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); $this->scanFile($path); $size = 0; -- cgit v1.2.3 From 186c9e77e89dcd057a311ed08df9e1bb9e13ea8f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:02:43 +0100 Subject: add Cache->getIncomplete for use in background scanning --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7c6bba4fadb..b52c0f40677 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -402,4 +402,23 @@ class Cache { } 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->storageId)); + if($row = $query->fetchRow()){ + return $row['path']; + }else{ + return false; + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9c469aa9374..e9105cd5abd 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -175,6 +175,23 @@ class Cache extends \UnitTestCase { $this->assertTrue($this->cache->inCache('folder/foobar/2')); } + function testGetIncomplete() { + $file1 = 'folder1'; + $file2 = 'folder2'; + $file3 = 'folder3'; + $file4 = 'folder4'; + $data = array('size' => 10, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $data['size'] = -1; + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $data['size'] = 12; + $this->cache->put($file4, $data); + + $this->assertEquals($file3, $this->cache->getIncomplete()); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 8687e0d346e7dad6890982c1a7b08befd8998aeb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:18:58 +0100 Subject: add Scanner->backgroundScan --- lib/files/cache/scanner.php | 10 ++++++++++ tests/lib/files/cache/scanner.php | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e650a220f56..3c83b6528a7 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -121,4 +121,14 @@ class Scanner { } 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); + } + } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index c53da92727c..6d26150d82b 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -104,6 +104,28 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder['size'], -1); } + function testBackgroundScan(){ + $this->fillTestFolders(); + $this->storage->mkdir('folder2'); + $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertFalse($this->cache->inCache('folder/bar.txt')); + $this->assertFalse($this->cache->inCache('folder/2bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(-1, $cachedData['size']); + + $this->scanner->backgroundScan(); + + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + + $cachedData = $this->cache->get(''); + $this->assertnotEquals(-1, $cachedData['size']); + + $this->assertFalse($this->cache->getIncomplete()); + } + function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); $this->scanner = new \OC\Files\Cache\Scanner($this->storage); -- cgit v1.2.3 From 810563ae8aa5884a101cc64226c4f8c3c897132e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 Nov 2012 12:44:31 +0100 Subject: don't redefine inherited functions as abstract --- lib/files/storage/common.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index cf6fe64a4f2..9978cea5712 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,18 +23,12 @@ namespace OC\Files\Storage; abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} - abstract public function getId(); - 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 @@ -46,8 +40,6 @@ abstract class Common implements \OC\Files\Storage\Storage { public function isCreatable($path) { return $this->isUpdatable($path); } - abstract public function isReadable($path); - abstract public function isUpdatable($path); public function isDeletable($path) { return $this->isUpdatable($path); } @@ -73,7 +65,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } return $permissions; } - abstract public function file_exists($path); public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; @@ -97,7 +88,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $handle = $this->fopen($path, "w"); return fwrite($handle, $data); } - abstract public function unlink($path); public function rename($path1,$path2) { if($this->copy($path1,$path2)) { return $this->unlink($path1); @@ -111,7 +101,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $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 @@ -180,7 +169,6 @@ abstract class Common implements \OC\Files\Storage\Storage { unlink($tmpFile); return $hash; } - abstract public function free_space($path); public function search($query) { return $this->searchInDir($query); } @@ -222,7 +210,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } } } - abstract public function touch($path, $mtime=null); protected function searchInDir($query,$dir='') { $files=array(); -- cgit v1.2.3 From 8ce5e0d30d874bf59a81aa01202a497ea4cb8492 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 Nov 2012 13:14:39 +0100 Subject: don't throw fatal error in updater cache if setup failed for some reason --- tests/lib/files/cache/updater.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 8059418dc16..b2eccf9130a 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -61,7 +61,9 @@ class Updater extends \PHPUnit_Framework_TestCase { } public function tearDown() { - $this->cache->clear(); + if($this->cache){ + $this->cache->clear(); + } Filesystem::tearDown(); } -- cgit v1.2.3 From ad706229f5dbc6382ade61493e9f100a2dc07293 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 00:17:18 +0100 Subject: explicitly sort files when using getFolderContents --- lib/files/cache/cache.php | 14 +++++++------- tests/lib/files/view.php | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index b52c0f40677..6b93673097b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -33,9 +33,9 @@ class Cache { * @param \OC\Files\Storage\Storage|string $storage */ public function __construct($storage) { - if($storage instanceof \OC\Files\Storage\Storage){ + if ($storage instanceof \OC\Files\Storage\Storage) { $this->storageId = $storage->getId(); - }else{ + } else { $this->storageId = $storage; } } @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ?'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { @@ -364,7 +364,7 @@ class Cache { */ public function calculateFolderSize($path) { $id = $this->getId($path); - if($id === -1){ + if ($id === -1) { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); @@ -412,12 +412,12 @@ class Cache { * * @return string|bool the path of the folder or false when no folder matched */ - public function getIncomplete(){ + 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->storageId)); - if($row = $query->fetchRow()){ + if ($row = $query->fetchRow()) { return $row['path']; - }else{ + } else { return false; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index a173094b1cc..ecfc803dc23 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,20 +55,20 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: - * folder * foo.png * foo.txt + * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('folder', $folderData[0]['name']); - $this->assertEquals('foo.png', $folderData[1]['name']); - $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); - $this->assertEquals($imageSize, $folderData[1]['size']); - $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($imageSize, $folderData[0]['size']); + $this->assertEquals($textSize, $folderData[1]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderView = new \OC\Files\View('/folder'); -- cgit v1.2.3 From 8fb4dfd2eabcc267725d3c151d93644d6f28f010 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 00:20:46 +0100 Subject: use background scanner --- apps/files/ajax/scan.php | 89 +++++++++++++++++++++++++++++++----------------- apps/files/js/files.js | 38 ++++++++------------- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 91b20fa8362..53ae4f5ff04 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -1,45 +1,70 @@ getAbsolutePath($dir); -$force=isset($_GET['force']) and $_GET['force']=='true'; -$dir=isset($_GET['dir'])?$_GET['dir']:''; -$checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true'; +$mountPoints = \OC\Files\Filesystem::getMountPoints($absolutePath); +$mountPoints[] = \OC\Files\Filesystem::getMountPoint($absolutePath); +$mountPoints = array_reverse($mountPoints); //start with the mount point of $dir -if(!$checkOnly) { - $eventSource=new OC_EventSource(); +foreach ($mountPoints as $mountPoint) { + $storage = \OC\Files\Filesystem::getStorage($mountPoint); + error_log('scanning mp '.$mountPoint); + ScanListener::$mountPoints[$storage->getId()] = $mountPoint; + $scanner = $storage->getScanner(); + if ($force) { + $scanner->scan(''); + } else { + $scanner->backgroundScan(); + } } -session_write_close(); +$eventSource->send('done', ScanListener::$fileCount); +$eventSource->close(); -//create the file cache if necesary -if($force or !OC_FileCache::inCache('')) { - if(!$checkOnly) { - OCP\DB::beginTransaction(); +class ScanListener { - if(OC_Cache::isFast()) { - OC_Cache::clear('fileid/'); //make sure the old fileid's don't mess things up - } + static public $fileCount = 0; + static public $lastCount = 0; - 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; + /** + * @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); } - if(isset($eventSource)) { - $eventSource->send('success', false); - } else { - exit; + + 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); + } } } -$eventSource->close(); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index bb80841055b..f95bfa2bf8f 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -602,12 +602,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 = []; @@ -676,27 +672,23 @@ $(document).ready(function() { resizeBreadcrumbs(true); }); -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('folder',function(path){ + console.log('now scanning ' + path) }); - scannerEventSource.listen('success',function(success){ + 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; -- cgit v1.2.3 From c47bf9bbcefb0640c24ab0aa6ee79f4c52222b45 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 16:42:54 -0500 Subject: Add checks for storage object --- apps/files/ajax/scan.php | 15 ++-- lib/files/view.php | 207 +++++++++++++++++++++++++---------------------- 2 files changed, 120 insertions(+), 102 deletions(-) diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 53ae4f5ff04..391b98608bd 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -20,13 +20,14 @@ $mountPoints = array_reverse($mountPoints); //start with the mount point of $dir foreach ($mountPoints as $mountPoint) { $storage = \OC\Files\Filesystem::getStorage($mountPoint); - error_log('scanning mp '.$mountPoint); - ScanListener::$mountPoints[$storage->getId()] = $mountPoint; - $scanner = $storage->getScanner(); - if ($force) { - $scanner->scan(''); - } else { - $scanner->backgroundScan(); + if ($storage) { + ScanListener::$mountPoints[$storage->getId()] = $mountPoint; + $scanner = $storage->getScanner(); + if ($force) { + $scanner->scan(''); + } else { + $scanner->backgroundScan(); + } } } diff --git a/lib/files/view.php b/lib/files/view.php index e516a4fed6a..468808566a7 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -671,39 +671,41 @@ class View { * - 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); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); + } - $data = $cache->get($internalPath); + $data = $cache->get($internalPath); - 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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); + 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); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); - $data['size'] += $rootEntry['size']; + $data['size'] += $rootEntry['size']; + } } - } - - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + } return $data; } @@ -714,75 +716,79 @@ class View { * @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); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $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']; + //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(); + $rootEntry = $subCache->get(''); + + $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; + $files[] = $rootEntry; } } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $files[] = $rootEntry; } - } - $ids = array(); + $ids = array(); - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache(); + foreach ($files as $i => $file) { + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + $permissionsCache = $storage->getPermissionsCache(); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; + } - 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; + 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; } - } else { - $result = $files; } - return $result; } @@ -802,14 +808,18 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } - return $cache->put($internalPath, $data); + return $cache->put($internalPath, $data); + } else { + return -1; + } } /** @@ -843,29 +853,32 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); - $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; + 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; } @@ -881,6 +894,10 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = $this->resolvePath($path); - return $storage->getETag($internalPath); + if ($storage) { + return $storage->getETag($internalPath); + } else { + return null; + } } } -- cgit v1.2.3 From d3e37fa157faa59598e92a9aa02c6bbf818b60e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 16:23:52 +0100 Subject: remove fileatime from common storage backend --- lib/fileproxy.php | 2 +- lib/files/storage/common.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/fileproxy.php b/lib/fileproxy.php index 2f81bde64a1..52ec79b4bdb 100644 --- a/lib/fileproxy.php +++ b/lib/fileproxy.php @@ -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 */ diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 9978cea5712..c891d0c3ad0 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -69,10 +69,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $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) { -- cgit v1.2.3 From 709aacfa0fef29692bff231f09625db5ba0bef6f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 24 Nov 2012 23:41:39 +0100 Subject: change behaviour of Filesystem::getMountPoint when a mountpoint is passed as path without trailing slash --- lib/files/filesystem.php | 8 +------- tests/lib/files/filesystem.php | 2 +- tests/lib/files/view.php | 12 ++++++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 9e8ce3ec184..4e3eb1989b7 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -144,13 +144,7 @@ class Filesystem { */ 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); + $path = self::normalizePath($path) . '/'; $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 363426511bd..5837093fdd6 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -60,7 +60,7 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/folder')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/')); - $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some')); list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); $this->assertEquals('folder',$internalPath); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ecfc803dc23..6f8d29c25b2 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -71,6 +71,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + $folderData = $rootView->getDirectoryContent('/substorage'); + /** + * expected entries: + * foo.png + * foo.txt + * folder + */ + $this->assertEquals(3, count($folderData)); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); + $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); -- cgit v1.2.3 From cc5d8e56098189f49fbd68c598c11be2b8354846 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 20:29:57 -0500 Subject: Check if data variable in scanner isn't null before using it --- lib/files/cache/scanner.php | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 3c83b6528a7..9ee509bb132 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -70,17 +70,19 @@ class Scanner { public function scanFile($file) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); - if ($file !== '') { - $parent = dirname($file); - if ($parent === '.') { - $parent = ''; - } - if (!$this->cache->inCache($parent)) { - $this->scanFile($parent); + if ($data) { + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } } + $id = $this->cache->put($file, $data); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } - $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } @@ -101,17 +103,19 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($data['mimetype'] === 'httpd/unix-directory') { - if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); - } else { - $data['size'] = -1; + if ($data) { + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } + } + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { + $size += $data['size']; } - } - if ($data['size'] === -1) { - $size = -1; - } elseif ($size !== -1) { - $size += $data['size']; } } } -- cgit v1.2.3 From 0cfef83ed98951f852b07ce61dc10ee2e8266445 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:08:35 +0100 Subject: sort output of getFolderContent by name --- lib/files/cache/cache.php | 2 +- tests/lib/files/view.php | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6b93673097b..bc52f21d910 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6f8d29c25b2..ed08dcc1148 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,33 +55,33 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: + * folder * foo.png * foo.txt - * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($imageSize, $folderData[0]['size']); - $this->assertEquals($textSize, $folderData[1]['size']); - $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderData = $rootView->getDirectoryContent('/substorage'); /** * expected entries: + * folder * foo.png * foo.txt - * folder */ $this->assertEquals(3, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); -- cgit v1.2.3 From a609992a75d1dad15398f55e22ad2244c78650dc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:30:57 +0100 Subject: better check if we are passing a fileid to Cache::get --- lib/files/cache/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index bc52f21d910..5aeb6f25af0 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -47,7 +47,7 @@ class Cache { * @return array */ public function get($file) { - if (is_string($file)) { + if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; $params = array($this->storageId, md5($file)); } else { //file id -- cgit v1.2.3 From dbbb357f62c1ba86bdff0fbe63e4cea9bc2977fc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 30 Nov 2012 01:41:30 +0100 Subject: add upgrade path from old cache to preserve file id's --- apps/files/appinfo/app.php | 14 +++++++++++-- apps/files/appinfo/version | 2 +- lib/files/cache/upgrade.php | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 lib/files/cache/upgrade.php diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index b431ddfec02..fb64a80ec0d 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -1,8 +1,18 @@ "files_index", "order" => 0, "href" => OCP\Util::linkTo( "files", "index.php" ), "icon" => OCP\Util::imagePath( "core", "places/home.svg" ), "name" => $l->t("Files") )); +OCP\App::addNavigationEntry(array("id" => "files_index", "order" => 0, "href" => OCP\Util::linkTo("files", "index.php"), "icon" => OCP\Util::imagePath("core", "places/home.svg"), "name" => $l->t("Files"))); OC_Search::registerProvider('OC_Search_Provider_File'); + +if (OC_User::isLoggedIn()) { + // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually + $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); + if ($cacheVersion < 5) { + \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); + \OC\Files\Cache\Upgrade::upgrade(); + OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); + } +} diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version index 0664a8fd291..2bf1ca5f549 100644 --- a/apps/files/appinfo/version +++ b/apps/files/appinfo/version @@ -1 +1 @@ -1.1.6 +1.1.7 diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php new file mode 100644 index 00000000000..5be04b42070 --- /dev/null +++ b/lib/files/cache/upgrade.php @@ -0,0 +1,50 @@ + + * 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 { + static $permissionsCaches = array(); + + static function upgrade() { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + $oldEntriesResult = $oldEntriesQuery->execute(); + + while ($row = $oldEntriesResult->fetchRow()) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath; + */ + $pathHash = md5($internalPath); + $storageId = $storage->getId(); + $parentId = ($internalPath === '') ? -1 : $row['parent']; + + $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); + + $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; + $permissionsCache = self::getPermissionsCache($storage); + $permissionsCache->set($row['id'], $row['user'], $permissions); + } + } + + /** + * @param \OC\Files\Storage\Storage $storage + * @return Permissions + */ + static function getPermissionsCache($storage) { + $storageId = $storage->getId(); + if (!isset(self::$permissionsCaches[$storageId])) { + self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + } + return self::$permissionsCaches[$storageId]; + } +} -- cgit v1.2.3 From 702444b2422326388e494091e815fd3d9b03cc87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 1 Dec 2012 00:59:49 +0100 Subject: fail gracefully when no old filecache is present during upgrade --- lib/files/cache/upgrade.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 5be04b42070..899f6f7ac83 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -16,7 +16,14 @@ class Upgrade { VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - $oldEntriesResult = $oldEntriesQuery->execute(); + try{ + $oldEntriesResult = $oldEntriesQuery->execute(); + }catch(\Exception $e){ + return; + } + if(!$oldEntriesResult){ + return; + } while ($row = $oldEntriesResult->fetchRow()) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); -- cgit v1.2.3 From 01eb5d2790638ab836adc95a9726b6a1003562b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 2 Dec 2012 03:43:51 +0100 Subject: fix some edge cases while scanning the root of a storage --- lib/files/cache/scanner.php | 4 ++-- lib/files/filesystem.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 9ee509bb132..4c0ec9617f9 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -71,7 +71,7 @@ class Scanner { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { - if ($file !== '') { + if ($file) { $parent = dirname($file); if ($parent === '.') { $parent = ''; @@ -101,7 +101,7 @@ class Scanner { if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = ($path !== '') ? $path . '/' . $file : $file; + $child = ($path) ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4e3eb1989b7..724c83b3618 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -143,8 +143,8 @@ class Filesystem { * @return string */ static public function getMountPoint($path) { - \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $path = self::normalizePath($path) . '/'; + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { @@ -205,7 +205,7 @@ class Filesystem { $mountpoint = self::getMountPoint($path); if ($mountpoint) { $storage = self::getStorage($mountpoint); - if ($mountpoint === $path) { + if ($mountpoint === $path or $mountpoint . '/' === $path) { $internalPath = ''; } else { $internalPath = substr($path, strlen($mountpoint)); -- cgit v1.2.3 From 18663100d9f68400fba1fc344874aacb62bb4659 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Sun, 2 Dec 2012 12:12:20 +0100 Subject: fixing syntax error + reformat the code --- apps/files_sharing/public.php | 356 ++++++++++++++++++++++-------------------- 1 file changed, 184 insertions(+), 172 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index fcf7063955e..27d2b9dfa48 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -9,10 +9,10 @@ if (isset($_GET['token'])) { unset($_GET['file']); $qry = \OC_DB::prepare('SELECT `source` FROM `*PREFIX*sharing` WHERE `target` = ? LIMIT 1'); $filepath = $qry->execute(array($_GET['token']))->fetchOne(); - if(isset($filepath)) { + if (isset($filepath)) { $rootView = new \OC\Files\View(''); $info = $rootView->getFileInfo($filepath, ''); - if(strtolower($info['mimetype']) == 'httpd/unix-directory') { + if (strtolower($info['mimetype']) == 'httpd/unix-directory') { $_GET['dir'] = $filepath; } else { $_GET['file'] = $filepath; @@ -27,7 +27,7 @@ function getID($path) { if (substr(\OC\Files\Filesystem::getMountPoint($path), -7, 6) == "Shared") { $path_parts = explode('/', $path, 5); $user = $path_parts[1]; - $intPath = '/'.$path_parts[4]; + $intPath = '/' . $path_parts[4]; $query = \OC_DB::prepare('SELECT `item_source` FROM `*PREFIX*share` WHERE `uid_owner` = ? AND `file_target` = ? '); $result = $query->execute(array($user, $intPath)); $row = $result->fetchRow(); @@ -40,11 +40,12 @@ function getID($path) { 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 */ @@ -64,60 +65,62 @@ if (isset($_GET['t'])) { $type = $linkItem['item_type']; $fileSource = $linkItem['file_source']; $shareOwner = $linkItem['uid_owner']; - - if (OCP\User::userExists($shareOwner) && $fileSource != -1 ) { - + + if (OCP\User::userExists($shareOwner) && $fileSource != -1) { + $pathAndUser = getPathAndUser($linkItem['file_source']); $fileOwner = $pathAndUser['user']; - + //if this is a reshare check the file owner also exists - if ($shareOwner != $fileOwner && ! OCP\User::userExists($fileOwner)) { - OCP\Util::writeLog('share', 'original file owner '.$fileOwner.' does not exist for share '.$linkItem['id'], \OCP\Util::ERROR); - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); + if ($shareOwner != $fileOwner && !OCP\User::userExists($fileOwner)) { + OCP\Util::writeLog('share', 'original file owner ' . $fileOwner . ' does not exist for share ' . $linkItem['id'], \OCP\Util::ERROR); + header('HTTP/1.0 404 Not Found'); + $tmpl = new OCP\Template('', '404', 'guest'); + $tmpl->printPage(); + exit(); } - + //mount filesystem of file owner 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); - } - $baseDir = $path; - $dir = $baseDir; - } else { - $type = 'file'; - $path = $_GET['file']; - 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); + } } - } - $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]; + $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 ($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(); @@ -125,11 +128,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']; @@ -137,7 +142,7 @@ if ($linkItem) { // Check Password $forcePortable = (CRYPT_BLOWFISH != 1); $hasher = new PasswordHash(8, $forcePortable); - if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) { + if (!($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) { $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); $tmpl->assign('URL', $url); $tmpl->assign('error', true); @@ -148,28 +153,30 @@ if ($linkItem) { $_SESSION['public_link_authenticated'] = $linkItem['id']; } } else { - OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type'].' for share id '.$linkItem['id'], \OCP\Util::ERROR); + OCP\Util::writeLog('share', 'Unknown share type ' . $linkItem['share_type'] . ' for share id ' . $linkItem['id'], \OCP\Util::ERROR); header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); exit(); } - // Check if item id is set in session - } else if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) { - // Prompt for password - $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); - $tmpl->assign('URL', $url); - $tmpl->printPage(); - exit(); + // Check if item id is set in session + } else { + if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) { + // Prompt for password + $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); + $tmpl->assign('URL', $url); + $tmpl->printPage(); + exit(); + } } } - $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); + 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(); @@ -179,13 +186,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); @@ -206,7 +215,7 @@ if ($linkItem) { $getPath = ''; } // - $urlLinkIdentifiers= (isset($token)?'&t='.$token:'').(isset($_GET['dir'])?'&dir='.$_GET['dir']:'').(isset($_GET['file'])?'&file='.$_GET['file']:''); + $urlLinkIdentifiers = (isset($token) ? '&t=' . $token : '') . (isset($_GET['dir']) ? '&dir=' . $_GET['dir'] : '') . (isset($_GET['file']) ? '&file=' . $_GET['file'] : ''); // Show file list if (OC_Filesystem::is_dir($path)) { OCP\Util::addStyle('files', 'files'); @@ -219,9 +228,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'] = ''; } @@ -238,98 +247,31 @@ if ($linkItem) { //add subdir breadcrumbs foreach (explode('/', urldecode($_GET['path'])) 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_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); + $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').'&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', '' ); + $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').'&dir='.urlencode($_GET['dir']).'&path=', 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('dir', basename($dir)); $folder->assign('isCreatable', false); $folder->assign('permissions', 0); $folder->assign('files', $files); @@ -337,43 +279,113 @@ if ($linkItem) { $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_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); + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); } 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_Filesystem::getMimeType($path)); if ($type == 'file') { - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.urlencode($_GET['file']).'&download', false); + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download'); } else { - if (isset($_GET['path'])) { - $getPath = $_GET['path']; + 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_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_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 { - $getPath = ''; + // 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_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->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.urlencode($_GET['dir']).'&path='.urlencode($getPath), false); + $tmpl->printPage(); } } $tmpl->printPage(); } + exit(); + } else { + 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(); + -- cgit v1.2.3 From 317cd4c70a3042c4e16424cafb4a8b34c8cd8c3c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 6 Dec 2012 17:49:35 +0100 Subject: catch error if old filecache table is not present during upgrade --- lib/files/cache/upgrade.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 899f6f7ac83..ebac387de96 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -15,13 +15,17 @@ class Upgrade { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - try{ + try { + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + } catch (\Exception $e) { + return; + } + try { $oldEntriesResult = $oldEntriesQuery->execute(); - }catch(\Exception $e){ + } catch (\Exception $e) { return; } - if(!$oldEntriesResult){ + if (!$oldEntriesResult) { return; } -- cgit v1.2.3 From 8635699db932959ac147193473b014406b0e9e09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:06:21 +0100 Subject: fix cache behaviour for non existing files --- lib/files/view.php | 28 +++++++++++++++------------- tests/lib/files/cache/cache.php | 5 +++++ tests/lib/files/view.php | 3 +++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 468808566a7..994dbcc85cf 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -691,20 +691,22 @@ class View { $data = $cache->get($internalPath); - 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); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if ($data) { + 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); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } } - } - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + } } return $data; } @@ -888,7 +890,7 @@ class View { * @param string $path * @return string */ - public function getETag($path){ + public function getETag($path) { /** * @var Storage\Storage $storage * @var string $internalPath diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index e9105cd5abd..a2b131ac0ac 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -192,6 +192,11 @@ class Cache extends \UnitTestCase { $this->assertEquals($file3, $this->cache->getIncomplete()); } + function testNonExisting() { + $this->assertFalse($this->cache->get('foo.txt')); + $this->assertEquals(array(), $this->cache->getFolderContents('foo')); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ed08dcc1148..1b8f6dc1e8c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -92,6 +92,9 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertTrue($cachedData['encrypted']); $this->assertEquals($cachedData['fileid'], $id); + + $this->assertFalse($rootView->getFileInfo('/non/existing')); + $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } public function testAutoScan() { -- cgit v1.2.3 From 438d3c21f651240e416b6e50ad49f72dd079a9ae Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:24:53 +0100 Subject: actually connect the filesystem hooks to the cache updater --- lib/files/filesystem.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 724c83b3618..c5b56ba9f01 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -685,4 +685,8 @@ class Filesystem { \OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); +\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(); -- cgit v1.2.3 From cc0a0df88b3b6fdd2b1f9c85349683eb640f9670 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:25:21 +0100 Subject: one additional test case for the cache updater --- tests/lib/files/cache/updater.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index b2eccf9130a..d19966c1910 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -99,6 +99,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + + Filesystem::mkdir('bar_folder'); + $this->assertTrue($this->cache->inCache('bar_folder')); + Filesystem::rmdir('bar_folder'); + $this->assertFalse($this->cache->inCache('bar_folder')); } public function testRename() { -- cgit v1.2.3 From c6a5ce54a706efe6d157ec30a3960a3ebf8719a7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 02:22:09 +0100 Subject: these functions should be static --- lib/files.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/files.php b/lib/files.php index 768a2ad2191..2d7e335e969 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,11 +28,11 @@ class OC_Files { static $tmpFiles = array(); - public function getFileInfo($path){ + static public function getFileInfo($path){ return \OC\Files\Filesystem::getFileInfo($path); } - public function getDirectoryContent($path){ + static public function getDirectoryContent($path){ return \OC\Files\Filesystem::getDirectoryContent($path); } -- cgit v1.2.3 From bc52f121626bb1bb1f67bc1f876d0420d153b3d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 02:29:34 +0100 Subject: dont insert and entry in the filecache during upgrade if the id already exists in the filecache most likely the result from an incompelte upgrade --- lib/files/cache/upgrade.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index ebac387de96..9219deebef5 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -29,7 +29,13 @@ class Upgrade { return; } + $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + while ($row = $oldEntriesResult->fetchRow()) { + if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + continue; + } + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); /** * @var \OC\Files\Storage\Storage $storage -- cgit v1.2.3 From 4be039e6cbc0a826b07fc2af1a6c6d94888a9187 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:10:56 +0100 Subject: Filecache Watcher: use scan or scanFile based on the current item, not the cached item --- lib/files/cache/watcher.php | 6 ++++-- tests/lib/files/cache/watcher.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index d6039d9945c..31059ec7f56 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -44,12 +44,14 @@ class Watcher { public function checkUpdate($path) { $cachedEntry = $this->cache->get($path); if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) { - if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + if ($this->storage->is_dir($path)) { $this->scanner->scan($path, Scanner::SCAN_SHALLOW); - $this->cleanFolder($path); } else { $this->scanner->scanFile($path); } + if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->cleanFolder($path); + } $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 0125dd843b9..07c8ac3640c 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -63,6 +63,40 @@ class Watcher extends \PHPUnit_Framework_TestCase { $this->assertFalse($cache->inCache('folder/bar2.txt')); } + public function testFileToFolder() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate(''); + + $entry= $cache->get('foo.txt'); + $this->assertEquals(-1, $entry['size']); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertFalse($cache->inCache('folder')); + $this->assertFalse($cache->inCache('folder/bar.txt')); + + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('foo.txt', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate('foo.txt'); + + $entry= $cache->get('foo.txt'); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertTrue($cache->inCache('foo.txt/bar.txt')); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage -- cgit v1.2.3 From cf3665057c0c195bb3a0e2d9f8f8746f5d2f5787 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:20:50 +0100 Subject: make sure folders that are not fully scanned are at least shallow scanned when we open them the fact that they are in the cache does not mean they are scanned --- lib/files/view.php | 2 +- tests/lib/files/view.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index 994dbcc85cf..6d917bb585e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -728,7 +728,7 @@ class View { if ($storage) { $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { + if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 1b8f6dc1e8c..712166ab32c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -97,6 +97,19 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testCacheIncompleteFolder() { + $storage1 = $this->getTestStorage(false); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + $rootView = new \OC\Files\View(''); + + $entries = $rootView->getDirectoryContent('/'); + $this->assertEquals(3, count($entries)); + + // /folder will already be in the cache but not scanned + $entries = $rootView->getDirectoryContent('/folder'); + $this->assertEquals(1, count($entries)); + } + public function testAutoScan() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(false); -- cgit v1.2.3 From 8951769cae5f1acc9b709ac676fffe26513d14f6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 15 Dec 2012 17:16:26 -0500 Subject: Check sub storage isn't null or false --- lib/files/view.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 6d917bb585e..592c484a21c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -697,10 +697,11 @@ class View { $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if ($subStorage) { + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + $data['size'] += $rootEntry['size']; + } } } -- cgit v1.2.3 From b12abb2c94072ab5b84d0477ecb7ce9789bdda0d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 23:28:07 +0100 Subject: use numeric ids for storages in the filecache --- db_structure.xml | 40 ++++++++++++++++++++++++++++++++++++++-- lib/files/cache/cache.php | 44 ++++++++++++++++++++++++++++++++++---------- lib/files/cache/upgrade.php | 21 +++++++++++++++++++-- lib/util.php | 2 +- 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 2856ee4ff94..aa0916264c9 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -58,6 +58,42 @@
+ + + *dbprefix*storages + + + + + id + text + + true + 64 + + + + numeric_id + integer + 0 + true + 1 + 4 + + + + storages_id_index + true + + id + ascending + + + + + +
+ *dbprefix*filecache @@ -75,10 +111,10 @@ storage - text + integer true - 64 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5aeb6f25af0..3ebae9baa5d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -29,6 +29,13 @@ class Cache { */ private $storageId; + /** + * numeric storage id + * + * @var int $numericId + */ + private $numericId; + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -38,6 +45,20 @@ class Cache { } 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; } /** @@ -49,7 +70,7 @@ class Cache { public function get($file) { if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($this->storageId, md5($file)); + $params = array($this->numericId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -128,7 +149,7 @@ class Cache { list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $this->storageId; + $params[] = $this->numericId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); @@ -189,7 +210,7 @@ class Cache { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -273,7 +294,10 @@ class Cache { * 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 = \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)); } @@ -285,7 +309,7 @@ class Cache { 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->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { return self::SHALLOW; @@ -312,7 +336,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' ); - $result = $query->execute(array($pattern, $this->storageId)); + $result = $query->execute(array($pattern, $this->numericId)); $files = array(); while ($row = $result->fetchRow()) { $files[] = $row; @@ -336,7 +360,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); - $result = $query->execute(array($mimetype, $this->storageId)); + $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } @@ -368,7 +392,7 @@ class Cache { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); - $result = $query->execute(array($id, $this->storageId)); + $result = $query->execute(array($id, $this->numericId)); $totalSize = 0; $hasChilds = 0; while ($row = $result->fetchRow()) { @@ -395,7 +419,7 @@ class Cache { */ public function getAll() { $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); - $result = $query->execute(array($this->storageId)); + $result = $query->execute(array($this->numericId)); $ids = array(); while ($row = $result->fetchRow()) { $ids[] = $row['fileid']; @@ -414,7 +438,7 @@ class Cache { */ 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->storageId)); + $query->execute(array($this->numericId)); if ($row = $query->fetchRow()) { return $row['path']; } else { diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 9219deebef5..77db4c2339e 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -11,6 +11,8 @@ namespace OC\Files\Cache; class Upgrade { static $permissionsCaches = array(); + static $numericIds = array(); + static function upgrade() { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); @@ -32,7 +34,7 @@ class Upgrade { $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); while ($row = $oldEntriesResult->fetchRow()) { - if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { continue; } @@ -42,7 +44,7 @@ class Upgrade { * @var string $internalPath; */ $pathHash = md5($internalPath); - $storageId = $storage->getId(); + $storageId = self::getNumericId($storage); $parentId = ($internalPath === '') ? -1 : $row['parent']; $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); @@ -64,4 +66,19 @@ class Upgrade { } return self::$permissionsCaches[$storageId]; } + + /** + * get the numeric storage id + * + * @param \OC\Files\Storage\Storage $storage + * @return int + */ + static function getNumericId($storage) { + $storageId = $storage->getId(); + if (!isset(self::$numericIds[$storageId])) { + $cache = new Cache($storage); + self::$numericIds[$storageId] = $cache->getNumericStorageId(); + } + return self::$numericIds[$storageId]; + } } diff --git a/lib/util.php b/lib/util.php index 0f6ead24190..4411b327310 100755 --- a/lib/util.php +++ b/lib/util.php @@ -75,7 +75,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,02); + return array(4,91,04); } /** -- cgit v1.2.3 From bf05ff351faa693337107ed4a316e36e9aacd296 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 15 Dec 2012 19:44:46 -0500 Subject: Initial support for file sharing with filesystem branch --- apps/files_sharing/appinfo/app.php | 3 + apps/files_sharing/lib/cache.php | 220 +++++++++++++++++++++++++++++++ apps/files_sharing/lib/permissions.php | 82 ++++++++++++ apps/files_sharing/lib/scanner.php | 69 ++++++++++ apps/files_sharing/lib/share/file.php | 74 ++++++----- apps/files_sharing/lib/share/folder.php | 28 ---- apps/files_sharing/lib/sharedstorage.php | 148 +++++++++------------ lib/public/share.php | 8 +- 8 files changed, 475 insertions(+), 157 deletions(-) create mode 100644 apps/files_sharing/lib/cache.php create mode 100644 apps/files_sharing/lib/permissions.php create mode 100644 apps/files_sharing/lib/scanner.php diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 210c78ad174..189fd20cae3 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -3,6 +3,9 @@ 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\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_Scanner'] = 'apps/files_sharing/lib/scanner.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'); diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php new file mode 100644 index 00000000000..196e767cf6e --- /dev/null +++ b/apps/files_sharing/lib/cache.php @@ -0,0 +1,220 @@ +. +*/ + +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(); + + /** + * @brief Get the source cache of a shared file or folder + * @param string Shared target file path + * @return \OC\Files\Storage\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']); + $this->files[$target] = $internalPath; + return $storage->getCache(); + } + return false; + } + + /** + * get the stored metadata of a file or folder + * + * @param string/int $file + * @return array + */ + public function get($file) { + 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']; + return $data; + } + return false; + } + + /** + * get the metadata of all files stored in $folder + * + * @param string $folder + * @return array + */ + public function getFolderContents($folder) { + if ($folder == '') { + return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); + } else { + return $this->getSourceCache($folder)->getFolderContents('/'.$this->files[$folder]); + } + } + + /** + * 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]); + } + 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; + } + + /** + * 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 ($cache = $this->getSourceCache($file)) { + return $cache->getStatus($this->files[$file]); + } + return false; + } + + /** + * 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` = ?'; + } + $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); + } + +} \ No newline at end of file diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php new file mode 100644 index 00000000000..51ae4cf102b --- /dev/null +++ b/apps/files_sharing/lib/permissions.php @@ -0,0 +1,82 @@ +. +*/ +namespace OC\Files\Cache; + +class Shared_Permissions { + + /** + * get the permissions for a single file + * + * @param int $fileId + * @param string $user + * @return int (-1 if file no permissions set) + */ + static public function get($fileId, $user) { + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + if ($source) { + return $source['permissions']; + } else { + return -1; + } + } + + /** + * set the permissions of a file + * + * @param int $fileId + * @param string $user + * @param int $permissions + */ + static 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[] + */ + static 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 + */ + static public function remove($fileId, $user) { + // Not a valid action for Shared Permissions + } + + static public function removeMultiple($fileIds, $user) { + // Not a valid action for Shared Permissions + } +} diff --git a/apps/files_sharing/lib/scanner.php b/apps/files_sharing/lib/scanner.php new file mode 100644 index 00000000000..d13d2f9cbc3 --- /dev/null +++ b/apps/files_sharing/lib/scanner.php @@ -0,0 +1,69 @@ +. +*/ + +namespace OC\Files\Cache; + +class Shared_Scanner extends Scanner { + + public function __construct(\OC\Files\Storage\Storage $storage) { + + } + + /** + * get all the metadata of a file or folder + * * + * + * @param string $path + * @return array with metadata of the file + */ + public function getData($path) { + // Not a valid action for Shared Scanner + } + + /** + * 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) { + // Not a valid action for Shared Scanner + } + + /** + * scan all the files in a folder and store them in the cache + * + * @param string $path + * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @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) { + // Not a valid action for Shared Scanner + } + + /** + * walk over any folders that are not fully scanned yet and scan them + */ + public function backgroundScan() { + // Not a valid action for Shared Scanner + } + +} \ No newline at end of file diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index ac585236831..52220dc5b2b 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -22,16 +22,17 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { const FORMAT_SHARED_STORAGE = 0; - const FORMAT_FILE_APP = 1; - const FORMAT_FILE_APP_ROOT = 2; + const FORMAT_GET_FOLDER_CONTENTS = 1; + const FORMAT_GET_ALL = 2; const FORMAT_OPENDIR = 3; 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,50 +71,29 @@ 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['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; - } else if ($format == self::FORMAT_FILE_APP_ROOT) { - $mtime = 0; - $size = 0; + } else if ($format == self::FORMAT_GET_ALL) { + $ids = array(); foreach ($items as $item) { - if ($item['mtime'] > $mtime) { - $mtime = $item['mtime']; - } - $size += $item['size']; + $ids[] = $item['file_source']; } - 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 $ids; } else if ($format == self::FORMAT_OPENDIR) { $files = array(); foreach ($items as $item) { @@ -124,4 +104,26 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { return array(); } + public static function getSource($target) { + $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; + } + } diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index d414fcf10fc..a1bb843d726 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -21,34 +21,6 @@ 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); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 5abdbf29f03..960aa64099e 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -34,41 +34,8 @@ class Shared extends \OC\Files\Storage\Common { $this->sharedFolder = $arguments['sharedFolder']; } - /** - * @brief Get the source file path and the permissions granted for a shared file - * @param string Shared target file path - * @return array with the keys path and permissions 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]; - } - } - \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); - return false; - } + public function getId(){ + return 'shared::' . $this->sharedFolder; } /** @@ -77,13 +44,13 @@ class Shared extends \OC\Files\Storage\Common { * @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\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); - return $file['path']; + if (!isset($this->files[$target])) { + $source = \OC_Share_Backend_File::getSource($target); + $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + $this->files[$target] = $source; + \OC\Files\Filesystem::initMountPoints($source['uid_owner']); } - return false; + return $this->files[$target]['path']; } /** @@ -92,26 +59,18 @@ class Shared extends \OC\Files\Storage\Common { * @return int CRUDS permissions granted or false if not found */ public function getPermissions($target) { - $file = $this->getFile($target); - if (isset($file['permissions'])) { - return $file['permissions']; + if (!isset($this->files[$target])) { + $source = \OC_Share_Backend_File::getSource($target); + $this->files[$target] = $source; } - return false; - } - - 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; + return $this->files[$target]['permissions']; } public function mkdir($path) { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->mkdir($internalPath); } return false; @@ -119,7 +78,7 @@ class Shared extends \OC\Files\Storage\Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->rmdir($internalPath); } return false; @@ -131,7 +90,7 @@ class Shared extends \OC\Files\Storage\Common { \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->opendir($internalPath); } return false; @@ -141,7 +100,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->is_dir($internalPath); } return false; @@ -149,7 +108,7 @@ class Shared extends \OC\Files\Storage\Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->is_file($internalPath); } return false; @@ -161,7 +120,7 @@ class Shared extends \OC\Files\Storage\Common { $stat['mtime'] = $this->filemtime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->stat($internalPath); } return false; @@ -171,7 +130,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filetype($internalPath); } return false; @@ -181,7 +140,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filesize($internalPath); } return false; @@ -191,7 +150,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\PERMISSION_CREATE); + return ($this->getPermissions($path) & \OCP\PERMISSION_CREATE); } public function isReadable($path) { @@ -202,28 +161,28 @@ class Shared extends \OC\Files\Storage\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)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->file_exists($internalPath); } return false; @@ -244,7 +203,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filemtime($internalPath); } } @@ -258,7 +217,7 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->file_get_contents($internalPath); } } @@ -274,7 +233,7 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); $result = $storage->file_put_contents($internalPath, $data); return $result; } @@ -285,7 +244,7 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($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 @@ -309,8 +268,8 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); } } else { @@ -325,8 +284,8 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); } } @@ -372,7 +331,7 @@ class Shared extends \OC\Files\Storage\Common { 'mode' => $mode, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->fopen($internalPath, $mode); } return false; @@ -383,7 +342,7 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->getMimeType($internalPath); } return false; @@ -392,21 +351,21 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->free_space($internalPath); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($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)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->touch($internalPath, $mtime); } return false; @@ -417,17 +376,28 @@ class Shared extends \OC\Files\Storage\Common { \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 - return false; + public function getCache() { + return new \OC\Files\Cache\Shared_Cache($this); } - public function getId(){ - return 'shared::' . $this->sharedFolder; + public function getScanner(){ + return new \OC\Files\Cache\Shared_Scanner($this); } + + public function getPermissionsCache() { + return new \OC\Files\Cache\Shared_Permissions($this); + } + + public function getOwner($path) { + if (!isset($this->files[$path])) { + $source = \OC_Share_Backend_File::getSource($path); + $this->files[$path] = $source; + } + return $this->files[$path]['uid_owner']; + } + + public function getETag($path) { + + } + } diff --git a/lib/public/share.php b/lib/public/share.php index 9bb64a38c8b..8981de1b508 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -552,7 +552,7 @@ class Share { // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { $root = \OC\Files\Filesystem::getRoot(); - $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; + $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; } @@ -569,7 +569,7 @@ class Share { $itemTypes = $collectionTypes; } $placeholders = join(',', array_fill(0, count($itemTypes), '?')); - $where .= ' WHERE `item_type` IN ('.$placeholders.'))'; + $where = ' WHERE `item_type` IN ('.$placeholders.'))'; $queryArgs = $itemTypes; } else { $where = ' WHERE `item_type` = ?'; @@ -681,8 +681,8 @@ class Share { } } else { if ($fileDependent) { - if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_FILE_APP || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { - $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, `versioned`, `writable`'; + if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS) { + $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } -- cgit v1.2.3 From b4515d874e5259647886d148db902f9753bbeb81 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 26 Dec 2012 15:36:50 -0500 Subject: Only folders have Create permission --- lib/files/storage/common.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index c891d0c3ad0..3cf960d05df 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -38,7 +38,10 @@ abstract class Common implements \OC\Files\Storage\Storage { } } public function isCreatable($path) { - return $this->isUpdatable($path); + if ($this->is_dir($path) && $this->isUpdatable($path)) { + return true; + } + return false; } public function isDeletable($path) { return $this->isUpdatable($path); -- cgit v1.2.3 From 1910057900476c5b7509a456a460d70664c01610 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 26 Dec 2012 16:20:10 -0500 Subject: Fix shared statuses inside folders --- apps/files_sharing/lib/share/folder.php | 4 ++-- lib/public/share.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index a1bb843d726..bbe4c130bdd 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -26,11 +26,11 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share $parents = array($itemSource); 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']; diff --git a/lib/public/share.php b/lib/public/share.php index 8981de1b508..2775a07f133 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -739,7 +739,8 @@ class Share { if (isset($row['parent'])) { $row['path'] = '/Shared/'.basename($row['path']); } else { - $row['path'] = substr($row['path'], $root); + // Strip 'files' from path + $row['path'] = substr($row['path'], 5); } } if (isset($row['expiration'])) { -- cgit v1.2.3 From 65f1e521079968a4450468917649b241b0fb6b24 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 27 Dec 2012 15:49:48 -0500 Subject: Change old is_readable to isReadable, fixes downloads --- lib/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files.php b/lib/files.php index e12797bd610..15bfbc3fc29 100644 --- a/lib/files.php +++ b/lib/files.php @@ -100,7 +100,7 @@ class OC_Files { $filename = $dir . '/' . $files; } OC_Util::obEnd(); - if($zip or \OC\Files\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) ) . '"' ); } else { -- cgit v1.2.3 From b03562670973fd924a042064644994639a59667d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 27 Dec 2012 16:53:32 -0500 Subject: Retrieve storage correctly, filename is not the mountpoint --- lib/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files.php b/lib/files.php index 15bfbc3fc29..e1a31c6f033 100644 --- a/lib/files.php +++ b/lib/files.php @@ -117,7 +117,7 @@ class OC_Files { }else{ header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); - $storage = \OC\Files\Filesystem::getStorage($filename); + list($storage) = \OC\Files\Filesystem::resolvePath($filename); if ($storage instanceof \OC\File\Storage\Local) { self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); } -- cgit v1.2.3 From 8bdfb040565eafb33bc27305463eb08374f14e32 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 28 Dec 2012 15:06:12 -0500 Subject: Fix shared folders --- apps/files_sharing/lib/cache.php | 17 ++++++++++++++--- lib/files/filesystem.php | 1 + lib/util.php | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 196e767cf6e..d2ac8ccaaad 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -30,6 +30,10 @@ 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 Shared target file path @@ -41,8 +45,12 @@ class Shared_Cache extends Cache { $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; \OC\Files\Filesystem::initMountPoints($source['uid_owner']); list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']); - $this->files[$target] = $internalPath; - return $storage->getCache(); + if ($storage) { + $this->files[$target] = $internalPath; + $cache = $storage->getCache(); + $this->numericId = $cache->getNumericStorageId(); + return $cache; + } } return false; } @@ -83,8 +91,11 @@ class Shared_Cache extends Cache { if ($folder == '') { return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); } else { - return $this->getSourceCache($folder)->getFolderContents('/'.$this->files[$folder]); + if ($cache = $this->getSourceCache($folder)) { + return $cache->getFolderContents($this->files[$folder]); + } } + return false; } /** diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index c5b56ba9f01..8183b8ff99c 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -276,6 +276,7 @@ class Filesystem { } // 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])) { diff --git a/lib/util.php b/lib/util.php index 4ebc2564d1c..c5a495234d0 100755 --- a/lib/util.php +++ b/lib/util.php @@ -51,7 +51,6 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); -- cgit v1.2.3 From fb053f8e73056108acfd1574973d7b18581fc833 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 11:09:57 -0500 Subject: Fix retrieving of shared source paths --- apps/files_sharing/lib/sharedstorage.php | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 960aa64099e..cb9b36482fa 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -39,18 +39,33 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the source file path for a shared file + * @brief Get the source file path, permissions, and owner for a shared file * @param string Shared target file path - * @return string source file path or false if not found + * @return Returns array with the keys path, permissions, and owner or false if not found */ - private function getSourcePath($target) { + private function getFile($target) { if (!isset($this->files[$target])) { $source = \OC_Share_Backend_File::getSource($target); - $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + if ($source) { + $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + } $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 string source file path or false if not found + */ + private function getSourcePath($target) { + $source = $this->getFile($target); + if ($source) { \OC\Files\Filesystem::initMountPoints($source['uid_owner']); + return $source['path']; } - return $this->files[$target]['path']; + return false; } /** @@ -59,11 +74,11 @@ class Shared extends \OC\Files\Storage\Common { * @return int CRUDS permissions granted or false if not found */ public function getPermissions($target) { - if (!isset($this->files[$target])) { - $source = \OC_Share_Backend_File::getSource($target); - $this->files[$target] = $source; + $source = $this->getFile($target); + if ($source) { + return $source['permissions']; } - return $this->files[$target]['permissions']; + return false; } public function mkdir($path) { @@ -389,11 +404,11 @@ class Shared extends \OC\Files\Storage\Common { } public function getOwner($path) { - if (!isset($this->files[$path])) { - $source = \OC_Share_Backend_File::getSource($path); - $this->files[$path] = $source; + $source = $this->getFile($path); + if ($source) { + return $source['uid_owner']; } - return $this->files[$path]['uid_owner']; + return false; } public function getETag($path) { -- cgit v1.2.3 From cfc3526b25f1b96ab7a989f1c89f5b3911bc18fc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 11:45:13 -0500 Subject: Fix data for shared root folder --- apps/files_sharing/lib/cache.php | 4 +++- apps/files_sharing/lib/permissions.php | 3 +++ apps/files_sharing/lib/share/file.php | 22 +++++++++++++++++----- lib/public/share.php | 2 +- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index d2ac8ccaaad..a22e7af7f59 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -62,7 +62,9 @@ class Shared_Cache extends Cache { * @return array */ public function get($file) { - if (is_string($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]); } diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 51ae4cf102b..6eaed34b33d 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -30,6 +30,9 @@ class Shared_Permissions { * @return int (-1 if file no permissions set) */ static 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); if ($source) { return $source['permissions']; diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 52220dc5b2b..5e98c455d35 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -23,8 +23,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { const FORMAT_SHARED_STORAGE = 0; const FORMAT_GET_FOLDER_CONTENTS = 1; - const FORMAT_GET_ALL = 2; + const FORMAT_FILE_APP_ROOT = 2; const FORMAT_OPENDIR = 3; + const FORMAT_GET_ALL = 4; private $path; @@ -82,24 +83,35 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $file['parent'] = $item['file_parent']; $file['name'] = basename($item['file_target']); $file['mimetype'] = $item['mimetype']; + $file['mimepart'] = $item['mimepart']; $file['size'] = $item['size']; $file['mtime'] = $item['mtime']; $file['encrypted'] = $item['encrypted']; $files[] = $file; } return $files; - } else if ($format == self::FORMAT_GET_ALL) { - $ids = array(); + } else if ($format == self::FORMAT_FILE_APP_ROOT) { + $mtime = 0; + $size = 0; foreach ($items as $item) { - $ids[] = $item['file_source']; + if ($item['mtime'] > $mtime) { + $mtime = $item['mtime']; + } + $size += (int)$item['size']; } - return $ids; + 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(); } diff --git a/lib/public/share.php b/lib/public/share.php index 2775a07f133..e438386ca36 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -681,7 +681,7 @@ class Share { } } else { if ($fileDependent) { - if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS) { + if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; -- cgit v1.2.3 From d275725e233092f21247a62bde3e46a352d5a1b5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 13:43:44 -0500 Subject: No longer need to create folders locally for external storage mount points --- apps/files_external/lib/config.php | 41 -------------------------------------- 1 file changed, 41 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 0e0bc56ad0e..323e4060a43 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -178,22 +178,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 @@ -216,33 +200,8 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } - $view = new \OC\Files\View('/'.OCP\User::getUser().'/files'); - self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { - $view = new \OC\Files\View('/'); - 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))); -- cgit v1.2.3 From 2c23e143d33e231e62dccb450bf1f1b0f3938ccd Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 16:32:55 -0500 Subject: Store etags in the file cache --- db_structure.xml | 8 ++++++++ lib/files/cache/cache.php | 10 +++++----- lib/files/cache/scanner.php | 1 + lib/util.php | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index aa0916264c9..7c67ca78f4e 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -189,6 +189,14 @@ 4 + + etag + text + + true + 250 + + storage_path_hash true diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5d..d105f865ebd 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -76,7 +76,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -107,7 +107,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + '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)); return $result->fetchAll(); @@ -180,7 +180,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag'); $params = array(); $queryParts = array(); @@ -333,7 +333,7 @@ class Cache { */ public function search($pattern) { $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 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)); @@ -357,7 +357,7 @@ class Cache { $where = '`mimepart` = ?'; } $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); $result = $query->execute(array($mimetype, $this->numericId)); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f9..e7bfb1898e1 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -58,6 +58,7 @@ class Scanner { $data['size'] = $this->storage->filesize($path); $data['permissions'] = $this->storage->getPermissions($path); } + $data['etag'] = $this->storage->getETag($path); return $data; } diff --git a/lib/util.php b/lib/util.php index c5a495234d0..df26a825d1c 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** -- cgit v1.2.3 From a5cb7363a5031d25d3e4cbd46817930c19893143 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:18:05 -0500 Subject: Use etags from file cache in SabreDAV connector --- lib/connector/sabre/directory.php | 2 +- lib/connector/sabre/node.php | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 8d4dd92a3d4..a7201579366 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -121,8 +121,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $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 diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ad08bd434f2..d4023dfad78 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -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 @@ -210,14 +211,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @return string|null Returns null if the ETag can not effectively be determined */ static public function getETagPropertyForPath($path) { - $tag = \OC\Files\Filesystem::getETag($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; } /** -- cgit v1.2.3 From 83064aca51db7d8382282743ade2ab9da2a6e1b0 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:23:31 -0500 Subject: Remove old etag code --- lib/connector/sabre/node.php | 24 ------------------------ lib/files/filesystem.php | 21 --------------------- lib/files/view.php | 2 -- lib/filesystem.php | 7 ------- 4 files changed, 54 deletions(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index d4023dfad78..dd8ae152ff5 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -218,28 +218,4 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr 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 )); - } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99c..d62b5186cbe 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -582,23 +582,6 @@ class Filesystem { 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 View($root); - $count = 1; - $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); - } - - $path = self::normalizePath($path); - \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); - } - /** * normalize a path * @@ -682,10 +665,6 @@ class Filesystem { } } -\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_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'); diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21c..77146895e64 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -462,8 +462,6 @@ class View { Filesystem::signal_post_write, array(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 - Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 20b5ab27909..57cca902303 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -398,13 +398,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::hasUpdated($path, $time); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function removeETagHook($params, $root = false) { - \OC\Files\Filesystem::removeETagHook($params, $root); - } - /** * normalize a path * -- cgit v1.2.3 From 77f12c526bf0010219e363844b588ffae27f1251 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:54:51 -0500 Subject: Update etags in parent folders --- lib/files/cache/updater.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e8..d57e4a1abe6 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -34,6 +34,7 @@ class Updater { $scanner = new Scanner($storage); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); } static public function deleteUpdate($path) { @@ -45,6 +46,29 @@ class Updater { $cache = new Cache($storage); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); + } + + static public function eTagUpdate($path) { + if ($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('etag' => $storage->getETag($internalPath))); + self::updateFolderETags($parent); + } + } + } } /** -- cgit v1.2.3 From 3ee3323b8766992a0b60bb76b909e49fc1ea76d2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 20:27:38 -0500 Subject: Fix retrieving of cache and scanner in Updater class --- lib/files/cache/updater.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e8..c8c96a97eea 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -30,10 +30,12 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $scanner = new Scanner($storage); - $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } } static public function deleteUpdate($path) { @@ -42,9 +44,11 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $cache->remove($internalPath); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } } /** -- cgit v1.2.3 From 96e08a1d962b42782d03721009970cbab352eec2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 21:23:17 -0500 Subject: Fix function name --- lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index d57e4a1abe6..7fc9bd382fe 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -65,7 +65,7 @@ class Updater { $id = $cache->getId($internalPath); if ($id !== -1) { $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::updateFolderETags($parent); + self::eTagUpdate($parent); } } } -- cgit v1.2.3 From 29b82ccdf32f8a13723e7f49be0c3cbf7e64a404 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 21:23:54 -0500 Subject: Change length of etag field to 40 --- db_structure.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_structure.xml b/db_structure.xml index 7c67ca78f4e..527b53040da 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -194,7 +194,7 @@ text true - 250 + 40 -- cgit v1.2.3 From d0a50fae8317e4b4871027ee4b2940ab5443961f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 31 Dec 2012 18:16:44 -0500 Subject: Fix eTagUpdate and add tests --- lib/files/cache/updater.php | 2 +- tests/lib/files/cache/updater.php | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 26041590091..cfc1ec731e2 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -54,7 +54,7 @@ class Updater { } static public function eTagUpdate($path) { - if ($path !== '') { + if ($path !== '' && $path !== '/') { $parent = dirname($path); if ($parent === '.') { $parent = ''; diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index d19966c1910..cad3d9d46fc 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -70,14 +70,18 @@ class Updater extends \PHPUnit_Framework_TestCase { public function testWrite() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); + $fooCachedData = $this->cache->get('foo.txt'); Filesystem::file_put_contents('foo.txt', 'asd'); $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::file_put_contents('bar.txt', 'asd'); @@ -86,38 +90,50 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, $cachedData['size']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testDelete() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); Filesystem::unlink('foo.txt', 'asd'); $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); $this->assertTrue($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::rmdir('bar_folder'); $this->assertFalse($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testRename() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); + $fooCachedData = $this->cache->get('foo.txt'); $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } } -- cgit v1.2.3 From f2ca7023e1ece60dc3cebc5cd770c7373f53c93a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 11:19:33 -0500 Subject: Fix Shared root problems with Watcher and Quota proxy --- apps/files_sharing/lib/cache.php | 3 +++ apps/files_sharing/lib/sharedstorage.php | 13 +++++++++++++ lib/fileproxy/quota.php | 4 +++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index a22e7af7f59..60f29ce5eeb 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -169,6 +169,9 @@ class Shared_Cache extends Cache { * @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]); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index cb9b36482fa..3a1d7ef101a 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -364,6 +364,9 @@ class Shared extends \OC\Files\Storage\Common { } public function free_space($path) { + if ($path == '') { + return -1; + } $source = $this->getSourcePath($path); if ($source) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); @@ -391,6 +394,13 @@ class Shared extends \OC\Files\Storage\Common { \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } + public function hasUpdated($path, $time) { + if ($path == '') { + return false; + } + return $this->filemtime($path) > $time; + } + public function getCache() { return new \OC\Files\Cache\Shared_Cache($this); } @@ -404,6 +414,9 @@ class Shared extends \OC\Files\Storage\Common { } public function getOwner($path) { + if ($path == '') { + return false; + } $source = $this->getFile($path); if ($source) { return $source['uid_owner']; diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 80270728aba..c333efa6cdf 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -63,6 +63,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $owner=$storage->getOwner($internalPath); + if (!$owner) { + return -1; + } $totalSpace=$this->getQuota($owner); if($totalSpace==-1) { @@ -73,7 +76,6 @@ class OC_FileProxy_Quota extends OC_FileProxy{ $rootInfo=$view->getFileInfo('/'); $usedSpace=isset($rootInfo['size'])?$rootInfo['size']:0; - $usedSpace=isset($sharedInfo['size'])?$usedSpace-$sharedInfo['size']:$usedSpace; return $totalSpace-$usedSpace; } -- cgit v1.2.3 From b41189de4420ea8a48adaaf7bb59f9227124b70a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:04:29 +0100 Subject: Cache: allow storage backends to overwrite Watcher --- lib/files/storage/common.php | 7 +++++++ lib/files/storage/storage.php | 5 +++++ lib/files/view.php | 4 ++-- tests/lib/files/cache/watcher.php | 14 +++++++------- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3cf960d05df..ab167f28646 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -249,6 +249,13 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Permissions($this); } + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(){ + return new \OC\Files\Cache\Watcher($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 73dcb8fe36b..b603381dc90 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -69,6 +69,11 @@ interface Storage{ */ public function getPermissionsCache(); + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21c..d3f93d39f5a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -685,7 +685,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } @@ -733,7 +733,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 07c8ac3640c..e8a1689cab0 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -32,7 +32,7 @@ class Watcher extends \PHPUnit_Framework_TestCase { function testWatcher() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); @@ -66,16 +66,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { public function testFileToFolder() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate(''); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals(-1, $entry['size']); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertFalse($cache->inCache('folder')); @@ -83,16 +83,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate('foo.txt'); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertTrue($cache->inCache('foo.txt/bar.txt')); } -- cgit v1.2.3 From 4b65dd608a70117141c52749f4a06e6c5466ff7b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:07:10 +0100 Subject: Share: small phpdoc fixes --- apps/files_sharing/lib/cache.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 60f29ce5eeb..679e42d94d1 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -36,8 +36,8 @@ class Shared_Cache extends Cache { /** * @brief Get the source cache of a shared file or folder - * @param string Shared target file path - * @return \OC\Files\Storage\Cache + * @param string $target Shared target file path + * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { $source = \OC_Share_Backend_File::getSource($target); @@ -230,7 +230,7 @@ class Shared_Cache extends Cache { * @return int[] */ public function getAll() { - return OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); + return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); } -} \ No newline at end of file +} -- cgit v1.2.3 From 0ac78a64110b628832d94061c78fb8f1b89405cb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:10:38 +0100 Subject: Share: fix cache put function --- apps/files_sharing/lib/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 679e42d94d1..07c305bb952 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -110,7 +110,7 @@ class Shared_Cache extends Cache { */ public function put($file, array $data) { if ($cache = $this->getSourceCache($file)) { - return $cache->put($this->files[$file]); + return $cache->put($this->files[$file], $data); } return false; } -- cgit v1.2.3 From f4e4a06826459befc4a7df429fe02081a14348f3 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 11:26:04 -0500 Subject: Forgot to select storage from filecache --- lib/public/share.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/public/share.php b/lib/public/share.php index e438386ca36..c74960b94c5 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -682,7 +682,7 @@ class Share { } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { - $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; + $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } -- cgit v1.2.3 From 3b67613afc6d0b74c0e49e567f5e22ec020172d3 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 12:43:38 -0500 Subject: Remove Shared_Scanner and add Shared_Watcher instead --- apps/files_sharing/appinfo/app.php | 2 +- apps/files_sharing/lib/scanner.php | 69 -------------------------------- apps/files_sharing/lib/sharedstorage.php | 8 ++-- 3 files changed, 5 insertions(+), 74 deletions(-) delete mode 100644 apps/files_sharing/lib/scanner.php diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 189fd20cae3..d3e05cc62d8 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -5,7 +5,7 @@ OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder 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_Scanner'] = 'apps/files_sharing/lib/scanner.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'); diff --git a/apps/files_sharing/lib/scanner.php b/apps/files_sharing/lib/scanner.php deleted file mode 100644 index d13d2f9cbc3..00000000000 --- a/apps/files_sharing/lib/scanner.php +++ /dev/null @@ -1,69 +0,0 @@ -. -*/ - -namespace OC\Files\Cache; - -class Shared_Scanner extends Scanner { - - public function __construct(\OC\Files\Storage\Storage $storage) { - - } - - /** - * get all the metadata of a file or folder - * * - * - * @param string $path - * @return array with metadata of the file - */ - public function getData($path) { - // Not a valid action for Shared Scanner - } - - /** - * 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) { - // Not a valid action for Shared Scanner - } - - /** - * scan all the files in a folder and store them in the cache - * - * @param string $path - * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive - * @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) { - // Not a valid action for Shared Scanner - } - - /** - * walk over any folders that are not fully scanned yet and scan them - */ - public function backgroundScan() { - // Not a valid action for Shared Scanner - } - -} \ No newline at end of file diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3a1d7ef101a..8504a2d8944 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -405,14 +405,14 @@ class Shared extends \OC\Files\Storage\Common { return new \OC\Files\Cache\Shared_Cache($this); } - public function getScanner(){ - return new \OC\Files\Cache\Shared_Scanner($this); - } - public function getPermissionsCache() { return new \OC\Files\Cache\Shared_Permissions($this); } + public function getWatcher() { + return new \OC\Files\Cache\Shared_Watcher($this); + } + public function getOwner($path) { if ($path == '') { return false; -- cgit v1.2.3 From 268c7acfc47eb44ab154eb90cfbb4484bd64b296 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 13:16:42 -0500 Subject: Actually add Shared_Watcher --- apps/files_sharing/lib/watcher.php | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 apps/files_sharing/lib/watcher.php diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php new file mode 100644 index 00000000000..e67d1ee9086 --- /dev/null +++ b/apps/files_sharing/lib/watcher.php @@ -0,0 +1,51 @@ +. +*/ + +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); + } + } + +} \ No newline at end of file -- cgit v1.2.3 From 04f83e3b539c6a20ce819bbe4f66c1996e7169f7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:11:39 +0100 Subject: Cache: optional path argument for getCache/Scanner/etc --- lib/files/storage/common.php | 11 ++++------- lib/files/storage/storage.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index ab167f28646..e859d447f39 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -237,22 +237,19 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->filemtime($path)>$time; } - public function getCache(){ + public function getCache($path=''){ return new \OC\Files\Cache\Cache($this); } - public function getScanner(){ + public function getScanner($path=''){ return new \OC\Files\Cache\Scanner($this); } - public function getPermissionsCache(){ + public function getPermissionsCache($path=''){ return new \OC\Files\Cache\Permissions($this); } - /** - * @return \OC\Files\Cache\Watcher - */ - public function getWatcher(){ + public function getWatcher($path=''){ return new \OC\Files\Cache\Watcher($this); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b603381dc90..2cc835236ba 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -54,25 +54,29 @@ interface Storage{ public function hasUpdated($path,$time); /** + * @param string $path * @return \OC\Files\Cache\Cache */ - public function getCache(); + public function getCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Scanner */ - public function getScanner(); + public function getScanner($path=''); public function getOwner($path); /** + * @param string $path * @return \OC\Files\Cache\Permissions */ - public function getPermissionsCache(); + public function getPermissionsCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Watcher */ - public function getWatcher(); + public function getWatcher($path=''); /** * get the ETag for a file or folder -- cgit v1.2.3 From a164fd160fb0d3da548dfe01ec27df67d76b0b59 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:19:53 +0100 Subject: Cache: provide path hints to getCache/etc where available --- lib/files/cache/updater.php | 6 +++--- lib/files/view.php | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index c8c96a97eea..c14adba3e55 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -31,8 +31,8 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); - $scanner = $storage->getScanner(); + $cache = $storage->getCache($internalPath); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); } @@ -45,7 +45,7 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); } diff --git a/lib/files/view.php b/lib/files/view.php index d3f93d39f5a..8558b03fe1e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -679,13 +679,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -698,14 +698,14 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += $rootEntry['size']; } } } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); } } @@ -727,13 +727,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -745,7 +745,7 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $relativePath = trim(substr($mountPoint, $dirLength), '/'); @@ -769,7 +769,7 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { @@ -812,10 +812,10 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($path); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } @@ -857,7 +857,7 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $results = $cache->$method($query); foreach ($results as $result) { @@ -871,7 +871,7 @@ class View { foreach ($mountPoints as $mountPoint) { $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $relativeMountPoint = substr($mountPoint, $rootLength); $results = $cache->$method($query); -- cgit v1.2.3 From fe90130618e4ce9b1829b4ce8e87311a15f53b83 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 14:13:05 -0500 Subject: Initialize storageId variable in shared cache --- apps/files_sharing/lib/cache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 07c305bb952..0534d6dd89f 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -48,6 +48,7 @@ class Shared_Cache extends Cache { if ($storage) { $this->files[$target] = $internalPath; $cache = $storage->getCache(); + $this->storageId = $storage->getId(); $this->numericId = $cache->getNumericStorageId(); return $cache; } -- cgit v1.2.3 From a1f7c28e28e221a6939a74eb5ae7b43c02a1d8e6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 14:47:25 -0500 Subject: Use the source Scanner for shared storage when the path is specified --- apps/files_sharing/lib/sharedstorage.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 8504a2d8944..3a5755c01fc 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -401,15 +401,25 @@ class Shared extends \OC\Files\Storage\Common { return $this->filemtime($path) > $time; } - public function getCache() { + public function getCache($path = '') { return new \OC\Files\Cache\Shared_Cache($this); } - public function getPermissionsCache() { + public function getScanner($path = '') { + if ($path != '' && ($source = $this->getSourcePath($path))) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + if ($storage) { + return $storage->getScanner($internalPath); + } + } + return new \OC\Files\Cache\Scanner($this); + } + + public function getPermissionsCache($path = '') { return new \OC\Files\Cache\Shared_Permissions($this); } - public function getWatcher() { + public function getWatcher($path = '') { return new \OC\Files\Cache\Shared_Watcher($this); } -- cgit v1.2.3 From a068ddff64bb6071de204b948129c4ca23c16d26 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 2 Jan 2013 14:40:06 -0500 Subject: Use the sub storage's permission cache for retrieving the correct permission --- lib/files/view.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 8558b03fe1e..9ba3eea3cf9 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -739,6 +739,18 @@ class View { $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']; + } + + $permissionsCache = $storage->getPermissionsCache($internalPath); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; + } + //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); @@ -758,24 +770,14 @@ class View { } } 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(''); + $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); $files[] = $rootEntry; } } } - $ids = array(); - - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } - if ($mimetype_filter) { foreach ($files as $file) { if (strpos($mimetype_filter, '/')) { -- cgit v1.2.3 From 6a6d6756b7a6495d044d44c8d6081505880d96b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 3 Jan 2013 00:29:10 +0100 Subject: Cache: rename index to prevent colissions with old fscache indexes --- db_structure.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index aa0916264c9..e47cf3c6292 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -190,7 +190,7 @@ - storage_path_hash + fs_storage_path_hash true storage @@ -203,7 +203,7 @@ - parent_name_hash + fs_parent_name_hash parent ascending -- cgit v1.2.3 From f144be8857e3356495acefca787637b5672f73ef Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 2 Jan 2013 19:20:34 -0500 Subject: Don't mount shared storage unless there are shared files --- apps/files_sharing/lib/sharedstorage.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3a5755c01fc..24096e0c10c 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -390,8 +390,10 @@ class Shared extends \OC\Files\Storage\Common { } public static function setup($options) { - $user_dir = $options['user_dir']; - \OC\Files\Filesystem::mount('\OC\Files\Storage\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/'); + } } public function hasUpdated($path, $time) { -- cgit v1.2.3 From 38876fc98a11a917e68780357d7f4b5a146ba89a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:07:04 -0500 Subject: Update old storage classes names to the new namespace during mounting --- apps/files_external/lib/config.php | 12 ++++++++++++ lib/files/filesystem.php | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 323e4060a43..d7286c52c02 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -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, strlen($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, strlen($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, strlen($mount['class']) - 15); + } // Remove '/uid/files/' from mount point $personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99c..b9fd6a03762 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,7 +364,10 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; -- cgit v1.2.3 From 1137723b2a46c37d61e7f501694c73562b21ef74 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:13:45 -0500 Subject: Remove unnecessary length parameter from last commit --- apps/files_external/lib/config.php | 6 +++--- lib/files/filesystem.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index d7286c52c02..3bb512493d8 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -122,7 +122,7 @@ class OC_Mount_Config { 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, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -145,7 +145,7 @@ class OC_Mount_Config { 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, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -179,7 +179,7 @@ class OC_Mount_Config { 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, strlen($mount['class']) - 15); + $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'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b9fd6a03762..d9487bde806 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -366,7 +366,7 @@ class Filesystem { } // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + $class = '\OC\Files\Storage\\'.substr($class, 15); } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); -- cgit v1.2.3 From 0ca5047da56c1b6d0614174b01d42bace85d53ee Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 00:36:01 +0100 Subject: Autoload namespaced test classes --- lib/base.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/base.php b/lib/base.php index 3d3e7d59f90..80e5c5ed77b 100644 --- a/lib/base.php +++ b/lib/base.php @@ -105,6 +105,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; } -- cgit v1.2.3 From 457dc270f5147863c00b55355542298ba4d41762 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 00:36:39 +0100 Subject: Fix messed up mounts --- lib/files/filesystem.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d9487bde806..b3ba62c3a49 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,14 +364,14 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - // Update old classes to new namespace - if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); - } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; } else { + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15); + } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } } -- cgit v1.2.3 From 439578288facbae3144f131aca85a7235f622053 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:03:11 +0100 Subject: Cache: split permission cache scanning and cache scanning --- lib/files/cache/scanner.php | 9 --------- lib/files/view.php | 30 ++++++++++++++++++++++-------- tests/lib/files/view.php | 1 + 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f9..526d4a2aab5 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -24,11 +24,6 @@ class Scanner { */ private $cache; - /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - private $permissionsCache; - const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; @@ -36,7 +31,6 @@ class Scanner { $this->storage = $storage; $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -53,10 +47,8 @@ class Scanner { $data['mtime'] = $this->storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { $data['size'] = -1; //unknown - $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { $data['size'] = $this->storage->filesize($path); - $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -81,7 +73,6 @@ class Scanner { } } $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 9ba3eea3cf9..124345f3c6f 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -680,6 +680,8 @@ class View { 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); @@ -705,8 +707,12 @@ class View { } } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissions = $permissionsCache->get($data['fileid'], $user); + if ($permissions === -1) { + $permissions = $storage->getPermissions($internalPath); + $permissionsCache->set($data['fileid'], $user, $permissions); + } + $data['permissions'] = $permissions; } } return $data; @@ -728,6 +734,8 @@ class View { 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); @@ -743,12 +751,13 @@ class View { foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$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 @@ -772,7 +781,12 @@ class View { $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $subPermissionsCache = $subStorage->getPermissionsCache(''); - $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); + $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); + if ($permissions === -1) { + $permissions = $subStorage->getPermissions($rootEntry['path']); + $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); + } + $rootEntry['permissions'] = $subPermissionsCache; $files[] = $rootEntry; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 712166ab32c..4b0abc2201d 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -43,6 +43,7 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); + $this->assertEquals(\OCP\PERMISSION_ALL ^ \OCP\PERMISSION_CREATE, $cachedData['permissions']); $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); -- cgit v1.2.3 From ad3badeabff9dde839827558c281a691c611cf87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:03:11 +0100 Subject: Cache: split permission cache scanning and cache scanning --- tests/lib/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 4b0abc2201d..53271142672 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -43,7 +43,7 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); - $this->assertEquals(\OCP\PERMISSION_ALL ^ \OCP\PERMISSION_CREATE, $cachedData['permissions']); + $this->assertNotEquals(-1, $cachedData['permissions']); $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); -- cgit v1.2.3 From d0377b1951a156e218ca0200340e2bcfb51ac0c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:40:09 +0100 Subject: Cache: normalize mimetypes --- db_structure.xml | 44 +++++++++++++++++++++++++++++++---- lib/files/cache/cache.php | 59 +++++++++++++++++++++++++++++++++++++++++++---- lib/files/view.php | 2 +- lib/util.php | 2 +- 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index e47cf3c6292..3022983473b 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -94,6 +94,42 @@
+ + + *dbprefix*mimetypes + + + + + id + integer + 0 + true + 1 + 4 + + + + mimetype + text + + true + 64 + + + + mimetype_id_index + true + + mimetype + ascending + + + + + +
+ *dbprefix*filecache @@ -151,18 +187,18 @@ mimetype - text + integer true - 64 + 4 mimepart - text + integer true - 32 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5d..0001c2752da 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -36,6 +36,9 @@ class Cache { */ private $numericId; + private $mimetypeIds = array(); + private $mimetypes = array(); + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -61,6 +64,41 @@ class Cache { 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 * @@ -92,6 +130,8 @@ class Cache { $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; @@ -110,7 +150,12 @@ class Cache { 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); - return $result->fetchAll(); + $files = $result->fetchAll(); + foreach ($files as &$file) { + $file['mimetype'] = $this->getMimetype($file['mimetype']); + $file['mimepart'] = $this->getMimetype($file['mimepart']); + } + return $files; } else { return array(); } @@ -179,22 +224,23 @@ class Cache { * @param array $data * @return array */ - static function buildParts(array $data) { + function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { if (array_search($name, $fields) !== false) { - $params[] = $value; - $queryParts[] = '`' . $name . '`'; if ($name === 'path') { $params[] = md5($value); $queryParts[] = '`path_hash`'; } elseif ($name === 'mimetype') { - $params[] = substr($value, 0, strpos($value, '/')); + $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); $queryParts[] = '`mimepart`'; + $value = $this->getMimetypeId($value); } + $params[] = $value; + $queryParts[] = '`' . $name . '`'; } } return array($queryParts, $params); @@ -339,6 +385,8 @@ class Cache { $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; @@ -360,6 +408,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); + $mimetype = $this->getMimetypeId($mimetype); $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } diff --git a/lib/files/view.php b/lib/files/view.php index 124345f3c6f..8303a080bd8 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -693,7 +693,7 @@ class View { $data = $cache->get($internalPath); - if ($data) { + if ($data and $data['fileid']) { if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = Filesystem::getMountPoints($path); diff --git a/lib/util.php b/lib/util.php index 805ef6f18b0..93c0d0f26d8 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** -- cgit v1.2.3 From 5174eda23270463f09c82db77f2f61d3496f752f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 15:21:38 -0500 Subject: Fix permissions for mount point --- lib/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index 8303a080bd8..94c89603aed 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -786,7 +786,7 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - $rootEntry['permissions'] = $subPermissionsCache; + $rootEntry['permissions'] = $permissions; $files[] = $rootEntry; } } -- cgit v1.2.3 From a7d4d042239236082d7f2c2679249ea7d48e596c Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 15:27:22 -0500 Subject: Fix mimetypes in shared cache --- apps/files_sharing/lib/cache.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 0534d6dd89f..8b989db3b07 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -79,6 +79,8 @@ class Shared_Cache extends Cache { $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; @@ -92,7 +94,12 @@ class Shared_Cache extends Cache { */ public function getFolderContents($folder) { if ($folder == '') { - return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); + $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]); -- cgit v1.2.3 From 8f8a5bbfb750b3c9091da810749a43cada2740b2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 18:17:14 -0500 Subject: Maked Shared_Permissions extend Permissions class --- apps/files_sharing/lib/permissions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 6eaed34b33d..508c3a384f0 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -20,7 +20,7 @@ */ namespace OC\Files\Cache; -class Shared_Permissions { +class Shared_Permissions extends Permissions { /** * get the permissions for a single file @@ -29,7 +29,7 @@ class Shared_Permissions { * @param string $user * @return int (-1 if file no permissions set) */ - static public function get($fileId, $user) { + public function get($fileId, $user) { if ($fileId == -1) { return \OCP\PERMISSION_READ; } @@ -48,7 +48,7 @@ class Shared_Permissions { * @param string $user * @param int $permissions */ - static public function set($fileId, $user, $permissions) { + public function set($fileId, $user, $permissions) { // Not a valid action for Shared Permissions } @@ -59,7 +59,7 @@ class Shared_Permissions { * @param string $user * @return int[] */ - static public function getMultiple($fileIds, $user) { + public function getMultiple($fileIds, $user) { if (count($fileIds) === 0) { return array(); } @@ -75,11 +75,11 @@ class Shared_Permissions { * @param int $fileId * @param string $user */ - static public function remove($fileId, $user) { + public function remove($fileId, $user) { // Not a valid action for Shared Permissions } - static public function removeMultiple($fileIds, $user) { + public function removeMultiple($fileIds, $user) { // Not a valid action for Shared Permissions } } -- cgit v1.2.3 From e8b195bf109d702402735e628b2d239b199088e5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 20:52:51 -0500 Subject: Almost fix Shared scanner... --- apps/files_sharing/lib/cache.php | 13 +++++++++++++ apps/files_sharing/lib/permissions.php | 2 +- apps/files_sharing/lib/share/file.php | 3 +++ apps/files_sharing/lib/share/folder.php | 11 +++++++++-- apps/files_sharing/lib/sharedstorage.php | 6 ------ lib/public/share.php | 5 ++++- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 8b989db3b07..d35a5148de2 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -136,6 +136,19 @@ class Shared_Cache extends Cache { 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 * diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 508c3a384f0..2b068ff9350 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -33,7 +33,7 @@ class Shared_Permissions extends Permissions { if ($fileId == -1) { return \OCP\PERMISSION_READ; } - $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE, null, true); if ($source) { return $source['permissions']; } else { diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 5e98c455d35..6d3c55a008f 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -117,6 +117,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { } public static function getSource($target) { + if ($target == '') { + return false; + } $target = '/'.$target; $target = rtrim($target, '/'); $pos = strpos($target, '/', 1); diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index bbe4c130bdd..11c8c6b1e80 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -24,6 +24,13 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share 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 `fileid`, `name`, `mimetype` FROM `*PREFIX*filecache` WHERE `parent` IN ('.$parents.')'); @@ -32,8 +39,8 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share while ($file = $result->fetchRow()) { $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']; } } } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 24096e0c10c..c8756af8ed7 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -408,12 +408,6 @@ class Shared extends \OC\Files\Storage\Common { } public function getScanner($path = '') { - if ($path != '' && ($source = $this->getSourcePath($path))) { - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); - if ($storage) { - return $storage->getScanner($internalPath); - } - } return new \OC\Files\Cache\Scanner($this); } diff --git a/lib/public/share.php b/lib/public/share.php index c74960b94c5..7722e0b86cc 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -756,7 +756,7 @@ class Share { $collectionItems = array(); foreach ($items as &$row) { // Return only the item instead of a 2-dimensional array - if ($limit == 1 && $row['item_type'] == $itemType && $row[$column] == $item) { + if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { if ($format == self::FORMAT_NONE) { return $row; } else { @@ -823,6 +823,9 @@ class Share { if (!empty($collectionItems)) { $items = array_merge($items, $collectionItems); } + if (empty($items) && $limit == 1) { + return false; + } if ($format == self::FORMAT_NONE) { return $items; } else if ($format == self::FORMAT_STATUSES) { -- cgit v1.2.3 From 464dafd7d2627d59732c09e01986d705d604ee56 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 9 Jan 2013 22:17:39 -0500 Subject: Make Google Drive storage id unique, before it was anonymousanonymous --- apps/files_external/lib/google.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index bbb315c4910..4c485773e7b 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -41,7 +41,7 @@ class Google extends \OC\Files\Storage\Common { ) { $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; - $this->id = 'google::' . $consumer_key . $consumer_secret; + $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(); -- cgit v1.2.3 From 106541361c3857ed8e35c6869c91faffb8ae984d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 9 Jan 2013 22:57:42 -0500 Subject: Change length of mimetypes to 255, the maximum length according to RFC 4288 --- db_structure.xml | 2 +- lib/util.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 3022983473b..7b6829aa301 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -114,7 +114,7 @@ text true - 64 + 255 diff --git a/lib/util.php b/lib/util.php index 93c0d0f26d8..e814a3a32df 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,05); + return array(4,91,06); } /** -- cgit v1.2.3 From aa15fcf22f4c32026eca5ff8ae5e5df244f2c53e Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 12:09:55 -0500 Subject: Scan mount points in root before adding a entry --- lib/files/view.php | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 94c89603aed..703cda5123c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -767,27 +767,37 @@ class View { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { $subCache = $subStorage->getCache(''); - $rootEntry = $subCache->get(''); - $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']; + if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + $subScanner = $subStorage->getScanner(''); + $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + } else { + $subWatcher = $subStorage->getWatcher(''); + $subWatcher->checkUpdate(''); + } + + $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; + $files[] = $rootEntry; } - } 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; - $files[] = $rootEntry; } } } -- cgit v1.2.3 From 4835525c469d5ac75104e92c2dfbbb049d62890c Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 22:28:50 -0500 Subject: Switch scan to scanFile for root of mount points --- lib/files/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 703cda5123c..fa031b7478d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -768,9 +768,9 @@ class View { if ($subStorage) { $subCache = $subStorage->getCache(''); - if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); - $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + $subScanner->scanFile(''); } else { $subWatcher = $subStorage->getWatcher(''); $subWatcher->checkUpdate(''); -- cgit v1.2.3 From 36cac7f924ad07738a3cb72fee06f21d07baad42 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 22:29:47 -0500 Subject: Return NOT_FOUND in shared cache --- apps/files_sharing/lib/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index d35a5148de2..0b187a3c3ff 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -196,7 +196,7 @@ class Shared_Cache extends Cache { if ($cache = $this->getSourceCache($file)) { return $cache->getStatus($this->files[$file]); } - return false; + return self::NOT_FOUND; } /** -- cgit v1.2.3 From 8a63bcc1e85499335ade1df459f0c9f467161404 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 20:56:36 -0500 Subject: Don't use more entropy for etags --- lib/files/storage/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e859d447f39..591803f0440 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -274,7 +274,7 @@ abstract class Common implements \OC\Files\Storage\Storage { $hash = call_user_func($ETagFunction, $path); return $hash; }else{ - return uniqid('', true); + return uniqid(); } } } -- cgit v1.2.3 From 9e2f3a53244e353cb75f9927e1c69ef40f589db7 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 20:59:53 -0500 Subject: Remove old create etag function --- lib/connector/sabre/file.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 1770b491280..e0723e12301 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -101,15 +101,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D 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\Files\Filesystem::hash('md5', $path); - } - /** * Returns the mime-type for a file * -- cgit v1.2.3 From a00b9e0a03a7cdb1103415d33d2c3f22e86edffb Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:01:28 -0500 Subject: Bump version --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index e814a3a32df..faae962859a 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,06); + return array(4,91,07); } /** -- cgit v1.2.3 From b30648cb7dc258208fad4dadb297aa1d792fa7ef Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:09:01 -0500 Subject: Don't waste time making another call since we know it doesn't exist --- lib/connector/sabre/file.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index e0723e12301..1c18a391742 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -98,7 +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); + return null; } /** -- cgit v1.2.3 From 094a852bff378c03c873b6e8fd94587d2a2c784e Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:09:58 -0500 Subject: Wrap the etag in double quotes --- lib/connector/sabre/node.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index dd8ae152ff5..93d8fc477d6 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -213,7 +213,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr static public function getETagPropertyForPath($path) { $data = \OC\Files\Filesystem::getFileInfo($path); if (isset($data['etag'])) { - return $data['etag']; + return '"'.$data['etag'].'"'; } return null; } -- cgit v1.2.3 From 94068e5d08cba776e410d925e26037d442b5bc62 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 3 Jan 2013 00:26:13 +0100 Subject: Cache: show upgrade progress --- apps/files/ajax/upgrade.php | 42 +++++++++++ apps/files/appinfo/app.php | 10 --- apps/files/css/files.css | 9 +++ apps/files/index.php | 72 ++++++++++-------- apps/files/js/upgrade.js | 17 +++++ apps/files/templates/upgrade.php | 4 + lib/files/cache/legacy.php | 73 ++++++++++++++++++ lib/files/cache/upgrade.php | 155 ++++++++++++++++++++++++++++----------- 8 files changed, 302 insertions(+), 80 deletions(-) create mode 100644 apps/files/ajax/upgrade.php create mode 100644 apps/files/js/upgrade.js create mode 100644 apps/files/templates/upgrade.php create mode 100644 lib/files/cache/legacy.php diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php new file mode 100644 index 00000000000..965c0073b8a --- /dev/null +++ b/apps/files/ajax/upgrade.php @@ -0,0 +1,42 @@ +hasItems()) { + OC_Hook::connect('\OC\Files\Cache\Upgrade', 'migrate_path', $listener, 'upgradePath'); + + $upgrade = new \OC\Files\Cache\Upgrade($legacy); + $count = $legacy->getCount(); + $eventSource->send('total', $count); + $upgrade->upgradePath('/' . $user . '/files'); +} +\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); + } + } +} diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index 643d8ed18a2..ab2f3b01a29 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -10,13 +10,3 @@ OCP\App::addNavigationEntry( array( "id" => "files_index", "name" => $l->t("Files") )); OC_Search::registerProvider('OC_Search_Provider_File'); - -if (OC_User::isLoggedIn()) { - // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually - $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); - if ($cacheVersion < 5) { - \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); - \OC\Files\Cache\Upgrade::upgrade(); - OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); - } -} diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 36a1e5c954b..0c130efe472 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -122,3 +122,12 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } #scanning-message{ top:40%; left:40%; position:absolute; display:none; } div.crumb a{ padding:0.9em 0 0.7em 0; } + +#upgrade { + width: 400px; + position: absolute; + top: 200px; + left: 50%; + text-align: center; + margin-left: -200px; +} diff --git a/apps/files/index.php b/apps/files/index.php index 993d8b4dcff..0dce7686962 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -28,7 +28,6 @@ OCP\User::checkLoggedIn(); OCP\Util::addStyle('files', 'files'); OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); -OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'filelist'); OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'keyboardshortcuts'); @@ -37,8 +36,8 @@ OCP\App::setActiveNavigationEntry('files_index'); // Load the files $dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; // Redirect if directory does not exist -if(!\OC\Files\Filesystem::is_dir($dir . '/')) { - header('Location: '.$_SERVER['SCRIPT_NAME'].''); +if (!\OC\Files\Filesystem::is_dir($dir . '/')) { + header('Location: ' . $_SERVER['SCRIPT_NAME'] . ''); exit(); } @@ -53,16 +52,25 @@ function fileCmp($a, $b) { } $files = array(); -foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { - $i['date'] = OCP\Util::formatDate($i['mtime'] ); - if($i['type'] == 'file') { +$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']); $i['basename'] = $fileinfo['filename']; if (!empty($fileinfo['extension'])) { - $i['extension']='.' . $fileinfo['extension']; - } - else { - $i['extension']=''; + $i['extension'] = '.' . $fileinfo['extension']; + } else { + $i['extension'] = ''; } } $i['directory'] = $dir; @@ -74,10 +82,10 @@ usort($files, "fileCmp"); // Make breadcrumb $breadcrumb = array(); $pathtohere = ''; -foreach( explode( '/', $dir ) as $i ) { - if( $i != '' ) { +foreach (explode('/', $dir) as $i) { + if ($i != '') { $pathtohere .= '/' . $i; - $breadcrumb[] = array( 'dir' => $pathtohere, 'name' => $i ); + $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); } } @@ -94,29 +102,35 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace = \OC\Files\Filesystem::free_space($dir); -$freeSpace = max($freeSpace,0); +$freeSpace = max($freeSpace, 0); $maxUploadFilesize = min($maxUploadFilesize, $freeSpace); $permissions = OCP\PERMISSION_READ; if (\OC\Files\Filesystem::isUpdatable($dir . '/')) { - $permissions |= OCP\PERMISSION_UPDATE; + $permissions |= OCP\PERMISSION_UPDATE; } if (\OC\Files\Filesystem::isDeletable($dir . '/')) { - $permissions |= OCP\PERMISSION_DELETE; + $permissions |= OCP\PERMISSION_DELETE; } if (\OC\Files\Filesystem::isSharable($dir . '/')) { - $permissions |= OCP\PERMISSION_SHARE; + $permissions |= OCP\PERMISSION_SHARE; } -$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->printPage(); +if ($needUpgrade) { + OCP\Util::addscript('files', 'upgrade'); + $tmpl = new OCP\Template('files', 'upgrade', 'user'); + $tmpl->printPage(); +} else { + OCP\Util::addscript('files', 'files'); + $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->printPage(); +} diff --git a/apps/files/js/upgrade.js b/apps/files/js/upgrade.js new file mode 100644 index 00000000000..02d57fc9e6c --- /dev/null +++ b/apps/files/js/upgrade.js @@ -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(); + }); +}); diff --git a/apps/files/templates/upgrade.php b/apps/files/templates/upgrade.php new file mode 100644 index 00000000000..de6cc713028 --- /dev/null +++ b/apps/files/templates/upgrade.php @@ -0,0 +1,4 @@ +
+ t('Upgrading filesystem cache...');?> +
+
diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php new file mode 100644 index 00000000000..ee10a1c1350 --- /dev/null +++ b/lib/files/cache/legacy.php @@ -0,0 +1,73 @@ + + * 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; + + 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() { + try { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); + } catch (\Exception $e) { + return false; + } + try { + $result = $query->execute(array($this->user)); + } catch (\Exception $e) { + return false; + } + return (bool)$result->fetchRow(); + } + + /** + * @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(); + } +} diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 77db4c2339e..1032e0a844c 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -9,62 +9,102 @@ namespace OC\Files\Cache; class Upgrade { - static $permissionsCaches = array(); + /** + * @var Legacy $legacy + */ + private $legacy; - static $numericIds = array(); + private $permissionsCaches = array(); - static function upgrade() { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + private $numericIds = array(); - try { - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - } catch (\Exception $e) { - return; - } - try { - $oldEntriesResult = $oldEntriesQuery->execute(); - } catch (\Exception $e) { - return; - } - if (!$oldEntriesResult) { + 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); - $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + if ($row = $this->legacy->get($path)) { + $data = $this->getNewData($row); + $this->insert($data); - while ($row = $oldEntriesResult->fetchRow()) { - if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { - continue; + $children = $this->legacy->getChildren($data['id']); + foreach ($children as $child) { + if ($mode == Scanner::SCAN_SHALLOW) { + $childData = $this->getNewData($child); + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); + $this->insert($childData); + } else { + $this->upgradePath($child['path']); + } } + } + } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath; - */ - $pathHash = md5($internalPath); - $storageId = self::getNumericId($storage); - $parentId = ($internalPath === '') ? -1 : $row['parent']; + /** + * @param array $data the data for the new cache + */ + function insert($data) { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` + ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); + $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'])); - $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; - $permissionsCache = self::getPermissionsCache($storage); - $permissionsCache->set($row['id'], $row['user'], $permissions); - } + $permissionsCache = $this->getPermissionsCache($data['storage_object']); + $permissionsCache->set($data['id'], $data['user'], $data['permissions']); + } + + /** + * 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; } /** * @param \OC\Files\Storage\Storage $storage * @return Permissions */ - static function getPermissionsCache($storage) { + function getPermissionsCache($storage) { $storageId = $storage->getId(); - if (!isset(self::$permissionsCaches[$storageId])) { - self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + if (!isset($this->permissionsCaches[$storageId])) { + $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); } - return self::$permissionsCaches[$storageId]; + return $this->permissionsCaches[$storageId]; } /** @@ -73,12 +113,45 @@ class Upgrade { * @param \OC\Files\Storage\Storage $storage * @return int */ - static function getNumericId($storage) { + function getNumericId($storage) { $storageId = $storage->getId(); - if (!isset(self::$numericIds[$storageId])) { + 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); - self::$numericIds[$storageId] = $cache->getNumericStorageId(); + $this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype); } - return self::$numericIds[$storageId]; + 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); } } -- cgit v1.2.3 From 7debfac0dc8f602168d8db480cfd4757b4d612b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Jan 2013 19:11:12 +0100 Subject: Cache: more efficient upgrading --- apps/files/ajax/upgrade.php | 2 ++ lib/files/cache/legacy.php | 10 +++++++++- lib/files/cache/upgrade.php | 24 +++++++++++++++--------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php index 965c0073b8a..7237b02c0b0 100644 --- a/apps/files/ajax/upgrade.php +++ b/apps/files/ajax/upgrade.php @@ -10,10 +10,12 @@ $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); diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php index ee10a1c1350..33d4b8e7c9f 100644 --- a/lib/files/cache/legacy.php +++ b/lib/files/cache/legacy.php @@ -14,6 +14,8 @@ namespace OC\Files\Cache; class Legacy { private $user; + private $cacheHasItems = null; + public function __construct($user) { $this->user = $user; } @@ -34,17 +36,23 @@ class Legacy { * @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; } - return (bool)$result->fetchRow(); + $this->cacheHasItems = (bool)$result->fetchRow(); + return $this->cacheHasItems; } /** diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 1032e0a844c..cd9a9e91a8c 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -43,15 +43,21 @@ class Upgrade { $data = $this->getNewData($row); $this->insert($data); - $children = $this->legacy->getChildren($data['id']); - foreach ($children as $child) { - if ($mode == Scanner::SCAN_SHALLOW) { - $childData = $this->getNewData($child); - \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); - $this->insert($childData); - } else { - $this->upgradePath($child['path']); - } + $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']); } } } -- cgit v1.2.3 From 29ec00797948d98ffa5dcb0baa1518630ab3ef56 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 19:11:33 +0100 Subject: Cache: dont migrate permissions, cache them on demain instead --- lib/files/cache/upgrade.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index cd9a9e91a8c..19e3d9ad575 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -14,8 +14,6 @@ class Upgrade { */ private $legacy; - private $permissionsCaches = array(); - private $numericIds = array(); private $mimeTypeIds = array(); @@ -72,9 +70,6 @@ class Upgrade { $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'])); - - $permissionsCache = $this->getPermissionsCache($data['storage_object']); - $permissionsCache->set($data['id'], $data['user'], $data['permissions']); } /** @@ -101,18 +96,6 @@ class Upgrade { return $newData; } - /** - * @param \OC\Files\Storage\Storage $storage - * @return Permissions - */ - function getPermissionsCache($storage) { - $storageId = $storage->getId(); - if (!isset($this->permissionsCaches[$storageId])) { - $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); - } - return $this->permissionsCaches[$storageId]; - } - /** * get the numeric storage id * -- cgit v1.2.3 From f9c42a196f03bb193b07a8f5f8ecf42b911ef4b5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:36:04 +0100 Subject: Cache: no longer using this file --- lib/files/file.php | 61 ------------------------------------------------------ 1 file changed, 61 deletions(-) delete mode 100644 lib/files/file.php diff --git a/lib/files/file.php b/lib/files/file.php deleted file mode 100644 index 0d33cea7ee7..00000000000 --- a/lib/files/file.php +++ /dev/null @@ -1,61 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files; - -/** - * representation of the location a file or folder is stored - */ - -class File{ - /** - * @var Storage\Storage $storage - */ - private $storage; - /** - * @var string internalPath - */ - private $internalPath; - - public function __construct(Storage\Storage $storage, $internalPath){ - $this->storage = $storage; - $this->internalPath = $internalPath; - } - - public static function resolve($fullPath){ - $storage = null; - $internalPath = ''; - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); - return new File($storage, $internalPath); - } - - /** - * get the internal path of the file inside the filestorage - * @return string - */ - public function getInternalPath(){ - return $this->internalPath; - } - - /** - * get the storage the file is stored in - * @return \OC\Files\Storage\Storage - */ - public function getStorage(){ - return $this->storage; - } - - /** - * get the id of the storage the file is stored in - * @return string - */ - public function getStorageId(){ - return $this->storage->getId(); - } - -} -- cgit v1.2.3 From bb43cf378b5e7c6a18a30d8fbb226b72f1e4eb88 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:36:25 +0100 Subject: Files: make sure keybinds js is loaded after files js --- apps/files/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/index.php b/apps/files/index.php index 0dce7686962..854218eee55 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -30,7 +30,6 @@ OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); OCP\Util::addscript('files', 'filelist'); OCP\Util::addscript('files', 'fileactions'); -OCP\Util::addscript('files', 'keyboardshortcuts'); OCP\App::setActiveNavigationEntry('files_index'); // Load the files @@ -122,6 +121,7 @@ if ($needUpgrade) { $tmpl->printPage(); } else { 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); -- cgit v1.2.3 From 6871a150bd1309af0ca22e45487043d9640bb356 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:58:17 +0100 Subject: Cache: use a database transition for scanning each folder gives a massive speed improvement while scanning files --- lib/files/cache/scanner.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index b62a093cec7..bf0ef01d6b3 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -83,14 +83,19 @@ class Scanner { * * @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) { + 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)); - $this->scanFile($path); + $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; @@ -98,10 +103,12 @@ class Scanner { if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + $childQueue[] = $child; + $data['size'] = 0; } else { $data['size'] = -1; } + } else { } if ($data['size'] === -1) { $size = -1; @@ -111,6 +118,15 @@ class Scanner { } } } + \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)); } -- cgit v1.2.3 From 5df6f9d14d5a05d91d6706b420c8ad9a387a9f6d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 18 Jan 2013 23:56:47 -0500 Subject: Fix merge --- lib/public/share.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 9d2a64b4590..5f9ad7fc09d 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -684,13 +684,13 @@ class Share { } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') - && $format == \OC_Share_Backend_File::FORMAT_FILE_APP + && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT ) { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, ' - .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, ' - .'`expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, ' - .'`versioned`, `writable`'; + .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' + .'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' + .'`name` `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } -- cgit v1.2.3 From cd8d8360b0bcc07e22c4c9b86252ef1676b123dc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 18 Jan 2013 23:57:13 -0500 Subject: Disable fancy folder sharing for now --- lib/public/share.php | 56 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 5f9ad7fc09d..f65d272ff17 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -300,36 +300,36 @@ class Share { throw new \Exception($message); } // If the item is a folder, scan through the folder looking for equivalent item types - if ($itemType == 'folder') { - $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); - if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { - for ($i = 0; $i < count($files); $i++) { - $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' - && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/') - ) { - // Continue scanning into child folders - array_push($files, $children); - } else { - // Check file extension for an equivalent item type to convert to - $extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1)); - foreach (self::$backends as $type => $backend) { - if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) { - $itemType = $type; - break; - } - } - // Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted - self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder); - } - } - return true; - } - return false; - } else { +// if ($itemType == 'folder') { +// $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); +// if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { +// for ($i = 0; $i < count($files); $i++) { +// $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); +// if ($files[$i]['mimetype'] == 'httpd/unix-directory' +// && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/') +// ) { +// // Continue scanning into child folders +// array_push($files, $children); +// } else { +// // Check file extension for an equivalent item type to convert to +// $extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1)); +// foreach (self::$backends as $type => $backend) { +// if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) { +// $itemType = $type; +// break; +// } +// } +// // Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted +// self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder); +// } +// } +// return true; +// } +// return false; +// } else { // Put the item into the database return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions); - } +// } } /** -- cgit v1.2.3 From 8ca30d244c19b33e7e3b0da247b70160a3acc44f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 19 Jan 2013 00:02:40 -0500 Subject: Implement getETag() in shared storage --- apps/files_sharing/lib/sharedstorage.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index c8756af8ed7..b0be6843c56 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -431,7 +431,14 @@ class Shared extends \OC\Files\Storage\Common { } 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; } } -- cgit v1.2.3 From 664f33a29c81701fbf6a7fb18eda81e1c4665ecc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 19 Jan 2013 21:04:25 -0500 Subject: Update mtimes of all parent folders after change inside --- lib/files/cache/updater.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 8b0d3835033..d04541c219f 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -35,7 +35,7 @@ class Updater { $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, $storage->filemtime($internalPath)); } } @@ -49,11 +49,17 @@ class Updater { $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, time()); } } - static public function eTagUpdate($path) { + /** + * 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 === '.') { @@ -68,8 +74,8 @@ class Updater { $cache = $storage->getCache(); $id = $cache->getId($internalPath); if ($id !== -1) { - $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::eTagUpdate($parent); + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + self::correctFolder($parent, $time); } } } -- cgit v1.2.3 From 42a1a17a30b8299a7dc4ea71aed57e607bdc2838 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:01:22 +0100 Subject: Cache: return non numberic storage id --- lib/files/cache/cache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5c306c2ed16..7f6d191fee4 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -130,6 +130,7 @@ class Cache { $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']); } -- cgit v1.2.3 From 1762378f67085cc9e8fecb287d73f1f1570cb3cc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:07:55 +0100 Subject: Files: don't load fileactions.js when upgrading filecache --- apps/files/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/index.php b/apps/files/index.php index c10ae76e9ea..b1cd40f2546 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -30,7 +30,6 @@ OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); OCP\Util::addscript('files', 'jquery-visibility'); OCP\Util::addscript('files', 'filelist'); -OCP\Util::addscript('files', 'fileactions'); OCP\App::setActiveNavigationEntry('files_index'); // Load the files @@ -116,6 +115,7 @@ if ($needUpgrade) { $tmpl = new OCP\Template('files', 'upgrade', 'user'); $tmpl->printPage(); } else { + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); $tmpl = new OCP\Template('files', 'index', 'user'); -- cgit v1.2.3 From 8ede3290ae2da4b04f451ff3d502f0ac60ac6585 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:31:44 +0100 Subject: Cache: add database indexes for mimetype and mimepart --- db_structure.xml | 24 ++++++++++++++++++++++++ lib/util.php | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/db_structure.xml b/db_structure.xml index f1f02572819..479ee3259ff 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -258,6 +258,30 @@ + + fs_storage_mimetype + + storage + ascending + + + mimetype + ascending + + + + + fs_storage_mimepart + + storage + ascending + + + mimepart + ascending + + +
diff --git a/lib/util.php b/lib/util.php index 59566c9f4fb..f947ed9c178 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,07); + return array(4,91,8); } /** -- cgit v1.2.3 From e666ce3622bed37ba6d9327aeecdf4a96dc7f5f4 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 21 Jan 2013 23:57:26 -0500 Subject: Fix external storage UI for new storage namespaces --- apps/files_external/js/dropbox.js | 4 ++-- apps/files_external/js/google.js | 7 ++++--- apps/files_external/js/settings.js | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js index c1e38640708..a9a3155e677 100644 --- a/apps/files_external/js/dropbox.js +++ b/apps/files_external/js/dropbox.js @@ -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) { diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js index 0b3c314eb5d..7d759d13da4 100644 --- a/apps/files_external/js/google.js +++ b/apps/files_external/js/google.js @@ -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(''+t('files_external', 'Grant access')+''); @@ -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 { diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 0dc983ca8ad..6cbc2180084 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -100,7 +100,7 @@ $(document).ready(function() { td.append(''); } }); - 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; -- cgit v1.2.3 From 465c100d8f5932340ea80f8a426ca7f404fc97c6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 22 Jan 2013 00:43:43 -0500 Subject: Add tests for mtime changes in folders - testRename is failing right now --- tests/lib/files/cache/updater.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index cad3d9d46fc..8bf395698ae 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -78,9 +78,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $rootCachedData['mtime']); $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); @@ -88,9 +90,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->cache->inCache('bar.txt')); $cachedData = $this->cache->get('bar.txt'); $this->assertEquals(3, $cachedData['size']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $rootCachedData['mtime']); } public function testDelete() { @@ -105,6 +109,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); @@ -116,6 +121,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('bar_folder')); $cachedData = $this->cache->get(''); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } public function testRename() { @@ -132,8 +138,10 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->cache->inCache('bar.txt')); $cachedData = $this->cache->get('foo.txt'); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); } } -- cgit v1.2.3 From db2b485b9681b93200bcca6b5780b78008f9c1de Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 16:36:03 +0100 Subject: Cache: fix test case Updater::testRename --- tests/lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 8bf395698ae..b4f373cdc2a 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -136,7 +136,7 @@ class Updater extends \PHPUnit_Framework_TestCase { Filesystem::rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); - $cachedData = $this->cache->get('foo.txt'); + $cachedData = $this->cache->get('bar.txt'); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); -- cgit v1.2.3 From 7330fcf5e81e7d91ed37f01da7cc45833e10f1c4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:57:15 +0100 Subject: Cache: make mounts overwrite existing folders, prevents duplicate entries --- lib/files/view.php | 8 ++++++++ tests/lib/files/view.php | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 06027910123..c50897603eb 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -794,6 +794,14 @@ class View { $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; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 53271142672..586ad178425 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -98,6 +98,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testMountPointOverwrite() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(); + $storage1->mkdir('substorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + + $rootView = new \OC\Files\View(''); + $folderContent = $rootView->getDirectoryContent('/'); + $this->assertEquals(4, count($folderContent)); + } + function testCacheIncompleteFolder() { $storage1 = $this->getTestStorage(false); \OC\Files\Filesystem::mount($storage1, array(), '/'); -- cgit v1.2.3 From 9a1f65aab176604c90114891b4bc0346fbb7d561 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:58:09 +0100 Subject: Some style fixes --- lib/files/filesystem.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 28e8b046896..9a3d13e343b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -231,16 +231,16 @@ class Filesystem { } /** - * Initialize system and personal mount points for a user - * - * @param string $user - */ + * 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')) { + if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { @@ -277,8 +277,8 @@ class Filesystem { // 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 (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); @@ -370,7 +370,7 @@ class Filesystem { } else { // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); + $class = '\OC\Files\Storage\\' . substr($class, 15); } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } @@ -663,7 +663,7 @@ class Filesystem { * @param string $path * @return string */ - static public function getETag($path){ + static public function getETag($path) { return self::$defaultInstance->getETag($path); } } -- cgit v1.2.3 From 7237ebf08b5a20fe6072a99be33f3520d4bf3871 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 26 Jan 2013 15:16:53 -0500 Subject: Fix OC_Helper and change deprecated methods --- lib/helper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/helper.php b/lib/helper.php index 1dd11cce041..c2a0d83f6b1 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -760,7 +760,7 @@ class OC_Helper { $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); - $freeSpace = OC_Filesystem::free_space($dir); + $freeSpace = \OC\Files\Filesystem::free_space($dir); $freeSpace = max($freeSpace, 0); return min($maxUploadFilesize, $freeSpace); @@ -790,12 +790,12 @@ class OC_Helper { * Calculate the disc space */ public static function getStorageInfo() { - $rootInfo = OC_FileCache::get(''); + $rootInfo = \OC\Files\Filesystem::getFileInfo('/'); $used = $rootInfo['size']; if ($used < 0) { $used = 0; } - $free = OC_Filesystem::free_space(); + $free = \OC\Files\Filesystem::free_space(); $total = $free + $used; if ($total == 0) { $total = 1; // prevent division by zero -- cgit v1.2.3 From 177537dbccac7c30ab42dfee56e92974e5cdf042 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 21:41:14 +0100 Subject: Cache: port test cases to PHPUnit --- tests/lib/files/cache/cache.php | 42 +++++++++++++++---------------- tests/lib/files/cache/scanner.php | 52 +++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index a2b131ac0ac..96a7623dac5 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -8,7 +8,7 @@ namespace Test\Files\Cache; -class Cache extends \UnitTestCase { +class Cache extends \PHPUnit_Framework_TestCase { /** * @var \OC\Files\Storage\Temporary $storage; */ @@ -26,56 +26,56 @@ class Cache extends \UnitTestCase { $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $this->assertFalse($this->cache->inCache($file1)); - $this->assertEqual($this->cache->get($file1), null); + $this->assertEquals($this->cache->get($file1), null); $id1 = $this->cache->put($file1, $data1); $this->assertTrue($this->cache->inCache($file1)); $cacheData1 = $this->cache->get($file1); foreach ($data1 as $key => $value) { - $this->assertEqual($value, $cacheData1[$key]); + $this->assertEquals($value, $cacheData1[$key]); } - $this->assertEqual($cacheData1['mimepart'], 'foo'); - $this->assertEqual($cacheData1['fileid'], $id1); - $this->assertEqual($id1, $this->cache->getId($file1)); + $this->assertEquals($cacheData1['mimepart'], 'foo'); + $this->assertEquals($cacheData1['fileid'], $id1); + $this->assertEquals($id1, $this->cache->getId($file1)); $this->assertFalse($this->cache->inCache($file2)); $id2 = $this->cache->put($file2, $data2); $this->assertTrue($this->cache->inCache($file2)); $cacheData2 = $this->cache->get($file2); foreach ($data2 as $key => $value) { - $this->assertEqual($value, $cacheData2[$key]); + $this->assertEquals($value, $cacheData2[$key]); } - $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); - $this->assertEqual($cacheData2['fileid'], $id2); - $this->assertEqual($id2, $this->cache->getId($file2)); - $this->assertEqual($id1, $this->cache->getParentId($file2)); + $this->assertEquals($cacheData1['fileid'], $cacheData2['parent']); + $this->assertEquals($cacheData2['fileid'], $id2); + $this->assertEquals($id2, $this->cache->getId($file2)); + $this->assertEquals($id1, $this->cache->getParentId($file2)); $newSize = 1050; $newId2 = $this->cache->put($file2, array('size' => $newSize)); $cacheData2 = $this->cache->get($file2); - $this->assertEqual($newId2, $id2); - $this->assertEqual($cacheData2['size'], $newSize); - $this->assertEqual($cacheData1, $this->cache->get($file1)); + $this->assertEquals($newId2, $id2); + $this->assertEquals($cacheData2['size'], $newSize); + $this->assertEquals($cacheData1, $this->cache->get($file1)); $this->cache->remove($file2); $this->assertFalse($this->cache->inCache($file2)); - $this->assertEqual($this->cache->get($file2), null); + $this->assertEquals($this->cache->get($file2), null); $this->assertTrue($this->cache->inCache($file1)); - $this->assertEqual($cacheData1, $this->cache->get($id1)); + $this->assertEquals($cacheData1, $this->cache->get($id1)); } public function testPartial() { $file1 = 'foo'; $this->cache->put($file1, array('size' => 10)); - $this->assertEqual(array('size' => 10), $this->cache->get($file1)); + $this->assertEquals(array('size' => 10), $this->cache->get($file1)); $this->cache->put($file1, array('mtime' => 15)); - $this->assertEqual(array('size' => 10, 'mtime' => 15), $this->cache->get($file1)); + $this->assertEquals(array('size' => 10, 'mtime' => 15), $this->cache->get($file1)); $this->cache->put($file1, array('size' => 12)); - $this->assertEqual(array('size' => 12, 'mtime' => 15), $this->cache->get($file1)); + $this->assertEquals(array('size' => 12, 'mtime' => 15), $this->cache->get($file1)); } public function testFolder() { @@ -92,11 +92,11 @@ class Cache extends \UnitTestCase { $this->cache->put($file3, $fileData['foo']); $content = $this->cache->getFolderContents($file1); - $this->assertEqual(count($content), 2); + $this->assertEquals(count($content), 2); foreach ($content as $cachedData) { $data = $fileData[$cachedData['name']]; foreach ($data as $name => $value) { - $this->assertEqual($value, $cachedData[$name]); + $this->assertEquals($value, $cachedData[$name]); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 6d26150d82b..3885c99e6d3 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -8,7 +8,7 @@ namespace Test\Files\Cache; -class Scanner extends \UnitTestCase { +class Scanner extends \PHPUnit_Framework_TestCase { /** * @var \OC\Files\Storage\Storage $storage */ @@ -29,20 +29,20 @@ class Scanner extends \UnitTestCase { $this->storage->file_put_contents('foo.txt', $data); $this->scanner->scanFile('foo.txt'); - $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEquals($this->cache->inCache('foo.txt'), true); $cachedData = $this->cache->get('foo.txt'); - $this->assertEqual($cachedData['size'], strlen($data)); - $this->assertEqual($cachedData['mimetype'], 'text/plain'); - $this->assertNotEqual($cachedData['parent'], -1); //parent folders should be scanned automatically + $this->assertEquals($cachedData['size'], strlen($data)); + $this->assertEquals($cachedData['mimetype'], 'text/plain'); + $this->assertNotEquals($cachedData['parent'], -1); //parent folders should be scanned automatically $data = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); $this->storage->file_put_contents('foo.png', $data); $this->scanner->scanFile('foo.png'); - $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEquals($this->cache->inCache('foo.png'), true); $cachedData = $this->cache->get('foo.png'); - $this->assertEqual($cachedData['size'], strlen($data)); - $this->assertEqual($cachedData['mimetype'], 'image/png'); + $this->assertEquals($cachedData['size'], strlen($data)); + $this->assertEquals($cachedData['mimetype'], 'image/png'); } private function fillTestFolders() { @@ -58,11 +58,11 @@ class Scanner extends \UnitTestCase { $this->fillTestFolders(); $this->scanner->scan(''); - $this->assertEqual($this->cache->inCache(''), true); - $this->assertEqual($this->cache->inCache('foo.txt'), true); - $this->assertEqual($this->cache->inCache('foo.png'), true); - $this->assertEqual($this->cache->inCache('folder'), true); - $this->assertEqual($this->cache->inCache('folder/bar.txt'), true); + $this->assertEquals($this->cache->inCache(''), true); + $this->assertEquals($this->cache->inCache('foo.txt'), true); + $this->assertEquals($this->cache->inCache('foo.png'), true); + $this->assertEquals($this->cache->inCache('folder'), true); + $this->assertEquals($this->cache->inCache('folder/bar.txt'), true); $cachedDataText = $this->cache->get('foo.txt'); $cachedDataText2 = $this->cache->get('foo.txt'); @@ -70,38 +70,38 @@ class Scanner extends \UnitTestCase { $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertEqual($cachedDataImage['parent'], $cachedDataText['parent']); - $this->assertEqual($cachedDataFolder['fileid'], $cachedDataImage['parent']); - $this->assertEqual($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); - $this->assertEqual($cachedDataFolder2['size'], $cachedDataText2['size']); + $this->assertEquals($cachedDataImage['parent'], $cachedDataText['parent']); + $this->assertEquals($cachedDataFolder['fileid'], $cachedDataImage['parent']); + $this->assertEquals($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); + $this->assertEquals($cachedDataFolder2['size'], $cachedDataText2['size']); } function testShallow() { $this->fillTestFolders(); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); - $this->assertEqual($this->cache->inCache(''), true); - $this->assertEqual($this->cache->inCache('foo.txt'), true); - $this->assertEqual($this->cache->inCache('foo.png'), true); - $this->assertEqual($this->cache->inCache('folder'), true); - $this->assertEqual($this->cache->inCache('folder/bar.txt'), false); + $this->assertEquals($this->cache->inCache(''), true); + $this->assertEquals($this->cache->inCache('foo.txt'), true); + $this->assertEquals($this->cache->inCache('foo.png'), true); + $this->assertEquals($this->cache->inCache('folder'), true); + $this->assertEquals($this->cache->inCache('folder/bar.txt'), false); $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertEqual(-1, $cachedDataFolder['size']); - $this->assertEqual(-1, $cachedDataFolder2['size']); + $this->assertEquals(-1, $cachedDataFolder['size']); + $this->assertEquals(-1, $cachedDataFolder2['size']); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertNotEqual($cachedDataFolder2['size'], -1); + $this->assertNotEquals($cachedDataFolder2['size'], -1); $this->cache->correctFolderSize('folder'); $cachedDataFolder = $this->cache->get(''); - $this->assertNotEqual($cachedDataFolder['size'], -1); + $this->assertNotEquals($cachedDataFolder['size'], -1); } function testBackgroundScan(){ -- cgit v1.2.3 From f25db779d90814f1d54d594caf1bb830ea417b95 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 21:42:59 +0100 Subject: Filesystem: move mount management to it's own class --- lib/files/filesystem.php | 99 ++++++--------------------- lib/files/mount.php | 171 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 79 deletions(-) create mode 100644 lib/files/mount.php diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 9a3d13e343b..048116a44bb 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -30,8 +30,6 @@ namespace OC\Files; class Filesystem { - static private $storages = array(); - static private $mounts = array(); public static $loaded = false; /** * @var \OC\Files\View $defaultInstance @@ -143,19 +141,12 @@ class Filesystem { * @return string */ static public function getMountPoint($path) { - $path = self::normalizePath($path) . '/'; - \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); - $foundMountPoint = ''; - $mountPoints = array_keys(self::$mounts); - foreach ($mountPoints as $mountpoint) { - if ($mountpoint == $path) { - return $mountpoint; - } - if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { - $foundMountPoint = $mountpoint; - } + $mount = Mount::find($path); + if ($mount) { + return $mount->getMountPoint(); + } else { + return ''; } - return $foundMountPoint; } /** @@ -165,18 +156,10 @@ class Filesystem { * @return string[] */ static public function getMountPoints($path) { - $path = self::normalizePath($path); - if (strlen($path) > 1) { - $path .= '/'; - } - $pathLength = strlen($path); - - $mountPoints = array_keys(self::$mounts); $result = array(); - foreach ($mountPoints as $mountPoint) { - if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { - $result[] = $mountPoint; - } + $mounts = Mount::findIn($path); + foreach ($mounts as $mount) { + $result[] = $mount->getMountPoint(); } return $result; } @@ -188,11 +171,8 @@ class Filesystem { * @return \OC\Files\Storage\Storage */ public static function getStorage($mountPoint) { - if (!isset(self::$storages[$mountPoint])) { - $mount = self::$mounts[$mountPoint]; - self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); - } - return self::$storages[$mountPoint]; + $mount = Mount::find($mountPoint); + return $mount->getStorage(); } /** @@ -202,15 +182,9 @@ class Filesystem { * @return array consisting of the storage and the internal path */ static public function resolvePath($path) { - $mountpoint = self::getMountPoint($path); - if ($mountpoint) { - $storage = self::getStorage($mountpoint); - if ($mountpoint === $path or $mountpoint . '/' === $path) { - $internalPath = ''; - } else { - $internalPath = substr($path, strlen($mountpoint)); - } - return array($storage, $internalPath); + $mount = Mount::find($path); + if ($mount) { + return array($mount->getStorage(), $mount->getInternalPath($path)); } else { return array(null, null); } @@ -291,6 +265,7 @@ class Filesystem { * fill in the correct values for $user, and $password placeholders * * @param string $input + * @param string $input * @return string */ private static function setUserVars($user, $input) { @@ -310,28 +285,7 @@ class Filesystem { * 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; - } + self::clearMounts(); } /** @@ -348,8 +302,7 @@ class Filesystem { * clear all mounts and storage backends */ public static function clearMounts() { - self::$mounts = array(); - self::$storages = array(); + Mount::clear(); } /** @@ -360,20 +313,7 @@ class Filesystem { * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - $mountpoint = self::normalizePath($mountpoint); - if (strlen($mountpoint) > 1) { - $mountpoint .= '/'; - } - if ($class instanceof \OC\Files\Storage\Storage) { - self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); - self::$storages[$mountpoint] = $class; - } else { - // Update old classes to new namespace - if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\' . substr($class, 15); - } - self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); - } + new Mount($class, $mountpoint, $arguments); } /** @@ -578,6 +518,7 @@ class Filesystem { /** * check if a file or folder has been updated since $time * + * @param string $path * @param int $time * @return bool */ @@ -653,8 +594,8 @@ class Filesystem { * @param string $directory path under datadirectory * @return array */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); + public static function getDirectoryContent($directory) { + return self::$defaultInstance->getDirectoryContent($directory); } /** diff --git a/lib/files/mount.php b/lib/files/mount.php new file mode 100644 index 00000000000..c6746d2a337 --- /dev/null +++ b/lib/files/mount.php @@ -0,0 +1,171 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files; + +class 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 + */ + 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(); + } +} -- cgit v1.2.3 From 03b947e3ece28325d3bc64319a228d66d493d182 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 26 Jan 2013 16:11:35 -0500 Subject: Don't check for updates for sub storages, these scans should be done in the background --- lib/files/view.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index c50897603eb..e6b52fb35b6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -769,9 +769,6 @@ class View { if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); $subScanner->scanFile(''); - } else { - $subWatcher = $subStorage->getWatcher(''); - $subWatcher->checkUpdate(''); } $rootEntry = $subCache->get(''); -- cgit v1.2.3 From 69f11151e90f0a17b02e58f7f94ca7f7a521f13a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 23:49:05 +0100 Subject: Filesystem: add Mount::findById --- lib/files/mount.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/files/mount.php b/lib/files/mount.php index c6746d2a337..e28b6471fe3 100644 --- a/lib/files/mount.php +++ b/lib/files/mount.php @@ -9,6 +9,9 @@ namespace OC\Files; class Mount { + /** + * @var Mount[] + */ static private $mounts = array(); /** @@ -23,7 +26,7 @@ class Mount { /** * @param string|\OC\Files\Storage\Storage $storage * @param string $mountpoint - * @param array $arguments + * @param array $arguments (optional) */ public function __construct($storage, $mountpoint, $arguments = null) { if (is_null($arguments)) { @@ -168,4 +171,17 @@ class Mount { public static function clear() { self::$mounts = array(); } + + /** + * @param string $id + * @return \OC\Files\Storage\Storage + */ + public static function findById($id) { + foreach (self::$mounts as $mount) { + if ($mount->getStorageId() === $id) { + return $mount; + } + } + return null; + } } -- cgit v1.2.3 From 8c42e2de8c8be9bd5914794dbf01a10f575788d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 23:49:14 +0100 Subject: Test cases for new mount management --- tests/lib/files/mount.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/lib/files/mount.php diff --git a/tests/lib/files/mount.php b/tests/lib/files/mount.php new file mode 100644 index 00000000000..9f16b036275 --- /dev/null +++ b/tests/lib/files/mount.php @@ -0,0 +1,37 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files; + +use \OC\Files\Storage\Temporary; + +class Mount extends \PHPUnit_Framework_TestCase { + public function setup() { + \OC_Util::setupFS(); + \OC\Files\Mount::clear(); + } + + public function testFind() { + $this->assertNull(\OC\Files\Mount::find('/')); + + $rootMount = new \OC\Files\Mount(new Temporary(array()), '/'); + $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); + $this->assertEquals($rootMount, \OC\Files\Mount::find('/foo/bar')); + + $mount = new \OC\Files\Mount(new Temporary(array()), '/foo'); + $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); + $this->assertEquals($mount, \OC\Files\Mount::find('/foo/bar')); + + $this->assertEquals(1, count(\OC\Files\Mount::findIn('/'))); + new \OC\Files\Mount(new Temporary(array()), '/bar'); + $this->assertEquals(2, count(\OC\Files\Mount::findIn('/'))); + + $id = $mount->getStorageId(); + $this->assertEquals($mount, \OC\Files\Mount::findById($id)); + } +} -- cgit v1.2.3 From 9e2a066c7bf04dfcc3e2dcc539e1b33053ba70ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 26 Jan 2013 23:59:29 +0100 Subject: Cache: add function to get storage id and internal path of a file by id --- lib/files/cache/cache.php | 24 ++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7f6d191fee4..69cbaea8516 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -494,4 +494,28 @@ class Cache { 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; + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 96a7623dac5..c466fbb63e7 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -197,6 +197,13 @@ class Cache extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $this->cache->getFolderContents('foo')); } + function testGetById() { + $storageId = $this->storage->getId(); + $data = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $id = $this->cache->put('foo', $data); + $this->assertEquals(array($storageId, 'foo'), \OC\Files\Cache\Cache::getById($id)); + } + public function tearDown() { $this->cache->clear(); } -- cgit v1.2.3 From 17bcea15855784f00791ab19984d520a773aa0ca Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 27 Jan 2013 00:13:16 +0100 Subject: Filesystem: add View->getPath to the cache api --- lib/files/view.php | 15 +++++++++++++++ tests/lib/files/view.php | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index e6b52fb35b6..c2038f222a0 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -932,4 +932,19 @@ class View { 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); + $mount = Mount::findById($storage); + $fullPath = $mount->getMountPoint() . $internalPath; + return $this->getRelativePath($fullPath); + } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 586ad178425..a064e44f3ef 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -98,6 +98,29 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testGetPath() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $id1 = $cachedData['fileid']; + $this->assertEquals('/foo.txt', $rootView->getPath($id1)); + + $cachedData = $rootView->getFileInfo('/substorage/foo.txt'); + $id2 = $cachedData['fileid']; + $this->assertEquals('/substorage/foo.txt', $rootView->getPath($id2)); + + $folderView = new \OC\Files\View('/substorage'); + $this->assertEquals('/foo.txt', $folderView->getPath($id2)); + $this->assertNull($folderView->getPath($id1)); + } + function testMountPointOverwrite() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(); -- cgit v1.2.3 From 4cae1416733019fe4c7465f3e167a456fb790502 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 27 Jan 2013 00:18:15 +0100 Subject: Filesystem: also add getPath to \OC\Filesystem --- lib/files/filesystem.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 048116a44bb..262fde320a1 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -598,6 +598,18 @@ class Filesystem { 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 * -- cgit v1.2.3 From 577e3b11d7b486d09334f39215814638704e84b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 00:59:43 +0100 Subject: Filesystem: return all matching mounts in Mount::findById --- lib/files/mount.php | 7 ++++--- tests/lib/files/mount.php | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/files/mount.php b/lib/files/mount.php index e28b6471fe3..74ee483b1be 100644 --- a/lib/files/mount.php +++ b/lib/files/mount.php @@ -174,14 +174,15 @@ class Mount { /** * @param string $id - * @return \OC\Files\Storage\Storage + * @return \OC\Files\Storage\Storage[] */ public static function findById($id) { + $result = array(); foreach (self::$mounts as $mount) { if ($mount->getStorageId() === $id) { - return $mount; + $result[] = $mount; } } - return null; + return $result; } } diff --git a/tests/lib/files/mount.php b/tests/lib/files/mount.php index 9f16b036275..f223f0f6c53 100644 --- a/tests/lib/files/mount.php +++ b/tests/lib/files/mount.php @@ -23,7 +23,8 @@ class Mount extends \PHPUnit_Framework_TestCase { $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); $this->assertEquals($rootMount, \OC\Files\Mount::find('/foo/bar')); - $mount = new \OC\Files\Mount(new Temporary(array()), '/foo'); + $storage = new Temporary(array()); + $mount = new \OC\Files\Mount($storage, '/foo'); $this->assertEquals($rootMount, \OC\Files\Mount::find('/')); $this->assertEquals($mount, \OC\Files\Mount::find('/foo/bar')); @@ -32,6 +33,9 @@ class Mount extends \PHPUnit_Framework_TestCase { $this->assertEquals(2, count(\OC\Files\Mount::findIn('/'))); $id = $mount->getStorageId(); - $this->assertEquals($mount, \OC\Files\Mount::findById($id)); + $this->assertEquals(array($mount), \OC\Files\Mount::findById($id)); + + $mount2 = new \OC\Files\Mount($storage, '/foo/bar'); + $this->assertEquals(array($mount, $mount2), \OC\Files\Mount::findById($id)); } } -- cgit v1.2.3 From 3e59a8715390d659b433797c8a0ed080518e5e7d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 01:02:04 +0100 Subject: Filesystem: use the updated Mount::findById in getPath to ensure we get the correct path if the storage is also mounted outside the view --- lib/files/view.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index c2038f222a0..302232b5134 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -943,8 +943,16 @@ class View { */ public function getPath($id) { list($storage, $internalPath) = Cache\Cache::getById($id); - $mount = Mount::findById($storage); - $fullPath = $mount->getMountPoint() . $internalPath; - return $this->getRelativePath($fullPath); + $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; } } -- cgit v1.2.3 From c9c919da5738f963247307ca3878e06beff87ade Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:34:15 +0100 Subject: Move streamwrappers to seperate files and put them in a namespace --- apps/files_external/lib/amazons3.php | 54 +++--- apps/files_external/lib/dropbox.php | 4 +- apps/files_external/lib/ftp.php | 2 +- apps/files_external/lib/google.php | 4 +- apps/files_external/lib/swift.php | 4 +- apps/files_external/lib/webdav.php | 6 +- apps/files_sharing/lib/sharedstorage.php | 2 +- lib/archive/tar.php | 2 +- lib/archive/zip.php | 2 +- lib/base.php | 7 +- lib/files/stream/close.php | 100 ++++++++++ lib/files/stream/dir.php | 47 +++++ lib/files/stream/staticstream.php | 191 ++++++++++++++++++++ lib/streamwrappers.php | 301 ------------------------------- tests/lib/streamwrappers.php | 76 ++++---- 15 files changed, 420 insertions(+), 382 deletions(-) create mode 100644 lib/files/stream/close.php create mode 100644 lib/files/stream/dir.php create mode 100644 lib/files/stream/staticstream.php delete mode 100644 lib/streamwrappers.php diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index a209f0d0507..494885a1dd3 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -1,24 +1,24 @@ . -*/ + * 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 . + */ namespace OC\Files\Storage; @@ -36,7 +36,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { - $this->id = 'amazon::'.$params['key'] . md5($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']; } @@ -51,7 +51,7 @@ class AmazonS3 extends \OC\Files\Storage\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; @@ -61,7 +61,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - public function getId(){ + public function getId() { return $this->id; } @@ -104,8 +104,8 @@ class AmazonS3 extends \OC\Files\Storage\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; } @@ -194,13 +194,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \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; } @@ -209,8 +209,8 @@ class AmazonS3 extends \OC\Files\Storage\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); } diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 9223b4ca87b..11644e4a2c8 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -114,7 +114,7 @@ class Dropbox extends \OC\Files\Storage\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; @@ -232,7 +232,7 @@ class Dropbox extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 973b33fbfd7..9a27b63323a 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -84,7 +84,7 @@ class FTP extends \OC\Files\Storage\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); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 4c485773e7b..7396c7e3f27 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -273,7 +273,7 @@ class Google extends \OC\Files\Storage\Common { $this->entries[$name] = $entry; } } - \OC_FakeDirStream::$dirs['google'.$path] = $files; + \OC\Files\Stream\Dir::register('google'.$path, $files); return opendir('fakedir://google'.$path); } @@ -450,7 +450,7 @@ class Google extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index bd1f4c572a6..cbf2007052b 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -371,7 +371,7 @@ class SWIFT extends \OC\Files\Storage\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); } @@ -465,7 +465,7 @@ class SWIFT extends \OC\Files\Storage\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); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 6d43a03058a..571b4d79ae2 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -104,13 +104,15 @@ class DAV extends \OC\Files\Storage\Common{ try { $response=$this->client->propfind($path, array(), 1); $id=md5('webdav'.$this->root.$path); + $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) { return false; @@ -194,7 +196,7 @@ class DAV extends \OC\Files\Storage\Common{ $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); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b0be6843c56..ea28ca69b93 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -102,7 +102,7 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); - \OC_FakeDirStream::$dirs['shared'] = $files; + \OC\Files\Stream\Dir::register('shared', $files); return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); diff --git a/lib/archive/tar.php b/lib/archive/tar.php index 0fa633c6038..117d88e5f42 100644 --- a/lib/archive/tar.php +++ b/lib/archive/tar.php @@ -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); } diff --git a/lib/archive/zip.php b/lib/archive/zip.php index 1c967baa08f..8e31795ded1 100644 --- a/lib/archive/zip.php +++ b/lib/archive/zip.php @@ -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); } diff --git a/lib/base.php b/lib/base.php index e3baa617c32..45e2f633cb7 100644 --- a/lib/base.php +++ b/lib/base.php @@ -421,10 +421,9 @@ 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'); self::checkConfig(); self::checkInstalled(); diff --git a/lib/files/stream/close.php b/lib/files/stream/close.php new file mode 100644 index 00000000000..80de3497c36 --- /dev/null +++ b/lib/files/stream/close.php @@ -0,0 +1,100 @@ + + * 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; + } +} diff --git a/lib/files/stream/dir.php b/lib/files/stream/dir.php new file mode 100644 index 00000000000..6ca884fc994 --- /dev/null +++ b/lib/files/stream/dir.php @@ -0,0 +1,47 @@ + + * 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; + } +} diff --git a/lib/files/stream/staticstream.php b/lib/files/stream/staticstream.php new file mode 100644 index 00000000000..7725a6a5a04 --- /dev/null +++ b/lib/files/stream/staticstream.php @@ -0,0 +1,191 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Stream; + +class StaticStream { + public $context; + protected static $data = array(); + + protected $path = ''; + protected $pointer = 0; + protected $writable = false; + + public function stream_close() { + } + + public function stream_eof() { + return $this->pointer >= strlen(self::$data[$this->path]); + } + + public function stream_flush() { + } + + public function stream_open($path, $mode, $options, &$opened_path) { + switch ($mode[0]) { + case 'r': + if (!isset(self::$data[$path])) return false; + $this->path = $path; + $this->writable = isset($mode[1]) && $mode[1] == '+'; + break; + case 'w': + self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + break; + case 'a': + if (!isset(self::$data[$path])) self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + $this->pointer = strlen(self::$data[$path]); + break; + case 'x': + if (isset(self::$data[$path])) return false; + $this->path = $path; + $this->writable = true; + break; + case 'c': + if (!isset(self::$data[$path])) self::$data[$path] = ''; + $this->path = $path; + $this->writable = true; + break; + default: + return false; + } + $opened_path = $this->path; + return true; + } + + public function stream_read($count) { + $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count); + $data = substr(self::$data[$this->path], $this->pointer, $bytes); + $this->pointer += $bytes; + return $data; + } + + public function stream_seek($offset, $whence = SEEK_SET) { + $len = strlen(self::$data[$this->path]); + switch ($whence) { + case SEEK_SET: + if ($offset <= $len) { + $this->pointer = $offset; + return true; + } + break; + case SEEK_CUR: + if ($this->pointer + $offset <= $len) { + $this->pointer += $offset; + return true; + } + break; + case SEEK_END: + if ($len + $offset <= $len) { + $this->pointer = $len + $offset; + return true; + } + break; + } + return false; + } + + public function stream_stat() { + $size = strlen(self::$data[$this->path]); + $time = time(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + + public function stream_tell() { + return $this->pointer; + } + + public function stream_write($data) { + if (!$this->writable) return 0; + $size = strlen($data); + if ($this->stream_eof()) { + self::$data[$this->path] .= $data; + } else { + self::$data[$this->path] = substr_replace( + self::$data[$this->path], + $data, + $this->pointer + ); + } + $this->pointer += $size; + return $size; + } + + public function unlink($path) { + if (isset(self::$data[$path])) { + unset(self::$data[$path]); + } + return true; + } + + public function url_stat($path) { + if (isset(self::$data[$path])) { + $size = strlen(self::$data[$path]); + $time = time(); + return array( + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0777, + 'mode' => 0777, + 3 => 1, + 'nlink' => 1, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => '', + 'rdev' => '', + 7 => $size, + 'size' => $size, + 8 => $time, + 'atime' => $time, + 9 => $time, + 'mtime' => $time, + 10 => $time, + 'ctime' => $time, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ); + } + return false; + } +} diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php deleted file mode 100644 index 981c280f0dd..00000000000 --- a/lib/streamwrappers.php +++ /dev/null @@ -1,301 +0,0 @@ -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 { - public $context; - protected static $data = array(); - - protected $path = ''; - protected $pointer = 0; - protected $writable = false; - - public function stream_close() {} - - public function stream_eof() { - return $this->pointer >= strlen(self::$data[$this->path]); - } - - public function stream_flush() {} - - public function stream_open($path, $mode, $options, &$opened_path) { - switch ($mode[0]) { - case 'r': - if (!isset(self::$data[$path])) return false; - $this->path = $path; - $this->writable = isset($mode[1]) && $mode[1] == '+'; - break; - case 'w': - self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - break; - case 'a': - if (!isset(self::$data[$path])) self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - $this->pointer = strlen(self::$data[$path]); - break; - case 'x': - if (isset(self::$data[$path])) return false; - $this->path = $path; - $this->writable = true; - break; - case 'c': - if (!isset(self::$data[$path])) self::$data[$path] = ''; - $this->path = $path; - $this->writable = true; - break; - default: - return false; - } - $opened_path = $this->path; - return true; - } - - public function stream_read($count) { - $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count); - $data = substr(self::$data[$this->path], $this->pointer, $bytes); - $this->pointer += $bytes; - return $data; - } - - public function stream_seek($offset, $whence = SEEK_SET) { - $len = strlen(self::$data[$this->path]); - switch ($whence) { - case SEEK_SET: - if ($offset <= $len) { - $this->pointer = $offset; - return true; - } - break; - case SEEK_CUR: - if ($this->pointer + $offset <= $len) { - $this->pointer += $offset; - return true; - } - break; - case SEEK_END: - if ($len + $offset <= $len) { - $this->pointer = $len + $offset; - return true; - } - break; - } - return false; - } - - public function stream_stat() { - $size = strlen(self::$data[$this->path]); - $time = time(); - return array( - 0 => 0, - 'dev' => 0, - 1 => 0, - 'ino' => 0, - 2 => 0777, - 'mode' => 0777, - 3 => 1, - 'nlink' => 1, - 4 => 0, - 'uid' => 0, - 5 => 0, - 'gid' => 0, - 6 => '', - 'rdev' => '', - 7 => $size, - 'size' => $size, - 8 => $time, - 'atime' => $time, - 9 => $time, - 'mtime' => $time, - 10 => $time, - 'ctime' => $time, - 11 => -1, - 'blksize' => -1, - 12 => -1, - 'blocks' => -1, - ); - } - - public function stream_tell() { - return $this->pointer; - } - - public function stream_write($data) { - if (!$this->writable) return 0; - $size = strlen($data); - if ($this->stream_eof()) { - self::$data[$this->path] .= $data; - } else { - self::$data[$this->path] = substr_replace( - self::$data[$this->path], - $data, - $this->pointer - ); - } - $this->pointer += $size; - return $size; - } - - public function unlink($path) { - if (isset(self::$data[$path])) { - unset(self::$data[$path]); - } - return true; - } - - public function url_stat($path) { - if (isset(self::$data[$path])) { - $size = strlen(self::$data[$path]); - $time = time(); - return array( - 0 => 0, - 'dev' => 0, - 1 => 0, - 'ino' => 0, - 2 => 0777, - 'mode' => 0777, - 3 => 1, - 'nlink' => 1, - 4 => 0, - 'uid' => 0, - 5 => 0, - 'gid' => 0, - 6 => '', - 'rdev' => '', - 7 => $size, - 'size' => $size, - 8 => $time, - 'atime' => $time, - 9 => $time, - 'mtime' => $time, - 10 => $time, - 'ctime' => $time, - 11 => -1, - 'blksize' => -1, - 12 => -1, - 'blocks' => -1, - ); - } - 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); - } -} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index aebbc93b902..e40f2e76128 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -1,41 +1,41 @@ . -* -*/ + * ownCloud + * + * @author Robin Appelman + * @copyright 2012 Robin Appelman icewind@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 . + * + */ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testFakeDir() { - $items=array('foo', 'bar'); - OC_FakeDirStream::$dirs['test']=$items; - $dh=opendir('fakedir://test'); - $result=array(); - while($file=readdir($dh)) { - $result[]=$file; + $items = array('foo', 'bar'); + \OC\Files\Stream\Dir::register('test', $items); + $dh = opendir('fakedir://test'); + $result = array(); + while ($file = readdir($dh)) { + $result[] = $file; $this->assertContains($file, $items); } $this->assertEquals(count($items), count($result)); } public function testStaticStream() { - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $staticFile='static://test'; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $staticFile = 'static://test'; $this->assertFalse(file_exists($staticFile)); file_put_contents($staticFile, file_get_contents($sourceFile)); $this->assertTrue(file_exists($staticFile)); @@ -47,27 +47,27 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testCloseStream() { //ensure all basic stream stuff works - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; $this->assertTrue(file_exists($file)); file_put_contents($file, file_get_contents($sourceFile)); $this->assertEquals(file_get_contents($sourceFile), file_get_contents($file)); unlink($file); clearstatcache(); $this->assertFalse(file_exists($file)); - + //test callback - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array('Test_StreamWrappers', 'closeCallBack'); - $fh=fopen($file, 'w'); + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; + \OC\Files\Stream\Close::registerCallback($tmpFile, array('Test_StreamWrappers', 'closeCallBack')); + $fh = fopen($file, 'w'); fwrite($fh, 'asd'); - try{ + try { fclose($fh); $this->fail('Expected exception'); - }catch(Exception $e) { - $path=$e->getMessage(); + } catch (Exception $e) { + $path = $e->getMessage(); $this->assertEquals($path, $tmpFile); } } -- cgit v1.2.3 From 232cc3211b2b312d4e32e7d0fb482a2b7affe89a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:35:30 +0100 Subject: add oc:// streamwrapper to provide access to ownCloud's virtual filesystem --- lib/base.php | 1 + lib/files/stream/oc.php | 129 +++++++++++++++++++++++++++++++++++++++++++ tests/lib/streamwrappers.php | 19 +++++++ 3 files changed, 149 insertions(+) create mode 100644 lib/files/stream/oc.php diff --git a/lib/base.php b/lib/base.php index 45e2f633cb7..e6f00839aa2 100644 --- a/lib/base.php +++ b/lib/base.php @@ -424,6 +424,7 @@ class OC 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(); diff --git a/lib/files/stream/oc.php b/lib/files/stream/oc.php new file mode 100644 index 00000000000..88e7e062df9 --- /dev/null +++ b/lib/files/stream/oc.php @@ -0,0 +1,129 @@ + + * 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); + } +} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index e40f2e76128..2237ee7d378 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -75,4 +75,23 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public static function closeCallBack($path) { throw new Exception($path); } + + public function testOC() { + \OC\Files\Mount::clear(); + $storage = new \OC\Files\Storage\Temporary(array()); + $storage->file_put_contents('foo.txt', 'asd'); + new \OC\Files\Mount($storage, '/'); + + $this->assertTrue(file_exists('oc:///foo.txt')); + $this->assertEquals('asd', file_get_contents('oc:///foo.txt')); + $this->assertEquals(array('.', '..', 'foo.txt'), scandir('oc:///')); + + file_put_contents('oc:///bar.txt', 'qwerty'); + $this->assertEquals('qwerty', $storage->file_get_contents('bar.txt')); + $this->assertEquals(array('.', '..', 'bar.txt', 'foo.txt'), scandir('oc:///')); + $this->assertEquals('qwerty', file_get_contents('oc:///bar.txt')); + + unlink('oc:///foo.txt'); + $this->assertEquals(array('.', '..', 'bar.txt'), scandir('oc:///')); + } } -- cgit v1.2.3 From 7207211f3a9546f9d33cfffec0caf26ea419c50e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 19:58:24 +0100 Subject: change required ownCloud version to 4.91 --- apps/files/appinfo/info.xml | 2 +- apps/files_external/appinfo/info.xml | 2 +- apps/files_sharing/appinfo/info.xml | 2 +- apps/files_versions/appinfo/info.xml | 2 +- apps/user_ldap/appinfo/info.xml | 2 +- apps/user_webdavauth/appinfo/info.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml index 0a1b196b06f..7c82c839dab 100644 --- a/apps/files/appinfo/info.xml +++ b/apps/files/appinfo/info.xml @@ -5,7 +5,7 @@ File Management AGPL Robin Appelman - 4.9 + 4.91 true diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml index 3da1913c5fc..2c04216a9fb 100644 --- a/apps/files_external/appinfo/info.xml +++ b/apps/files_external/appinfo/info.xml @@ -5,7 +5,7 @@ Mount external storage sources AGPL Robin Appelman, Michael Gapczynski - 4.9 + 4.91 true diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml index a44d0338bb6..1f24a4dde83 100644 --- a/apps/files_sharing/appinfo/info.xml +++ b/apps/files_sharing/appinfo/info.xml @@ -5,7 +5,7 @@ File sharing between users AGPL Michael Gapczynski - 4.9 + 4.91 true diff --git a/apps/files_versions/appinfo/info.xml b/apps/files_versions/appinfo/info.xml index e4e5a365d51..0155f8e830f 100644 --- a/apps/files_versions/appinfo/info.xml +++ b/apps/files_versions/appinfo/info.xml @@ -4,7 +4,7 @@ Versions AGPL Frank Karlitschek - 4.9 + 4.91 true Versioning of files diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml index a7605775274..53269edfb34 100644 --- a/apps/user_ldap/appinfo/info.xml +++ b/apps/user_ldap/appinfo/info.xml @@ -7,7 +7,7 @@ This app is not compatible to the WebDAV user backend. AGPL Dominik Schmidt and Arthur Schiwon - 4.9 + 4.91 true diff --git a/apps/user_webdavauth/appinfo/info.xml b/apps/user_webdavauth/appinfo/info.xml index e51f2e9ec4f..f62f03577e8 100755 --- a/apps/user_webdavauth/appinfo/info.xml +++ b/apps/user_webdavauth/appinfo/info.xml @@ -7,7 +7,7 @@ This app is not compatible to the LDAP user and group backend. AGPL Frank Karlitschek - 4.9 + 4.91 true -- cgit v1.2.3 From 929b8c3e6926dbe4cf2c3e0b2eb00b502d49f64a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 20:04:10 +0100 Subject: fix files_version hooks --- apps/files_versions/lib/hooks.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php index 3a64e571d5a..5cefc532895 100644 --- a/apps/files_versions/lib/hooks.php +++ b/apps/files_versions/lib/hooks.php @@ -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 ); + } } -- cgit v1.2.3 From 86e5a9cd7354225572507343015107edc665aa08 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 21:09:18 +0100 Subject: Files: fix sharing newly uploaded files --- apps/files/ajax/upload.php | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index befb94d0844..9ecc1a6c2f4 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -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,14 +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\Files\Filesystem::free_space($dir)) { - OCP\JSON::error(array('data' => array( 'message' => $l->t( 'Not enough space available' ), - 'uploadMaxFilesize'=>$maxUploadFilesize, - 'maxHumanFilesize'=>$maxHumanFilesize))); +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(); } @@ -58,18 +61,18 @@ if (strpos($dir, '..') === false) { $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\Files\Filesystem::normalizePath($target); - if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $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( 'status' => 'success', - 'mime'=>$meta['mimetype'], - 'size'=>$meta['size'], - 'id'=>$id, - 'name'=>basename($target), - 'uploadMaxFilesize'=>$maxUploadFilesize, - 'maxHumanFilesize'=>$maxHumanFilesize + $result[] = array('status' => 'success', + 'mime' => $meta['mimetype'], + 'size' => $meta['size'], + 'id' => $meta['fileid'], + 'name' => basename($target), + 'uploadMaxFilesize' => $maxUploadFilesize, + 'maxHumanFilesize' => $maxHumanFilesize ); } } -- cgit v1.2.3 From a67f11c8afb78fc7ee011982257124f49910d269 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 21:25:19 +0100 Subject: Sharing: partailly fix searchByMime --- apps/files_sharing/lib/cache.php | 55 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 0b187a3c3ff..9655e447875 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -1,23 +1,23 @@ . -*/ + * 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 . + */ namespace OC\Files\Cache; @@ -31,18 +31,18 @@ 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 - */ + * @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']; + $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) { @@ -170,10 +170,10 @@ class Shared_Cache extends Cache { if ($cache = $this->getSourceCache($source)) { $targetPath = \OC_Share_Backend_File::getSourcePath(dirname($target)); if ($targetPath) { - $targetPath .= '/'.basename($target); + $targetPath .= '/' . basename($target); $cache->move($this->files[$source], $targetPath); } - + } } @@ -222,11 +222,12 @@ class Shared_Cache extends Cache { } 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.')' + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN (' . $placeholders . ')' ); $result = $query->execute(array_merge(array($mimetype), $ids)); return $result->fetchAll(); -- cgit v1.2.3 From ca4c006d5ab71acbd15ea011fba72eaddc34a901 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 28 Jan 2013 23:51:35 -0500 Subject: Make zip downloads use actual folder names, fix spelling mistakes --- lib/files.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/files.php b/lib/files.php index 4d09946a23f..e3245653f99 100644 --- a/lib/files.php +++ b/lib/files.php @@ -37,10 +37,10 @@ class OC_Files { } /** - * return the content of a file or return a zip file containning multiply files + * return the content of a file or return a zip file containing multiple files * * @param string $dir - * @param string $file ; seperated list of files to download + * @param string $file ; separated 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) { @@ -77,6 +77,7 @@ class OC_Files { } } $zip->close(); + $name = basename($dir) . '.zip'; set_time_limit($executionTime); } elseif (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) { self::validateZipDownload($dir, $files); @@ -94,18 +95,20 @@ class OC_Files { $file = $dir . '/' . $files; self::zipAddDir($file, $zip); $zip->close(); + $name = $files . '.zip'; set_time_limit($executionTime); } else { $zip = false; $filename = $dir . '/' . $files; + $name = $files; } OC_Util::obEnd(); 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(); @@ -125,7 +128,7 @@ class OC_Files { } 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->assign('file', $name); $tmpl->printPage(); } else { header("HTTP/1.0 403 Forbidden"); -- cgit v1.2.3 From af3b0e30ed2dd66212c3fc25bb5c406b77fa9e5d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 30 Jan 2013 18:17:56 +0100 Subject: Cache: don't insert duplicated during upgrade --- lib/files/cache/upgrade.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 19e3d9ad575..eb8c7297c3e 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -64,12 +64,25 @@ class Upgrade { * @param array $data the data for the new cache */ function insert($data) { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` - ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + 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'])); + $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(); } /** -- cgit v1.2.3 From 95352fbc1568e0c49be25461a07d53b3d5ad3b45 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 30 Jan 2013 19:18:32 +0100 Subject: Files: Dont get maxUploadSize if the filecache needs to be upgraded --- apps/files/index.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index 894758d38f6..d2cd76a7106 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -98,8 +98,6 @@ $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\Files\Filesystem::isCreatable($dir . '/')) { $permissions |= OCP\PERMISSION_CREATE; @@ -121,7 +119,8 @@ if ($needUpgrade) { } else { // information about storage capacities $storageInfo=OC_Helper::getStorageInfo(); - + $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); -- cgit v1.2.3 From 6043789394252a8f9042acfe0e62c1a5fb4e73d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 30 Jan 2013 19:37:02 +0100 Subject: Bumb version number for displayname db upgrade --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index f2d2e782ffc..e8057abe9ae 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4, 91, 8); + return array(4, 91, 9); } /** -- cgit v1.2.3