From e928a342c452b49ed84e36d3534bb9715f55845b Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 28 Dec 2012 20:10:01 -0500 Subject: [PATCH 001/216] Check if extra / is necessary for the folder URL --- apps/files/js/fileactions.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index e1d8b60d315..533b11a6e50 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -190,7 +190,11 @@ FileActions.register('all', 'Rename', OC.PERMISSION_UPDATE, function () { FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { - window.location = OC.linkTo('files', 'index.php') + '?dir=' + encodeURIComponent($('#dir').val()).replace(/%2F/g, '/') + '/' + encodeURIComponent(filename); + var dir = encodeURIComponent($('#dir').val()).replace(/%2F/g, '/'); + if (dir != '/') { + dir = dir + '/'; + } + window.location = OC.linkTo('files', 'index.php') + '?dir=' + dir + encodeURIComponent(filename); }); FileActions.setDefault('dir', 'Open'); -- GitLab From 855c9480b73d0ea3f6d0562503db5d72f64c14db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Sat, 9 Feb 2013 13:07:44 +0100 Subject: [PATCH 002/216] only encodeURIComponent once --- apps/files/js/fileactions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 533b11a6e50..316acda5133 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -190,11 +190,11 @@ FileActions.register('all', 'Rename', OC.PERMISSION_UPDATE, function () { FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) { - var dir = encodeURIComponent($('#dir').val()).replace(/%2F/g, '/'); + var dir = $('#dir').val() if (dir != '/') { dir = dir + '/'; } - window.location = OC.linkTo('files', 'index.php') + '?dir=' + dir + encodeURIComponent(filename); + window.location = OC.linkTo('files', 'index.php') + '?dir=' + encodeURIComponent(dir + filename); }); FileActions.setDefault('dir', 'Open'); -- GitLab From c6dbb33e1562ad1748feb3cb931ea5016520b867 Mon Sep 17 00:00:00 2001 From: kondou Date: Sat, 13 Apr 2013 14:48:16 +0200 Subject: [PATCH 003/216] Fix textfield label overlapping value. --- core/templates/installation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/templates/installation.php b/core/templates/installation.php index c70903cba55..4987e50d1ce 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -162,7 +162,7 @@

+ value="" />

-- GitLab From 07df94def66a78bda40560a5bdd31058f61e2238 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sun, 3 Mar 2013 12:06:00 +0100 Subject: [PATCH 004/216] Convert OC_Config to object interface --- lib/config.php | 111 ++++++++++++++++++----------------------- lib/hintexception.php | 27 ++++++++++ lib/legacy/config.php | 98 ++++++++++++++++++++++++++++++++++++ lib/setup.php | 16 +----- tests/lib/config.php | 113 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 288 insertions(+), 77 deletions(-) create mode 100644 lib/hintexception.php create mode 100644 lib/legacy/config.php create mode 100644 tests/lib/config.php diff --git a/lib/config.php b/lib/config.php index 9b87d4ce4e5..dcc659395a7 100644 --- a/lib/config.php +++ b/lib/config.php @@ -34,17 +34,27 @@ * */ +namespace OC; + /** * This class is responsible for reading and writing config.php, the very basic * configuration file of owncloud. */ -class OC_Config{ +class Config { // associative array key => value - private static $cache = array(); + protected $cache = array(); + + protected $config_dir; + protected $config_filename; - // Is the cache filled? - private static $init = false; + protected $debug_mode; + public function __construct($config_dir, $debug_mode) { + $this->config_dir = $config_dir; + $this->debug_mode = $debug_mode; + $this->config_filename = $this->config_dir.'config.php'; + $this->readData(); + } /** * @brief Lists all available config keys * @return array with key names @@ -52,10 +62,8 @@ class OC_Config{ * This function returns all keys saved in config.php. Please note that it * does not return the values. */ - public static function getKeys() { - self::readData(); - - return array_keys( self::$cache ); + public function getKeys() { + return array_keys( $this->cache ); } /** @@ -67,11 +75,9 @@ class OC_Config{ * This function gets the value from config.php. If it does not exist, * $default will be returned. */ - public static function getValue( $key, $default = null ) { - self::readData(); - - if( array_key_exists( $key, self::$cache )) { - return self::$cache[$key]; + public function getValue( $key, $default = null ) { + if( array_key_exists( $key, $this->cache )) { + return $this->cache[$key]; } return $default; @@ -81,57 +87,43 @@ class OC_Config{ * @brief Sets a value * @param string $key key * @param string $value value - * @return bool * * This function sets the value and writes the config.php. If the file can * not be written, false will be returned. */ - public static function setValue( $key, $value ) { - self::readData(); - + public function setValue( $key, $value ) { // Add change - self::$cache[$key] = $value; + $this->cache[$key] = $value; // Write changes - self::writeData(); - return true; + $this->writeData(); } /** * @brief Removes a key from the config * @param string $key key - * @return bool * * This function removes a key from the config.php. If owncloud has no * write access to config.php, the function will return false. */ - public static function deleteKey( $key ) { - self::readData(); - - if( array_key_exists( $key, self::$cache )) { + public function deleteKey( $key ) { + if( array_key_exists( $key, $this->cache )) { // Delete key from cache - unset( self::$cache[$key] ); + unset( $this->cache[$key] ); // Write changes - self::writeData(); + $this->writeData(); } - - return true; } /** * @brief Loads the config file - * @return bool * * Reads the config file and saves it to the cache */ - private static function readData() { - if( self::$init ) { - return true; - } - + private function readData() { // read all file in config dir ending by config.php - $config_files = glob( OC::$SERVERROOT."/config/*.config.php"); + $config_files = glob( $this->config_dir.'*.config.php'); //Filter only regular files $config_files = array_filter($config_files, 'is_file'); @@ -140,54 +132,49 @@ class OC_Config{ natsort($config_files); // Add default config - array_unshift($config_files,OC::$SERVERROOT."/config/config.php"); + array_unshift($config_files, $this->config_filename); //Include file and merge config - foreach($config_files as $file){ + foreach($config_files as $file) { + if( !file_exists( $file) ) { + continue; + } + unset($CONFIG); include $file; if( isset( $CONFIG ) && is_array( $CONFIG )) { - self::$cache = array_merge(self::$cache, $CONFIG); + $this->cache = array_merge($this->cache, $CONFIG); } } - - // We cached everything - self::$init = true; - - return true; } /** * @brief Writes the config file - * @return bool * * Saves the config to the config file. * */ - public static function writeData() { + private function writeData() { // Create a php file ... - $content = "debug_mode) { $content .= "define('DEBUG',true);\n"; } - $content .= "\$CONFIG = "; - $content .= var_export(self::$cache, true); + $content .= '$CONFIG = '; + $content .= var_export($this->cache, true); $content .= ";\n"; + //var_dump($content, $this); - $filename = OC::$SERVERROOT."/config/config.php"; // Write the file - $result=@file_put_contents( $filename, $content ); + $result=@file_put_contents( $this->config_filename, $content ); if(!$result) { - $tmpl = new OC_Template( '', 'error', 'guest' ); - $tmpl->assign('errors', array(1=>array( - 'error'=>"Can't write into config directory 'config'", - 'hint'=>'You can usually fix this by giving the webserver user write access' - .' to the config directory in owncloud'))); - $tmpl->printPage(); - exit; + throw new HintException( + "Can't write into config directory 'config'", + 'You can usually fix this by giving the webserver user write access' + .' to the config directory in owncloud'); } // Prevent others not to read the config - @chmod($filename, 0640); - - return true; + @chmod($this->config_filename, 0640); } } + +require_once __DIR__.'/legacy/'.basename(__FILE__); diff --git a/lib/hintexception.php b/lib/hintexception.php new file mode 100644 index 00000000000..8c64258435b --- /dev/null +++ b/lib/hintexception.php @@ -0,0 +1,27 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +class HintException extends \Exception +{ + private $hint; + + public function __construct($message, $hint, $code = 0, Exception $previous = null) { + $this->hint = $hint; + parent::__construct($message, $code, $previous); + } + + public function __toString() { + return __CLASS__ . ": [{$this->code}]: {$this->message} ({$this->hint})\n"; + } + + public function getHint() { + return $this->hint; + } +} diff --git a/lib/legacy/config.php b/lib/legacy/config.php new file mode 100644 index 00000000000..d030bbe3676 --- /dev/null +++ b/lib/legacy/config.php @@ -0,0 +1,98 @@ +. + * + */ +/* + * + * An example of config.php + * + * "mysql", + * "firstrun" => false, + * "pi" => 3.14 + * ); + * ?> + * + */ + +/** + * This class is responsible for reading and writing config.php, the very basic + * configuration file of owncloud. + */ +OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/', defined('DEBUG') && DEBUG); +class OC_Config{ + public static $object; + /** + * @brief Lists all available config keys + * @return array with key names + * + * This function returns all keys saved in config.php. Please note that it + * does not return the values. + */ + public static function getKeys() { + return self::$object->getKeys(); + } + + /** + * @brief Gets a value from config.php + * @param string $key key + * @param string $default = null default value + * @return string the value or $default + * + * This function gets the value from config.php. If it does not exist, + * $default will be returned. + */ + public static function getValue( $key, $default = null ) { + return self::$object->getValue( $key, $default ); + } + + /** + * @brief Sets a value + * @param string $key key + * @param string $value value + * + * This function sets the value and writes the config.php. If the file can + * not be written, false will be returned. + */ + public static function setValue( $key, $value ) { + try { + self::$object->setValue( $key, $value ); + } catch (\OC\HintException $e) { + \OC_Template::printErrorPage( $e->getMessage(), $e->getHint() ); + } + } + + /** + * @brief Removes a key from the config + * @param string $key key + * + * This function removes a key from the config.php. If owncloud has no + * write access to config.php, the function will return false. + */ + public static function deleteKey( $key ) { + try { + self::$object->deleteKey( $key ); + } catch (\OC\HintException $e) { + \OC_Template::printErrorPage( $e->getMessage(), $e->getHint() ); + } + } +} diff --git a/lib/setup.php b/lib/setup.php index d1197b3ebf3..e05db554320 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -1,21 +1,7 @@ hint = $hint; - parent::__construct($message, $code, $previous); - } - - public function __toString() { - return __CLASS__ . ": [{$this->code}]: {$this->message} ({$this->hint})\n"; - } - - public function getHint() { - return $this->hint; - } } class OC_Setup { diff --git a/tests/lib/config.php b/tests/lib/config.php new file mode 100644 index 00000000000..e22bf3fd7de --- /dev/null +++ b/tests/lib/config.php @@ -0,0 +1,113 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Config extends PHPUnit_Framework_TestCase { + const CONFIG_FILE = 'static://config.php'; + const CONFIG_DIR = 'static://'; + const TESTCONTENT = '"bar");'; + + public function testReadData() + { + $config = new OC\Config(self::CONFIG_DIR, false); + $this->assertAttributeEquals(array(), 'cache', $config); + + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $config = new OC\Config(self::CONFIG_DIR, false); + $this->assertAttributeEquals(array('foo'=>'bar'), 'cache', $config); + } + + public function testGetKeys() + { + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $config = new OC\Config(self::CONFIG_DIR, false); + $this->assertEquals(array('foo'), $config->getKeys()); + } + + public function testGetValue() + { + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $config = new OC\Config(self::CONFIG_DIR, false); + $this->assertEquals('bar', $config->getValue('foo')); + $this->assertEquals(null, $config->getValue('bar')); + $this->assertEquals('moo', $config->getValue('bar', 'moo')); + } + + public function testSetValue() + { + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $config = new OC\Config(self::CONFIG_DIR, false); + $config->setValue('foo', 'moo'); + $this->assertAttributeEquals(array('foo'=>'moo'), 'cache', $config); + $content = file_get_contents(self::CONFIG_FILE); + $this->assertEquals(<< 'moo', +); + +EOL +, $content); + $config->setValue('bar', 'red'); + $this->assertAttributeEquals(array('foo'=>'moo', 'bar'=>'red'), 'cache', $config); + $content = file_get_contents(self::CONFIG_FILE); + $this->assertEquals(<< 'moo', + 'bar' => 'red', +); + +EOL +, $content); + } + + public function testDeleteKey() + { + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $config = new OC\Config(self::CONFIG_DIR, false); + $config->deleteKey('foo'); + $this->assertAttributeEquals(array(), 'cache', $config); + $content = file_get_contents(self::CONFIG_FILE); + $this->assertEquals(<<deleteKey('foo'); // change something so we save to the config file + $this->assertAttributeEquals(array(), 'cache', $config); + $this->assertAttributeEquals(true, 'debug_mode', $config); + $content = file_get_contents(self::CONFIG_FILE); + $this->assertEquals(<<setValue('foo', 'bar'); + } catch (\OC\HintException $e) { + return; + } + $this->fail(); + } +} -- GitLab From e620286b253bcd43806fa9deab5e2e67decda582 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 19 Mar 2013 08:47:29 +0100 Subject: [PATCH 005/216] Fix returns of values in OCP\Config --- lib/public/config.php | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/public/config.php b/lib/public/config.php index 8076d640b49..73476d7551d 100644 --- a/lib/public/config.php +++ b/lib/public/config.php @@ -49,7 +49,7 @@ class Config { * $default will be returned. */ public static function getSystemValue( $key, $default = null ) { - return(\OC_Config::getValue( $key, $default )); + return \OC_Config::getValue( $key, $default ); } /** @@ -62,7 +62,12 @@ class Config { * not be written, false will be returned. */ public static function setSystemValue( $key, $value ) { - return(\OC_Config::setValue( $key, $value )); + try { + \OC_Config::setValue( $key, $value ); + } catch (Exception $e) { + return false; + } + return true; } /** @@ -76,7 +81,7 @@ class Config { * not exist the default value will be returned */ public static function getAppValue( $app, $key, $default = null ) { - return(\OC_Appconfig::getValue( $app, $key, $default )); + return \OC_Appconfig::getValue( $app, $key, $default ); } /** @@ -89,7 +94,12 @@ class Config { * Sets a value. If the key did not exist before it will be created. */ public static function setAppValue( $app, $key, $value ) { - return(\OC_Appconfig::setValue( $app, $key, $value )); + try { + \OC_Appconfig::setValue( $app, $key, $value ); + } catch (Exception $e) { + return false; + } + return true; } /** @@ -104,7 +114,7 @@ class Config { * not exist the default value will be returned */ public static function getUserValue( $user, $app, $key, $default = null ) { - return(\OC_Preferences::getValue( $user, $app, $key, $default )); + return \OC_Preferences::getValue( $user, $app, $key, $default ); } /** @@ -119,6 +129,11 @@ class Config { * will be added automagically. */ public static function setUserValue( $user, $app, $key, $value ) { - return(\OC_Preferences::setValue( $user, $app, $key, $value )); + try { + \OC_Preferences::setValue( $user, $app, $key, $value ); + } catch (Exception $e) { + return false; + } + return true; } } -- GitLab From ba9db1964053be769b42452fee65ac4720489f81 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 7 May 2013 19:42:46 +0200 Subject: [PATCH 006/216] Add wrapper storage backend --- lib/files/storage/wrapper.php | 420 ++++++++++++++++++++++++++++ tests/lib/files/storage/wrapper.php | 26 ++ 2 files changed, 446 insertions(+) create mode 100644 lib/files/storage/wrapper.php create mode 100644 tests/lib/files/storage/wrapper.php diff --git a/lib/files/storage/wrapper.php b/lib/files/storage/wrapper.php new file mode 100644 index 00000000000..5939faec562 --- /dev/null +++ b/lib/files/storage/wrapper.php @@ -0,0 +1,420 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +class Wrapper implements Storage { + /** + * @var Storage $storage + */ + protected $storage; + + /** + * @param array $parameters + */ + public function __construct($parameters) { + $this->storage = $parameters['storage']; + } + + /** + * Get the identifier for the storage, + * the returned id should be the same for every storage object that is created with the same parameters + * and two storage objects with the same id should refer to two storages that display the same files. + * + * @return string + */ + public function getId() { + return $this->storage->getId(); + } + + /** + * see http://php.net/manual/en/function.mkdir.php + * + * @param string $path + * @return bool + */ + public function mkdir($path) { + return $this->storage->mkdir($path); + } + + /** + * see http://php.net/manual/en/function.rmdir.php + * + * @param string $path + * @return bool + */ + public function rmdir($path) { + return $this->storage->rmdir($path); + } + + /** + * see http://php.net/manual/en/function.opendir.php + * + * @param string $path + * @return resource + */ + public function opendir($path) { + return $this->storage->opendir($path); + } + + /** + * see http://php.net/manual/en/function.is_dir.php + * + * @param string $path + * @return bool + */ + public function is_dir($path) { + return $this->storage->is_dir($path); + } + + /** + * see http://php.net/manual/en/function.is_file.php + * + * @param string $path + * @return bool + */ + public function is_file($path) { + return $this->storage->is_file($path); + } + + /** + * see http://php.net/manual/en/function.stat.php + * only the following keys are required in the result: size and mtime + * + * @param string $path + * @return array + */ + public function stat($path) { + return $this->storage->stat($path); + } + + /** + * see http://php.net/manual/en/function.filetype.php + * + * @param string $path + * @return bool + */ + public function filetype($path) { + return $this->storage->filetype($path); + } + + /** + * see http://php.net/manual/en/function.filesize.php + * The result for filesize when called on a folder is required to be 0 + * + * @param string $path + * @return int + */ + public function filesize($path) { + return $this->storage->filesize($path); + } + + /** + * check if a file can be created in $path + * + * @param string $path + * @return bool + */ + public function isCreatable($path) { + return $this->storage->isCreatable($path); + } + + /** + * check if a file can be read + * + * @param string $path + * @return bool + */ + public function isReadable($path) { + return $this->storage->isReadable($path); + } + + /** + * check if a file can be written to + * + * @param string $path + * @return bool + */ + public function isUpdatable($path) { + return $this->storage->isUpdatable($path); + } + + /** + * check if a file can be deleted + * + * @param string $path + * @return bool + */ + public function isDeletable($path) { + return $this->storage->isDeletable($path); + } + + /** + * check if a file can be shared + * + * @param string $path + * @return bool + */ + public function isSharable($path) { + return $this->storage->isSharable($path); + } + + /** + * get the full permissions of a path. + * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php + * + * @param string $path + * @return int + */ + public function getPermissions($path) { + return $this->storage->getPermissions($path); + } + + /** + * see http://php.net/manual/en/function.file_exists.php + * + * @param string $path + * @return bool + */ + public function file_exists($path) { + return $this->storage->file_exists($path); + } + + /** + * see http://php.net/manual/en/function.filemtime.php + * + * @param string $path + * @return int + */ + public function filemtime($path) { + return $this->storage->filemtime($path); + } + + /** + * see http://php.net/manual/en/function.file_get_contents.php + * + * @param string $path + * @return string + */ + public function file_get_contents($path) { + return $this->storage->file_get_contents($path); + } + + /** + * see http://php.net/manual/en/function.file_put_contents.php + * + * @param string $path + * @param string $data + * @return bool + */ + public function file_put_contents($path, $data) { + return $this->storage->file_put_contents($path, $data); + } + + /** + * see http://php.net/manual/en/function.unlink.php + * + * @param string $path + * @return bool + */ + public function unlink($path) { + return $this->storage->unlink($path); + } + + /** + * see http://php.net/manual/en/function.rename.php + * + * @param string $path1 + * @param string $path2 + * @return bool + */ + public function rename($path1, $path2) { + return $this->storage->rename($path1, $path2); + } + + /** + * see http://php.net/manual/en/function.copy.php + * + * @param string $path1 + * @param string $path2 + * @return bool + */ + public function copy($path1, $path2) { + return $this->storage->copy($path1, $path2); + } + + /** + * see http://php.net/manual/en/function.fopen.php + * + * @param string $path + * @param string $mode + * @return resource + */ + public function fopen($path, $mode) { + return $this->storage->fopen($path, $mode); + } + + /** + * get the mimetype for a file or folder + * The mimetype for a folder is required to be "httpd/unix-directory" + * + * @param string $path + * @return string + */ + public function getMimeType($path) { + return $this->storage->getMimeType($path); + } + + /** + * see http://php.net/manual/en/function.hash.php + * + * @param string $type + * @param string $path + * @param bool $raw + * @return string + */ + public function hash($type, $path, $raw = false) { + return $this->storage->hash($type, $path, $raw); + } + + /** + * see http://php.net/manual/en/function.free_space.php + * + * @param string $path + * @return int + */ + public function free_space($path) { + return $this->storage->free_space($path); + } + + /** + * search for occurrences of $query in file names + * + * @param string $query + * @return array + */ + public function search($query) { + return $this->storage->search($query); + } + + /** + * see http://php.net/manual/en/function.touch.php + * If the backend does not support the operation, false should be returned + * + * @param string $path + * @param int $mtime + * @return bool + */ + public function touch($path, $mtime = null) { + return $this->storage->touch($path, $mtime); + } + + /** + * get the path to a local version of the file. + * The local version of the file can be temporary and doesn't have to be persistent across requests + * + * @param string $path + * @return string + */ + public function getLocalFile($path) { + return $this->storage->getLocalFile($path); + } + + /** + * get the path to a local version of the folder. + * The local version of the folder can be temporary and doesn't have to be persistent across requests + * + * @param string $path + * @return string + */ + public function getLocalFolder($path) { + return $this->storage->getLocalFolder($path); + } + + /** + * check if a file or folder has been updated since $time + * + * @param string $path + * @param int $time + * @return bool + * + * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. + * returning true for other changes in the folder is optional + */ + public function hasUpdated($path, $time) { + return $this->storage->hasUpdated($path, $time); + } + + /** + * get a cache instance for the storage + * + * @param string $path + * @return \OC\Files\Cache\Cache + */ + public function getCache($path = '') { + return $this->storage->getCache($path); + } + + /** + * get a scanner instance for the storage + * + * @param string $path + * @return \OC\Files\Cache\Scanner + */ + public function getScanner($path = '') { + return $this->storage->getScanner($path); + } + + + /** + * get the user id of the owner of a file or folder + * + * @param string $path + * @return string + */ + public function getOwner($path) { + return $this->storage->getOwner($path); + } + + /** + * get a permissions cache instance for the cache + * + * @param string $path + * @return \OC\Files\Cache\Permissions + */ + public function getPermissionsCache($path = '') { + return $this->storage->getPermissions($path); + } + + /** + * get a watcher instance for the cache + * + * @param string $path + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher($path = '') { + return $this->storage->getWatcher($path); + } + + /** + * @return \OC\Files\Cache\Storage + */ + public function getStorageCache() { + return $this->storage->getStorageCache(); + } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path) { + return $this->storage->getETag($path); + } +} diff --git a/tests/lib/files/storage/wrapper.php b/tests/lib/files/storage/wrapper.php new file mode 100644 index 00000000000..8452949a723 --- /dev/null +++ b/tests/lib/files/storage/wrapper.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 Test\Files\Storage; + +class Wrapper extends Storage { + /** + * @var string tmpDir + */ + private $tmpDir; + + public function setUp() { + $this->tmpDir = \OC_Helper::tmpFolder(); + $storage = new \OC\Files\Storage\Local(array('datadir' => $this->tmpDir)); + $this->instance = new \OC\Files\Storage\Wrapper(array('storage' => $storage)); + } + + public function tearDown() { + \OC_Helper::rmdirr($this->tmpDir); + } +} -- GitLab From 9f5b7657fb27d86792a034d3665efdac6eb304e5 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 8 May 2013 18:17:26 +0200 Subject: [PATCH 007/216] Remove include for loading legacy class --- lib/config.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/config.php b/lib/config.php index dcc659395a7..1c27292d6b3 100644 --- a/lib/config.php +++ b/lib/config.php @@ -176,5 +176,3 @@ class Config { @chmod($this->config_filename, 0640); } } - -require_once __DIR__.'/legacy/'.basename(__FILE__); -- GitLab From 83444d9c641b77144cd74e5dc71c5ad18964944e Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 8 May 2013 18:20:44 +0200 Subject: [PATCH 008/216] camelCase class properties --- lib/config.php | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/config.php b/lib/config.php index 1c27292d6b3..63301cf0ab2 100644 --- a/lib/config.php +++ b/lib/config.php @@ -44,15 +44,15 @@ class Config { // associative array key => value protected $cache = array(); - protected $config_dir; - protected $config_filename; + protected $configDir; + protected $configFilename; - protected $debug_mode; + protected $debugMode; - public function __construct($config_dir, $debug_mode) { - $this->config_dir = $config_dir; - $this->debug_mode = $debug_mode; - $this->config_filename = $this->config_dir.'config.php'; + public function __construct($configDir, $debugMode) { + $this->configDir = $configDir; + $this->debugMode = $debugMode; + $this->configFilename = $this->configDir.'config.php'; $this->readData(); } /** @@ -123,19 +123,19 @@ class Config { */ private function readData() { // read all file in config dir ending by config.php - $config_files = glob( $this->config_dir.'*.config.php'); + $configFiles = glob( $this->configDir.'*.config.php'); //Filter only regular files - $config_files = array_filter($config_files, 'is_file'); + $configFiles = array_filter($configFiles, 'is_file'); //Sort array naturally : - natsort($config_files); + natsort($configFiles); // Add default config - array_unshift($config_files, $this->config_filename); + array_unshift($configFiles, $this->configFilename); //Include file and merge config - foreach($config_files as $file) { + foreach($configFiles as $file) { if( !file_exists( $file) ) { continue; } @@ -156,16 +156,15 @@ class Config { private function writeData() { // Create a php file ... $content = "debug_mode) { + if ($this->debugMode) { $content .= "define('DEBUG',true);\n"; } $content .= '$CONFIG = '; $content .= var_export($this->cache, true); $content .= ";\n"; - //var_dump($content, $this); // Write the file - $result=@file_put_contents( $this->config_filename, $content ); + $result=@file_put_contents( $this->configFilename, $content ); if(!$result) { throw new HintException( "Can't write into config directory 'config'", @@ -173,6 +172,6 @@ class Config { .' to the config directory in owncloud'); } // Prevent others not to read the config - @chmod($this->config_filename, 0640); + @chmod($this->configFilename, 0640); } } -- GitLab From d97ef0805ba5c5687e0642bb8f7c085966153ac9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 8 May 2013 22:35:10 +0200 Subject: [PATCH 009/216] Add mechanism to allow apps to wraper storage classes --- lib/files/mount/mount.php | 26 +++++++++++++++++++++++++- lib/files/storage/loader.php | 17 +++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 lib/files/storage/loader.php diff --git a/lib/files/mount/mount.php b/lib/files/mount/mount.php index 69b8285ab4c..d25a7b3be6e 100644 --- a/lib/files/mount/mount.php +++ b/lib/files/mount/mount.php @@ -22,6 +22,11 @@ class Mount { private $arguments = array(); private $mountPoint; + /** + * @var callable[] $storageWrappers + */ + private $storageWrappers = array(); + /** * @param string|\OC\Files\Storage\Storage $storage * @param string $mountpoint @@ -62,7 +67,7 @@ class Mount { private function createStorage() { if (class_exists($this->class)) { try { - return new $this->class($this->arguments); + return $this->loadStorage($this->class, $this->arguments); } catch (\Exception $exception) { \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); return null; @@ -73,6 +78,25 @@ class Mount { } } + /** + * allow modifier storage behaviour by adding wrappers around storages + * + * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage + * + * @param callable $callback + */ + public function addStorageWrapper($callback) { + $this->storageWrappers[] = $callback; + } + + private function loadStorage($class, $arguments) { + $storage = new $class($arguments); + foreach ($this->storageWrappers as $wrapper) { + $storage = $wrapper($this->mountPoint, $storage); + } + return $storage; + } + /** * @return \OC\Files\Storage\Storage */ diff --git a/lib/files/storage/loader.php b/lib/files/storage/loader.php new file mode 100644 index 00000000000..7330cae4cc4 --- /dev/null +++ b/lib/files/storage/loader.php @@ -0,0 +1,17 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +class Loader { + private function $wrappers + + public function load($class, $arguments) { + return new $class($arguments); + } +} -- GitLab From b41999a2c0628f3241b07afcae0b29bae682583c Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 9 Mar 2013 21:00:48 +0100 Subject: [PATCH 010/216] Implement OC\Log as proxy to OC_Log OC\Log implements the Psr\Log\LoggerInterface interface. See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md for the full interface specification. --- lib/legacy/log.php | 72 ++++++++++++++++++++ lib/log.php | 165 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 199 insertions(+), 38 deletions(-) create mode 100644 lib/legacy/log.php diff --git a/lib/legacy/log.php b/lib/legacy/log.php new file mode 100644 index 00000000000..4e6642b6a2f --- /dev/null +++ b/lib/legacy/log.php @@ -0,0 +1,72 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * logging utilities + * + * Log is saved by default at data/owncloud.log using OC_Log_Owncloud. + * Selecting other backend is done with a config option 'log_type'. + */ + +OC_Log::$object = new \OC\Log(); +class OC_Log { + public static $object; + + const DEBUG=0; + const INFO=1; + const WARN=2; + const ERROR=3; + const FATAL=4; + + static public $enabled = true; + static protected $class = null; + + /** + * write a message in the log + * @param string $app + * @param string $message + * @param int level + */ + public static function write($app, $message, $level) { + if (self::$enabled) { + if (!self::$class) { + self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud')); + call_user_func(array(self::$class, 'init')); + } + $log_class=self::$class; + $log_class::write($app, $message, $level); + } + } + + //Fatal errors handler + public static function onShutdown() { + $error = error_get_last(); + if($error) { + //ob_end_clean(); + self::write('PHP', $error['message'] . ' at ' . $error['file'] . '#' . $error['line'], self::FATAL); + } else { + return true; + } + } + + // Uncaught exception handler + public static function onException($exception) { + self::write('PHP', + $exception->getMessage() . ' at ' . $exception->getFile() . '#' . $exception->getLine(), + self::FATAL); + } + + //Recoverable errors handler + public static function onError($number, $message, $file, $line) { + if (error_reporting() === 0) { + return; + } + self::write('PHP', $message . ' at ' . $file . '#' . $line, self::WARN); + + } +} diff --git a/lib/log.php b/lib/log.php index 3f3334801e5..f7a68c30680 100644 --- a/lib/log.php +++ b/lib/log.php @@ -1,69 +1,158 @@ + * Copyright (c) 2013 Bart Visscher * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ +namespace OC; + /** * logging utilities * - * Log is saved by default at data/owncloud.log using OC_Log_Owncloud. - * Selecting other backend is done with a config option 'log_type'. + * This is a stand in, this should be replaced by a Psr\Log\LoggerInterface + * compatible logger. See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md + * for the full interface specification. + * + * MonoLog is an example implementing this interface. */ -class OC_Log { +class Log { const DEBUG=0; const INFO=1; const WARN=2; const ERROR=3; const FATAL=4; - static public $enabled = true; - static protected $class = null; + const NOTICE=5; + const CRITICAL=6; + const ALERT=7; /** - * write a message in the log - * @param string $app + * System is unusable. + * * @param string $message - * @param int level + * @param array $context + * @return null */ - public static function write($app, $message, $level) { - if (self::$enabled) { - if (!self::$class) { - self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud')); - call_user_func(array(self::$class, 'init')); - } - $log_class=self::$class; - $log_class::write($app, $message, $level); - } + public function emergency($message, array $context = array()) + { + $this->log(OC_Log::FATAL, $message, $context); } - //Fatal errors handler - public static function onShutdown() { - $error = error_get_last(); - if($error) { - //ob_end_clean(); - self::write('PHP', $error['message'] . ' at ' . $error['file'] . '#' . $error['line'], self::FATAL); - } else { - return true; - } + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(self::ALERT, $message, $context); } - // Uncaught exception handler - public static function onException($exception) { - self::write('PHP', - $exception->getMessage() . ' at ' . $exception->getFile() . '#' . $exception->getLine(), - self::FATAL); + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(self::CRITICAL, $message, $context); } - //Recoverable errors handler - public static function onError($number, $message, $file, $line) { - if (error_reporting() === 0) { - return; - } - self::write('PHP', $message . ' at ' . $file . '#' . $line, self::WARN); + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(OC_Log::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(OC_Log::WARN, $message, $context); + } + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(self::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(OC_Log::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(OC_Log::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + protected function log($level, $message, array $context = array()) + { + if (isset($context['app'])) { + $app = $context['app']; + } else { + $app = 'no app in context'; + } + OC_Log::write($app, $message, $level); } } + +require_once __DIR__.'/legacy/'.basename(__FILE__); -- GitLab From 7e5bb96027ee4409d8883afffa2cad50cdc3c782 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 20 Mar 2013 17:36:57 +0100 Subject: [PATCH 011/216] Fix OC\Log with OC_Log in wrong namespace --- lib/log.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/log.php b/lib/log.php index f7a68c30680..6353693a289 100644 --- a/lib/log.php +++ b/lib/log.php @@ -38,7 +38,7 @@ class Log { */ public function emergency($message, array $context = array()) { - $this->log(OC_Log::FATAL, $message, $context); + $this->log(self::FATAL, $message, $context); } /** @@ -80,7 +80,7 @@ class Log { */ public function error($message, array $context = array()) { - $this->log(OC_Log::ERROR, $message, $context); + $this->log(self::ERROR, $message, $context); } /** @@ -95,7 +95,7 @@ class Log { */ public function warning($message, array $context = array()) { - $this->log(OC_Log::WARN, $message, $context); + $this->log(self::WARN, $message, $context); } /** @@ -121,7 +121,7 @@ class Log { */ public function info($message, array $context = array()) { - $this->log(OC_Log::INFO, $message, $context); + $this->log(self::INFO, $message, $context); } /** @@ -133,7 +133,7 @@ class Log { */ public function debug($message, array $context = array()) { - $this->log(OC_Log::DEBUG, $message, $context); + $this->log(self::DEBUG, $message, $context); } /** @@ -151,7 +151,7 @@ class Log { } else { $app = 'no app in context'; } - OC_Log::write($app, $message, $level); + \OC_Log::write($app, $message, $level); } } -- GitLab From 0b4018e7ff5f2660850338e8ea0aaab57c48209e Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 8 May 2013 18:21:07 +0200 Subject: [PATCH 012/216] Remove include for loading legacy class --- lib/log.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/log.php b/lib/log.php index 6353693a289..d83f88c1df8 100644 --- a/lib/log.php +++ b/lib/log.php @@ -154,5 +154,3 @@ class Log { \OC_Log::write($app, $message, $level); } } - -require_once __DIR__.'/legacy/'.basename(__FILE__); -- GitLab From 31ad43f9221899b2379b3b72e43270b17fa9f881 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 13 May 2013 08:05:53 +0200 Subject: [PATCH 013/216] Code style --- lib/log.php | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/lib/log.php b/lib/log.php index d83f88c1df8..3bedcd4ed36 100644 --- a/lib/log.php +++ b/lib/log.php @@ -36,8 +36,7 @@ class Log { * @param array $context * @return null */ - public function emergency($message, array $context = array()) - { + public function emergency($message, array $context = array()) { $this->log(self::FATAL, $message, $context); } @@ -51,8 +50,7 @@ class Log { * @param array $context * @return null */ - public function alert($message, array $context = array()) - { + public function alert($message, array $context = array()) { $this->log(self::ALERT, $message, $context); } @@ -65,8 +63,7 @@ class Log { * @param array $context * @return null */ - public function critical($message, array $context = array()) - { + public function critical($message, array $context = array()) { $this->log(self::CRITICAL, $message, $context); } @@ -78,8 +75,7 @@ class Log { * @param array $context * @return null */ - public function error($message, array $context = array()) - { + public function error($message, array $context = array()) { $this->log(self::ERROR, $message, $context); } @@ -93,8 +89,7 @@ class Log { * @param array $context * @return null */ - public function warning($message, array $context = array()) - { + public function warning($message, array $context = array()) { $this->log(self::WARN, $message, $context); } @@ -105,8 +100,7 @@ class Log { * @param array $context * @return null */ - public function notice($message, array $context = array()) - { + public function notice($message, array $context = array()) { $this->log(self::NOTICE, $message, $context); } @@ -119,8 +113,7 @@ class Log { * @param array $context * @return null */ - public function info($message, array $context = array()) - { + public function info($message, array $context = array()) { $this->log(self::INFO, $message, $context); } @@ -131,8 +124,7 @@ class Log { * @param array $context * @return null */ - public function debug($message, array $context = array()) - { + public function debug($message, array $context = array()) { $this->log(self::DEBUG, $message, $context); } @@ -144,8 +136,7 @@ class Log { * @param array $context * @return null */ - protected function log($level, $message, array $context = array()) - { + protected function log($level, $message, array $context = array()) { if (isset($context['app'])) { $app = $context['app']; } else { -- GitLab From 061fb79e5c26ec1cf3432dda8c439a167bfc4e1d Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 13 May 2013 08:13:31 +0200 Subject: [PATCH 014/216] Use the constants from OC_Log --- lib/log.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/log.php b/lib/log.php index 3bedcd4ed36..fc190f1378b 100644 --- a/lib/log.php +++ b/lib/log.php @@ -19,12 +19,6 @@ namespace OC; */ class Log { - const DEBUG=0; - const INFO=1; - const WARN=2; - const ERROR=3; - const FATAL=4; - const NOTICE=5; const CRITICAL=6; const ALERT=7; @@ -37,7 +31,7 @@ class Log { * @return null */ public function emergency($message, array $context = array()) { - $this->log(self::FATAL, $message, $context); + $this->log(\OC_Log::FATAL, $message, $context); } /** @@ -76,7 +70,7 @@ class Log { * @return null */ public function error($message, array $context = array()) { - $this->log(self::ERROR, $message, $context); + $this->log(\OC_Log::ERROR, $message, $context); } /** @@ -90,7 +84,7 @@ class Log { * @return null */ public function warning($message, array $context = array()) { - $this->log(self::WARN, $message, $context); + $this->log(\OC_Log::WARN, $message, $context); } /** @@ -114,7 +108,7 @@ class Log { * @return null */ public function info($message, array $context = array()) { - $this->log(self::INFO, $message, $context); + $this->log(\OC_Log::INFO, $message, $context); } /** @@ -125,7 +119,7 @@ class Log { * @return null */ public function debug($message, array $context = array()) { - $this->log(self::DEBUG, $message, $context); + $this->log(\OC_Log::DEBUG, $message, $context); } /** -- GitLab From 009e9559f3a12d7275ab242ececaa7f9452165c1 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 13 May 2013 08:16:41 +0200 Subject: [PATCH 015/216] Remove default return hint --- lib/log.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/log.php b/lib/log.php index fc190f1378b..442872af9c4 100644 --- a/lib/log.php +++ b/lib/log.php @@ -28,7 +28,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function emergency($message, array $context = array()) { $this->log(\OC_Log::FATAL, $message, $context); @@ -42,7 +41,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function alert($message, array $context = array()) { $this->log(self::ALERT, $message, $context); @@ -55,7 +53,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function critical($message, array $context = array()) { $this->log(self::CRITICAL, $message, $context); @@ -67,7 +64,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function error($message, array $context = array()) { $this->log(\OC_Log::ERROR, $message, $context); @@ -81,7 +77,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function warning($message, array $context = array()) { $this->log(\OC_Log::WARN, $message, $context); @@ -92,7 +87,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function notice($message, array $context = array()) { $this->log(self::NOTICE, $message, $context); @@ -105,7 +99,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function info($message, array $context = array()) { $this->log(\OC_Log::INFO, $message, $context); @@ -116,7 +109,6 @@ class Log { * * @param string $message * @param array $context - * @return null */ public function debug($message, array $context = array()) { $this->log(\OC_Log::DEBUG, $message, $context); @@ -128,7 +120,6 @@ class Log { * @param mixed $level * @param string $message * @param array $context - * @return null */ protected function log($level, $message, array $context = array()) { if (isset($context['app'])) { -- GitLab From 1d799f22c1a8cec5a8dd45a0fdd182c011a6f5f0 Mon Sep 17 00:00:00 2001 From: kondou Date: Tue, 28 May 2013 17:34:57 +0200 Subject: [PATCH 016/216] Default to localhost, if nothing is entered. --- lib/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/setup.php b/lib/setup.php index 7082f0b2afd..b0af0620527 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -61,7 +61,7 @@ class OC_Setup { $error[] = $l->t("%s you may not use dots in the database name", array($dbprettyname)); } if($dbtype != 'oci' && empty($options['dbhost'])) { - $error[] = $l->t("%s set the database host.", array($dbprettyname)); + $options['dbhost'] = 'localhost'; } } -- GitLab From d50d663928a924a359b504c20406550758da7c2d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 3 Jun 2013 18:05:38 -0400 Subject: [PATCH 017/216] Style and comment fixes --- lib/config.php | 38 +++++++++++++++++++------------------- lib/hintexception.php | 4 ++-- lib/legacy/config.php | 30 ++++++++++++++++-------------- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/lib/config.php b/lib/config.php index 63301cf0ab2..563e8ec8696 100644 --- a/lib/config.php +++ b/lib/config.php @@ -38,7 +38,7 @@ namespace OC; /** * This class is responsible for reading and writing config.php, the very basic - * configuration file of owncloud. + * configuration file of ownCloud. */ class Config { // associative array key => value @@ -63,7 +63,7 @@ class Config { * does not return the values. */ public function getKeys() { - return array_keys( $this->cache ); + return array_keys($this->cache); } /** @@ -75,8 +75,8 @@ class Config { * This function gets the value from config.php. If it does not exist, * $default will be returned. */ - public function getValue( $key, $default = null ) { - if( array_key_exists( $key, $this->cache )) { + public function getValue($key, $default = null) { + if (isset($this->cache[$key])) { return $this->cache[$key]; } @@ -88,10 +88,10 @@ class Config { * @param string $key key * @param string $value value * - * This function sets the value and writes the config.php. If the file can - * not be written, false will be returned. + * This function sets the value and writes the config.php. + * */ - public function setValue( $key, $value ) { + public function setValue($key, $value) { // Add change $this->cache[$key] = $value; @@ -103,13 +103,13 @@ class Config { * @brief Removes a key from the config * @param string $key key * - * This function removes a key from the config.php. If owncloud has no - * write access to config.php, the function will return false. + * This function removes a key from the config.php. + * */ - public function deleteKey( $key ) { - if( array_key_exists( $key, $this->cache )) { + public function deleteKey($key) { + if (isset($this->cache[$key])) { // Delete key from cache - unset( $this->cache[$key] ); + unset($this->cache[$key]); // Write changes $this->writeData(); @@ -123,7 +123,7 @@ class Config { */ private function readData() { // read all file in config dir ending by config.php - $configFiles = glob( $this->configDir.'*.config.php'); + $configFiles = glob($this->configDir.'*.config.php'); //Filter only regular files $configFiles = array_filter($configFiles, 'is_file'); @@ -135,13 +135,13 @@ class Config { array_unshift($configFiles, $this->configFilename); //Include file and merge config - foreach($configFiles as $file) { - if( !file_exists( $file) ) { + foreach ($configFiles as $file) { + if (!file_exists($file)) { continue; } unset($CONFIG); include $file; - if( isset( $CONFIG ) && is_array( $CONFIG )) { + if (isset($CONFIG) && is_array($CONFIG)) { $this->cache = array_merge($this->cache, $CONFIG); } } @@ -164,12 +164,12 @@ class Config { $content .= ";\n"; // Write the file - $result=@file_put_contents( $this->configFilename, $content ); - if(!$result) { + $result = @file_put_contents( $this->configFilename, $content); + if (!$result) { throw new HintException( "Can't write into config directory 'config'", 'You can usually fix this by giving the webserver user write access' - .' to the config directory in owncloud'); + .' to the config directory in ownCloud'); } // Prevent others not to read the config @chmod($this->configFilename, 0640); diff --git a/lib/hintexception.php b/lib/hintexception.php index 8c64258435b..c8bff750033 100644 --- a/lib/hintexception.php +++ b/lib/hintexception.php @@ -8,8 +8,8 @@ namespace OC; -class HintException extends \Exception -{ +class HintException extends \Exception { + private $hint; public function __construct($message, $hint, $code = 0, Exception $previous = null) { diff --git a/lib/legacy/config.php b/lib/legacy/config.php index d030bbe3676..635f0af66f8 100644 --- a/lib/legacy/config.php +++ b/lib/legacy/config.php @@ -36,11 +36,13 @@ /** * This class is responsible for reading and writing config.php, the very basic - * configuration file of owncloud. + * configuration file of ownCloud. */ OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/', defined('DEBUG') && DEBUG); -class OC_Config{ +class OC_Config { + public static $object; + /** * @brief Lists all available config keys * @return array with key names @@ -61,8 +63,8 @@ class OC_Config{ * This function gets the value from config.php. If it does not exist, * $default will be returned. */ - public static function getValue( $key, $default = null ) { - return self::$object->getValue( $key, $default ); + public static function getValue($key, $default = null) { + return self::$object->getValue($key, $default); } /** @@ -70,14 +72,14 @@ class OC_Config{ * @param string $key key * @param string $value value * - * This function sets the value and writes the config.php. If the file can - * not be written, false will be returned. + * This function sets the value and writes the config.php. + * */ - public static function setValue( $key, $value ) { + public static function setValue($key, $value) { try { - self::$object->setValue( $key, $value ); + self::$object->setValue($key, $value); } catch (\OC\HintException $e) { - \OC_Template::printErrorPage( $e->getMessage(), $e->getHint() ); + \OC_Template::printErrorPage($e->getMessage(), $e->getHint()); } } @@ -85,14 +87,14 @@ class OC_Config{ * @brief Removes a key from the config * @param string $key key * - * This function removes a key from the config.php. If owncloud has no - * write access to config.php, the function will return false. + * This function removes a key from the config.php. + * */ - public static function deleteKey( $key ) { + public static function deleteKey($key) { try { - self::$object->deleteKey( $key ); + self::$object->deleteKey($key); } catch (\OC\HintException $e) { - \OC_Template::printErrorPage( $e->getMessage(), $e->getHint() ); + \OC_Template::printErrorPage($e->getMessage(), $e->getHint()); } } } -- GitLab From e0359b0b24a2fbc490fa1c96ee722ef82a191c04 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 3 Jun 2013 18:17:32 -0400 Subject: [PATCH 018/216] One more style fix --- lib/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config.php b/lib/config.php index 563e8ec8696..a6095296453 100644 --- a/lib/config.php +++ b/lib/config.php @@ -164,7 +164,7 @@ class Config { $content .= ";\n"; // Write the file - $result = @file_put_contents( $this->configFilename, $content); + $result = @file_put_contents($this->configFilename, $content); if (!$result) { throw new HintException( "Can't write into config directory 'config'", -- GitLab From bd675124096707a925faac2774516975ec7049c1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Jun 2013 17:07:13 +0200 Subject: [PATCH 019/216] manage creating and wrapping storages in it's own class --- lib/files/filesystem.php | 11 +++++++-- lib/files/mount/mount.php | 45 +++++++++++++----------------------- lib/files/storage/loader.php | 27 +++++++++++++++++++--- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index eadd8a93faf..ce89c5c23ff 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -30,6 +30,7 @@ namespace OC\Files; +use OC\Files\Storage\Loader; const FREE_SPACE_UNKNOWN = -2; const FREE_SPACE_UNLIMITED = -3; @@ -142,6 +143,11 @@ class Filesystem { */ const signal_param_run = 'run'; + /** + * @var \OC\Files\Storage\Loader $loader + */ + private static $loader; + /** * get the mountpoint of the storage object for a path * ( note: because a storage is not always mounted inside the fakeroot, the @@ -221,6 +227,7 @@ class Filesystem { if (self::$defaultInstance) { return false; } + self::$loader = new Loader(); self::$defaultInstance = new View($root); self::$mounts = new Mount\Manager(); @@ -232,7 +239,7 @@ class Filesystem { return true; } - static public function initMounts(){ + static public function initMounts() { self::$mounts = new Mount\Manager(); } @@ -365,7 +372,7 @@ class Filesystem { * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - $mount = new Mount\Mount($class, $mountpoint, $arguments); + $mount = new Mount\Mount($class, $mountpoint, $arguments, self::$loader); self::$mounts->addMount($mount); } diff --git a/lib/files/mount/mount.php b/lib/files/mount/mount.php index d25a7b3be6e..17b0055ee84 100644 --- a/lib/files/mount/mount.php +++ b/lib/files/mount/mount.php @@ -9,10 +9,10 @@ namespace OC\Files\Mount; use \OC\Files\Filesystem; +use OC\Files\Storage\Loader; +use OC\Files\Storage\Storage; class Mount { - - /** * @var \OC\Files\Storage\Storage $storage */ @@ -23,24 +23,30 @@ class Mount { private $mountPoint; /** - * @var callable[] $storageWrappers + * @var \OC\Files\Storage\Loader $loader */ - private $storageWrappers = array(); + private $loader; /** - * @param string|\OC\Files\Storage\Storage $storage + * @param string | \OC\Files\Storage\Storage $storage * @param string $mountpoint - * @param array $arguments (optional) + * @param array $arguments (optional)\ + * @param \OC\Files\Storage\Loader $loader */ - public function __construct($storage, $mountpoint, $arguments = null) { + public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { if (is_null($arguments)) { $arguments = array(); } + if (is_null($loader)) { + $this->loader = new Loader(); + } else { + $this->loader = $loader; + } $mountpoint = $this->formatPath($mountpoint); - if ($storage instanceof \OC\Files\Storage\Storage) { + if ($storage instanceof Storage) { $this->class = get_class($storage); - $this->storage = $storage; + $this->storage = $this->loader->wrap($mountpoint, $storage); } else { // Update old classes to new namespace if (strpos($storage, 'OC_Filestorage_') !== false) { @@ -67,7 +73,7 @@ class Mount { private function createStorage() { if (class_exists($this->class)) { try { - return $this->loadStorage($this->class, $this->arguments); + return $this->loader->load($this->mountPoint, $this->class, $this->arguments); } catch (\Exception $exception) { \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); return null; @@ -78,25 +84,6 @@ class Mount { } } - /** - * allow modifier storage behaviour by adding wrappers around storages - * - * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage - * - * @param callable $callback - */ - public function addStorageWrapper($callback) { - $this->storageWrappers[] = $callback; - } - - private function loadStorage($class, $arguments) { - $storage = new $class($arguments); - foreach ($this->storageWrappers as $wrapper) { - $storage = $wrapper($this->mountPoint, $storage); - } - return $storage; - } - /** * @return \OC\Files\Storage\Storage */ diff --git a/lib/files/storage/loader.php b/lib/files/storage/loader.php index 7330cae4cc4..2572ef443bc 100644 --- a/lib/files/storage/loader.php +++ b/lib/files/storage/loader.php @@ -9,9 +9,30 @@ namespace OC\Files\Storage; class Loader { - private function $wrappers + /** + * @var callable[] $storageWrappers + */ + private $storageWrappers = array(); - public function load($class, $arguments) { - return new $class($arguments); + /** + * allow modifier storage behaviour by adding wrappers around storages + * + * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage + * + * @param callable $callback + */ + public function addStorageWrapper($callback) { + $this->storageWrappers[] = $callback; + } + + public function load($mountPoint, $class, $arguments) { + return $this->wrap($mountPoint, new $class($arguments)); + } + + public function wrap($mountPoint, $storage) { + foreach ($this->storageWrappers as $wrapper) { + $storage = $wrapper($mountPoint, $storage); + } + return $storage; } } -- GitLab From 85a9b7f0949932b1def24f86ab7dc3df87933e6f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Jun 2013 17:12:45 +0200 Subject: [PATCH 020/216] Storage wrapper: provide access to the wrapped storage --- lib/files/storage/wrapper.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/files/storage/wrapper.php b/lib/files/storage/wrapper.php index 5939faec562..78892a564c4 100644 --- a/lib/files/storage/wrapper.php +++ b/lib/files/storage/wrapper.php @@ -10,7 +10,7 @@ namespace OC\Files\Storage; class Wrapper implements Storage { /** - * @var Storage $storage + * @var \OC\Files\Storage\Storage $storage */ protected $storage; @@ -21,6 +21,13 @@ class Wrapper implements Storage { $this->storage = $parameters['storage']; } + /** + * @return \OC\Files\Storage\Storage + */ + public function getWrapperStorage() { + return $this->storage; + } + /** * Get the identifier for the storage, * the returned id should be the same for every storage object that is created with the same parameters -- GitLab From 2708ab09abf12321df97ed730a83c328d2b360fc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Jun 2013 17:40:19 +0200 Subject: [PATCH 021/216] storage loader needs to be accessible by apps --- 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 0daa863e79d..a7b1da57c1a 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -146,7 +146,7 @@ class Filesystem { /** * @var \OC\Files\Storage\Loader $loader */ - private static $loader; + public static $loader; /** * get the mountpoint of the storage object for a path -- GitLab From 31693d393749c94591dc0814cc502eac8d415e11 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Jun 2013 17:40:38 +0200 Subject: [PATCH 022/216] add test cases for Mount --- tests/lib/files/mount/mount.php | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/lib/files/mount/mount.php diff --git a/tests/lib/files/mount/mount.php b/tests/lib/files/mount/mount.php new file mode 100644 index 00000000000..aa98db856f4 --- /dev/null +++ b/tests/lib/files/mount/mount.php @@ -0,0 +1,46 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Mount; + + +use OC\Files\Storage\Loader; +use OC\Files\Storage\Wrapper; + +class Mount extends \PHPUnit_Framework_TestCase { + public function testFromStorageObject() { + $storage = $this->getMockBuilder('\OC\Files\Storage\Temporary') + ->disableOriginalConstructor() + ->getMock(); + $mount = new \OC\Files\Mount\Mount($storage, '/foo'); + $this->assertInstanceOf('\OC\Files\Storage\Temporary', $mount->getStorage()); + } + + public function testFromStorageClassname() { + $mount = new \OC\Files\Mount\Mount('\OC\Files\Storage\Temporary', '/foo'); + $this->assertInstanceOf('\OC\Files\Storage\Temporary', $mount->getStorage()); + } + + public function testWrapper() { + $test = $this; + $wrapper = function ($mountPoint, $storage) use (&$test) { + $test->assertEquals('/foo/', $mountPoint); + $test->assertInstanceOf('\OC\Files\Storage\Storage', $storage); + return new Wrapper(array('storage' => $storage)); + }; + + $loader = new Loader(); + $loader->addStorageWrapper($wrapper); + + $storage = $this->getMockBuilder('\OC\Files\Storage\Temporary') + ->disableOriginalConstructor() + ->getMock(); + $mount = new \OC\Files\Mount\Mount($storage, '/foo', array(), $loader); + $this->assertInstanceOf('\OC\Files\Storage\Wrapper', $mount->getStorage()); + } +} -- GitLab From 94ca576c9ac30b7e5878c108a5efe2cad16faa94 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Jun 2013 17:50:10 +0200 Subject: [PATCH 023/216] use a getter for the storage loader to ensure the instance is created --- lib/files/filesystem.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index a7b1da57c1a..3d7d5abf8fe 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -146,7 +146,14 @@ class Filesystem { /** * @var \OC\Files\Storage\Loader $loader */ - public static $loader; + private static $loader; + + public static function getLoader(){ + if (!self::$loader) { + self::$loader = new Loader(); + } + return self::$loader; + } /** * get the mountpoint of the storage object for a path @@ -245,7 +252,7 @@ class Filesystem { if (self::$defaultInstance) { return false; } - self::$loader = new Loader(); + self::getLoader(); self::$defaultInstance = new View($root); if (!self::$mounts) { @@ -400,7 +407,7 @@ class Filesystem { if (!self::$mounts) { \OC_Util::setupFS(); } - $mount = new Mount\Mount($class, $mountpoint, $arguments, self::$loader); + $mount = new Mount\Mount($class, $mountpoint, $arguments, self::getLoader()); self::$mounts->addMount($mount); } -- GitLab From b7b6075d55abdf656128c0044d6649c976e40a00 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 10 Jun 2013 11:42:20 -0400 Subject: [PATCH 024/216] Fix potential glob error --- lib/config.php | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/config.php b/lib/config.php index a6095296453..4003339ea5c 100644 --- a/lib/config.php +++ b/lib/config.php @@ -122,21 +122,17 @@ class Config { * Reads the config file and saves it to the cache */ private function readData() { - // read all file in config dir ending by config.php - $configFiles = glob($this->configDir.'*.config.php'); - - //Filter only regular files - $configFiles = array_filter($configFiles, 'is_file'); - - //Sort array naturally : - natsort($configFiles); - - // Add default config - array_unshift($configFiles, $this->configFilename); - - //Include file and merge config + // Default config + $configFiles = array($this->configFilename); + // Add all files in the config dir ending with config.php + $extra = glob($this->configDir.'*.config.php'); + if (is_array($extra)) { + natsort($extra); + $configFiles = array_merge($configFiles, $extra); + } + // Include file and merge config foreach ($configFiles as $file) { - if (!file_exists($file)) { + if (!is_file($file)) { continue; } unset($CONFIG); -- GitLab From 969e43c87b7afb6184846fe27849167c9c6f5eab Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 10 Jun 2013 12:07:25 -0400 Subject: [PATCH 025/216] Can't determine if debug mode is defined until we read the config --- lib/config.php | 9 +++------ lib/legacy/config.php | 2 +- tests/lib/config.php | 18 +++++++++--------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/config.php b/lib/config.php index 4003339ea5c..a3663949d16 100644 --- a/lib/config.php +++ b/lib/config.php @@ -47,11 +47,8 @@ class Config { protected $configDir; protected $configFilename; - protected $debugMode; - - public function __construct($configDir, $debugMode) { + public function __construct($configDir) { $this->configDir = $configDir; - $this->debugMode = $debugMode; $this->configFilename = $this->configDir.'config.php'; $this->readData(); } @@ -152,7 +149,7 @@ class Config { private function writeData() { // Create a php file ... $content = "debugMode) { + if (defined('DEBUG') && DEBUG) { $content .= "define('DEBUG',true);\n"; } $content .= '$CONFIG = '; @@ -167,7 +164,7 @@ class Config { 'You can usually fix this by giving the webserver user write access' .' to the config directory in ownCloud'); } - // Prevent others not to read the config + // Prevent others from reading the config @chmod($this->configFilename, 0640); } } diff --git a/lib/legacy/config.php b/lib/legacy/config.php index 635f0af66f8..f68d7c31b25 100644 --- a/lib/legacy/config.php +++ b/lib/legacy/config.php @@ -38,7 +38,7 @@ * This class is responsible for reading and writing config.php, the very basic * configuration file of ownCloud. */ -OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/', defined('DEBUG') && DEBUG); +OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/'); class OC_Config { public static $object; diff --git a/tests/lib/config.php b/tests/lib/config.php index e22bf3fd7de..acc2a536fd0 100644 --- a/tests/lib/config.php +++ b/tests/lib/config.php @@ -13,25 +13,25 @@ class Test_Config extends PHPUnit_Framework_TestCase { public function testReadData() { - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $this->assertAttributeEquals(array(), 'cache', $config); file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $this->assertAttributeEquals(array('foo'=>'bar'), 'cache', $config); } public function testGetKeys() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $this->assertEquals(array('foo'), $config->getKeys()); } public function testGetValue() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $this->assertEquals('bar', $config->getValue('foo')); $this->assertEquals(null, $config->getValue('bar')); $this->assertEquals('moo', $config->getValue('bar', 'moo')); @@ -40,7 +40,7 @@ class Test_Config extends PHPUnit_Framework_TestCase { public function testSetValue() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $config->setValue('foo', 'moo'); $this->assertAttributeEquals(array('foo'=>'moo'), 'cache', $config); $content = file_get_contents(self::CONFIG_FILE); @@ -69,7 +69,7 @@ EOL public function testDeleteKey() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config(self::CONFIG_DIR); $config->deleteKey('foo'); $this->assertAttributeEquals(array(), 'cache', $config); $content = file_get_contents(self::CONFIG_FILE); @@ -84,11 +84,11 @@ EOL public function testSavingDebugMode() { + define('DEBUG',true); file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, true); + $config = new OC\Config(self::CONFIG_DIR); $config->deleteKey('foo'); // change something so we save to the config file $this->assertAttributeEquals(array(), 'cache', $config); - $this->assertAttributeEquals(true, 'debug_mode', $config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<setValue('foo', 'bar'); } catch (\OC\HintException $e) { -- GitLab From e0547a25ab9c5a3d9454611f72e00e3bc667e2d2 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 3 May 2013 00:15:28 +0200 Subject: [PATCH 026/216] if rename of file fails, the rename is undone in the view - #fix 2820 Changes: * OC.dialog -> OC.Notification * Added test * Fixed OC.Notification.show() issue for queued items * Highlight failed item and show notification --- apps/files/js/filelist.js | 41 ++++++++++++++++++++++++++++---- apps/files/lib/app.php | 2 +- apps/files/tests/ajax_rename.php | 2 +- core/js/js.js | 4 ++-- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e19a35bbc5b..c6663836fd7 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -208,13 +208,44 @@ var FileList={ if (FileList.checkName(name, newname, false)) { newname = name; } else { - $.get(OC.filePath('files','ajax','rename.php'), { dir : $('#dir').val(), newname: newname, file: name },function(result) { - if (!result || result.status == 'error') { - OC.dialogs.alert(result.data.message, 'Error moving file'); - newname = name; + // save background image, because it's replaced by a spinner while async request + var oldBackgroundImage = td.css('background-image'); + // mark as loading + td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); + $.ajax({ + url: OC.filePath('files','ajax','rename.php'), + data: { + dir : $('#dir').val(), + newname: newname, + file: name + }, + success: function(result) { + if (!result || result.status === 'error') { + OC.Notification.show(result.data.message); + newname = name; + // revert changes + tr.attr('data-file', newname); + var path = td.children('a.name').attr('href'); + td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname))); + if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { + var basename=newname.substr(0,newname.lastIndexOf('.')); + } else { + var basename=newname; + } + td.find('a.name span.nametext').text(basename); + if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { + if (td.find('a.name span.extension').length === 0 ) { + td.find('a.name span.nametext').append(''); + } + td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.'))); + } + tr.find('.fileactions').effect('highlight', {}, 5000); + tr.effect('highlight', {}, 5000); + } + // remove loading mark and recover old image + td.css('background-image', oldBackgroundImage); } }); - } } tr.data('renaming',false); diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index c2a4b9c2675..f7052ef80b0 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -70,7 +70,7 @@ class App { } else { // rename failed $result['data'] = array( - 'message' => $this->l10n->t('Unable to rename file') + 'message' => $this->l10n->t('%s could not be renamed', array($oldname)) ); } return $result; diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 23e5761ddda..2b90a11743d 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -50,7 +50,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $result = $this->files->rename($dir, $oldname, $newname); $expected = array( 'success' => false, - 'data' => array('message' => 'Unable to rename file') + 'data' => array('message' => '%s could not be renamed') ); $this->assertEquals($expected, $result); diff --git a/core/js/js.js b/core/js/js.js index 3cb4d3dd151..55db625a339 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -349,10 +349,10 @@ OC.Notification={ }, show: function(text) { if(($('#notification').filter('span.undo').length == 1) || OC.Notification.isHidden()){ - $('#notification').html(text); + $('#notification').text(text); $('#notification').fadeIn().css("display","inline"); }else{ - OC.Notification.queuedNotifications.push($(text).html()); + OC.Notification.queuedNotifications.push($('
').text(text).html()); } }, isHidden: function() { -- GitLab From 383e4c62b578996b343b540e03c7afed61be644e Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Mon, 17 Jun 2013 00:02:42 +0200 Subject: [PATCH 027/216] in case $_SERVER['HTTP_HOST']) is not set let's return localhost - better than nothing --- lib/request.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/request.php b/lib/request.php index 4d8380eb9ac..aa5f53c08eb 100755 --- a/lib/request.php +++ b/lib/request.php @@ -19,7 +19,7 @@ class OC_Request { /** * @brief Returns the server host - * @returns the server host + * @returns string the server host * * Returns the server host, even if the website uses one or more * reverse proxies @@ -40,7 +40,7 @@ class OC_Request { } } else{ - $host = $_SERVER['HTTP_HOST']; + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; } return $host; } @@ -48,7 +48,7 @@ class OC_Request { /** * @brief Returns the server protocol - * @returns the server protocol + * @returns string the server protocol * * Returns the server protocol. It respects reverse proxy servers and load balancers */ @@ -70,7 +70,7 @@ class OC_Request { /** * @brief Returns the request uri - * @returns the request uri + * @returns string the request uri * * Returns the request uri, even if the website uses one or more * reverse proxies @@ -85,7 +85,7 @@ class OC_Request { /** * @brief Returns the script name - * @returns the script name + * @returns string the script name * * Returns the script name, even if the website uses one or more * reverse proxies @@ -139,7 +139,7 @@ class OC_Request { /** * @brief Check if this is a no-cache request - * @returns true for no-cache + * @returns boolean true for no-cache */ static public function isNoCache() { if (!isset($_SERVER['HTTP_CACHE_CONTROL'])) { @@ -150,7 +150,7 @@ class OC_Request { /** * @brief Check if the requestor understands gzip - * @returns true for gzip encoding supported + * @returns boolean true for gzip encoding supported */ static public function acceptGZip() { if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { -- GitLab From 9e78e6b2e5bc9231265e5cb8e8ba1d7cdebab94b Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:14:36 +0200 Subject: [PATCH 028/216] differentiate delete from close icon --- core/css/styles.css | 1 - core/img/actions/delete-hover.png | Bin 254 -> 0 bytes core/img/actions/delete-hover.svg | 6 --- core/img/actions/delete.png | Bin 240 -> 334 bytes core/img/actions/delete.svg | 67 ++++++++++++++++++++++++++++-- 5 files changed, 63 insertions(+), 11 deletions(-) delete mode 100644 core/img/actions/delete-hover.png delete mode 100644 core/img/actions/delete-hover.svg diff --git a/core/css/styles.css b/core/css/styles.css index 40a17a42876..7100b8c290d 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -655,7 +655,6 @@ div.crumb:active { /* icons */ .folder-icon { background-image: url('../img/places/folder.svg'); } .delete-icon { background-image: url('../img/actions/delete.svg'); } -.delete-icon:hover { background-image: url('../img/actions/delete-hover.svg'); } .edit-icon { background-image: url('../img/actions/rename.svg'); } /* buttons */ diff --git a/core/img/actions/delete-hover.png b/core/img/actions/delete-hover.png deleted file mode 100644 index 048d91cee5143ce826ef9ef3d7619d835bce0877..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFtWs_ aoD4g!3*63oe>4_o2!p4qpUXO@geCyPB2g0n diff --git a/core/img/actions/delete-hover.svg b/core/img/actions/delete-hover.svg deleted file mode 100644 index 3e8d26c9786..00000000000 --- a/core/img/actions/delete-hover.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/core/img/actions/delete.png b/core/img/actions/delete.png index fa8e18183ed3d126ab5706d093f7e64d944c835a..6362903937c001f3bd5ebac47fe8ed48195c66a9 100644 GIT binary patch delta 232 zcmV+&}~bf3=zHpZ|7e*Ceq`u^d4TTzUyp%6)=tL3jrL8e=F`1_{v2FgFH?d(zz{22yHp2FkHy i{}pye@U`kQEzujdT3cnj%BXMv0000BD)H2AVO_LHz0xN sSfI!Nio8H^AW|b5DN9I0Gcy4I+7e6GgT+Z{00000NkvXXt^-0~g7-r)8UO$Q diff --git a/core/img/actions/delete.svg b/core/img/actions/delete.svg index ef564bfd482..08ea381f378 100644 --- a/core/img/actions/delete.svg +++ b/core/img/actions/delete.svg @@ -1,6 +1,65 @@ - - - - + + + + + image/svg+xml + + + + + + + + + -- GitLab From 257ebc2830a04272c0b662cce85fea6470e77f7c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:18:45 +0200 Subject: [PATCH 029/216] use consistent icon for 'restore'/versions/history, also SVG --- apps/files_trashbin/js/trash.js | 2 +- core/img/actions/undelete.png | Bin 624 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 core/img/actions/undelete.png diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 691642811b7..82119a59517 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -2,7 +2,7 @@ $(document).ready(function() { if (typeof FileActions !== 'undefined') { - FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/undelete.png'), function(filename) { + FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history.svg'), function(filename) { var tr=$('tr').filterAttr('data-file', filename); var spinner = ''; var undeleteAction = $('tr').filterAttr('data-file',filename).children("td.date"); diff --git a/core/img/actions/undelete.png b/core/img/actions/undelete.png deleted file mode 100644 index d712527ef617dca921bcf75b917a1f728bc2102c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 624 zcmV-$0+0QPP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_fl`9S#00007bV*G`2i*Z4 z3Ih^4(F+g&000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0005YNkljtP1&(N=qgyIH-$IORb=2uhU1ruT51DFWl*#dmi_k^F&qomon=Oo)3xb zj>=#_0(psc4$7&g?G1sdimGz4pCVn^hZoMX?U1D;m^xyn5ga2-8>EgMC~^JMc6Ucr zR|pFGxD+(hFimy9A+%|hcwz)YArWV^HN-675Z&{FTb~mR34jVvp?Oz@d)n=NY5oQ~ z`(jKYIP4u7N7eWU&h>KHB?ua7q>ewLq8oiAqomuzR1GaPuD&~{sw*O<+b9ELz}Syv zMp*p#gzxw)ik#KgNBVfP%+gQF;~9XUJIs}JDhE@4vMuzLIiQ2ZxfY*|6Gvsgh~%X| zm;D{Vw`Mv3XiY5nYq778i8U^$D(`R7xjV`$1cz{BhONnAV<;qJ+}Yg341z Date: Mon, 17 Jun 2013 12:22:09 +0200 Subject: [PATCH 030/216] transparent background for lock icon --- core/img/actions/lock.png | Bin 182 -> 295 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/img/actions/lock.png b/core/img/actions/lock.png index dbcffa3990f7dace24aaae6836977a142d57fe47..f3121811ea69565b897e2806f7d9aa66ac90bd68 100644 GIT binary patch delta 279 zcmdnSxSVN%WIY=L1B3kM|A|0~rP#?cgaZg_I8r)*e9i)o$YKTt-s>RD=%g{b0w^e1 z;u=vBoS#-wo>-L1P+nfHmzkGcoSayYs+V7sKKq@G6j0F;PZ!4!i{7{A^|_oJC0IV( z?>d+z*ps&Sp!Uh^vi=VTURl~SDcn1fu#v02ZEMZH==uCdk_r+MZc09zJ+U}UD0t0A z{&j}ApUOl$G(&GZ>T&(hlbdl~L$ANk>FR}5T)BU~#LvijGiz1bKIgk;iA`s{&sv*3 z+_{kF#p4@71w7|(H}p?Tnmy%`(B>UQ6_4dznnTZ3^4(=GY>{g_Xx6i?f4%x2<~qd( aOw%K3&I{Q5%Mt>*n8DN4&t;ucLK6V}&2v=% delta 165 zcmZ3^w2g6sWIY2ASj||l7f3M{J9&n1JmZR<3FL4VctjR6Fz_7#VaBQ2e9}O{Xipc% z5Q*^QAN)+|heSn{&o|HHQAkqUe0$2vcRHsNn9OflIi4x&+Z`b4+Lmzi|5vRAOzT_) z8f)}dG}M~9EVv`t?!er?#8ATHgIV+1-t>m%6gev{5wF9JFaQ5%*vHx)6&$7Z6lf2F Mr>mdKI;Vst042>j5dZ)H -- GitLab From 344a73b173c3dc0a1a203e5db4fa64adab7f0e48 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:26:32 +0200 Subject: [PATCH 031/216] use mail icon consistent with Mail app icon --- core/img/actions/mail.png | Bin 405 -> 303 bytes core/img/actions/mail.svg | 100 +++++++++++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/core/img/actions/mail.png b/core/img/actions/mail.png index 8e884fbc0ea87ee8549053f603bbf9bf55c29817..be6142444ae8052e6f96c4b8afc3d267704d1507 100644 GIT binary patch delta 202 zcmV;*05$)W1Fr&*ZGQl)Nklr_MR^`+ZL{%_JcNRaUK%`xgM%Abc4cF&QKMz?eo)$N(qw--Mjd z!!ZvC*vE}mkRv+S<$8C5ExIL;1KL;@`VYb>8U@G!bxfY#Rc=|2~>PY$^U<*8}*KjdyZyb!vFvP07*qoM6N<$ Ef?jo5dH?_b delta 305 zcmV-10nYxf0+j=hZGQn0NklS$-FB#tb_!SEaWFs;Y9Dro1c*cU{M(X^P;C8Fpa46iAZ9 zQ51={<$2DAVQ?JBJdUFX&X{2b1}q#=;JWU)ZCh@dh8@Sbd9&wvBG)r8VBx@}X_{Wb zFnnv=6|ivNk}9Go4|~PW*<89D44u~8{V^x{_rLKK%>&TsaB3rf00000NkvXXu0mjf DVI7Wk diff --git a/core/img/actions/mail.svg b/core/img/actions/mail.svg index 2c63daac034..6e8a4bd7f6b 100644 --- a/core/img/actions/mail.svg +++ b/core/img/actions/mail.svg @@ -1,8 +1,96 @@ - - - - - - + + + + + + + image/svg+xml + + + + + + + + + + + + + + + -- GitLab From 078835ee9dd02e8f4cd8387c0eeace9913dc9349 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:27:45 +0200 Subject: [PATCH 032/216] remove unused big images --- core/img/remoteStorage-big.png | Bin 8372 -> 0 bytes core/img/weather-clear.png | Bin 21917 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 core/img/remoteStorage-big.png delete mode 100644 core/img/weather-clear.png diff --git a/core/img/remoteStorage-big.png b/core/img/remoteStorage-big.png deleted file mode 100644 index 7e76e21209e539354805d12d8f92c5a8176c0861..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8372 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 -- GitLab From d9dcba9a39a468a0fe5cfaad99d6a7282ba2702a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:35:25 +0200 Subject: [PATCH 033/216] remove unused loading spinners, just have one --- apps/files_trashbin/js/trash.js | 4 ++-- core/img/loader.gif | Bin 847 -> 0 bytes core/img/loading-dark.gif | Bin 673 -> 0 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 core/img/loader.gif delete mode 100644 core/img/loading-dark.gif diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 82119a59517..307ac743a3c 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -4,7 +4,7 @@ $(document).ready(function() { if (typeof FileActions !== 'undefined') { FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history.svg'), function(filename) { var tr=$('tr').filterAttr('data-file', filename); - var spinner = ''; + var spinner = ''; var undeleteAction = $('tr').filterAttr('data-file',filename).children("td.date"); var files = tr.attr('data-file'); undeleteAction[0].innerHTML = undeleteAction[0].innerHTML+spinner; @@ -94,7 +94,7 @@ $(document).ready(function() { $('.undelete').click('click',function(event) { event.preventDefault(); - var spinner = ''; + var spinner = ''; var files=getSelectedFiles('file'); var fileslist = JSON.stringify(files); var dirlisting=getSelectedFiles('dirlisting')[0]; diff --git a/core/img/loader.gif b/core/img/loader.gif deleted file mode 100644 index e192ca895cd00d6b752ec84619b787188f30ee41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 847 zcmZ?wbhEHb6krfw_`<;O|Nnmm28JI$eppyow6wIav9YPCsa?BvZN-WeVq#)tWo2n; zX-}R!nK5I=v17+PJUqg}!hq_D2a5l>{aizWogD*Qjr0td8G$+#|4BI)r6!i7rYMwW zmSiX-W+hhSNI#p{aB=u^kJ9BqzM)+D@@g7D>_ZH z6>Nk>K2^#dec$hd&5{fSg)a9?JsDb3M<1+M;h^GLd*HyqYe$(ldZsj_W{3#!96X@l zAjsu&py5MupnEfu)0U^(0!(Kp*sL-QO$pql{X%Kq;`Av7E5z0lI$B?E`RzKdsAZ)9=nHHN!5+~JF4SY+VADb}iE(C2i8t1nx?>)BhL zPS>_TA<--6ZN7=uLx=rfr*28JR#UU9l!(BR!@3s} qR&*pBVEQRw*vTQWVY)*bLIMx~ diff --git a/core/img/loading-dark.gif b/core/img/loading-dark.gif deleted file mode 100644 index 5fe86acabc41f3cd97b09eb626e5e9020d5ea28e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 673 zcmZ?wbhEHb6krfw_{0DL|Ns24v9{i`YZs6)XV$Em>gt^AY{h?4&PAz-C8;S2<(VZJ z3W-^X6*>8dDSDZCY55F_KUo;KfLay*bNji51UowhxEkphFf#&$bU;Re3};|A=Gb-T zpTQ~5Y~f@MD-Ovy?0z%SI9)dy9@-@`^WZkUgd>LvFX%=~Sl(U6ZYjaT?v?%A185}J zXhvjnOhD%N^(ZPxxA5%V@T|+F&?zt^!BA2m!N)aPYDJCA*3$cL6D8Oi6s}7=YIBy{ zq^hDN1T}~W*&s8HT}H~XscN4xYMc0GPFQ?v_cG2_MIIJIm-a*%!BuWe z8!pN-Ck4fRwv{)q(2?ptv82e-2j({xWOIx-b`_~>dp%DP`5^Jxr;$gk>~KO%Qpl9n zmYs4LkxrWDPdNxM%e}ObKdc5eCukDP7*=FsfX-1kG{I8*amn*Nx8@m09+!EbsOPk8 z?y2xKiwt?#xJ8N+cW*HLK9#Z2U;}68?)kZzUNCdmkj())=gz+moPsy!gvQQde0Qs` zU}{3g-NZR}O{TRvx*atTnUFAh8zV2vAqRokh7E_Votp?Vh8@EgV9c*hb-FS~^ST@d t$6EjG|h_^oWQ_f4N5p*002a;)W84$ -- GitLab From 0f904b3c9c9542d542ea52bc7683c79e6916fe18 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 12:58:43 +0200 Subject: [PATCH 034/216] use proper style for add icon --- core/img/actions/add.png | Bin 441 -> 195 bytes core/img/actions/add.svg | 68 ++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/core/img/actions/add.png b/core/img/actions/add.png index 25d472b2dc41bd4412507d422b579ff36abad887..13e20df6626b5c5b907176c9887386b19545c25d 100644 GIT binary patch delta 108 zcmV-y0F(c@1H%E3I|~ih000fw0YWI7c#%dYRscXrL_t(IjqQ>_3IHGs!>suKFUPaE zL1BU*=GxJ*FafQ?$O1`AGoWa$m)5^gAYc>b0_gq;XB>pVeY0UKMn?p36o*~&(ft!qZt?&(m=SZtSlZVCP9h;+%sp+jDi`EpPwHG6cZ!K z3;q55kuU?&)6+o)h~P7T_uad9axnby<42X2mKL}H@$vC-pFe-rL{lRKH{i^fGa8|x zf1znsR#tGVtgM^{GeAa021U-((=%<)o;{Xu1ArVgAb@KighfO|(l&42Yz8-A+qP}W z$TkwfLPA1mt5&Tth8wVd|9+Xu%1XbYq9PvGX z(7+c9tiHa!!7u|%O-*A!F+)l;vN$?AP6ojY(9zKW8Nfk`0nBD*W`QsRR8&-=fnw~W z7{Fv=V&V@B?GzB!(9nnkd5aVS7@!)EF(au45QPDtx=du=nI6{w0000 - - - - - - - - + + + + + image/svg+xml + + + + + + + + + + -- GitLab From 1f518025a3f5c1078b7b94e93f218b8ed58b556c Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 13:20:02 +0200 Subject: [PATCH 035/216] standardize on 32px loading spinner, decrease size in CSS where needed --- core/css/styles.css | 7 +++++++ core/img/loading-dark.gif | Bin 0 -> 3208 bytes core/img/loading.gif | Bin 1849 -> 3208 bytes 3 files changed, 7 insertions(+) create mode 100644 core/img/loading-dark.gif diff --git a/core/css/styles.css b/core/css/styles.css index 7100b8c290d..6c9d00114a0 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -416,7 +416,13 @@ a.bookmarklet { background-color:#ddd; border:1px solid #ccc; padding:5px;paddin #oc-dialog-filepicker-content .filepicker_element_selected { background-color:lightblue;} .ui-dialog {position:fixed !important;} span.ui-icon {float: left; margin: 3px 7px 30px 0;} + .loading { background: url('../img/loading.gif') no-repeat center; cursor: wait; } +.move2trash { /* decrease spinner size */ + width: 16px; + height: 16px; +} + /* ---- CATEGORIES ---- */ #categoryform .scrollarea { position:absolute; left:10px; top:10px; right:10px; bottom:50px; overflow:auto; border:1px solid #ddd; background:#f8f8f8; } @@ -661,6 +667,7 @@ div.crumb:active { button.loading { background-image: url('../img/loading.gif'); background-position: right 10px center; background-repeat: no-repeat; + background-size: 16px; padding-right: 30px; } diff --git a/core/img/loading-dark.gif b/core/img/loading-dark.gif new file mode 100644 index 0000000000000000000000000000000000000000..13f0f64eab152fa4949476ed83ea24d6fd45a9bc GIT binary patch literal 3208 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 A6951J literal 0 HcmV?d00001 diff --git a/core/img/loading.gif b/core/img/loading.gif index 5b33f7e54f4e55b6b8774d86d96895db9af044b4..f8f3dff6fb955ebc02453352e59c845461723292 100644 GIT binary patch literal 3208 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 literal 1849 zcma*odr(tX9tZI2z31lM+(&YVk%mZ}5P~KlG2s=WSbGzm0!x7^P##Mnh7t-jP!X0Q zk_SQ}Po-L1tlDK;6l?(>v)e5ZBQx4|Y-Q?nr@Px3?9h(3ZWr3^tj=`TP57gKr87N$ zp2wWee1GRRCwo_xahnw)5cxNPJbCg2L6DV|6`#+yw6v6!mDS$f9-JvFD^n;GQ&UrZ zzh5jCkByB101O60U0q#p_1BM>Cv-vP?&s4@g_((4_1L=L$(a91)0=J91Gas#R{McE znYG^9*0A5YZ>#;~+Wkn(W5B0^yELIYLP!K}mB~<)AM@1&nqekynuaEGqPrzoH|KodRXJy)%+w_fu3nE5>@Bd_b zqC$EQ;{c`T&?EsNO|igL9gC7Ygxv?aQUEXMq?~>wg{EyW;VcJ37CUF#HjrT=KQO_* zS>M9yydXk18D(+QDJ1>r);Lav_uYKp$T?4vr{Q$lTo&pKv^?(>L-)G2*lwH!Ah7k? z7oH<8h-(KTKt5V6$8gF)C7Io&P5=SjTh)=zV=E2EUhQZP##L8S{d%UK>>+y82>+FV+#^BzW7u3F)Bb>=lYQ%%j`F>ASe zo*cw@V#u6T`A2He;70mR(V&iV&-7{qP~=SRf&jm9-T{*ZeZ}$rd0#6c&fLG^xJcf5 z+p<`wJYgW+_s*V{uI$nMB;%8`S_3>PfGOj3Rq}@Cx^+j?rk92fANSFDBYnOqQ>Vdj z)(|$AhP4t&Lb=Gvo2#3Gl%9<=Gv`Mz?Po@P4iLF!x}GUWJICDlFk-hS^Whyh7x~VH z@0vD1>HYD4&e+~yzS*-sFR{9`{QEEZO1zg7>R&7cHts-6j!xHVdA8eI+ZlVzd%`es zJT@$#GX(gvCJ1oJN%yLBK}{V=V;seo;!w|Yte!W1%5qLNFWqvZW>h&IiH+oPT=b@E zPhGzv5=(Un*X>v`>%8h_nj^NdYcE6NHS_ifkCV$*D)Tqrbu`s;<=t<4 zAHNqNV?6(g<1PY-w@#I-WYFViz?9TrkMr)u0g`O`u|>T;k|2sV*YF^punvT;$SuTy{j3Gv)yqD!R_CF>yR)MzmmYS5v+~R zXAdD%ng9?df;wd8GxR#%3O+gz};Vo;)sK%Bj-q>Oq%R7JU-KD?vYu>#2UjaDo z&8$>5xW~?KPD_#XFToU1hIb*VOMidUr6iYiO0N|i-7s`T8!cFT`rN!^1Pt78J93i6 z5HI1wIM$94m{3SLDvISDe6$ZG1;eq_D9RTaaC>=cO{@Bs>$IlPCPJJ$h$)-3vzNUQ6OsN#_zWxey!_9%hxwH2_dEJi=yY|1c7nDm2_Lm!Cof8-R_+9UkS zcBE(o47yE)oMR(Q=dp1a2wTX5KvvGyLqlWTa7V&!A*|w|)ax~1_~aJ0=_Lilg*0iQk7#ZD EAHN$8j{pDw -- GitLab From 2a5776354251ddfeccc854d2d0af157575afa28d Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Mon, 17 Jun 2013 13:30:57 +0200 Subject: [PATCH 036/216] use history icon in Deleted Files template as well --- apps/files_trashbin/js/trash.js | 2 +- apps/files_trashbin/templates/index.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index 307ac743a3c..87dfea491e7 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -2,7 +2,7 @@ $(document).ready(function() { if (typeof FileActions !== 'undefined') { - FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history.svg'), function(filename) { + FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { var tr=$('tr').filterAttr('data-file', filename); var spinner = ''; var undeleteAction = $('tr').filterAttr('data-file',filename).children("td.date"); diff --git a/apps/files_trashbin/templates/index.php b/apps/files_trashbin/templates/index.php index cb5edaa2c91..66ec36df867 100644 --- a/apps/files_trashbin/templates/index.php +++ b/apps/files_trashbin/templates/index.php @@ -18,7 +18,7 @@ <?php p($l->t( 'Restore' )); ?>" /> + src="" /> t('Restore'))?> -- GitLab From 63c898c064233d08823e1b18ec7cb20185b1fe05 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 6 Jun 2013 20:47:20 +0200 Subject: [PATCH 037/216] Make rmdir recursive for local storage --- lib/files/storage/local.php | 22 +++++++++++++++++++++- tests/lib/files/storage/storage.php | 14 +++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index d684905bf9a..b08fd73ce19 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -39,7 +39,27 @@ if (\OC_Util::runningOnWindows()) { } public function rmdir($path) { - return @rmdir($this->datadir . $path); + try { + $it = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->datadir . $path), + \RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($it as $file) { + /** + * @var \SplFileInfo $file + */ + if (in_array($file->getBasename(), array('.', '..'))) { + continue; + } elseif ($file->isDir()) { + rmdir($file->getPathname()); + } elseif ($file->isFile() || $file->isLink()) { + unlink($file->getPathname()); + } + } + return rmdir($this->datadir . $path); + } catch (\UnexpectedValueException $e) { + return false; + } } public function opendir($path) { diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 0e22f26ae83..fb3e05e66b3 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -258,9 +258,21 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals(file_get_contents($textFile), $content); } - public function testTouchCreateFile(){ + public function testTouchCreateFile() { $this->assertFalse($this->instance->file_exists('foo')); $this->instance->touch('foo'); $this->assertTrue($this->instance->file_exists('foo')); } + + public function testRecursiveRmdir() { + $this->instance->mkdir('folder'); + $this->instance->mkdir('folder/bar'); + $this->instance->file_put_contents('folder/asd.txt', 'foobar'); + $this->instance->file_put_contents('folder/bar/foo.txt', 'asd'); + $this->instance->rmdir('folder'); + $this->assertFalse($this->instance->file_exists('folder/asd.txt')); + $this->assertFalse($this->instance->file_exists('folder/bar/foo.txt')); + $this->assertFalse($this->instance->file_exists('folder/bar')); + $this->assertFalse($this->instance->file_exists('folder')); + } } -- GitLab From 46f97f4c389572eb1edac30d8cfa7086835c58fb Mon Sep 17 00:00:00 2001 From: mvn23 Date: Wed, 19 Jun 2013 15:36:48 +0200 Subject: [PATCH 038/216] Implement X-Sendfile2 for resume support in LigHTTPd LigHTTPd does not support HTTP Range headers with the X-Sendfile header in the way Apache does. Instead, it needs to be handled in the backend. This commit does exactly that, using the X-Sendfile2 header to send ranges of files. To accomplish this without breaking web servers that don't support X-Sendfile2, a new variable MOD_X_SENDFILE2_ENABLED was introduced to separate this method from X-Sendfile and X-Accel-Redirect. --- lib/files.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/files.php b/lib/files.php index abb1617c25e..5dd65e85a43 100644 --- a/lib/files.php +++ b/lib/files.php @@ -45,7 +45,7 @@ class OC_Files { */ public static function get($dir, $files, $only_header = false) { $xsendfile = false; - if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || + if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || isset($_SERVER['MOD_X_SENDFILE2_ENABLED']) || isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { $xsendfile = true; } @@ -170,6 +170,18 @@ class OC_Files { private static function addSendfileHeader($filename) { if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) { header("X-Sendfile: " . $filename); + } + if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { + if (isset($_SERVER['HTTP_RANGE']) && preg_match('/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/', $_SERVER['HTTP_RANGE'], $range)) { + if ($range['end'] == "") { + $range['end'] = filesize($filename) - 1; + } + header("Content-Range: bytes " . $range['start'] . "-" . $range['end'] . "/" . filesize($filename)); + header("HTTP/1.1 206 Partial content"); + header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " " . $range['start'] . "-" . $range['end']); + } else { + header("X-Sendfile: " . $filename); + } } if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { header("X-Accel-Redirect: " . $filename); -- GitLab From a25bfa92917075d1ab26649c4d6d5bea6150e623 Mon Sep 17 00:00:00 2001 From: mvn23 Date: Wed, 19 Jun 2013 23:44:45 +0200 Subject: [PATCH 039/216] Update files.php --- lib/files.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/files.php b/lib/files.php index 5dd65e85a43..123c87eb5ff 100644 --- a/lib/files.php +++ b/lib/files.php @@ -45,7 +45,8 @@ class OC_Files { */ public static function get($dir, $files, $only_header = false) { $xsendfile = false; - if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || isset($_SERVER['MOD_X_SENDFILE2_ENABLED']) || + if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || + isset($_SERVER['MOD_X_SENDFILE2_ENABLED']) || isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { $xsendfile = true; } @@ -172,7 +173,8 @@ class OC_Files { header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { - if (isset($_SERVER['HTTP_RANGE']) && preg_match('/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/', $_SERVER['HTTP_RANGE'], $range)) { + if (isset($_SERVER['HTTP_RANGE']) && + preg_match("/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/", $_SERVER['HTTP_RANGE'], $range)) { if ($range['end'] == "") { $range['end'] = filesize($filename) - 1; } -- GitLab From 372f261fe304463a67fc347b0e1c345653332ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 10:27:02 +0200 Subject: [PATCH 040/216] remove unnecessary exception handling --- lib/db.php | 149 +++++++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 85 deletions(-) diff --git a/lib/db.php b/lib/db.php index a6b81aaba69..66900f46be9 100644 --- a/lib/db.php +++ b/lib/db.php @@ -180,28 +180,18 @@ class OC_DB { $dsn = 'oci:dbname=//' . $host . '/' . $name; } break; - case 'mssql': + case 'mssql': if ($port) { $dsn='sqlsrv:Server='.$host.','.$port.';Database='.$name; } else { $dsn='sqlsrv:Server='.$host.';Database='.$name; } - break; + break; default: return false; } - try{ - self::$PDO=new PDO($dsn, $user, $pass, $opts); - }catch(PDOException $e) { - OC_Log::write('core', $e->getMessage(), OC_Log::FATAL); - OC_User::setUserId(null); - - // send http status 503 - header('HTTP/1.1 503 Service Temporarily Unavailable'); - header('Status: 503 Service Temporarily Unavailable'); - OC_Template::printErrorPage('Failed to connect to database'); - die(); - } + self::$PDO=new PDO($dsn, $user, $pass, $opts); + // We always, really always want associative arrays self::$PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); self::$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); @@ -299,19 +289,8 @@ class OC_DB { // Try to establish connection self::$MDB2 = MDB2::factory( $dsn, $options ); - - // Die if we could not connect - if( PEAR::isError( self::$MDB2 )) { - OC_Log::write('core', self::$MDB2->getUserInfo(), OC_Log::FATAL); - OC_Log::write('core', self::$MDB2->getMessage(), OC_Log::FATAL); - OC_User::setUserId(null); - - // send http status 503 - header('HTTP/1.1 503 Service Temporarily Unavailable'); - header('Status: 503 Service Temporarily Unavailable'); - OC_Template::printErrorPage('Failed to connect to database'); - die(); - } + + self::raiseExceptionOnError( self::$MDB2 ); // We always, really always want associative arrays self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC); @@ -760,9 +739,9 @@ class OC_DB { $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query ); $query = str_replace( 'LENGTH(', 'LEN(', $query ); $query = str_replace( 'SUBSTR(', 'SUBSTRING(', $query ); - - $query = self::fixLimitClauseForMSSQL($query); - } + + $query = self::fixLimitClauseForMSSQL($query); + } // replace table name prefix $query = str_replace( '*PREFIX*', $prefix, $query ); @@ -770,60 +749,60 @@ class OC_DB { return $query; } - private static function fixLimitClauseForMSSQL($query) { - $limitLocation = stripos ($query, "LIMIT"); - - if ( $limitLocation === false ) { - return $query; - } - - // total == 0 means all results - not zero results - // - // First number is either total or offset, locate it by first space - // - $offset = substr ($query, $limitLocation + 5); - $offset = substr ($offset, 0, stripos ($offset, ' ')); - $offset = trim ($offset); - - // check for another parameter - if (stripos ($offset, ',') === false) { - // no more parameters - $offset = 0; - $total = intval ($offset); - } else { - // found another parameter - $offset = intval ($offset); - - $total = substr ($query, $limitLocation + 5); - $total = substr ($total, stripos ($total, ',')); - - $total = substr ($total, 0, stripos ($total, ' ')); - $total = intval ($total); - } - - $query = trim (substr ($query, 0, $limitLocation)); - - if ($offset == 0 && $total !== 0) { - if (strpos($query, "SELECT") === false) { - $query = "TOP {$total} " . $query; - } else { - $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query); - } - } else if ($offset > 0) { - $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query); - $query = 'SELECT * - FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 - FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3'; - - if ($total > 0) { - $query .= ' WHERE line3 BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $total); - } else { - $query .= ' WHERE line3 > ' . $offset; - } - } - return $query; - } - + private static function fixLimitClauseForMSSQL($query) { + $limitLocation = stripos ($query, "LIMIT"); + + if ( $limitLocation === false ) { + return $query; + } + + // total == 0 means all results - not zero results + // + // First number is either total or offset, locate it by first space + // + $offset = substr ($query, $limitLocation + 5); + $offset = substr ($offset, 0, stripos ($offset, ' ')); + $offset = trim ($offset); + + // check for another parameter + if (stripos ($offset, ',') === false) { + // no more parameters + $offset = 0; + $total = intval ($offset); + } else { + // found another parameter + $offset = intval ($offset); + + $total = substr ($query, $limitLocation + 5); + $total = substr ($total, stripos ($total, ',')); + + $total = substr ($total, 0, stripos ($total, ' ')); + $total = intval ($total); + } + + $query = trim (substr ($query, 0, $limitLocation)); + + if ($offset == 0 && $total !== 0) { + if (strpos($query, "SELECT") === false) { + $query = "TOP {$total} " . $query; + } else { + $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query); + } + } else if ($offset > 0) { + $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query); + $query = 'SELECT * + FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 + FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3'; + + if ($total > 0) { + $query .= ' WHERE line3 BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $total); + } else { + $query .= ' WHERE line3 > ' . $offset; + } + } + return $query; + } + /** * @brief drop a table * @param string $tableName the table to drop @@ -1124,7 +1103,7 @@ class PDOStatementWrapper{ die ($entry); } } - + /** * provide numRows */ -- GitLab From 3f20a080fedd47e2614c44ebe1824f2ee46bb767 Mon Sep 17 00:00:00 2001 From: mvn23 Date: Thu, 20 Jun 2013 12:23:25 +0300 Subject: [PATCH 041/216] Revert most changes for testing --- lib/files.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/files.php b/lib/files.php index 123c87eb5ff..20ad2405fcd 100644 --- a/lib/files.php +++ b/lib/files.php @@ -173,18 +173,20 @@ class OC_Files { header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { - if (isset($_SERVER['HTTP_RANGE']) && - preg_match("/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/", $_SERVER['HTTP_RANGE'], $range)) { - if ($range['end'] == "") { - $range['end'] = filesize($filename) - 1; - } - header("Content-Range: bytes " . $range['start'] . "-" . $range['end'] . "/" . filesize($filename)); - header("HTTP/1.1 206 Partial content"); - header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " " . $range['start'] . "-" . $range['end']); - } else { - header("X-Sendfile: " . $filename); - } + /* if (isset($_SERVER['HTTP_RANGE']) && + * preg_match("/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/", $_SERVER['HTTP_RANGE'], $range)) { + * if ($range['end'] == "") { + * $range['end'] = filesize($filename) - 1; + * } + * header("Content-Range: bytes " . $range['start'] . "-" . $range['end'] . "/" . filesize($filename)); + * header("HTTP/1.1 206 Partial content"); + * header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " " . $range['start'] . "-" . $range['end']); + * } else { + */ + header("X-Sendfile: " . $filename); + // } } + if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { header("X-Accel-Redirect: " . $filename); } -- GitLab From 59fa3055e1e2f4f070a0443bcc0f06fcd6e892eb Mon Sep 17 00:00:00 2001 From: mvn23 Date: Thu, 20 Jun 2013 17:46:36 +0300 Subject: [PATCH 042/216] Reviewed code for X-Sendfile2 Made some small changes which might have caused a segfault on ci.tmit.eu earlier. --- lib/files.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/files.php b/lib/files.php index 20ad2405fcd..f5dffd970d2 100644 --- a/lib/files.php +++ b/lib/files.php @@ -173,18 +173,18 @@ class OC_Files { header("X-Sendfile: " . $filename); } if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { - /* if (isset($_SERVER['HTTP_RANGE']) && - * preg_match("/\Abytes=(?P[0-9]+)-(?P[0-9]*)\z/", $_SERVER['HTTP_RANGE'], $range)) { - * if ($range['end'] == "") { - * $range['end'] = filesize($filename) - 1; - * } - * header("Content-Range: bytes " . $range['start'] . "-" . $range['end'] . "/" . filesize($filename)); - * header("HTTP/1.1 206 Partial content"); - * header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " " . $range['start'] . "-" . $range['end']); - * } else { - */ - header("X-Sendfile: " . $filename); - // } + if (isset($_SERVER['HTTP_RANGE']) && + preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { + $filelength = filesize($filename); + if ($range[2] == "") { + $range[2] = $filelength - 1; + } + header("Content-Range: bytes $range[1]-$range[2]/" . $filelength); + header("HTTP/1.1 206 Partial content"); + header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " $range[1]-$range[2]"); + } else { + header("X-Sendfile: " . $filename); + } } if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { -- GitLab From 7fd45e2875f3f62f4bff3b107076578f15665366 Mon Sep 17 00:00:00 2001 From: kondou Date: Fri, 21 Jun 2013 04:24:40 +0200 Subject: [PATCH 043/216] Optimize pictures with optipng and scour --- core/img/actions/add.png | Bin 195 -> 184 bytes core/img/actions/add.svg | 64 ++---------------------- core/img/actions/delete.png | Bin 334 -> 262 bytes core/img/actions/delete.svg | 66 ++----------------------- core/img/actions/mail.svg | 96 +----------------------------------- 5 files changed, 9 insertions(+), 217 deletions(-) diff --git a/core/img/actions/add.png b/core/img/actions/add.png index 13e20df6626b5c5b907176c9887386b19545c25d..1aac02b84544ac0e8436d7c8e3b14176cd35fb88 100644 GIT binary patch delta 110 zcmX@ixPx(mgajiq0|SGqZLSiKVlH;_4B_D5xc$)o!9+t_Z?*uR5ZC|z{{y8$4_&SU zQj8@*e!&b5&u*jvIpUr!jv*Y;$tej5DfhaYUcDCN@a<}3WDqRn?ws&BdNxoAgQu&X J%Q~loCII_8B7Xn? delta 121 zcmdnNc$jg5gd_(W0|SHn=l_X7ilx}eGlT;OYB*9lCK}j=I(WJ`hFJ8zo#e>Hpulr@ z&5!^3$2aeAOl(qkcI)Cs1ID$7PB3|T8!yOMH~rfFK!pV1XG|~tai+_(9IRKF9kS>& Z%Ml$3Vc}J4dVq#Ac)I$ztaD0e0ssI?Ed2lg diff --git a/core/img/actions/add.svg b/core/img/actions/add.svg index 6db768d9a42..250746e1660 100644 --- a/core/img/actions/add.svg +++ b/core/img/actions/add.svg @@ -1,62 +1,6 @@ - - - - - image/svg+xml - - - - - - - - - - + + + + diff --git a/core/img/actions/delete.png b/core/img/actions/delete.png index 6362903937c001f3bd5ebac47fe8ed48195c66a9..fe826a14dd2f14c3e50e57bdbd1d0fc583aea929 100644 GIT binary patch delta 189 zcmX@d)W$SHLV|^vfq~)e-A6${in-XyGlYYK*WG`LR|m<|9_Ez;VJ{e z6$}KF;`K2(0MyA*666=mz-?Q$;qKGF%p20S0ma-rT^vI=qLULG7!tROI18K=xp?v7 zDu$F5S%~(8kOhecVUkg@=Q|gP?+=1#b(O1*O6c=(aL3 Yy!2Lk&1A~I8fYYgr>mdKI;Vst0Pl`KW&i*H delta 261 zcmV+g0s8)i0?q=E7#Ro#0000V^Z#K0000DYLP=Bz2nYy#2xN$nFg<_ENklY9d7)C*(rw46x?ldoEYoV%q=6IV6hxQ4qSQ(Q_6jU zY(aPi{~BW`RR#&r%rG|wiF?xBB?eMza0be;Wd9X*NAR`kGcC~@w_00eyvnF>00000 LNkvXXu0mjfPWf)3 diff --git a/core/img/actions/delete.svg b/core/img/actions/delete.svg index 08ea381f378..8024d402a85 100644 --- a/core/img/actions/delete.svg +++ b/core/img/actions/delete.svg @@ -1,65 +1,5 @@ - - - - - image/svg+xml - - - - - - - - - + + + diff --git a/core/img/actions/mail.svg b/core/img/actions/mail.svg index 6e8a4bd7f6b..c01f2c113e7 100644 --- a/core/img/actions/mail.svg +++ b/core/img/actions/mail.svg @@ -1,96 +1,4 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - - - + + -- GitLab From a06d901e3782a58f3f98bac4eca81430e56089ae Mon Sep 17 00:00:00 2001 From: Roland Hager Date: Thu, 13 Jun 2013 09:18:50 +0200 Subject: [PATCH 044/216] Fix: The check if upload_max_filesize or post_max_size is 0 fails if only one of them is 0. $upload_max_filesize and $post_max_size need to be casted to (int) to match "=== 0" --- lib/helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/helper.php b/lib/helper.php index a315c640d1a..1860a55fc8f 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -787,9 +787,9 @@ class OC_Helper { $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize')); $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $freeSpace = \OC\Files\Filesystem::free_space($dir); - if ($upload_max_filesize == 0 and $post_max_size == 0) { + if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) { $maxUploadFilesize = \OC\Files\FREE_SPACE_UNLIMITED; - } elseif ($upload_max_filesize === 0 or $post_max_size === 0) { + } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) { $maxUploadFilesize = max($upload_max_filesize, $post_max_size); //only the non 0 value counts } else { $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -- GitLab From 643c8d308847197550480507120b5f0f34f8fc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 14:46:22 +0200 Subject: [PATCH 045/216] make PDOStatementWrapper return number of updated rows on INSERT, UPDATE or DELETE queries, introduces isManipulation() to guess type of query --- lib/db.php | 80 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/lib/db.php b/lib/db.php index a6b81aaba69..984c2bcf149 100644 --- a/lib/db.php +++ b/lib/db.php @@ -330,7 +330,7 @@ class OC_DB { * * SQL query via MDB2 prepare(), needs to be execute()'d! */ - static public function prepare( $query , $limit=null, $offset=null ) { + static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) { if (!is_null($limit) && $limit != -1) { if (self::$backend == self::BACKEND_MDB2) { @@ -367,12 +367,23 @@ class OC_DB { OC_Log::write('core', 'DB prepare : '.$query, OC_Log::DEBUG); } self::connect(); + + if ($isManipulation === null) { + //try to guess, so we return the number of rows on manipulations + $isManipulation = self::isManipulation($query); + } + // return the result if(self::$backend==self::BACKEND_MDB2) { - $result = self::$connection->prepare( $query ); + // differentiate between query and manipulation + if ($isManipulation) { + $result = self::$connection->prepare( $query, null, MDB2_PREPARE_MANIP ); + } else { + $result = self::$connection->prepare( $query, null, MDB2_PREPARE_RESULT ); + } // Die if we have an error (error means: bad query, not 0 results!) - if( PEAR::isError($result)) { + if( self::isError($result)) { throw new DatabaseException($result->getMessage(), $query); } }else{ @@ -381,7 +392,12 @@ class OC_DB { }catch(PDOException $e) { throw new DatabaseException($e->getMessage(), $query); } - $result=new PDOStatementWrapper($result); + // differentiate between query and manipulation + if ($isManipulation) { + $result=new PDOStatementWrapper($result, true); + } else { + $result=new PDOStatementWrapper($result, false); + } } if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) { $type = OC_Config::getValue( "dbtype", "sqlite" ); @@ -391,7 +407,33 @@ class OC_DB { } return $result; } - + + /** + * tries to guess the type of statement based on the first 10 characters + * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements + * + * @param string $sql + */ + static public function isManipulation( $sql ) { + $selectOccurence = stripos ($sql, "SELECT"); + if ($selectOccurence !== false && $selectOccurence < 10) { + return false; + } + $insertOccurence = stripos ($sql, "INSERT"); + if ($insertOccurence !== false && $insertOccurence < 10) { + return true; + } + $updateOccurence = stripos ($sql, "UPDATE"); + if ($updateOccurence !== false && $updateOccurence < 10) { + return true; + } + $deleteOccurance = stripos ($sql, "DELETE"); + if ($deleteOccurance !== false && $deleteOccurance < 10) { + return true; + } + return false; + } + /** * @brief execute a prepared statement, on error write log and throw exception * @param mixed $stmt PDOStatementWrapper | MDB2_Statement_Common , @@ -718,6 +760,9 @@ class OC_DB { } catch(PDOException $e) { OC_Template::printExceptionErrorPage( $e ); } + if ($result === 0) { + return true; + } return $result; } @@ -919,7 +964,7 @@ class OC_DB { * @return bool */ public static function isError($result) { - if(!$result) { + if(self::$backend==self::BACKEND_PDO and $result === false) { return true; }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)) { return true; @@ -997,11 +1042,13 @@ class PDOStatementWrapper{ /** * @var PDOStatement */ - private $statement=null; - private $lastArguments=array(); + private $statement = null; + private $isManipulation = false; + private $lastArguments = array(); - public function __construct($statement) { - $this->statement=$statement; + public function __construct($statement, $isManipulation = false) { + $this->statement = $statement; + $this->isManipulation = $isManipulation; } /** @@ -1023,16 +1070,19 @@ class PDOStatementWrapper{ $input = $this->tryFixSubstringLastArgumentDataForMSSQL($input); } - $result=$this->statement->execute($input); + $result = $this->statement->execute($input); } else { - $result=$this->statement->execute(); + $result = $this->statement->execute(); } - if ($result) { - return $this; - } else { + if ($result === false) { return false; } + if ($this->isManipulation) { + return $this->statement->rowCount(); + } else { + return $this; + } } private function tryFixSubstringLastArgumentDataForMSSQL($input) { -- GitLab From 88fc410c1936510b84497b677248cd20db9fd87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 14:47:12 +0200 Subject: [PATCH 046/216] fix numRows usage in user_ldap --- apps/user_ldap/lib/access.php | 6 ++---- apps/user_ldap/lib/helper.php | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 04f73cf01fe..6f6b8d0f016 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -578,14 +578,12 @@ abstract class Access { '); //feed the DB - $res = $insert->execute(array($dn, $ocname, $this->getUUID($dn), $dn, $ocname)); + $insRows = $insert->execute(array($dn, $ocname, $this->getUUID($dn), $dn, $ocname)); - if(\OCP\DB::isError($res)) { + if(\OCP\DB::isError($insRows)) { return false; } - $insRows = $res->numRows(); - if($insRows === 0) { return false; } diff --git a/apps/user_ldap/lib/helper.php b/apps/user_ldap/lib/helper.php index 10ed40ebd6a..f65f466789f 100644 --- a/apps/user_ldap/lib/helper.php +++ b/apps/user_ldap/lib/helper.php @@ -90,13 +90,13 @@ class Helper { AND `appid` = \'user_ldap\' AND `configkey` NOT IN (\'enabled\', \'installed_version\', \'types\', \'bgjUpdateGroupsLastRun\') '); - $res = $query->execute(array($prefix.'%')); + $delRows = $query->execute(array($prefix.'%')); - if(\OCP\DB::isError($res)) { + if(\OCP\DB::isError($delRows)) { return false; } - if($res->numRows() === 0) { + if($delRows === 0) { return false; } -- GitLab From c223bee6df33b3208dbb5a7c46dbeb98eccf10ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 14:47:42 +0200 Subject: [PATCH 047/216] fix numRows usage in core lib --- lib/connector/sabre/locks.php | 2 +- lib/vcategories.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/connector/sabre/locks.php b/lib/connector/sabre/locks.php index cbc495dec19..e057b059947 100644 --- a/lib/connector/sabre/locks.php +++ b/lib/connector/sabre/locks.php @@ -178,7 +178,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $sql = 'DELETE FROM `*PREFIX*locks` WHERE `userid` = ? AND `uri` = ? AND `token` = ?'; $result = OC_DB::executeAudited( $sql, array(OC_User::getUser(), $uri, $lockInfo->token)); - return $result->numRows() === 1; + return $result === 1; } diff --git a/lib/vcategories.php b/lib/vcategories.php index 7bac6e7d4e3..84036958359 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -125,7 +125,7 @@ class OC_VCategories { OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); return false; } - return ($result->numRows() == 0); + return ($result->numRows() === 0); } catch(Exception $e) { OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR); -- GitLab From c79f7f4f3cb460f890fccb5a7de7d62ea0a5fc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 14:49:10 +0200 Subject: [PATCH 048/216] fix numRows usage in files_encryption --- apps/files_encryption/lib/util.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index e8e53859bd8..b3de85254e2 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -362,17 +362,7 @@ class Util { } - $query = \OCP\DB::prepare($sql); - - if ($query->execute($args)) { - - return true; - - } else { - - return false; - - } + return is_numeric(\OC_DB::executeAudited($sql, $args)); } @@ -1063,8 +1053,7 @@ class Util { $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; $args = array(self::MIGRATION_IN_PROGRESS, $this->userId, self::MIGRATION_OPEN); $query = \OCP\DB::prepare($sql); - $result = $query->execute($args); - $manipulatedRows = $result->numRows(); + $manipulatedRows = $query->execute($args); if ($manipulatedRows === 1) { $return = true; @@ -1087,8 +1076,7 @@ class Util { $sql = 'UPDATE `*PREFIX*encryption` SET `migration_status` = ? WHERE `uid` = ? and `migration_status` = ?'; $args = array(self::MIGRATION_COMPLETED, $this->userId, self::MIGRATION_IN_PROGRESS); $query = \OCP\DB::prepare($sql); - $result = $query->execute($args); - $manipulatedRows = $result->numRows(); + $manipulatedRows = $query->execute($args); if ($manipulatedRows === 1) { $return = true; -- GitLab From 1b97c186b4f2946753123fb73314597b818aea70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 15:38:02 +0200 Subject: [PATCH 049/216] use assertEquals number of rows in db tests --- tests/lib/db.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/lib/db.php b/tests/lib/db.php index afbdb413c3d..0ba7d5d4b06 100644 --- a/tests/lib/db.php +++ b/tests/lib/db.php @@ -40,7 +40,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { $this->assertFalse((bool)$row); //PDO returns false, MDB2 returns null $query = OC_DB::prepare('INSERT INTO `*PREFIX*'.$this->table2.'` (`fullname`,`uri`) VALUES (?,?)'); $result = $query->execute(array('fullname test', 'uri_1')); - $this->assertTrue((bool)$result); + $this->assertEquals('1', $result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM `*PREFIX*'.$this->table2.'` WHERE `uri` = ?'); $result = $query->execute(array('uri_1')); $this->assertTrue((bool)$result); @@ -57,7 +57,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { public function testNOW() { $query = OC_DB::prepare('INSERT INTO `*PREFIX*'.$this->table2.'` (`fullname`,`uri`) VALUES (NOW(),?)'); $result = $query->execute(array('uri_2')); - $this->assertTrue((bool)$result); + $this->assertEquals('1', $result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM `*PREFIX*'.$this->table2.'` WHERE `uri` = ?'); $result = $query->execute(array('uri_2')); $this->assertTrue((bool)$result); @@ -66,7 +66,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { public function testUNIX_TIMESTAMP() { $query = OC_DB::prepare('INSERT INTO `*PREFIX*'.$this->table2.'` (`fullname`,`uri`) VALUES (UNIX_TIMESTAMP(),?)'); $result = $query->execute(array('uri_3')); - $this->assertTrue((bool)$result); + $this->assertEquals('1', $result); $query = OC_DB::prepare('SELECT `fullname`,`uri` FROM `*PREFIX*'.$this->table2.'` WHERE `uri` = ?'); $result = $query->execute(array('uri_3')); $this->assertTrue((bool)$result); @@ -105,7 +105,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { // Normal test to have same known data inserted. $query = OC_DB::prepare('INSERT INTO `*PREFIX*'.$this->table2.'` (`fullname`, `uri`, `carddata`) VALUES (?, ?, ?)'); $result = $query->execute(array($fullname, $uri, $carddata)); - $this->assertTrue((bool)$result); + $this->assertEquals('1', $result); $query = OC_DB::prepare('SELECT `fullname`, `uri`, `carddata` FROM `*PREFIX*'.$this->table2.'` WHERE `uri` = ?'); $result = $query->execute(array($uri)); $this->assertTrue((bool)$result); -- GitLab From b32d6d84878798b78afa757c4d8a068a84ab9513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 24 Jun 2013 22:52:01 +0200 Subject: [PATCH 050/216] for oracle use BITAND() instead of & in sharing permissions sql --- lib/public/share.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 122ab3fa030..f40cd0d77fa 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -662,9 +662,13 @@ class Share { // Remove the permissions for all reshares of this item if (!empty($ids)) { $ids = "'".implode("','", $ids)."'"; - $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = `permissions` & ?' - .' WHERE `id` IN ('.$ids.')'); - $query->execute(array($permissions)); + // the binary operator & works on sqlite, mysql, postgresql and mssql + $sql = 'UPDATE `*PREFIX*share` SET `permissions` = `permissions` & ? WHERE `id` IN ('.$ids.')'; + if (\OC_Config::getValue('dbtype', 'sqlite') === 'oci') { + // guess which dbms does not handle & and uses a function for this + $sql = 'UPDATE `*PREFIX*share` SET `permissions` = BITAND(`permissions`,?) WHERE `id` IN ('.$ids.')'; + } + \OC_DB::executeAudited($sql, array($permissions)); } } } -- GitLab From 7273b43cd5b0047207763ca48abc46e5d0fcb130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 25 Jun 2013 09:52:04 +0200 Subject: [PATCH 051/216] manuall calculate unix_timestamp for oracle --- lib/db.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/db.php b/lib/db.php index a6b81aaba69..f6acf6af1b7 100644 --- a/lib/db.php +++ b/lib/db.php @@ -754,6 +754,7 @@ class OC_DB { }elseif( $type == 'oci' ) { $query = str_replace( '`', '"', $query ); $query = str_ireplace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); + $query = str_ireplace( 'UNIX_TIMESTAMP()', '((CAST(SYS_EXTRACT_UTC(systimestamp) AS DATE))-TO_DATE(\'1970101000000\',\'YYYYMMDDHH24MiSS\'))*24*3600', $query ); }elseif( $type == 'mssql' ) { $query = preg_replace( "/\`(.*?)`/", "[$1]", $query ); $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query ); -- GitLab From ddb0ff346d3d8063f88fdba8749e098a81b92d54 Mon Sep 17 00:00:00 2001 From: Roman Geber Date: Tue, 25 Jun 2013 12:24:14 +0200 Subject: [PATCH 052/216] Public upload feature --- apps/files/ajax/upload.php | 48 +++++++- apps/files/index.php | 3 +- apps/files/js/filelist.js | 24 +++- apps/files/js/files.js | 149 +----------------------- apps/files/templates/index.php | 2 +- apps/files_sharing/css/public.css | 61 +++++++++- apps/files_sharing/js/public.js | 19 ++- apps/files_sharing/public.php | 18 ++- apps/files_sharing/templates/public.php | 42 ++++++- core/js/share.js | 43 ++++++- lib/files/view.php | 2 +- 11 files changed, 242 insertions(+), 169 deletions(-) diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index e1263744e1b..12db682c1e2 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -1,17 +1,53 @@ array_merge(array('message' => $l->t('Unable to set upload directory.'))))); + die(); + } +} else { + $linkItem = OCP\Share::getShareByToken($_POST['dirToken']); + + if ($linkItem === false) { + OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Invalid Token'))))); + die(); + } + + if (!($linkItem['permissions'] & OCP\PERMISSION_CREATE)) { + OCP\JSON::checkLoggedIn(); + } else { + + // The token defines the target directory (security reasons) + $dir = sprintf( + "/%s/%s", + $linkItem['file_target'], + isset($_POST['subdir']) ? $_POST['subdir'] : '' + ); + + if (!$dir || empty($dir) || $dir === false) { + OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Unable to set upload directory.'))))); + die(); + } + // Setup FS with owner + OC_Util::setupFS($linkItem['uid_owner']); + } +} + + +OCP\JSON::callCheck(); -$dir = $_POST['dir']; // get array with current storage stats (e.g. max file size) $storageStats = \OCA\files\lib\Helper::buildFileStorageStatistics($dir); diff --git a/apps/files/index.php b/apps/files/index.php index 20fbf7f93be..640c28c0075 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -26,6 +26,7 @@ OCP\User::checkLoggedIn(); // Load the files we need OCP\Util::addStyle('files', 'files'); +OCP\Util::addscript('files', 'file-upload'); OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); OCP\Util::addscript('files', 'jquery-visibility'); @@ -137,4 +138,4 @@ if ($needUpgrade) { $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->assign('usedSpacePercent', (int)$storageInfo['relative']); $tmpl->printPage(); -} \ No newline at end of file +} diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e19a35bbc5b..f4ca098eed1 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -71,8 +71,20 @@ var FileList={ tr.append(td); return tr; }, - addFile:function(name,size,lastModified,loading,hidden){ + addFile:function(name,size,lastModified,loading,hidden,param){ var imgurl; + + if (!param) { + param = {}; + } + + var download_url = null; + if (!param.download_url) { + download_url = OC.Router.generate('download', { file: $('#dir').val()+'/'+name }); + } else { + download_url = param.download_url; + } + if (loading) { imgurl = OC.imagePath('core', 'loading.gif'); } else { @@ -82,7 +94,7 @@ var FileList={ 'file', name, imgurl, - OC.Router.generate('download', { file: $('#dir').val()+'/'+name }), + download_url, size, lastModified, $('#permissions').val() @@ -197,7 +209,7 @@ var FileList={ len = input.val().length; } input.selectRange(0,len); - + form.submit(function(event){ event.stopPropagation(); event.preventDefault(); @@ -423,8 +435,12 @@ $(document).ready(function(){ size=data.files[0].size; } var date=new Date(); + var param = {}; + if ($('#publicUploadRequestToken')) { + param.download_url = document.location.href + '&download&path=/' + $('#dir').val() + '/' + uniqueName; + } // create new file context - data.context = FileList.addFile(uniqueName,size,date,true,false); + data.context = FileList.addFile(uniqueName,size,date,true,false,param); } } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 3438c1c30a1..51b3f31fb96 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -251,153 +251,6 @@ $(document).ready(function() { e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone }); - if ( document.getElementById('data-upload-form') ) { - $(function() { - $('#file_upload_start').fileupload({ - dropZone: $('#content'), // restrict dropZone to content div - //singleFileUploads is on by default, so the data.files array will always have length 1 - add: function(e, data) { - - if(data.files[0].type === '' && data.files[0].size == 4096) - { - data.textStatus = 'dirorzero'; - data.errorThrown = t('files','Unable to upload your file as it is a directory or has 0 bytes'); - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); - return true; //don't upload this file but go on with next in queue - } - - var totalSize=0; - $.each(data.originalFiles, function(i,file){ - totalSize+=file.size; - }); - - if(totalSize>$('#max_upload').val()){ - data.textStatus = 'notenoughspace'; - data.errorThrown = t('files','Not enough space available'); - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); - return false; //don't upload anything - } - - // start the actual file upload - var jqXHR = data.submit(); - - // remember jqXHR to show warning to user when he navigates away but an upload is still in progress - if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') { - var dirName = data.context.data('file'); - if(typeof uploadingFiles[dirName] === 'undefined') { - uploadingFiles[dirName] = {}; - } - uploadingFiles[dirName][data.files[0].name] = jqXHR; - } else { - uploadingFiles[data.files[0].name] = jqXHR; - } - - //show cancel button - if($('html.lte9').length === 0 && data.dataType !== 'iframe') { - $('#uploadprogresswrapper input.stop').show(); - } - }, - /** - * called after the first add, does NOT have the data param - * @param e - */ - start: function(e) { - //IE < 10 does not fire the necessary events for the progress bar. - if($('html.lte9').length > 0) { - return; - } - $('#uploadprogressbar').progressbar({value:0}); - $('#uploadprogressbar').fadeIn(); - }, - fail: function(e, data) { - if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) { - if (data.textStatus === 'abort') { - $('#notification').text(t('files', 'Upload cancelled.')); - } else { - // HTTP connection problem - $('#notification').text(data.errorThrown); - } - $('#notification').fadeIn(); - //hide notification after 5 sec - setTimeout(function() { - $('#notification').fadeOut(); - }, 5000); - } - delete uploadingFiles[data.files[0].name]; - }, - progress: function(e, data) { - // TODO: show nice progress bar in file row - }, - progressall: function(e, data) { - //IE < 10 does not fire the necessary events for the progress bar. - if($('html.lte9').length > 0) { - return; - } - var progress = (data.loaded/data.total)*100; - $('#uploadprogressbar').progressbar('value',progress); - }, - /** - * called for every successful upload - * @param e - * @param data - */ - done:function(e, data) { - // handle different responses (json or body from iframe for ie) - var response; - if (typeof data.result === 'string') { - response = data.result; - } else { - //fetch response from iframe - response = data.result[0].body.innerText; - } - var result=$.parseJSON(response); - - if(typeof result[0] !== 'undefined' && result[0].status === 'success') { - var file = result[0]; - } else { - data.textStatus = 'servererror'; - data.errorThrown = t('files', result.data.message); - var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); - fu._trigger('fail', e, data); - } - - var filename = result[0].originalname; - - // delete jqXHR reference - if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') { - var dirName = data.context.data('file'); - delete uploadingFiles[dirName][filename]; - if ($.assocArraySize(uploadingFiles[dirName]) == 0) { - delete uploadingFiles[dirName]; - } - } else { - delete uploadingFiles[filename]; - } - - }, - /** - * called after last upload - * @param e - * @param data - */ - stop: function(e, data) { - if(data.dataType !== 'iframe') { - $('#uploadprogresswrapper input.stop').hide(); - } - - //IE < 10 does not fire the necessary events for the progress bar. - if($('html.lte9').length > 0) { - return; - } - - $('#uploadprogressbar').progressbar('value',100); - $('#uploadprogressbar').fadeOut(); - } - }) - }); - } $.assocArraySize = function(obj) { // http://stackoverflow.com/a/6700/11236 var size = 0, key; @@ -804,7 +657,7 @@ var dragOptions={ // sane browsers support using the distance option if ( $('html.ie').length === 0) { dragOptions['distance'] = 20; -} +} var folderDropOptions={ drop: function( event, ui ) { diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index b576253f4f0..b9119f2cb62 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -50,7 +50,7 @@
- +
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 13298f113f8..68549d14fe1 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -15,15 +15,26 @@ body { padding:.5em; } -#details { +#header #details { color:#fff; + float: left; } +#header #public_upload, #header #download { font-weight:700; - margin-left:2em; + margin: 0 0.4em 0 2em; + padding: 0 5px; + height: 27px; + float: left; + +} + +#header #public_upload { + margin-left: 0.3em; } +#header #public_upload img, #header #download img { padding-left:.1em; padding-right:.3em; @@ -73,3 +84,49 @@ thead{ background-color: white; padding-left:0 !important; /* fixes multiselect bar offset on shared page */ } + +#data-upload-form { + position: relative; + right: 0; + height: 27px; + overflow: hidden; + padding: 0; + float: right; + display: inline; + margin: 0; +} + +#file_upload_start { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + opacity: 0; + z-index: 20; + position: absolute !important; + top: 0; + left: 0; + width: 100% !important; +} + +.header-right #download span { + position: relative; + bottom: 3px; +} + +#publicUploadButtonMock { + position:relative; + display:block; + width:100%; + height:27px; + cursor:pointer; + z-index:10; + background-image:url('%webroot%/core/img/actions/upload.svg'); + background-repeat:no-repeat; + background-position:7px 6px; +} + +#publicUploadButtonMock span { + margin: 0 5px 0 28px; + position: relative; + top: -2px; + color: #555; +} diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 916e35419c1..0244f392a0e 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -7,6 +7,8 @@ function fileDownloadPath(dir, file) { return url; } +var form_data; + $(document).ready(function() { if (typeof FileActions !== 'undefined') { @@ -46,4 +48,19 @@ $(document).ready(function() { }); } -}); \ No newline at end of file + // Add some form data to the upload handler + file_upload_param.formData = { + MAX_FILE_SIZE: $('#uploadMaxFilesize').val(), + requesttoken: $('#publicUploadRequestToken').val(), + dirToken: $('#dirToken').val(), + appname: 'files_sharing', + subdir: $('input#dir').val() + }; + + // Add Uploadprogress Wrapper to controls bar + $('#controls').append($('#additional_controls div#uploadprogresswrapper')); + + // Cancel upload trigger + $('#cancel_upload_button').click(Files.cancelUploads); + +}); diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 98d2a84fb66..fa8c25fc98d 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -132,15 +132,25 @@ if (isset($path)) { } exit(); } else { + OCP\Util::addScript('files', 'file-upload'); OCP\Util::addStyle('files_sharing', 'public'); OCP\Util::addScript('files_sharing', 'public'); OCP\Util::addScript('files', 'fileactions'); + OCP\Util::addScript('files', 'jquery.iframe-transport'); + OCP\Util::addScript('files', 'jquery.fileupload'); + $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('uidOwner', $shareOwner); $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); $tmpl->assign('filename', $file); + $tmpl->assign('directory_path', $linkItem['file_target']); $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('fileTarget', basename($linkItem['file_target'])); + $tmpl->assign('dirToken', $linkItem['token']); + $tmpl->assign('allowPublicUploadEnabled', (($linkItem['permissions'] & OCP\PERMISSION_CREATE) ? true : false )); + $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); + $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $urlLinkIdentifiers= (isset($token)?'&t='.$token:'') .(isset($_GET['dir'])?'&dir='.$_GET['dir']:'') .(isset($_GET['file'])?'&file='.$_GET['file']:''); @@ -191,15 +201,17 @@ if (isset($path)) { $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb); $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); + $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $folder = new OCP\Template('files', 'index', ''); $folder->assign('fileList', $list->fetchPage()); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); $folder->assign('dir', $getPath); $folder->assign('isCreatable', false); - $folder->assign('permissions', 0); + $folder->assign('permissions', OCP\PERMISSION_READ); + $folder->assign('isPublic',true); $folder->assign('files', $files); - $folder->assign('uploadMaxFilesize', 0); - $folder->assign('uploadMaxHumanFilesize', 0); + $folder->assign('uploadMaxFilesize', $maxUploadFilesize); + $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $folder->assign('usedSpacePercent', 0); $tmpl->assign('folder', $folder->fetchPage()); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index adf3c3e9cc8..3a1c370b4c0 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -1,3 +1,7 @@ +
+ +
+ @@ -13,13 +17,49 @@ t('%s shared the file %s with you', array($_['displayName'], $_['fileTarget']))) ?> + + Download" - />t('Download'))?> + />t('Download'))?> + + + + + + + + + + + + + + + + +
diff --git a/core/js/share.js b/core/js/share.js index 36e4babedf9..cb37dd70366 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -156,6 +156,19 @@ OC.Share={ html += '
'; } if (possiblePermissions & OC.PERMISSION_SHARE) { + // Determine the Allow Public Upload status. + // Used later on to determine if the + // respective checkbox should be checked or + // not. + + var allowPublicUploadStatus = false; + $.each(data.shares, function(key, value) { + if (allowPublicUploadStatus) { + return true; + } + allowPublicUploadStatus = (value.permissions & OC.PERMISSION_CREATE) ? true : false; + }); + html += ''; html += '
    '; html += '
'; @@ -168,12 +181,16 @@ OC.Share={ html += '
'; html += ''; html += '
'; - html += '
'; + html += '
'; html += ''; } + html += '
'; html += ''; html += ''; @@ -370,6 +387,7 @@ OC.Share={ $('#expiration').show(); $('#emailPrivateLink #email').show(); $('#emailPrivateLink #emailButton').show(); + $('#allowPublicUploadWrapper').show(); }, hideLink:function() { $('#linkText').hide('blind'); @@ -378,6 +396,7 @@ OC.Share={ $('#linkPass').hide(); $('#emailPrivateLink #email').hide(); $('#emailPrivateLink #emailButton').hide(); + $('#allowPublicUploadWrapper').hide(); }, dirname:function(path) { return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, ''); @@ -543,6 +562,28 @@ $(document).ready(function() { $(this).select(); }); + // Handle the Allow Public Upload Checkbox + $(document).on('click', '#sharingDialogAllowPublicUpload', function() { + + // Gather data + var allowPublicUpload = $(this).is(':checked'); + var itemType = $('#dropdown').data('item-type'); + var itemSource = $('#dropdown').data('item-source'); + var permissions = 0; + + // Calculate permissions + if (allowPublicUpload) { + permissions = OC.PERMISSION_UPDATE + OC.PERMISSION_CREATE + OC.PERMISSION_READ; + } else { + permissions = OC.PERMISSION_READ; + } + + // Update the share information + OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', permissions, function(data) { + return; + }); + }); + $(document).on('click', '#dropdown #showPassword', function() { $('#linkPass').toggle('blind'); if (!$('#showPassword').is(':checked') ) { diff --git a/lib/files/view.php b/lib/files/view.php index 25071709fbe..d8d99698023 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -754,7 +754,7 @@ class View { if ($subStorage) { $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); - $data['size'] += $rootEntry['size']; + $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; } } } -- GitLab From 620878033270b0cb987f419aa6df16cc4f626f06 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 25 Jun 2013 17:04:25 +0200 Subject: [PATCH 053/216] Sabre: throw exceptions when delete/create/write operations are not permitted --- lib/connector/sabre/directory.php | 15 +++++++++++++++ lib/connector/sabre/file.php | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 6ccb54b79ab..3d15a2a584d 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -45,9 +45,15 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * * @param string $name Name of the file * @param resource|string $data Initial payload + * @throws Sabre_DAV_Exception_Forbidden * @return null|string */ public function createFile($name, $data = null) { + + if (!\OC\Files\Filesystem::isCreatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { $info = OC_FileChunking::decodeName($name); if (empty($info)) { @@ -102,10 +108,15 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * Creates a new subdirectory * * @param string $name + * @throws Sabre_DAV_Exception_Forbidden * @return void */ public function createDirectory($name) { + if (!\OC\Files\Filesystem::isCreatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + $newPath = $this->path . '/' . $name; if(!\OC\Files\Filesystem::mkdir($newPath)) { throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath); @@ -203,9 +214,13 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * Deletes all files in this directory, and then itself * * @return void + * @throws Sabre_DAV_Exception_Forbidden */ public function delete() { + if (!\OC\Files\Filesystem::isDeletable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } if ($this->path != "/Shared") { foreach($this->getChildren() as $child) $child->delete(); \OC\Files\Filesystem::rmdir($this->path); diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 91646312e90..438d9871c22 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -41,24 +41,29 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * return an ETag, and just return null. * * @param resource $data + * @throws Sabre_DAV_Exception_Forbidden * @return string|null */ public function put($data) { + if (!\OC\Files\Filesystem::isUpdatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + // mark file as partial while uploading (ignored by the scanner) $partpath = $this->path . '.part'; \OC\Files\Filesystem::file_put_contents($partpath, $data); //detect aborted upload - if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) { + if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { if (isset($_SERVER['CONTENT_LENGTH'])) { $expected = $_SERVER['CONTENT_LENGTH']; $actual = \OC\Files\Filesystem::filesize($partpath); if ($actual != $expected) { \OC\Files\Filesystem::unlink($partpath); throw new Sabre_DAV_Exception_BadRequest( - 'expected filesize ' . $expected . ' got ' . $actual); + 'expected filesize ' . $expected . ' got ' . $actual); } } } @@ -69,7 +74,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D //allow sync clients to send the mtime along in a header $mtime = OC_Request::hasModificationTime(); if ($mtime !== false) { - if(\OC\Files\Filesystem::touch($this->path, $mtime)) { + if (\OC\Files\Filesystem::touch($this->path, $mtime)) { header('X-OC-MTime: accepted'); } } @@ -92,9 +97,13 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * Delete the current file * * @return void + * @throws Sabre_DAV_Exception_Forbidden */ public function delete() { + if (!\OC\Files\Filesystem::isDeletable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } \OC\Files\Filesystem::unlink($this->path); } -- GitLab From 794c189650d8eb2068da3a5df6ccd22966ee7f38 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Wed, 26 Jun 2013 09:19:19 +0200 Subject: [PATCH 054/216] session life time is now configurable and set to the same value --- config/config.sample.php | 3 +++ lib/base.php | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 72834009201..9254365e3e2 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -145,6 +145,9 @@ $CONFIG = array( /* Lifetime of the remember login cookie, default is 15 days */ "remember_login_cookie_lifetime" => 60*60*24*15, +/* Life time of a session after inactivity */ +"session_life_time" => 60 * 60 * 12, + /* Custom CSP policy, changing this will overwrite the standard policy */ "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *", diff --git a/lib/base.php b/lib/base.php index fd4870974fe..7097a376d6e 100644 --- a/lib/base.php +++ b/lib/base.php @@ -311,16 +311,17 @@ class OC { exit(); } + $sessionLifeTime = self::getSessionLifeTime(); // regenerate session id periodically to avoid session fixation if (!self::$session->exists('SID_CREATED')) { self::$session->set('SID_CREATED', time()); - } else if (time() - self::$session->get('SID_CREATED') > 60*60*12) { + } else if (time() - self::$session->get('SID_CREATED') > $sessionLifeTime) { session_regenerate_id(true); self::$session->set('SID_CREATED', time()); } // session timeout - if (self::$session->exists('LAST_ACTIVITY') && (time() - self::$session->get('LAST_ACTIVITY') > 60*60*24)) { + if (self::$session->exists('LAST_ACTIVITY') && (time() - self::$session->get('LAST_ACTIVITY') > $sessionLifeTime)) { if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 42000, $cookie_path); } @@ -332,6 +333,13 @@ class OC { self::$session->set('LAST_ACTIVITY', time()); } + /** + * @return int + */ + private static function getSessionLifeTime() { + return OC_Config::getValue('session_life_time', 60 * 60 * 12); + } + public static function getRouter() { if (!isset(OC::$router)) { OC::$router = new OC_Router(); @@ -393,9 +401,6 @@ class OC { @ini_set('post_max_size', '10G'); @ini_set('file_uploads', '50'); - //try to set the session lifetime to 60min - @ini_set('gc_maxlifetime', '3600'); - //copy http auth headers for apache+php-fcgid work around if (isset($_SERVER['HTTP_XAUTHORIZATION']) && !isset($_SERVER['HTTP_AUTHORIZATION'])) { $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['HTTP_XAUTHORIZATION']; @@ -455,6 +460,10 @@ class OC { exit; } + //try to set the session lifetime + $sessionLifeTime = self::getSessionLifeTime(); + @ini_set('gc_maxlifetime', (string)$sessionLifeTime); + // User and Groups if (!OC_Config::getValue("installed", false)) { self::$session->set('user_id',''); -- GitLab From bc61a9c09743eda0ffc18542d6bda2ed34d8553a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 26 Jun 2013 15:33:35 +0200 Subject: [PATCH 055/216] enable testing individual tests --- autotest.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autotest.sh b/autotest.sh index 4562b3ed08a..59f0240d99b 100755 --- a/autotest.sh +++ b/autotest.sh @@ -132,9 +132,9 @@ EOF php -f enable_all.php if [ "$1" == "sqlite" ] ; then # coverage only with sqlite - causes segfault on ci.tmit.eu - reason unknown - phpunit --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml --coverage-clover autotest-clover-$1.xml --coverage-html coverage-html-$1 + phpunit --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml --coverage-clover autotest-clover-$1.xml --coverage-html coverage-html-$1 $2 $3 else - phpunit --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml + phpunit --configuration phpunit-autotest.xml --log-junit autotest-results-$1.xml $2 $3 fi } @@ -149,7 +149,7 @@ if [ -z "$1" ] # we will add oci as soon as it's stable #execute_tests 'oci' else - execute_tests $1 + execute_tests $1 $2 $3 fi # -- GitLab From 5a20c8b66fdf7e33de5874920e82b5caef449bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 26 Jun 2013 15:51:22 +0200 Subject: [PATCH 056/216] add openssl_error_string() output to the owncloud.log --- apps/files_encryption/lib/crypt.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 927064012b6..6543a0de5f3 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -57,10 +57,11 @@ class Crypt { if ($res === false) { \OCP\Util::writeLog('Encryption library', 'couldn\'t generate users key-pair for ' . \OCP\User::getUser(), \OCP\Util::ERROR); + \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR); } elseif (openssl_pkey_export($res, $privateKey)) { // Get public key - $publicKey = openssl_pkey_get_details($res); - $publicKey = $publicKey['key']; + $keyDetails = openssl_pkey_get_details($res); + $publicKey = $keyDetails['key']; $return = array( 'publicKey' => $publicKey, @@ -68,6 +69,7 @@ class Crypt { ); } else { \OCP\Util::writeLog('Encryption library', 'couldn\'t export users private key, please check your servers openSSL configuration.' . \OCP\User::getUser(), \OCP\Util::ERROR); + \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR); } return $return; @@ -206,13 +208,10 @@ class Crypt { public static function encrypt($plainContent, $iv, $passphrase = '') { if ($encryptedContent = openssl_encrypt($plainContent, 'AES-128-CFB', $passphrase, false, $iv)) { - return $encryptedContent; - } else { - \OCP\Util::writeLog('Encryption library', 'Encryption (symmetric) of content failed', \OCP\Util::ERROR); - + \OCP\Util::writeLog('Encryption library', openssl_error_string(), \OCP\Util::ERROR); return false; } -- GitLab From bf49edde6bbd32fe847b8d56e8fb99c2587d5b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 26 Jun 2013 19:57:28 +0200 Subject: [PATCH 057/216] check item id is set --- 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 122ab3fa030..d1000e7bb9f 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -978,7 +978,7 @@ class Share { // Check if the same owner shared with the user twice // through a group and user share - this is allowed $id = $targets[$row[$column]]; - if ($items[$id]['uid_owner'] == $row['uid_owner']) { + if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) { // Switch to group share type to ensure resharing conditions aren't bypassed if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) { $items[$id]['share_type'] = self::SHARE_TYPE_GROUP; -- GitLab From 5d51118cb2648b37cfcb938e74756588025046cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 26 Jun 2013 20:03:24 +0200 Subject: [PATCH 058/216] fix type of numeric columns --- lib/public/share.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/public/share.php b/lib/public/share.php index d1000e7bb9f..a98cfda2089 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -963,6 +963,30 @@ class Share { $switchedItems = array(); $mounts = array(); while ($row = $result->fetchRow()) { + if (isset($row['id'])) { + $row['id']=(int)$row['id']; + } + if (isset($row['share_type'])) { + $row['share_type']=(int)$row['share_type']; + } + if (isset($row['parent'])) { + $row['parent']=(int)$row['parent']; + } + if (isset($row['file_parent'])) { + $row['file_parent']=(int)$row['file_parent']; + } + if (isset($row['file_source'])) { + $row['file_source']=(int)$row['file_source']; + } + if (isset($row['permissions'])) { + $row['permissions']=(int)$row['permissions']; + } + if (isset($row['storage'])) { + $row['storage']=(int)$row['storage']; + } + if (isset($row['stime'])) { + $row['stime']=(int)$row['stime']; + } // Filter out duplicate group shares for users with unique targets if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { $row['share_type'] = self::SHARE_TYPE_GROUP; -- GitLab From da0caadf4ecbf101bf8ea40007357baf98c8437b Mon Sep 17 00:00:00 2001 From: Roman Geber Date: Wed, 26 Jun 2013 22:51:38 +0200 Subject: [PATCH 059/216] Added file-upload to GIT repo Optimized CSS identifiers --- apps/files/js/file-upload.js | 343 ++++++++++++++++++++++++++++++ apps/files_sharing/css/public.css | 16 +- 2 files changed, 351 insertions(+), 8 deletions(-) create mode 100644 apps/files/js/file-upload.js diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js new file mode 100644 index 00000000000..942a07dfccc --- /dev/null +++ b/apps/files/js/file-upload.js @@ -0,0 +1,343 @@ +$(document).ready(function() { + + file_upload_param = { + dropZone: $('#content'), // restrict dropZone to content div + //singleFileUploads is on by default, so the data.files array will always have length 1 + add: function(e, data) { + + if(data.files[0].type === '' && data.files[0].size == 4096) + { + data.textStatus = 'dirorzero'; + data.errorThrown = t('files','Unable to upload your file as it is a directory or has 0 bytes'); + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + return true; //don't upload this file but go on with next in queue + } + + var totalSize=0; + $.each(data.originalFiles, function(i,file){ + totalSize+=file.size; + }); + + if(totalSize>$('#max_upload').val()){ + data.textStatus = 'notenoughspace'; + data.errorThrown = t('files','Not enough space available'); + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + return false; //don't upload anything + } + + // start the actual file upload + var jqXHR = data.submit(); + + // remember jqXHR to show warning to user when he navigates away but an upload is still in progress + if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') { + var dirName = data.context.data('file'); + if(typeof uploadingFiles[dirName] === 'undefined') { + uploadingFiles[dirName] = {}; + } + uploadingFiles[dirName][data.files[0].name] = jqXHR; + } else { + uploadingFiles[data.files[0].name] = jqXHR; + } + + //show cancel button + if($('html.lte9').length === 0 && data.dataType !== 'iframe') { + $('#uploadprogresswrapper input.stop').show(); + } + }, + /** + * called after the first add, does NOT have the data param + * @param e + */ + start: function(e) { + //IE < 10 does not fire the necessary events for the progress bar. + if($('html.lte9').length > 0) { + return; + } + $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').fadeIn(); + }, + fail: function(e, data) { + if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) { + if (data.textStatus === 'abort') { + $('#notification').text(t('files', 'Upload cancelled.')); + } else { + // HTTP connection problem + $('#notification').text(data.errorThrown); + } + $('#notification').fadeIn(); + //hide notification after 5 sec + setTimeout(function() { + $('#notification').fadeOut(); + }, 5000); + } + delete uploadingFiles[data.files[0].name]; + }, + progress: function(e, data) { + // TODO: show nice progress bar in file row + }, + progressall: function(e, data) { + //IE < 10 does not fire the necessary events for the progress bar. + if($('html.lte9').length > 0) { + return; + } + var progress = (data.loaded/data.total)*100; + $('#uploadprogressbar').progressbar('value',progress); + }, + /** + * called for every successful upload + * @param e + * @param data + */ + done:function(e, data) { + // handle different responses (json or body from iframe for ie) + var response; + if (typeof data.result === 'string') { + response = data.result; + } else { + //fetch response from iframe + response = data.result[0].body.innerText; + } + var result=$.parseJSON(response); + + if(typeof result[0] !== 'undefined' && result[0].status === 'success') { + var file = result[0]; + } else { + data.textStatus = 'servererror'; + data.errorThrown = t('files', result.data.message); + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + } + + var filename = result[0].originalname; + + // delete jqXHR reference + if (typeof data.context !== 'undefined' && data.context.data('type') === 'dir') { + var dirName = data.context.data('file'); + delete uploadingFiles[dirName][filename]; + if ($.assocArraySize(uploadingFiles[dirName]) == 0) { + delete uploadingFiles[dirName]; + } + } else { + delete uploadingFiles[filename]; + } + + }, + /** + * called after last upload + * @param e + * @param data + */ + stop: function(e, data) { + if(data.dataType !== 'iframe') { + $('#uploadprogresswrapper input.stop').hide(); + } + + //IE < 10 does not fire the necessary events for the progress bar. + if($('html.lte9').length > 0) { + return; + } + + $('#uploadprogressbar').progressbar('value',100); + $('#uploadprogressbar').fadeOut(); + } + } + var file_upload_handler = function() { + $('#file_upload_start').fileupload(file_upload_param); + }; + + + + if ( document.getElementById('data-upload-form') ) { + $(file_upload_handler); + } + $.assocArraySize = function(obj) { + // http://stackoverflow.com/a/6700/11236 + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) size++; + } + return size; + }; + + // warn user not to leave the page while upload is in progress + $(window).bind('beforeunload', function(e) { + if ($.assocArraySize(uploadingFiles) > 0) + return t('files','File upload is in progress. Leaving the page now will cancel the upload.'); + }); + + //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used) + if(navigator.userAgent.search(/konqueror/i)==-1){ + $('#file_upload_start').attr('multiple','multiple') + } + + //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder + var crumb=$('div.crumb').first(); + while($('div.controls').height()>40 && crumb.next('div.crumb').length>0){ + crumb.children('a').text('...'); + crumb=crumb.next('div.crumb'); + } + //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent + var crumb=$('div.crumb').first(); + var next=crumb.next('div.crumb'); + while($('div.controls').height()>40 && next.next('div.crumb').length>0){ + crumb.remove(); + crumb=next; + next=crumb.next('div.crumb'); + } + //still not enough, start shorting down the current folder name + var crumb=$('div.crumb>a').last(); + while($('div.controls').height()>40 && crumb.text().length>6){ + var text=crumb.text() + text=text.substr(0,text.length-6)+'...'; + crumb.text(text); + } + + $(document).click(function(){ + $('#new>ul').hide(); + $('#new').removeClass('active'); + $('#new li').each(function(i,element){ + if($(element).children('p').length==0){ + $(element).children('form').remove(); + $(element).append('

'+$(element).data('text')+'

'); + } + }); + }); + $('#new li').click(function(){ + if($(this).children('p').length==0){ + return; + } + + $('#new li').each(function(i,element){ + if($(element).children('p').length==0){ + $(element).children('form').remove(); + $(element).append('

'+$(element).data('text')+'

'); + } + }); + + var type=$(this).data('type'); + var text=$(this).children('p').text(); + $(this).data('text',text); + $(this).children('p').remove(); + var form=$('
'); + var input=$(''); + form.append(input); + $(this).append(form); + input.focus(); + form.submit(function(event){ + event.stopPropagation(); + event.preventDefault(); + var newname=input.val(); + if(type == 'web' && newname.length == 0) { + OC.Notification.show(t('files', 'URL cannot be empty.')); + return false; + } else if (type != 'web' && !Files.isFileNameValid(newname)) { + return false; + } else if( type == 'folder' && $('#dir').val() == '/' && newname == 'Shared') { + OC.Notification.show(t('files','Invalid folder name. Usage of \'Shared\' is reserved by ownCloud')); + return false; + } + if (FileList.lastAction) { + FileList.lastAction(); + } + var name = getUniqueName(newname); + if (newname != name) { + FileList.checkName(name, newname, true); + var hidden = true; + } else { + var hidden = false; + } + switch(type){ + case 'file': + $.post( + OC.filePath('files','ajax','newfile.php'), + {dir:$('#dir').val(),filename:name}, + function(result){ + if (result.status == 'success') { + var date=new Date(); + FileList.addFile(name,0,date,false,hidden); + var tr=$('tr').filterAttr('data-file',name); + tr.attr('data-mime',result.data.mime); + tr.attr('data-id', result.data.id); + getMimeIcon(result.data.mime,function(path){ + tr.find('td.filename').attr('style','background-image:url('+path+')'); + }); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } + } + ); + break; + case 'folder': + $.post( + OC.filePath('files','ajax','newfolder.php'), + {dir:$('#dir').val(),foldername:name}, + function(result){ + if (result.status == 'success') { + var date=new Date(); + FileList.addDir(name,0,date,hidden); + var tr=$('tr').filterAttr('data-file',name); + tr.attr('data-id', result.data.id); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } + } + ); + break; + case 'web': + if(name.substr(0,8)!='https://' && name.substr(0,7)!='http://'){ + name='http://'+name; + } + var localName=name; + if(localName.substr(localName.length-1,1)=='/'){//strip / + localName=localName.substr(0,localName.length-1) + } + if(localName.indexOf('/')){//use last part of url + localName=localName.split('/').pop(); + } else { //or the domain + localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); + } + localName = getUniqueName(localName); + //IE < 10 does not fire the necessary events for the progress bar. + if($('html.lte9').length > 0) { + } else { + $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').fadeIn(); + } + + var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); + eventSource.listen('progress',function(progress){ + //IE < 10 does not fire the necessary events for the progress bar. + if($('html.lte9').length > 0) { + } else { + $('#uploadprogressbar').progressbar('value',progress); + } + }); + eventSource.listen('success',function(data){ + var mime=data.mime; + var size=data.size; + var id=data.id; + $('#uploadprogressbar').fadeOut(); + var date=new Date(); + FileList.addFile(localName,size,date,false,hidden); + var tr=$('tr').filterAttr('data-file',localName); + tr.data('mime',mime).data('id',id); + tr.attr('data-id', id); + getMimeIcon(mime,function(path){ + tr.find('td.filename').attr('style','background-image:url('+path+')'); + }); + }); + eventSource.listen('error',function(error){ + $('#uploadprogressbar').fadeOut(); + alert(error); + }); + break; + } + var li=form.parent(); + form.remove(); + li.append('

'+li.data('text')+'

'); + $('#new>a').click(); + }); + }); +}); diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 68549d14fe1..71133145c87 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -15,13 +15,13 @@ body { padding:.5em; } -#header #details { +#details { color:#fff; - float: left; + float: left; } -#header #public_upload, -#header #download { +#public_upload, +#download { font-weight:700; margin: 0 0.4em 0 2em; padding: 0 5px; @@ -30,12 +30,12 @@ body { } -#header #public_upload { +#public_upload { margin-left: 0.3em; } -#header #public_upload img, -#header #download img { +#public_upload img, +#download img { padding-left:.1em; padding-right:.3em; vertical-align:text-bottom; @@ -107,7 +107,7 @@ thead{ width: 100% !important; } -.header-right #download span { +#download span { position: relative; bottom: 3px; } -- GitLab From 45c897acf34151672d68ee767ff15ab010676335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 27 Jun 2013 13:13:49 +0200 Subject: [PATCH 060/216] one if less --- lib/db.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/db.php b/lib/db.php index 984c2bcf149..fecc622d963 100644 --- a/lib/db.php +++ b/lib/db.php @@ -326,6 +326,7 @@ class OC_DB { * @param string $query Query string * @param int $limit * @param int $offset + * @param bool $isManipulation * @return MDB2_Statement_Common prepared SQL query * * SQL query via MDB2 prepare(), needs to be execute()'d! @@ -393,11 +394,7 @@ class OC_DB { throw new DatabaseException($e->getMessage(), $query); } // differentiate between query and manipulation - if ($isManipulation) { - $result=new PDOStatementWrapper($result, true); - } else { - $result=new PDOStatementWrapper($result, false); - } + $result = new PDOStatementWrapper($result, $isManipulation); } if ((is_null($limit) || $limit == -1) and self::$cachingEnabled ) { $type = OC_Config::getValue( "dbtype", "sqlite" ); -- GitLab From c4aef892788ced15812cc31abcf34c085b66ce5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 27 Jun 2013 14:09:22 +0200 Subject: [PATCH 061/216] introduce pre-disable-app hook and use it for the encryption app to reset migration status if the app was disabled --- apps/files_encryption/appinfo/app.php | 3 +++ apps/files_encryption/hooks/hooks.php | 13 +++++++++++++ apps/files_encryption/lib/helper.php | 9 +++++++++ lib/app.php | 1 + 4 files changed, 26 insertions(+) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index d97811bb791..ca3f2554e5e 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -22,6 +22,9 @@ if (!OC_Config::getValue('maintenance', false)) { // Filesystem related hooks OCA\Encryption\Helper::registerFilesystemHooks(); + // App manager related hooks + OCA\Encryption\Helper::registerAppHooks(); + stream_wrapper_register('crypt', 'OCA\Encryption\Stream'); // check if we are logged in diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index e39e068cc5d..09153918940 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -543,4 +543,17 @@ class Hooks { \OC_FileProxy::$enabled = $proxyStatus; } + + /** + * set migration status back to '0' so that all new files get encrypted + * if the app gets enabled again + * @param array $params contains the app ID + */ + public static function preDisable($params) { + if ($params['app'] === 'files_encryption') { + $query = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); + $query->execute(); + } + } + } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index a22c139c503..b2045bfcea8 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -62,6 +62,15 @@ class Helper { \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); } + /** + * @brief register filesystem related hooks + * + */ + public static function registerAppHooks() { + + \OCP\Util::connectHook('OC_App', 'pre_disable', 'OCA\Encryption\Hooks', 'preDisable'); + } + /** * @brief setup user for files_encryption * diff --git a/lib/app.php b/lib/app.php index f974dd9f594..f9b1c5ca7b5 100644 --- a/lib/app.php +++ b/lib/app.php @@ -259,6 +259,7 @@ class OC_App{ */ public static function disable( $app ) { // check if app is a shipped app or not. if not delete + \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app)); OC_Appconfig::setValue( $app, 'enabled', 'no' ); // check if app is a shipped app or not. if not delete -- GitLab From 2e6ebe1ab4e1ae6d0fb730e833c09ac4dbbb895c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 27 Jun 2013 14:14:25 +0200 Subject: [PATCH 062/216] fix function documentation --- apps/files_encryption/lib/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index b2045bfcea8..0d30dd8e7b5 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -63,7 +63,7 @@ class Helper { } /** - * @brief register filesystem related hooks + * @brief register app management related hooks * */ public static function registerAppHooks() { -- GitLab From 2eaad589221a9a189cece52390873f9bd27f113b Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 20:10:45 +0200 Subject: [PATCH 063/216] Make the object drive the logging backend This is the other way around then it was. --- lib/legacy/log.php | 17 +++++++++++------ lib/log.php | 12 +++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/legacy/log.php b/lib/legacy/log.php index 4e6642b6a2f..a316051d5af 100644 --- a/lib/legacy/log.php +++ b/lib/legacy/log.php @@ -23,6 +23,14 @@ class OC_Log { const ERROR=3; const FATAL=4; + static private $level_funcs = array( + self::DEBUG => 'debug', + self::INFO => 'info', + self::WARN => 'warning', + self::ERROR => 'error', + self::FATAL => 'emergency', + ); + static public $enabled = true; static protected $class = null; @@ -34,12 +42,9 @@ class OC_Log { */ public static function write($app, $message, $level) { if (self::$enabled) { - if (!self::$class) { - self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud')); - call_user_func(array(self::$class, 'init')); - } - $log_class=self::$class; - $log_class::write($app, $message, $level); + $context = array('app' => $app); + $func = array(self::$object, self::$level_funcs[$level]); + call_user_func($func, $message, $context); } } diff --git a/lib/log.php b/lib/log.php index 442872af9c4..2e26ccad2da 100644 --- a/lib/log.php +++ b/lib/log.php @@ -19,10 +19,6 @@ namespace OC; */ class Log { - const NOTICE=5; - const CRITICAL=6; - const ALERT=7; - /** * System is unusable. * @@ -114,6 +110,11 @@ class Log { $this->log(\OC_Log::DEBUG, $message, $context); } + public function __construct() { + $this->log_class = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); + call_user_func(array($this->log_class, 'init')); + } + /** * Logs with an arbitrary level. * @@ -127,6 +128,7 @@ class Log { } else { $app = 'no app in context'; } - \OC_Log::write($app, $message, $level); + $log_class=$this->log_class; + $log_class::write($app, $message, $level); } } -- GitLab From 64f16f1db1f05e032080c885ebf91f38f659e62f Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 21:57:59 +0200 Subject: [PATCH 064/216] Fix stupid namespace separator --- lib/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config.php b/lib/config.php index e204de0baee..19d58c90443 100644 --- a/lib/config.php +++ b/lib/config.php @@ -166,6 +166,6 @@ class Config { } // Prevent others from reading the config @chmod($this->configFilename, 0640); - OC_Util::clearOpcodeCache(); + \OC_Util::clearOpcodeCache(); } } -- GitLab From fb80cbd4997625c2d87457d5ba0b908206474d4d Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 22:01:52 +0200 Subject: [PATCH 065/216] Fix review points --- lib/log.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/log.php b/lib/log.php index 2e26ccad2da..8c157d003cf 100644 --- a/lib/log.php +++ b/lib/log.php @@ -19,6 +19,8 @@ namespace OC; */ class Log { + private $logClass; + /** * System is unusable. * @@ -111,8 +113,8 @@ class Log { } public function __construct() { - $this->log_class = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); - call_user_func(array($this->log_class, 'init')); + $this->logClass = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud')); + call_user_func(array($this->logClass, 'init')); } /** @@ -122,13 +124,13 @@ class Log { * @param string $message * @param array $context */ - protected function log($level, $message, array $context = array()) { + public function log($level, $message, array $context = array()) { if (isset($context['app'])) { $app = $context['app']; } else { $app = 'no app in context'; } - $log_class=$this->log_class; - $log_class::write($app, $message, $level); + $logClass=$this->logClass; + $logClass::write($app, $message, $level); } } -- GitLab From ae2b3732de4eeced50a71f9074d0b5dadf625edd Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 22:23:53 +0200 Subject: [PATCH 066/216] Use file_exists to fix the unittests --- lib/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config.php b/lib/config.php index 19d58c90443..7ccbc050508 100644 --- a/lib/config.php +++ b/lib/config.php @@ -129,7 +129,7 @@ class Config { } // Include file and merge config foreach ($configFiles as $file) { - if (!is_file($file)) { + if (!file_exists($file)) { continue; } unset($CONFIG); -- GitLab From 194b61b4c507e58eab0750ab40ed6eb6f085c06a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 22:24:17 +0200 Subject: [PATCH 067/216] Revert "Can't determine if debug mode is defined until we read the config" This reverts commit 969e43c87b7afb6184846fe27849167c9c6f5eab. --- lib/config.php | 9 ++++++--- lib/legacy/config.php | 2 +- tests/lib/config.php | 18 +++++++++--------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/config.php b/lib/config.php index 7ccbc050508..adf70ac841a 100644 --- a/lib/config.php +++ b/lib/config.php @@ -47,8 +47,11 @@ class Config { protected $configDir; protected $configFilename; - public function __construct($configDir) { + protected $debugMode; + + public function __construct($configDir, $debugMode) { $this->configDir = $configDir; + $this->debugMode = $debugMode; $this->configFilename = $this->configDir.'config.php'; $this->readData(); } @@ -149,7 +152,7 @@ class Config { private function writeData() { // Create a php file ... $content = "debugMode) { $content .= "define('DEBUG',true);\n"; } $content .= '$CONFIG = '; @@ -164,7 +167,7 @@ class Config { 'You can usually fix this by giving the webserver user write access' .' to the config directory in ownCloud'); } - // Prevent others from reading the config + // Prevent others not to read the config @chmod($this->configFilename, 0640); \OC_Util::clearOpcodeCache(); } diff --git a/lib/legacy/config.php b/lib/legacy/config.php index f68d7c31b25..635f0af66f8 100644 --- a/lib/legacy/config.php +++ b/lib/legacy/config.php @@ -38,7 +38,7 @@ * This class is responsible for reading and writing config.php, the very basic * configuration file of ownCloud. */ -OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/'); +OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/', defined('DEBUG') && DEBUG); class OC_Config { public static $object; diff --git a/tests/lib/config.php b/tests/lib/config.php index acc2a536fd0..e22bf3fd7de 100644 --- a/tests/lib/config.php +++ b/tests/lib/config.php @@ -13,25 +13,25 @@ class Test_Config extends PHPUnit_Framework_TestCase { public function testReadData() { - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $this->assertAttributeEquals(array(), 'cache', $config); file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $this->assertAttributeEquals(array('foo'=>'bar'), 'cache', $config); } public function testGetKeys() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $this->assertEquals(array('foo'), $config->getKeys()); } public function testGetValue() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $this->assertEquals('bar', $config->getValue('foo')); $this->assertEquals(null, $config->getValue('bar')); $this->assertEquals('moo', $config->getValue('bar', 'moo')); @@ -40,7 +40,7 @@ class Test_Config extends PHPUnit_Framework_TestCase { public function testSetValue() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $config->setValue('foo', 'moo'); $this->assertAttributeEquals(array('foo'=>'moo'), 'cache', $config); $content = file_get_contents(self::CONFIG_FILE); @@ -69,7 +69,7 @@ EOL public function testDeleteKey() { file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, false); $config->deleteKey('foo'); $this->assertAttributeEquals(array(), 'cache', $config); $content = file_get_contents(self::CONFIG_FILE); @@ -84,11 +84,11 @@ EOL public function testSavingDebugMode() { - define('DEBUG',true); file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR); + $config = new OC\Config(self::CONFIG_DIR, true); $config->deleteKey('foo'); // change something so we save to the config file $this->assertAttributeEquals(array(), 'cache', $config); + $this->assertAttributeEquals(true, 'debug_mode', $config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<setValue('foo', 'bar'); } catch (\OC\HintException $e) { -- GitLab From 12976fb2e1f6a4d6a054ba2b620f0e7707ce2c69 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Jun 2013 22:50:28 +0200 Subject: [PATCH 068/216] Set debugMode after reading the config file --- lib/config.php | 9 ++++++-- lib/legacy/config.php | 2 +- tests/lib/config.php | 50 +++++++++++++++++++------------------------ 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/lib/config.php b/lib/config.php index adf70ac841a..afd74c56b40 100644 --- a/lib/config.php +++ b/lib/config.php @@ -49,12 +49,17 @@ class Config { protected $debugMode; - public function __construct($configDir, $debugMode) { + public function __construct($configDir) { $this->configDir = $configDir; - $this->debugMode = $debugMode; $this->configFilename = $this->configDir.'config.php'; $this->readData(); + $this->setDebugMode(defined('DEBUG') && DEBUG); } + + public function setDebugMode($enable) { + $this->debugMode = $enable; + } + /** * @brief Lists all available config keys * @return array with key names diff --git a/lib/legacy/config.php b/lib/legacy/config.php index 635f0af66f8..f68d7c31b25 100644 --- a/lib/legacy/config.php +++ b/lib/legacy/config.php @@ -38,7 +38,7 @@ * This class is responsible for reading and writing config.php, the very basic * configuration file of ownCloud. */ -OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/', defined('DEBUG') && DEBUG); +OC_Config::$object = new \OC\Config(OC::$SERVERROOT.'/config/'); class OC_Config { public static $object; diff --git a/tests/lib/config.php b/tests/lib/config.php index e22bf3fd7de..8f52cf4ae76 100644 --- a/tests/lib/config.php +++ b/tests/lib/config.php @@ -11,38 +11,35 @@ class Test_Config extends PHPUnit_Framework_TestCase { const CONFIG_DIR = 'static://'; const TESTCONTENT = '"bar");'; + function setUp() { + file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); + $this->config = new OC\Config(self::CONFIG_DIR); + } + public function testReadData() { - $config = new OC\Config(self::CONFIG_DIR, false); + $config = new OC\Config('/non-existing'); $this->assertAttributeEquals(array(), 'cache', $config); - file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); - $this->assertAttributeEquals(array('foo'=>'bar'), 'cache', $config); + $this->assertAttributeEquals(array('foo'=>'bar'), 'cache', $this->config); } public function testGetKeys() { - file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); - $this->assertEquals(array('foo'), $config->getKeys()); + $this->assertEquals(array('foo'), $this->config->getKeys()); } public function testGetValue() { - file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); - $this->assertEquals('bar', $config->getValue('foo')); - $this->assertEquals(null, $config->getValue('bar')); - $this->assertEquals('moo', $config->getValue('bar', 'moo')); + $this->assertEquals('bar', $this->config->getValue('foo')); + $this->assertEquals(null, $this->config->getValue('bar')); + $this->assertEquals('moo', $this->config->getValue('bar', 'moo')); } public function testSetValue() { - file_put_contents(self::CONFIG_FILE, self::TESTCONTENT); - $config = new OC\Config(self::CONFIG_DIR, false); - $config->setValue('foo', 'moo'); - $this->assertAttributeEquals(array('foo'=>'moo'), 'cache', $config); + $this->config->setValue('foo', 'moo'); + $this->assertAttributeEquals(array('foo'=>'moo'), 'cache', $this->config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<setValue('bar', 'red'); - $this->assertAttributeEquals(array('foo'=>'moo', 'bar'=>'red'), 'cache', $config); + $this->config->setValue('bar', 'red'); + $this->assertAttributeEquals(array('foo'=>'moo', 'bar'=>'red'), 'cache', $this->config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<deleteKey('foo'); - $this->assertAttributeEquals(array(), 'cache', $config); + $this->config->deleteKey('foo'); + $this->assertAttributeEquals(array(), 'cache', $this->config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<deleteKey('foo'); // change something so we save to the config file - $this->assertAttributeEquals(array(), 'cache', $config); - $this->assertAttributeEquals(true, 'debug_mode', $config); + $this->config->setDebugMode(true); + $this->config->deleteKey('foo'); // change something so we save to the config file + $this->assertAttributeEquals(array(), 'cache', $this->config); + $this->assertAttributeEquals(true, 'debugMode', $this->config); $content = file_get_contents(self::CONFIG_FILE); $this->assertEquals(<<setValue('foo', 'bar'); } catch (\OC\HintException $e) { -- GitLab From de93b21505e1281c529cc2d1dc350b62bb387cca Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 27 Jun 2013 23:14:32 +0200 Subject: [PATCH 069/216] missing $ --- lib/legacy/log.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/legacy/log.php b/lib/legacy/log.php index a316051d5af..7802ead2412 100644 --- a/lib/legacy/log.php +++ b/lib/legacy/log.php @@ -38,7 +38,7 @@ class OC_Log { * write a message in the log * @param string $app * @param string $message - * @param int level + * @param int $level */ public static function write($app, $message, $level) { if (self::$enabled) { -- GitLab From 1edf01d09f12843528be3137d6b6595edb9e0ec4 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 28 Jun 2013 11:15:08 +0200 Subject: [PATCH 070/216] Fix usage of non existent consts --- lib/log.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/log.php b/lib/log.php index 8c157d003cf..e0b9fe3c696 100644 --- a/lib/log.php +++ b/lib/log.php @@ -41,7 +41,7 @@ class Log { * @param array $context */ public function alert($message, array $context = array()) { - $this->log(self::ALERT, $message, $context); + $this->log(\OC_Log::ERROR, $message, $context); } /** @@ -53,7 +53,7 @@ class Log { * @param array $context */ public function critical($message, array $context = array()) { - $this->log(self::CRITICAL, $message, $context); + $this->log(\OC_Log::ERROR, $message, $context); } /** @@ -87,7 +87,7 @@ class Log { * @param array $context */ public function notice($message, array $context = array()) { - $this->log(self::NOTICE, $message, $context); + $this->log(\OC_Log::INFO, $message, $context); } /** -- GitLab From 7f3ddd43411c9b5b1b26d42751a6dbe416ab5499 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Mon, 24 Jun 2013 22:38:05 +0200 Subject: [PATCH 071/216] Skip Test_Archive_TAR in php 5.5 for now --- tests/lib/archive/tar.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/lib/archive/tar.php b/tests/lib/archive/tar.php index e66a8740879..d831487b16f 100644 --- a/tests/lib/archive/tar.php +++ b/tests/lib/archive/tar.php @@ -10,6 +10,12 @@ require_once 'archive.php'; if (!OC_Util::runningOnWindows()) { class Test_Archive_TAR extends Test_Archive { + public function setUp() { + if (floatval(phpversion())>=5.5) { + $this->markTestSkipped('php 5.5 changed unpack function.'); + return; + } + } protected function getExisting() { $dir = OC::$SERVERROOT . '/tests/data'; return new OC_Archive_TAR($dir . '/data.tar.gz'); -- GitLab From 42cb77b9821eb032afce7e1b7f233c9ffcd0be41 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 28 Jun 2013 13:24:24 +0200 Subject: [PATCH 072/216] TimedJob: make PhpUnit happy with asserts --- tests/lib/backgroundjob/timedjob.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/lib/backgroundjob/timedjob.php b/tests/lib/backgroundjob/timedjob.php index 0af933afef8..f3c3eb4d0dd 100644 --- a/tests/lib/backgroundjob/timedjob.php +++ b/tests/lib/backgroundjob/timedjob.php @@ -41,6 +41,7 @@ class TimedJob extends \PHPUnit_Framework_TestCase { $this->fail("job should have run"); } catch (JobRun $e) { } + $this->assertTrue(true); } public function testShouldNotRunWithinInterval() { @@ -50,6 +51,7 @@ class TimedJob extends \PHPUnit_Framework_TestCase { } catch (JobRun $e) { $this->fail("job should not have run"); } + $this->assertTrue(true); } public function testShouldNotTwice() { @@ -64,5 +66,6 @@ class TimedJob extends \PHPUnit_Framework_TestCase { $this->fail("job should not have run the second time"); } } + $this->assertTrue(true); } } -- GitLab From 3abeb252d8b8777bce5ae2ec33d1234a77558b98 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 28 Jun 2013 14:37:52 +0200 Subject: [PATCH 073/216] make PHPUnit happy and add asserts --- tests/lib/session/session.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lib/session/session.php b/tests/lib/session/session.php index 72dee44e7cb..9ce11274c84 100644 --- a/tests/lib/session/session.php +++ b/tests/lib/session/session.php @@ -44,7 +44,9 @@ abstract class Session extends \PHPUnit_Framework_TestCase { } public function testRemoveNonExisting() { + $this->assertFalse($this->instance->exists('foo')); $this->instance->remove('foo'); + $this->assertFalse($this->instance->exists('foo')); } public function testNotExistsAfterClear() { -- GitLab From de66861ef1a440837cc6161eaea21fd3e401570f Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 28 Jun 2013 15:13:57 +0200 Subject: [PATCH 074/216] make phpunit happy - adding asserts --- tests/lib/hooks/basicemitter.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/lib/hooks/basicemitter.php b/tests/lib/hooks/basicemitter.php index f48dc53c563..0eae730d030 100644 --- a/tests/lib/hooks/basicemitter.php +++ b/tests/lib/hooks/basicemitter.php @@ -155,6 +155,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Test', 'test', $listener); $this->emitter->removeListener('Test', 'test', $listener); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } public function testRemoveWildcardListener() { @@ -168,6 +170,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Test', 'test', $listener2); $this->emitter->removeListener('Test', 'test'); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } public function testRemoveWildcardMethod() { @@ -179,6 +183,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->removeListener('Test', null, $listener); $this->emitter->emitEvent('Test', 'test'); $this->emitter->emitEvent('Test', 'foo'); + + $this->assertTrue(true); } public function testRemoveWildcardScope() { @@ -190,6 +196,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->removeListener(null, 'test', $listener); $this->emitter->emitEvent('Test', 'test'); $this->emitter->emitEvent('Bar', 'test'); + + $this->assertTrue(true); } public function testRemoveWildcardScopeAndMethod() { @@ -203,6 +211,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->emitEvent('Test', 'test'); $this->emitter->emitEvent('Test', 'foo'); $this->emitter->emitEvent('Bar', 'foo'); + + $this->assertTrue(true); } /** @@ -219,6 +229,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Test', 'test', $listener2); $this->emitter->removeListener('Test', 'test', $listener1); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } /** @@ -232,6 +244,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Test', 'foo', $listener); $this->emitter->removeListener('Test', 'foo', $listener); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } /** @@ -245,6 +259,8 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Bar', 'test', $listener); $this->emitter->removeListener('Bar', 'test', $listener); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } /** @@ -257,5 +273,7 @@ class BasicEmitter extends \PHPUnit_Framework_TestCase { $this->emitter->listen('Test', 'test', $listener); $this->emitter->removeListener('Bar', 'test', $listener); $this->emitter->emitEvent('Test', 'test'); + + $this->assertTrue(true); } } -- GitLab From 3b91ce695f784fc68d3bdfff0fe5ed0c37a89aff Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 28 Jun 2013 15:17:54 +0200 Subject: [PATCH 075/216] session_life_time -> session_lifetime default session_lifetime is 24hrs recreation of session is triggered at 50% of the session life time --- config/config.sample.php | 2 +- lib/base.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 9254365e3e2..dfa29f329c4 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -146,7 +146,7 @@ $CONFIG = array( "remember_login_cookie_lifetime" => 60*60*24*15, /* Life time of a session after inactivity */ -"session_life_time" => 60 * 60 * 12, +"session_lifetime" => 60 * 60 * 24, /* Custom CSP policy, changing this will overwrite the standard policy */ "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *", diff --git a/lib/base.php b/lib/base.php index 7097a376d6e..af54f439155 100644 --- a/lib/base.php +++ b/lib/base.php @@ -315,7 +315,7 @@ class OC { // regenerate session id periodically to avoid session fixation if (!self::$session->exists('SID_CREATED')) { self::$session->set('SID_CREATED', time()); - } else if (time() - self::$session->get('SID_CREATED') > $sessionLifeTime) { + } else if (time() - self::$session->get('SID_CREATED') > $sessionLifeTime / 2) { session_regenerate_id(true); self::$session->set('SID_CREATED', time()); } @@ -337,7 +337,7 @@ class OC { * @return int */ private static function getSessionLifeTime() { - return OC_Config::getValue('session_life_time', 60 * 60 * 12); + return OC_Config::getValue('session_lifetime', 60 * 60 * 24); } public static function getRouter() { -- GitLab From 125f9f4221d4c9c1d4ae653758f2bfa6b92ed9c1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 28 Jun 2013 15:34:25 +0200 Subject: [PATCH 076/216] move storage wrappers to their own namespace --- lib/files/storage/{ => wrapper}/wrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename lib/files/storage/{ => wrapper}/wrapper.php (99%) diff --git a/lib/files/storage/wrapper.php b/lib/files/storage/wrapper/wrapper.php similarity index 99% rename from lib/files/storage/wrapper.php rename to lib/files/storage/wrapper/wrapper.php index 78892a564c4..802c8ea0492 100644 --- a/lib/files/storage/wrapper.php +++ b/lib/files/storage/wrapper/wrapper.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -namespace OC\Files\Storage; +namespace OC\Files\Storage\Wrapper; class Wrapper implements Storage { /** -- GitLab From 6ad7a0336f58685f18454fd622395cf25d6908c1 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 26 Jun 2013 21:40:31 +0200 Subject: [PATCH 077/216] Oracle doesn't know & as bitwise AND Conflicts: lib/public/share.php --- lib/public/share.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index f40cd0d77fa..304cb7239eb 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -662,13 +662,15 @@ class Share { // Remove the permissions for all reshares of this item if (!empty($ids)) { $ids = "'".implode("','", $ids)."'"; - // the binary operator & works on sqlite, mysql, postgresql and mssql - $sql = 'UPDATE `*PREFIX*share` SET `permissions` = `permissions` & ? WHERE `id` IN ('.$ids.')'; - if (\OC_Config::getValue('dbtype', 'sqlite') === 'oci') { - // guess which dbms does not handle & and uses a function for this - $sql = 'UPDATE `*PREFIX*share` SET `permissions` = BITAND(`permissions`,?) WHERE `id` IN ('.$ids.')'; + // TODO this should be done with Doctrine platform objects + if (\OC_Config::getValue( "dbtype") === 'oci') { + $andOp = 'BITAND(`permissions`, ?)'; + } else { + $andOp = '`permissions` & ?'; } - \OC_DB::executeAudited($sql, array($permissions)); + $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp + .' WHERE `id` IN ('.$ids.')'); + $query->execute(array($permissions)); } } } -- GitLab From f726de3cabfd67b6aa2ab42ad27eb2fd90e84e27 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Fri, 28 Jun 2013 16:49:25 +0200 Subject: [PATCH 078/216] for now we disable public upload in case encryption is enabled --- apps/files_sharing/public.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index fa8c25fc98d..ef86013b3e7 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -147,7 +147,11 @@ if (isset($path)) { $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('fileTarget', basename($linkItem['file_target'])); $tmpl->assign('dirToken', $linkItem['token']); - $tmpl->assign('allowPublicUploadEnabled', (($linkItem['permissions'] & OCP\PERMISSION_CREATE) ? true : false )); + $allowPublicUploadEnabled = (($linkItem['permissions'] & OCP\PERMISSION_CREATE) ? true : false ); + if (\OCP\App::isEnabled('files_encryption')) { + $allowPublicUploadEnabled = false; + } + $tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -- GitLab From 8ca0a957add3b01efa5bed3762823fe9449414cf Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 28 Jun 2013 17:25:10 +0200 Subject: [PATCH 079/216] Allow setting defaults and requirements for the api route --- lib/api.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/api.php b/lib/api.php index fc76836995b..31f3f968d9b 100644 --- a/lib/api.php +++ b/lib/api.php @@ -67,6 +67,8 @@ class OC_API { OC::getRouter()->useCollection('ocs'); OC::getRouter()->create($name, $url) ->method($method) + ->defaults($defaults) + ->requirements($requirements) ->action('OC_API', 'call'); self::$actions[$name] = array(); } -- GitLab From 22d759964f120395cae67319e3d1e03f7ae4006b Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 28 Jun 2013 17:25:36 +0200 Subject: [PATCH 080/216] Use raw PathInfo for matching urls --- ocs/v1.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocs/v1.php b/ocs/v1.php index af83a56ff14..1c7d1c89768 100644 --- a/ocs/v1.php +++ b/ocs/v1.php @@ -26,7 +26,7 @@ use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; try { - OC::getRouter()->match('/ocs'.$_SERVER['PATH_INFO']); + OC::getRouter()->match('/ocs'.OC_Request::getRawPathInfo()); } catch (ResourceNotFoundException $e) { OC_OCS::notFound(); } catch (MethodNotAllowedException $e) { -- GitLab From a7c70915d592cd3cc06c6dc86ba3d2707d000871 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 28 Jun 2013 18:18:12 +0200 Subject: [PATCH 081/216] fix storage wrapper namespaces --- lib/files/storage/wrapper/wrapper.php | 2 +- tests/lib/files/mount/mount.php | 4 ++-- tests/lib/files/storage/wrapper.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/storage/wrapper/wrapper.php b/lib/files/storage/wrapper/wrapper.php index 802c8ea0492..4feb0520f12 100644 --- a/lib/files/storage/wrapper/wrapper.php +++ b/lib/files/storage/wrapper/wrapper.php @@ -8,7 +8,7 @@ namespace OC\Files\Storage\Wrapper; -class Wrapper implements Storage { +class Wrapper implements \OC\Files\Storage\Storage { /** * @var \OC\Files\Storage\Storage $storage */ diff --git a/tests/lib/files/mount/mount.php b/tests/lib/files/mount/mount.php index aa98db856f4..b057204ad35 100644 --- a/tests/lib/files/mount/mount.php +++ b/tests/lib/files/mount/mount.php @@ -10,7 +10,7 @@ namespace Test\Files\Mount; use OC\Files\Storage\Loader; -use OC\Files\Storage\Wrapper; +use OC\Files\Storage\Wrapper\Wrapper; class Mount extends \PHPUnit_Framework_TestCase { public function testFromStorageObject() { @@ -41,6 +41,6 @@ class Mount extends \PHPUnit_Framework_TestCase { ->disableOriginalConstructor() ->getMock(); $mount = new \OC\Files\Mount\Mount($storage, '/foo', array(), $loader); - $this->assertInstanceOf('\OC\Files\Storage\Wrapper', $mount->getStorage()); + $this->assertInstanceOf('\OC\Files\Storage\Wrapper\Wrapper', $mount->getStorage()); } } diff --git a/tests/lib/files/storage/wrapper.php b/tests/lib/files/storage/wrapper.php index 8452949a723..2794a0a6263 100644 --- a/tests/lib/files/storage/wrapper.php +++ b/tests/lib/files/storage/wrapper.php @@ -17,7 +17,7 @@ class Wrapper extends Storage { public function setUp() { $this->tmpDir = \OC_Helper::tmpFolder(); $storage = new \OC\Files\Storage\Local(array('datadir' => $this->tmpDir)); - $this->instance = new \OC\Files\Storage\Wrapper(array('storage' => $storage)); + $this->instance = new \OC\Files\Storage\Wrapper\Wrapper(array('storage' => $storage)); } public function tearDown() { -- GitLab From 156e72a0c465bc70f079933a6c5b376ca6552caa Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 28 Jun 2013 19:41:28 +0200 Subject: [PATCH 082/216] add option to clear the files in the static streamwrapper --- lib/files/stream/staticstream.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/files/stream/staticstream.php b/lib/files/stream/staticstream.php index 7725a6a5a04..1e3879a4e82 100644 --- a/lib/files/stream/staticstream.php +++ b/lib/files/stream/staticstream.php @@ -26,6 +26,10 @@ class StaticStream { public function stream_flush() { } + public static function clear() { + self::$data = array(); + } + public function stream_open($path, $mode, $options, &$opened_path) { switch ($mode[0]) { case 'r': -- GitLab From dc0ebe90077caeb67346ab96950f7305737a9de6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 28 Jun 2013 19:54:16 +0200 Subject: [PATCH 083/216] fix is_file and is_dir for the static streamwrapper --- lib/files/stream/staticstream.php | 51 ++++--------------------------- 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/lib/files/stream/staticstream.php b/lib/files/stream/staticstream.php index 1e3879a4e82..45b1a7a81f8 100644 --- a/lib/files/stream/staticstream.php +++ b/lib/files/stream/staticstream.php @@ -9,6 +9,8 @@ namespace OC\Files\Stream; class StaticStream { + const MODE_FILE = 0100000; + public $context; protected static $data = array(); @@ -98,36 +100,7 @@ class StaticStream { } 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, - ); + return $this->url_stat($this->path); } public function stream_tell() { @@ -161,34 +134,22 @@ class StaticStream { if (isset(self::$data[$path])) { $size = strlen(self::$data[$path]); $time = time(); - return array( - 0 => 0, + $data = array( 'dev' => 0, - 1 => 0, 'ino' => 0, - 2 => 0777, - 'mode' => 0777, - 3 => 1, + 'mode' => self::MODE_FILE | 0777, '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 array_values($data) + $data; } return false; } -- GitLab From a0d83771094df4d3a7d27ee72b9abb4a6854b604 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 28 Jun 2013 19:59:04 +0200 Subject: [PATCH 084/216] better unit tests for static stream wrapper --- tests/lib/files/stream/staticstream.php | 68 +++++++++++++++++++++++++ tests/lib/streamwrappers.php | 12 ----- 2 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 tests/lib/files/stream/staticstream.php diff --git a/tests/lib/files/stream/staticstream.php b/tests/lib/files/stream/staticstream.php new file mode 100644 index 00000000000..d55086196a0 --- /dev/null +++ b/tests/lib/files/stream/staticstream.php @@ -0,0 +1,68 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Stream; + +class StaticStream extends \PHPUnit_Framework_TestCase { + + private $sourceFile; + private $sourceText; + + public function __construct() { + $this->sourceFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; + $this->sourceText = file_get_contents($this->sourceFile); + } + + public function tearDown() { + \OC\Files\Stream\StaticStream::clear(); + } + + public function testContent() { + file_put_contents('static://foo', $this->sourceText); + $this->assertEquals($this->sourceText, file_get_contents('static://foo')); + } + + public function testMultipleFiles() { + file_put_contents('static://foo', $this->sourceText); + file_put_contents('static://bar', strrev($this->sourceText)); + $this->assertEquals($this->sourceText, file_get_contents('static://foo')); + $this->assertEquals(strrev($this->sourceText), file_get_contents('static://bar')); + } + + public function testOverwrite() { + file_put_contents('static://foo', $this->sourceText); + file_put_contents('static://foo', 'qwerty'); + $this->assertEquals('qwerty', file_get_contents('static://foo')); + } + + public function testIsFile() { + $this->assertFalse(is_file('static://foo')); + file_put_contents('static://foo', $this->sourceText); + $this->assertTrue(is_file('static://foo')); + } + + public function testIsDir() { + $this->assertFalse(is_dir('static://foo')); + file_put_contents('static://foo', $this->sourceText); + $this->assertFalse(is_dir('static://foo')); + } + + public function testFileType() { + file_put_contents('static://foo', $this->sourceText); + $this->assertEquals('file', filetype('static://foo')); + } + + public function testUnlink() { + $this->assertFalse(file_exists('static://foo')); + file_put_contents('static://foo', $this->sourceText); + $this->assertTrue(file_exists('static://foo')); + unlink('static://foo'); + clearstatcache(); + $this->assertFalse(file_exists('static://foo')); + } +} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index c7e51ccfa48..d15b712139d 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -33,18 +33,6 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { $this->assertEquals(count($items), count($result)); } - public function testStaticStream() { - $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)); - $this->assertEquals(file_get_contents($sourceFile), file_get_contents($staticFile)); - unlink($staticFile); - clearstatcache(); - $this->assertFalse(file_exists($staticFile)); - } - public function testCloseStream() { //ensure all basic stream stuff works $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; -- GitLab From 7b6fcddbc5314e7401e4f5579853aa6353d462f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 18 Jun 2013 18:24:48 +0200 Subject: [PATCH 085/216] use executeAudited, add table name to assert message, skip schema changing test on oracle --- tests/lib/dbschema.php | 87 +++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index 59f203993ef..5d52db6a5ab 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -7,9 +7,8 @@ */ class Test_DBSchema extends PHPUnit_Framework_TestCase { - protected static $schema_file = 'static://test_db_scheme'; - protected static $schema_file2 = 'static://test_db_scheme2'; - protected $test_prefix; + protected $schema_file = 'static://test_db_scheme'; + protected $schema_file2 = 'static://test_db_scheme2'; protected $table1; protected $table2; @@ -20,19 +19,20 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { $r = '_'.OC_Util::generate_random_bytes('4').'_'; $content = file_get_contents( $dbfile ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); - file_put_contents( self::$schema_file, $content ); + file_put_contents( $this->schema_file, $content ); $content = file_get_contents( $dbfile2 ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); - file_put_contents( self::$schema_file2, $content ); + file_put_contents( $this->schema_file2, $content ); - $this->test_prefix = $r; - $this->table1 = $this->test_prefix.'cntcts_addrsbks'; - $this->table2 = $this->test_prefix.'cntcts_cards'; + $prefix = OC_Config::getValue( "dbtableprefix", "oc_" ); + + $this->table1 = $prefix.$r.'cntcts_addrsbks'; + $this->table2 = $prefix.$r.'cntcts_cards'; } public function tearDown() { - unlink(self::$schema_file); - unlink(self::$schema_file2); + unlink($this->schema_file); + unlink($this->schema_file2); } // everything in one test, they depend on each other @@ -47,13 +47,19 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { } public function doTestSchemaCreating() { - OC_DB::createDbFromStructure(self::$schema_file); + OC_DB::createDbFromStructure($this->schema_file); $this->assertTableExist($this->table1); $this->assertTableExist($this->table2); } public function doTestSchemaChanging() { - OC_DB::updateDbFromStructure(self::$schema_file2); + if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { + $this->markTestSkipped( + // see http://abhijitbashetti.blogspot.de/2011/10/converting-varchar2-to-clob-and-clob-to.html + 'Oracle does not simply ALTER a VARCHAR into a CLOB.' + ); + } + OC_DB::updateDbFromStructure($this->schema_file2); $this->assertTableExist($this->table2); } @@ -66,67 +72,62 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { } public function doTestSchemaRemoving() { - OC_DB::removeDBStructure(self::$schema_file); + OC_DB::removeDBStructure($this->schema_file); $this->assertTableNotExist($this->table1); $this->assertTableNotExist($this->table2); } public function tableExist($table) { - $table = '*PREFIX*' . $table; switch (OC_Config::getValue( 'dbtype', 'sqlite' )) { case 'sqlite': case 'sqlite3': $sql = "SELECT name FROM sqlite_master " - . "WHERE type = 'table' AND name != 'sqlite_sequence' " - . "AND name != 'geometry_columns' AND name != 'spatial_ref_sys' " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type = 'table' AND name = '".$table."'"; - $query = OC_DB::prepare($sql); - $result = $query->execute(array()); - $exists = $result && $result->fetchOne(); + . "WHERE type = 'table' AND name = ? " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type = 'table' AND name = ?"; + $result = \OC_DB::executeAudited($sql, array($table, $table)); break; case 'mysql': - $sql = 'SHOW TABLES LIKE "'.$table.'"'; - $query = OC_DB::prepare($sql); - $result = $query->execute(array()); - $exists = $result && $result->fetchOne(); + $sql = 'SHOW TABLES LIKE ?'; + $result = \OC_DB::executeAudited($sql, array($table)); break; case 'pgsql': - $sql = "SELECT tablename AS table_name, schemaname AS schema_name " - . "FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' " - . "AND schemaname != 'information_schema' " - . "AND tablename = '".$table."'"; - $query = OC_DB::prepare($sql); - $result = $query->execute(array()); - $exists = $result && $result->fetchOne(); + $sql = 'SELECT tablename AS table_name, schemaname AS schema_name ' + . 'FROM pg_tables WHERE schemaname NOT LIKE \'pg_%\' ' + . 'AND schemaname != \'information_schema\' ' + . 'AND tablename = ?'; + $result = \OC_DB::executeAudited($sql, array($table)); break; case 'oci': - $sql = 'SELECT table_name FROM user_tables WHERE table_name = ?'; + $sql = 'SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME = ?'; $result = \OC_DB::executeAudited($sql, array($table)); - $exists = (bool)$result->fetchOne(); //oracle uses MDB2 and returns null break; case 'mssql': - $sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '{$table}'"; - $query = OC_DB::prepare($sql); - $result = $query->execute(array()); - $exists = $result && $result->fetchOne(); + $sql = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ?'; + $result = \OC_DB::executeAudited($sql, array($table)); break; } - return $exists; + + $name = $result->fetchOne(); //FIXME checking with '$result->numRows() === 1' does not seem to work? + OC_DB::raiseExceptionOnError($name); + if ($name === $table) { + return true; + } else { + return false; + } } public function assertTableExist($table) { - $this->assertTrue($this->tableExist($table)); + $this->assertTrue($this->tableExist($table), 'Table ' . $table . ' does not exist'); } public function assertTableNotExist($table) { $type=OC_Config::getValue( "dbtype", "sqlite" ); if( $type == 'sqlite' || $type == 'sqlite3' ) { // sqlite removes the tables after closing the DB - } - else { - $this->assertFalse($this->tableExist($table)); + } else { + $this->assertFalse($this->tableExist($table), 'Table ' . $table . ' exists.'); } } } -- GitLab From e62eb2e8d1937f1708ce7efdd6ab8a31e12c6f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 12:31:23 +0300 Subject: [PATCH 086/216] correctly handle error results of PDO and MDB2 backends --- lib/db.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/db.php b/lib/db.php index 4d6788f2bda..5e624bf30b9 100644 --- a/lib/db.php +++ b/lib/db.php @@ -962,11 +962,14 @@ class OC_DB { * @return bool */ public static function isError($result) { - if(self::$backend==self::BACKEND_PDO and $result === false) { + //PDO returns false on error (and throws an exception) + if (self::$backend===self::BACKEND_PDO and $result === false) { return true; - }elseif(self::$backend==self::BACKEND_MDB2 and PEAR::isError($result)) { + } else + //MDB2 returns an MDB2_Error object + if (self::$backend===self::BACKEND_MDB2 and PEAR::isError($result)) { return true; - }else{ + } else { return false; } } -- GitLab From 4bbdd67a22fd5ac0efc6b8c9dc3e024a0af45c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 20 Jun 2013 16:58:49 +0200 Subject: [PATCH 087/216] remove wrong check here --- tests/lib/dbschema.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index 5d52db6a5ab..103909e2e25 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -110,7 +110,6 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { } $name = $result->fetchOne(); //FIXME checking with '$result->numRows() === 1' does not seem to work? - OC_DB::raiseExceptionOnError($name); if ($name === $table) { return true; } else { -- GitLab From 66e1eaac9379e16bb0c9e60b2794b03bda3b9eec Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 27 Jun 2013 16:48:09 +0200 Subject: [PATCH 088/216] isError should detect a PEAR_Error even if the backend is PDO. This can happen on errors during schema migration - which is always done with MDB2 --- lib/db.php | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/db.php b/lib/db.php index 5e624bf30b9..515563b78e1 100644 --- a/lib/db.php +++ b/lib/db.php @@ -962,21 +962,21 @@ class OC_DB { * @return bool */ public static function isError($result) { + //MDB2 returns an MDB2_Error object + if (class_exists('PEAR') === true && PEAR::isError($result)) { + return true; + } //PDO returns false on error (and throws an exception) if (self::$backend===self::BACKEND_PDO and $result === false) { return true; - } else - //MDB2 returns an MDB2_Error object - if (self::$backend===self::BACKEND_MDB2 and PEAR::isError($result)) { - return true; - } else { - return false; } + + return false; } /** * check if a result is an error and throws an exception, works with MDB2 and PDOException * @param mixed $result - * @param string message + * @param string $message * @return void * @throws DatabaseException */ @@ -992,12 +992,15 @@ class OC_DB { } public static function getErrorCode($error) { - if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) { - $code = $error->getCode(); - } elseif ( self::$backend==self::BACKEND_PDO and self::$PDO ) { - $code = self::$PDO->errorCode(); + if ( class_exists('PEAR') === true && PEAR::isError($error) ) { + /** @var $error PEAR_Error */ + return $error->getCode(); + } + if ( self::$backend==self::BACKEND_PDO and self::$PDO ) { + return self::$PDO->errorCode(); } - return $code; + + return -1; } /** * returns the error code and message as a string for logging @@ -1006,23 +1009,24 @@ class OC_DB { * @return string */ public static function getErrorMessage($error) { - if ( self::$backend==self::BACKEND_MDB2 and PEAR::isError($error) ) { + if ( class_exists('PEAR') === true && PEAR::isError($error) ) { $msg = $error->getCode() . ': ' . $error->getMessage(); $msg .= ' (' . $error->getDebugInfo() . ')'; - } elseif (self::$backend==self::BACKEND_PDO and self::$PDO) { + + return $msg; + } + if (self::$backend==self::BACKEND_PDO and self::$PDO) { $msg = self::$PDO->errorCode() . ': '; $errorInfo = self::$PDO->errorInfo(); if (is_array($errorInfo)) { $msg .= 'SQLSTATE = '.$errorInfo[0] . ', '; $msg .= 'Driver Code = '.$errorInfo[1] . ', '; $msg .= 'Driver Message = '.$errorInfo[2]; - }else{ - $msg = ''; } - }else{ - $msg = ''; + return $msg; } - return $msg; + + return ''; } /** -- GitLab From c80e76720f4e65a5f7af31f67d70ec66019bcb68 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 28 Jun 2013 16:07:22 +0200 Subject: [PATCH 089/216] Going from text to clob is not something we do. Also Oracle DB has problems with this, see http://abhijitbashetti.blogspot.de/2011/10/converting-varchar2-to-clob-and-clob-to.html --- tests/data/db_structure2.xml | 3 ++- tests/lib/dbschema.php | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/data/db_structure2.xml b/tests/data/db_structure2.xml index fc6fe0bba7d..6f12f81f477 100644 --- a/tests/data/db_structure2.xml +++ b/tests/data/db_structure2.xml @@ -49,8 +49,9 @@ description - clob + text false + 1024 diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index 103909e2e25..c2e55eabf4b 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -53,12 +53,6 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { } public function doTestSchemaChanging() { - if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { - $this->markTestSkipped( - // see http://abhijitbashetti.blogspot.de/2011/10/converting-varchar2-to-clob-and-clob-to.html - 'Oracle does not simply ALTER a VARCHAR into a CLOB.' - ); - } OC_DB::updateDbFromStructure($this->schema_file2); $this->assertTableExist($this->table2); } -- GitLab From d110e60316f7dd28a2b5876e8911f983fea0883c Mon Sep 17 00:00:00 2001 From: Victor Dubiniuk Date: Fri, 28 Jun 2013 21:53:56 +0300 Subject: [PATCH 090/216] Hide a ghost image on the apps management page --- settings/js/apps.js | 5 +++++ settings/templates/apps.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/settings/js/apps.js b/settings/js/apps.js index 9c1604cfcd9..bdeddfb84c2 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -20,6 +20,11 @@ OC.Settings.Apps = OC.Settings.Apps || { page.find('span.score').html(app.score); page.find('p.description').text(app.description); page.find('img.preview').attr('src', app.preview); + if (app.preview && app.preview.length) { + page.find('img.preview').show(); + } else { + page.find('img.preview').hide(); + } page.find('small.externalapp').attr('style', 'visibility:visible'); page.find('span.author').text(app.author); page.find('span.licence').text(app.licence); diff --git a/settings/templates/apps.php b/settings/templates/apps.php index 0903b9bd5c4..d60fd82f917 100644 --- a/settings/templates/apps.php +++ b/settings/templates/apps.php @@ -34,7 +34,7 @@ class="version">

- +
-

- '); ?> - +

+

diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 4173212dfa3..ec73ad5456c 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -43,10 +43,7 @@

- - - - '); ?> -

+ +

diff --git a/lib/defaults.php b/lib/defaults.php index 7dc6fbd0ada..9043c04e7b6 100644 --- a/lib/defaults.php +++ b/lib/defaults.php @@ -71,4 +71,26 @@ class OC_Defaults { } } -} \ No newline at end of file + public static function getShortFooter() { + if (OC_Util::getEditionString() === '') { + $footer = "" .self::getEntity() . "". + ' – ' . self::getSlogan(); + } else { + $footer = "© 2013 ".self::getEntity()."". + " – " . self::getSlogan(); + } + + return $footer; + } + + public static function getLongFooter() { + if (OC_Util::getEditionString() === '') { + $footer = self::getShortFooter(); + } else { + $footer = "© 2013 ".self::getEntity()."". + "
" . self::getSlogan(); + } + return $footer; + } + +} diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 1ed3f6ef47f..0eba6862e6b 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -230,12 +230,16 @@ endfor;?> -