From 320353c237fbee2d9a8f12dd474feb3a0f6ddec6 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 9 Dec 2013 01:34:31 +0100 Subject: [PATCH 01/34] Add support for multiple memcached servers. --- config/config.sample.php | 10 ++++++++-- lib/private/memcache/memcached.php | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/config/config.sample.php b/config/config.sample.php index 1070ef72eda..67152accc3b 100755 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -114,8 +114,14 @@ $CONFIG = array( /* Password to use for sendmail mail, depends on mail_smtpauth if this is used */ "mail_smtppassword" => "", -/* memcached hostname and port (Only used when xCache, APC and APCu are absent.) */ -"memcached_server" => array('localhost', 11211), +/* memcached servers (Only used when xCache, APC and APCu are absent.) */ +"memcached_servers" => array( + // hostname, port and optional weight. Also see: + // http://www.php.net/manual/en/memcached.addservers.php + // http://www.php.net/manual/en/memcached.addserver.php + array('localhost', 11211), + //array('other.host.local', 11211), +), /* How long should ownCloud keep deleted files in the trash bin, default value: 30 days */ 'trashbin_retention_obligation' => 30, diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php index 978e6c2eff1..13b1867231a 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/memcache/memcached.php @@ -18,8 +18,8 @@ class Memcached extends Cache { parent::__construct($prefix); if (is_null(self::$cache)) { self::$cache = new \Memcached(); - list($host, $port) = \OC_Config::getValue('memcached_server', array('localhost', 11211)); - self::$cache->addServer($host, $port); + $servers = \OC_Config::getValue('memcached_servers', array(array('localhost', 11211))); + self::$cache->addServers($servers); } } From acd81f6c694373a18a0ee9ba29075b9924603c25 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 10 Jan 2014 00:57:40 +0100 Subject: [PATCH 02/34] Readd support for memcached_server config variable. --- lib/private/memcache/memcached.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php index 13b1867231a..075828eebad 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/memcache/memcached.php @@ -18,7 +18,15 @@ class Memcached extends Cache { parent::__construct($prefix); if (is_null(self::$cache)) { self::$cache = new \Memcached(); - $servers = \OC_Config::getValue('memcached_servers', array(array('localhost', 11211))); + $servers = \OC_Config::getValue('memcached_servers'); + if (!$servers) { + $server = \OC_Config::getValue('memcached_server'); + if ($server) { + $servers = array($server); + } else { + $servers = array(array('localhost', 11211)); + } + } self::$cache->addServers($servers); } } From 374e3475c9e2e0220cc8639a1a06f68b7f43fb2b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 21 Jan 2014 23:58:48 +0100 Subject: [PATCH 03/34] Also remove the user's home storage from the storage table when deleting a user --- lib/private/files/cache/storage.php | 13 +++++++++++++ lib/private/user.php | 3 +++ 2 files changed, 16 insertions(+) diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php index 5657cf06e12..6d7a1002c1b 100644 --- a/lib/private/files/cache/storage.php +++ b/lib/private/files/cache/storage.php @@ -70,4 +70,17 @@ class Storage { return false; } } + + /** + * remove the entry for the storage + * + * @param string $storageId + */ + public static function remove($storageId) { + if (strlen($storageId) > 64) { + $storageId = md5($storageId); + } + $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; + \OC_DB::executeAudited($sql, array($storageId)); + } } diff --git a/lib/private/user.php b/lib/private/user.php index 98ebebbe5c1..2519200d0f0 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -205,6 +205,9 @@ class OC_User { // Delete user files in /data/ OC_Helper::rmdirr(\OC_User::getHome($uid)); + // Delete the users entry in the storage table + \OC\Files\Cache\Storage::remove('home::' . $uid); + // Remove it from the Cache self::getManager()->delete($uid); } From 5a5b6f187e719e6c0bac5e64c411eb74e6d28389 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 22 Jan 2014 13:00:45 +0100 Subject: [PATCH 04/34] Use Cache->clear to cleanup the filecache for removed users --- lib/private/user.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/private/user.php b/lib/private/user.php index 2519200d0f0..7932f4aef76 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -205,8 +205,13 @@ class OC_User { // Delete user files in /data/ OC_Helper::rmdirr(\OC_User::getHome($uid)); - // Delete the users entry in the storage table - \OC\Files\Cache\Storage::remove('home::' . $uid); + // Cleanup the filecache + $mount = \OC\Files\Filesystem::getMountByStorageId('home::' . $uid); + if (count($mount) > 0) { + $mount = $mount[0]; + $cache = $mount->getStorage()->getCache(); + $cache->clear(); + } // Remove it from the Cache self::getManager()->delete($uid); @@ -243,15 +248,15 @@ class OC_User { $uid = $backend->getCurrentUserId(); $run = true; - OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid )); + OC_Hook::emit("OC_User", "pre_login", array("run" => &$run, "uid" => $uid)); - if($uid) { + if ($uid) { session_regenerate_id(true); self::setUserId($uid); self::setDisplayName($uid); self::getUserSession()->setLoginName($uid); - OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>'' )); + OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => '')); return true; } return false; From 229f13adc0eca770c07646e56773f1aa93fee643 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 29 Jan 2014 14:40:59 +0100 Subject: [PATCH 05/34] change order of issubdirectory() calls to avoid error messages for non-apps --- lib/private/l10n.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/l10n.php b/lib/private/l10n.php index 98665c84c55..1aa1dc5ea28 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -132,10 +132,10 @@ class OC_L10N implements \OCP\IL10N { $i18ndir = self::findI18nDir($app); // Localization is in /l10n, Texts are in $i18ndir // (Just no need to define date/time format etc. twice) - if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') - || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') + if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings') + || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') ) && file_exists($i18ndir.$lang.'.php')) { // Include the file, save the data from $CONFIG From 8d6a3a00b47aa7d034de378f498a7d5e329a8e1d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 3 Feb 2014 16:29:04 +0100 Subject: [PATCH 06/34] Revert "Use Cache->clear to cleanup the filecache for removed users" This reverts commit 5a5b6f187e719e6c0bac5e64c411eb74e6d28389. --- lib/private/user.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/private/user.php b/lib/private/user.php index 7932f4aef76..2519200d0f0 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -205,13 +205,8 @@ class OC_User { // Delete user files in /data/ OC_Helper::rmdirr(\OC_User::getHome($uid)); - // Cleanup the filecache - $mount = \OC\Files\Filesystem::getMountByStorageId('home::' . $uid); - if (count($mount) > 0) { - $mount = $mount[0]; - $cache = $mount->getStorage()->getCache(); - $cache->clear(); - } + // Delete the users entry in the storage table + \OC\Files\Cache\Storage::remove('home::' . $uid); // Remove it from the Cache self::getManager()->delete($uid); @@ -248,15 +243,15 @@ class OC_User { $uid = $backend->getCurrentUserId(); $run = true; - OC_Hook::emit("OC_User", "pre_login", array("run" => &$run, "uid" => $uid)); + OC_Hook::emit( "OC_User", "pre_login", array( "run" => &$run, "uid" => $uid )); - if ($uid) { + if($uid) { session_regenerate_id(true); self::setUserId($uid); self::setDisplayName($uid); self::getUserSession()->setLoginName($uid); - OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => '')); + OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>'' )); return true; } return false; From 0ae4022fb4fc6ade3ed300205ccdcdd32863dcdc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 3 Feb 2014 16:36:21 +0100 Subject: [PATCH 07/34] Also clean up the filecache table when deleting a storage entry --- lib/private/files/cache/storage.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php index 6d7a1002c1b..5b1b30176e8 100644 --- a/lib/private/files/cache/storage.php +++ b/lib/private/files/cache/storage.php @@ -77,10 +77,16 @@ class Storage { * @param string $storageId */ public static function remove($storageId) { + $storageCache = new Storage($storageId); + $numericId = $storageCache->getNumericId(); + if (strlen($storageId) > 64) { $storageId = md5($storageId); } $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?'; \OC_DB::executeAudited($sql, array($storageId)); + + $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?'; + \OC_DB::executeAudited($sql, array($numericId)); } } From d55ef442cd861d04b9ccfd4493aedf0c9a4164ff Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Tue, 4 Feb 2014 12:59:14 +0100 Subject: [PATCH 08/34] properly check if pdf and svg modules are installed --- lib/private/preview/office.php | 2 +- lib/private/preview/pdf.php | 2 +- lib/private/preview/svg.php | 2 +- lib/private/preview/unknown.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/private/preview/office.php b/lib/private/preview/office.php index 7a4826c76ec..884b6e7dc9b 100644 --- a/lib/private/preview/office.php +++ b/lib/private/preview/office.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ //both, libreoffice backend and php fallback, need imagick -if (extension_loaded('imagick')) { +if (extension_loaded('imagick') && count(\Imagick::queryFormats("PDF")) === 1) { $isShellExecEnabled = \OC_Helper::is_function_enabled('shell_exec'); // LibreOffice preview is currently not supported on Windows diff --git a/lib/private/preview/pdf.php b/lib/private/preview/pdf.php index cc974b68818..572b8788ac9 100644 --- a/lib/private/preview/pdf.php +++ b/lib/private/preview/pdf.php @@ -7,7 +7,7 @@ */ namespace OC\Preview; -if (extension_loaded('imagick')) { +if (extension_loaded('imagick') && count(\Imagick::queryFormats("PDF")) === 1) { class PDF extends Provider { diff --git a/lib/private/preview/svg.php b/lib/private/preview/svg.php index b49e51720fa..07a37e8f8c1 100644 --- a/lib/private/preview/svg.php +++ b/lib/private/preview/svg.php @@ -7,7 +7,7 @@ */ namespace OC\Preview; -if (extension_loaded('imagick')) { +if (extension_loaded('imagick') && count(\Imagick::queryFormats("SVG")) === 1) { class SVG extends Provider { diff --git a/lib/private/preview/unknown.php b/lib/private/preview/unknown.php index 4747f9e25ed..8145c826149 100644 --- a/lib/private/preview/unknown.php +++ b/lib/private/preview/unknown.php @@ -22,7 +22,7 @@ class Unknown extends Provider { $svgPath = substr_replace($path, 'svg', -3); - if (extension_loaded('imagick') && file_exists($svgPath)) { + if (extension_loaded('imagick') && file_exists($svgPath) && count(\Imagick::queryFormats("SVG")) === 1) { // http://www.php.net/manual/de/imagick.setresolution.php#85284 $svg = new \Imagick(); From 11f46e121caa30f46250a1980e315520d68eb593 Mon Sep 17 00:00:00 2001 From: Jens-Christian Fischer Date: Tue, 4 Feb 2014 17:03:52 +0100 Subject: [PATCH 09/34] close statement in MimeType detection is executed [#7069] close statement was never executed due to it being after a return statement. --- lib/private/files/type/detection.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php index d7cc9ebbf4e..11e439032ce 100644 --- a/lib/private/files/type/detection.php +++ b/lib/private/files/type/detection.php @@ -72,11 +72,12 @@ class Detection { and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME) ) { $info = @strtolower(finfo_file($finfo, $path)); + finfo_close($finfo); if ($info) { $mimeType = substr($info, 0, strpos($info, ';')); return empty($mimeType) ? 'application/octet-stream' : $mimeType; } - finfo_close($finfo); + } $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://'); if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) { From a8943ad02207afbf142ec48f4b53cbe1be943253 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Thu, 6 Feb 2014 16:01:42 +0100 Subject: [PATCH 10/34] replace 'size' with 'unencrypted_size' if encryption is enabled --- apps/files_sharing/lib/cache.php | 15 +++++++++++++-- apps/files_sharing/lib/share/file.php | 9 ++++++++- lib/public/share.php | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 86e324409fe..1b102f9e5f8 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -92,12 +92,11 @@ class Shared_Cache extends Cache { } else { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' - .' `size`, `mtime`, `encrypted`' + .' `size`, `mtime`, `encrypted`, `unencrypted_size`' .' FROM `*PREFIX*filecache` WHERE `fileid` = ?'); $result = $query->execute(array($file)); $data = $result->fetchRow(); $data['fileid'] = (int)$data['fileid']; - $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['storage_mtime'] = (int)$data['storage_mtime']; $data['encrypted'] = (bool)$data['encrypted']; @@ -106,6 +105,12 @@ class Shared_Cache extends Cache { if ($data['storage_mtime'] === 0) { $data['storage_mtime'] = $data['mtime']; } + if ($data['encrypted'] or ($data['unencrypted_size'] > 0 and $data['mimetype'] === 'httpd/unix-directory')) { + $data['encrypted_size'] = (int)$data['size']; + $data['size'] = (int)$data['unencrypted_size']; + } else { + $data['size'] = (int)$data['size']; + } return $data; } return false; @@ -334,6 +339,12 @@ class Shared_Cache extends Cache { } $row['mimetype'] = $this->getMimetype($row['mimetype']); $row['mimepart'] = $this->getMimetype($row['mimepart']); + if ($row['encrypted'] or ($row['unencrypted_size'] > 0 and $row['mimetype'] === 'httpd/unix-directory')) { + $row['encrypted_size'] = $row['size']; + $row['size'] = $row['unencrypted_size']; + } else { + $row['size'] = $row['size']; + } $files[] = $row; } } diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index c956c55a1df..ec0f368386f 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -91,10 +91,17 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $file['name'] = basename($item['file_target']); $file['mimetype'] = $item['mimetype']; $file['mimepart'] = $item['mimepart']; - $file['size'] = $item['size']; $file['mtime'] = $item['mtime']; $file['encrypted'] = $item['encrypted']; $file['etag'] = $item['etag']; + $storage = \OC\Files\Filesystem::getStorage('/'); + $cache = $storage->getCache(); + if ($item['encrypted'] or ($item['unencrypted_size'] > 0 and $cache->getMimetype($item['mimetype']) === 'httpd/unix-directory')) { + $file['size'] = $item['unencrypted_size']; + $file['encrypted_size'] = $item['size']; + } else { + $file['size'] = $item['size']; + } $files[] = $file; } return $files; diff --git a/lib/public/share.php b/lib/public/share.php index f832d04a70f..ae7d29e8b87 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -1152,7 +1152,7 @@ class Share { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, ' .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' .'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' - .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`'; + .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, From af7366cd30f0df27cc1043f2c2b55def836d03db Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 7 Feb 2014 12:53:42 +0100 Subject: [PATCH 11/34] Only add files to file list when uploading to current directory Fix Issue #6683 --- apps/files/ajax/upload.php | 6 ++++-- apps/files/js/filelist.js | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index 8f6c42d6620..754c34ef088 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -139,7 +139,8 @@ if (strpos($dir, '..') === false) { 'originalname' => $files['tmp_name'][$i], 'uploadMaxFilesize' => $maxUploadFileSize, 'maxHumanFilesize' => $maxHumanFileSize, - 'permissions' => $meta['permissions'] & $allowedPermissions + 'permissions' => $meta['permissions'] & $allowedPermissions, + 'directory' => \OC\Files\Filesystem::normalizePath(stripslashes($dir)), ); } @@ -166,7 +167,8 @@ if (strpos($dir, '..') === false) { 'originalname' => $files['tmp_name'][$i], 'uploadMaxFilesize' => $maxUploadFileSize, 'maxHumanFilesize' => $maxHumanFileSize, - 'permissions' => $meta['permissions'] & $allowedPermissions + 'permissions' => $meta['permissions'] & $allowedPermissions, + 'directory' => \OC\Files\Filesystem::normalizePath(stripslashes($dir)), ); } } diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index f538af10362..e6aefd33c96 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -924,8 +924,8 @@ $(document).ready(function() { data.context.find('td.filesize').text(humanFileSize(size)); } else { - // only append new file if dragged onto current dir's crumb (last) - if (data.context && data.context.hasClass('crumb') && !data.context.hasClass('last')) { + // only append new file if uploaded into the current folder + if (file.directory !== FileList.getCurrentDirectory()) { return; } From dc53c83e7bdbadeb24c74fe1c7794de54811c264 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 28 Jan 2014 17:42:26 +0100 Subject: [PATCH 12/34] getData() always needs to return an array --- lib/private/ocs/result.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/private/ocs/result.php b/lib/private/ocs/result.php index 84f06fa01c7..9f14e8da7e8 100644 --- a/lib/private/ocs/result.php +++ b/lib/private/ocs/result.php @@ -29,7 +29,13 @@ class OC_OCS_Result{ * @param $data mixed the data to return */ public function __construct($data=null, $code=100, $message=null) { - $this->data = $data; + if ($data === null) { + $this->data = array(); + } elseif (!is_array($data)) { + $this->data = array($this->data); + } else { + $this->data = $data; + } $this->statusCode = $code; $this->message = $message; } @@ -49,7 +55,7 @@ class OC_OCS_Result{ public function setItemsPerPage(int $items) { $this->perPage = $items; } - + /** * get the status code * @return int @@ -57,7 +63,7 @@ class OC_OCS_Result{ public function getStatusCode() { return $this->statusCode; } - + /** * get the meta data for the result * @return array @@ -76,15 +82,15 @@ class OC_OCS_Result{ return $meta; } - + /** * get the result data - * @return array|string|int + * @return array */ public function getData() { return $this->data; } - + /** * return bool if the method succedded * @return bool From dbec143f09f32832a52fb507ababb84518721370 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 7 Feb 2014 16:09:31 +0100 Subject: [PATCH 13/34] Change MySQL to MySQL/MariaDB in the frontend Fix issue #6269 --- core/setup/controller.php | 2 +- lib/private/setup/mysql.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/setup/controller.php b/core/setup/controller.php index 58ed4d28dc0..697408cfb57 100644 --- a/core/setup/controller.php +++ b/core/setup/controller.php @@ -91,7 +91,7 @@ class Controller { $databases['sqlite'] = 'SQLite'; } if ($hasMySQL) { - $databases['mysql'] = 'MySQL'; + $databases['mysql'] = 'MySQL/MariaDB'; } if ($hasPostgreSQL) { $databases['pgsql'] = 'PostgreSQL'; diff --git a/lib/private/setup/mysql.php b/lib/private/setup/mysql.php index d97b6d2602f..b2c28173b1c 100644 --- a/lib/private/setup/mysql.php +++ b/lib/private/setup/mysql.php @@ -3,13 +3,13 @@ namespace OC\Setup; class MySQL extends AbstractDatabase { - public $dbprettyname = 'MySQL'; + public $dbprettyname = 'MySQL/MariaDB'; public function setupDatabase($username) { //check if the database user has admin right $connection = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpassword); if(!$connection) { - throw new \DatabaseSetupException($this->trans->t('MySQL username and/or password not valid'), + throw new \DatabaseSetupException($this->trans->t('MySQL/MariaDB username and/or password not valid'), $this->trans->t('You need to enter either an existing account or the administrator.')); } $oldUser=\OC_Config::getValue('dbuser', false); @@ -82,14 +82,14 @@ class MySQL extends AbstractDatabase { $query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'"; $result = mysql_query($query, $connection); if (!$result) { - throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'localhost' exists already.", array($name)), - $this->trans->t("Drop this user from MySQL", array($name))); + throw new \DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'localhost' exists already.", array($name)), + $this->trans->t("Drop this user from MySQL/MariaDB", array($name))); } $query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'"; $result = mysql_query($query, $connection); if (!$result) { - throw new \DatabaseSetupException($this->trans->t("MySQL user '%s'@'%%' already exists", array($name)), - $this->trans->t("Drop this user from MySQL.")); + throw new \DatabaseSetupException($this->trans->t("MySQL/MariaDB user '%s'@'%%' already exists", array($name)), + $this->trans->t("Drop this user from MySQL/MariaDB.")); } } } From 13fa0e2a9d3f89e4479f30b847c7c197276e5537 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Fri, 7 Feb 2014 17:47:42 +0100 Subject: [PATCH 14/34] Fix implied evals and doubled definition of variable fixes #7119 fixes #7120 fixes #7121 fixes #7122 --- apps/files/js/filelist.js | 10 ++++------ apps/files/js/files.js | 2 +- settings/js/personal.js | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index f538af10362..2883218b2cc 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -435,10 +435,9 @@ window.FileList={ tr.attr('data-file', newname); var path = td.children('a.name').attr('href'); td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newname))); + var basename = newname; if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { - var basename=newname.substr(0,newname.lastIndexOf('.')); - } else { - var basename=newname; + basename = newname.substr(0,newname.lastIndexOf('.')); } td.find('a.name span.nametext').text(basename); if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { @@ -544,10 +543,9 @@ window.FileList={ td.children('a.name .span').text(newName); var path = td.children('a.name').attr('href'); td.children('a.name').attr('href', path.replace(encodeURIComponent(oldName), encodeURIComponent(newName))); + var basename = newName; if (newName.indexOf('.') > 0) { - var basename = newName.substr(0, newName.lastIndexOf('.')); - } else { - var basename = newName; + basename = newName.substr(0, newName.lastIndexOf('.')); } td.children('a.name').empty(); var span = $(''); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index a535700c1b3..1ec4c4ec7ab 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -405,7 +405,7 @@ $(document).ready(function() { Files.resizeBreadcrumbs(width, true); // display storage warnings - setTimeout ( "Files.displayStorageWarnings()", 100 ); + setTimeout(Files.displayStorageWarnings, 100); OC.Notification.setDefault(Files.displayStorageWarnings); // only possible at the moment if user is logged in diff --git a/settings/js/personal.js b/settings/js/personal.js index e6e1d538a19..3b876467756 100644 --- a/settings/js/personal.js +++ b/settings/js/personal.js @@ -158,7 +158,7 @@ $(document).ready(function(){ if(typeof timeout !== 'undefined'){ clearTimeout(timeout); } - timeout = setTimeout('changeDisplayName()',1000); + timeout = setTimeout(changeDisplayName, 1000); } }); @@ -173,7 +173,7 @@ $(document).ready(function(){ if(typeof timeout !== 'undefined'){ clearTimeout(timeout); } - timeout = setTimeout('changeEmailAddress()',1000); + timeout = setTimeout(changeEmailAddress, 1000); } }); From 91254c304d454b6f7977037dbd5dd2db5e00ff9f Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 7 Feb 2014 15:57:13 +0100 Subject: [PATCH 15/34] name users after test --- apps/files_encryption/tests/hooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_encryption/tests/hooks.php b/apps/files_encryption/tests/hooks.php index c26cba6406d..44525791743 100644 --- a/apps/files_encryption/tests/hooks.php +++ b/apps/files_encryption/tests/hooks.php @@ -36,8 +36,8 @@ use OCA\Encryption; */ class Test_Encryption_Hooks extends \PHPUnit_Framework_TestCase { - const TEST_ENCRYPTION_HOOKS_USER1 = "test-proxy-user1"; - const TEST_ENCRYPTION_HOOKS_USER2 = "test-proxy-user2"; + const TEST_ENCRYPTION_HOOKS_USER1 = "test-encryption-hooks-user1"; + const TEST_ENCRYPTION_HOOKS_USER2 = "test-encryption-hooks-user2"; /** * @var \OC_FilesystemView From 828985dc6092808bbb1a3cb07f637e6da0dfeb65 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 7 Feb 2014 18:12:01 +0100 Subject: [PATCH 16/34] Make google drive client secret and dropbox api secret a password field Fix issue #5794 --- apps/files_external/lib/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 01d588b3721..48fc4dfe46e 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -61,7 +61,7 @@ class OC_Mount_Config { 'configuration' => array( 'configured' => '#configured', 'app_key' => 'App key', - 'app_secret' => 'App secret', + 'app_secret' => '*App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'); @@ -80,7 +80,7 @@ class OC_Mount_Config { 'configuration' => array( 'configured' => '#configured', 'client_id' => 'Client ID', - 'client_secret' => 'Client secret', + 'client_secret' => '*Client secret', 'token' => '#token'), 'custom' => 'google'); From 050e84a08fa8eee14e52f4dbbee572596ba002ce Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 10 Feb 2014 10:56:11 +0100 Subject: [PATCH 17/34] refuse login as long as the initial encryption is running --- apps/files_encryption/hooks/hooks.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 4c4b3f2040f..83abf3ba9de 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -80,8 +80,15 @@ class Hooks { // Check if first-run file migration has already been performed $ready = false; - if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) { + $migrationStatus = $util->getMigrationStatus(); + if ($migrationStatus === Util::MIGRATION_OPEN) { $ready = $util->beginMigration(); + } elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) { + // refuse login as long as the initial encryption is running + while ($migrationStatus === Util::MIGRATION_IN_PROGRESS) { + sleep(60); + $migrationStatus = $util->getMigrationStatus(); + } } // If migration not yet done From bc17b40650875102521214d5f8b7580c3193b8df Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 4 Feb 2014 17:56:53 +0100 Subject: [PATCH 18/34] LDAP: extend LDAP wrapper search method for sizelimit, improves performance in wizard --- apps/user_ldap/lib/ildapwrapper.php | 4 +++- apps/user_ldap/lib/ldap.php | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php index 20587cba7db..e60cf5ec63f 100644 --- a/apps/user_ldap/lib/ildapwrapper.php +++ b/apps/user_ldap/lib/ildapwrapper.php @@ -145,9 +145,11 @@ interface ILDAPWrapper { * @param $baseDN The DN of the entry to read from * @param $filter An LDAP filter * @param $attr array of the attributes to read + * @param $attrsonly optional, 1 if only attribute types shall be returned + * @param $limit optional, limits the result entries * @return an LDAP search result resource, false on error */ - public function search($link, $baseDN, $filter, $attr); + public function search($link, $baseDN, $filter, $attr, $attrsonly = 0, $limit = 0); /** * @brief Sets the value of the specified option to be $value diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php index dda8533c41f..a99c6480121 100644 --- a/apps/user_ldap/lib/ldap.php +++ b/apps/user_ldap/lib/ldap.php @@ -85,9 +85,9 @@ class LDAP implements ILDAPWrapper { return $this->invokeLDAPMethod('read', $link, $baseDN, $filter, $attr); } - public function search($link, $baseDN, $filter, $attr) { - return $this->invokeLDAPMethod('search', $link, $baseDN, - $filter, $attr); + public function search($link, $baseDN, $filter, $attr, $attrsonly = 0, $limit = 0) { + return $this->invokeLDAPMethod('search', $link, $baseDN, $filter, + $attr, $attrsonly, $limit); } public function setOption($link, $option, $value) { From a908bd56953edb94f48dc483278f5427d51c17b2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 4 Feb 2014 19:37:40 +0100 Subject: [PATCH 19/34] throw an info message, when base dn test failed --- apps/user_ldap/lib/wizard.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index b70ede8599c..30ce455274b 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -567,6 +567,10 @@ class Wizard extends LDAPUtility { //get a result set > 0 on a proper base $rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1); if(!$this->ldap->isResource($rr)) { + $errorNo = $this->ldap->errno($cr); + $errorMsg = $this->ldap->error($cr); + \OCP\Util::writeLog('user_ldap', 'Wiz: Could not search base '.$base. + ' Error '.$errorNo.': '.$errorMsg, \OCP\Util::INFO); return false; } $entries = $this->ldap->countEntries($cr, $rr); From e825a008c9b99199bc91b87cb0e5ca88109aa202 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Feb 2014 10:29:09 +0100 Subject: [PATCH 20/34] Wizard: disable LDAP referrals, fixes #6670 --- apps/user_ldap/lib/wizard.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index 30ce455274b..00623b74fb1 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -1014,6 +1014,7 @@ class Wizard extends LDAPUtility { $this->configuration->ldapPort); $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3); + $this->ldap->setOption($cr, LDAP_OPT_REFERRALS, 0); $this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT); if($this->configuration->ldapTLS === 1) { $this->ldap->startTls($cr); From a76840d20650b09d1a403c3f8e78dbf398a46fda Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Feb 2014 10:30:56 +0100 Subject: [PATCH 21/34] Wizard: enable base DN for editing, if not base DN could have been detected. Also part of fix for #6670 --- apps/user_ldap/js/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js index acf88ef58a4..792638f2b58 100644 --- a/apps/user_ldap/js/settings.js +++ b/apps/user_ldap/js/settings.js @@ -240,6 +240,7 @@ var LdapWizard = { LdapWizard.hideSpinner('#ldap_base'); LdapWizard.showInfoBox('Please specify a Base DN'); LdapWizard.showInfoBox('Could not determine Base DN'); + $('#ldap_base').prop('disabled', false); } ); } From e156f85bfb7ea1b6d74227a49507e1a3b0e0e374 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Feb 2014 10:33:44 +0100 Subject: [PATCH 22/34] Rephrase and clarify log message --- apps/user_ldap/lib/access.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 72f9c740921..b619f62f296 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -729,7 +729,7 @@ class Access extends LDAPUtility { } } else { if(!is_null($limit)) { - \OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO); + \OCP\Util::writeLog('user_ldap', 'Paged search was not available', \OCP\Util::INFO); } } } From 299d37154b749855915c8dbc7ab8a123c4aa27f2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 7 Feb 2014 15:55:35 +0100 Subject: [PATCH 23/34] LDAP: add documentation info in info.xml --- apps/user_ldap/appinfo/info.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml index 148a72cecbb..9cc908e8522 100644 --- a/apps/user_ldap/appinfo/info.xml +++ b/apps/user_ldap/appinfo/info.xml @@ -14,4 +14,7 @@ + + http://doc.owncloud.org/server/6.0/go.php?to=admin-ldap + From 18e1a10e96a341e3333d0d8453dd270e62192b4d Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 6 Feb 2014 22:18:38 +0100 Subject: [PATCH 24/34] LDAP: also try MS AD's thumbnailPhoto when looking for an avatar image --- apps/user_ldap/user_ldap.php | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index a19af86086c..8b6521010f1 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -85,15 +85,14 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { return; } - $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto'); - \OCP\Config::setUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', time()); - if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) { + $avatarImage = $this->getAvatarImage($uid, $dn); + if($avatarImage === false) { //not set, nothing left to do; return; } $image = new \OCP\Image(); - $image->loadFromBase64(base64_encode($jpegPhoto[0])); + $image->loadFromBase64(base64_encode($avatarImage)); if(!$image->valid()) { \OCP\Util::writeLog('user_ldap', 'jpegPhoto data invalid for '.$dn, @@ -128,8 +127,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { if(!$dn) { return false; } - $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto'); - if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) { + if($this->getAvatarImage($uid, $dn) === false) { //The user is allowed to change his avatar in ownCloud only if no //avatar is provided by LDAP return true; @@ -137,6 +135,26 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { return false; } + /** + * @brief reads the image from LDAP that shall be used as Avatar + * @param $uid string, the ownCloud user name + * @param $dn string, the user DN + * @return image data (provided by LDAP) | false + */ + private function getAvatarImage($uid, $dn) { + $attributes = array('jpegPhoto', 'thumbnailPhoto'); + foreach($attributes as $attribute) { + $result = $this->access->readAttribute($dn, $attribute); + \OCP\Config::setUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', + time()); + if($result !== false && is_array($result) && isset($result[0])) { + return $result[0]; + } + } + + return false; + } + /** * @brief Check if the password is correct * @param $uid The username From 14d1abf63f88943d376b29e31ac04265456db2a4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 7 Feb 2014 08:42:38 +0100 Subject: [PATCH 25/34] LDAP: improve debug message --- apps/user_ldap/user_ldap.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 8b6521010f1..619a992bd12 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -256,7 +256,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { } //check if user really still exists by reading its entry if(!is_array($this->access->readAttribute($dn, ''))) { - \OCP\Util::writeLog('user_ldap', 'LDAP says no user '.$dn, \OCP\Util::DEBUG); + \OCP\Util::writeLog('user_ldap', 'LDAP says no user '.$dn.' on '. + $this->access->connection->ldapHost, \OCP\Util::DEBUG); $this->access->connection->writeToCache('userExists'.$uid, false); return false; } From 71e4d965a1d468ac01b404f233397def3b580ab2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Jan 2014 13:26:08 +0100 Subject: [PATCH 26/34] on filtering the share box users and groups whose name begins with the search term shall appear on top, fixes #6430 --- core/ajax/share.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/ajax/share.php b/core/ajax/share.php index 8b48effb458..784b2528f40 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -354,8 +354,32 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo break; } } + usort($shareWith, 'sortSearchFirst'); OC_JSON::success(array('data' => $shareWith)); } break; } } + + +/** + * User and Group names matching the search term at the beginning shall appear + * on top of the share dialog. + * Callback function for usort. http://php.net/usort + */ +function sortSearchFirst($a, $b) { + $enc = 'UTF-8'; + $nameA = mb_strtolower($a['label'], $enc); + $nameB = mb_strtolower($b['label'], $enc); + $term = mb_strtolower($_GET['search'], $enc); + $i = mb_strpos($nameA, $term, 0, 'UTF-8'); + $j = mb_strpos($nameB, $term, 0, 'UTF-8'); + + if($i === $j) { + return 0; + } else if ($i === 0) { + return -1; + } else { + return 1; + } +} From 1d0a2365631955944d746b4567cac85eb10a80db Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Jan 2014 14:02:18 +0100 Subject: [PATCH 27/34] respect coding guidelines --- core/ajax/share.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 784b2528f40..5c2dbc6654d 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -377,7 +377,7 @@ function sortSearchFirst($a, $b) { if($i === $j) { return 0; - } else if ($i === 0) { + } elseif ($i === 0) { return -1; } else { return 1; From 41e8d44cf7261e05a40842ab56d4d4c3f61cf083 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Jan 2014 17:55:05 +0100 Subject: [PATCH 28/34] move sorter into a class --- core/ajax/share.php | 27 ++---------- lib/private/share/searchresultsorter.php | 53 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 lib/private/share/searchresultsorter.php diff --git a/core/ajax/share.php b/core/ajax/share.php index 5c2dbc6654d..21e320a4732 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -354,32 +354,11 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo break; } } - usort($shareWith, 'sortSearchFirst'); + $sorter = new \OC\Share\SearchResultSorter($_GET['search'], + 'label'); + usort($shareWith, array($sorter, 'sort')); OC_JSON::success(array('data' => $shareWith)); } break; } } - - -/** - * User and Group names matching the search term at the beginning shall appear - * on top of the share dialog. - * Callback function for usort. http://php.net/usort - */ -function sortSearchFirst($a, $b) { - $enc = 'UTF-8'; - $nameA = mb_strtolower($a['label'], $enc); - $nameB = mb_strtolower($b['label'], $enc); - $term = mb_strtolower($_GET['search'], $enc); - $i = mb_strpos($nameA, $term, 0, 'UTF-8'); - $j = mb_strpos($nameB, $term, 0, 'UTF-8'); - - if($i === $j) { - return 0; - } elseif ($i === 0) { - return -1; - } else { - return 1; - } -} diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php new file mode 100644 index 00000000000..27f94a694ac --- /dev/null +++ b/lib/private/share/searchresultsorter.php @@ -0,0 +1,53 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ +namespace OC\Share; + +class SearchResultSorter { + private $search; + private $encoding; + private $key; + + /** + * @param $search the search term as was given by the user + * @param $key the array key containing the value that should be compared + * against + * @param $encoding optional, encoding to use, defaults to UTF-8 + */ + public function __construct($search, $key, $encoding = 'UTF-8') { + $this->encoding = $encoding; + $this->key = $key; + $this->search = mb_strtolower($search, $this->encoding); + } + + /** + * User and Group names matching the search term at the beginning shall appear + * on top of the share dialog. + * Callback function for usort. http://php.net/usort + */ + public function sort($a, $b) { + if(!isset($a[$this->key]) || !isset($b[$this->key])) { + \OCP\Util::writeLog('core', 'Sharing: cannot sort due to missing'. + 'array key', \OC_Log::ERROR); + return 0; + } + $nameA = mb_strtolower($a[$this->key], $this->encoding); + $nameB = mb_strtolower($b[$this->key], $this->encoding); + $i = mb_strpos($nameA, $this->search, 0, $this->encoding); + $j = mb_strpos($nameB, $this->search, 0, $this->encoding); + + if($i === $j) { + return 0; + } elseif ($i === 0) { + return -1; + } else { + return 1; + } + } +} + From 82716ced48c256ef5e2f8ca9b7a4e3ab20e146cd Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Jan 2014 18:19:20 +0100 Subject: [PATCH 29/34] sort following entries in alphabetical order --- lib/private/share/searchresultsorter.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php index 27f94a694ac..f64a4766ade 100644 --- a/lib/private/share/searchresultsorter.php +++ b/lib/private/share/searchresultsorter.php @@ -27,7 +27,7 @@ class SearchResultSorter { /** * User and Group names matching the search term at the beginning shall appear - * on top of the share dialog. + * on top of the share dialog. Following entries in alphabetical order. * Callback function for usort. http://php.net/usort */ public function sort($a, $b) { @@ -41,8 +41,9 @@ class SearchResultSorter { $i = mb_strpos($nameA, $this->search, 0, $this->encoding); $j = mb_strpos($nameB, $this->search, 0, $this->encoding); - if($i === $j) { - return 0; + if($i === $j || $i > 0 && $j > 0) { + return strcmp(mb_strtolower($nameA, $this->encoding), + mb_strtolower($nameB, $this->encoding)); } elseif ($i === 0) { return -1; } else { From 9a39cd3b38837421a5ac476a78207402e4c6c91c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Jan 2014 18:26:06 +0100 Subject: [PATCH 30/34] test for share dialoge sorter --- tests/lib/share/searchresultsorter.php | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/lib/share/searchresultsorter.php diff --git a/tests/lib/share/searchresultsorter.php b/tests/lib/share/searchresultsorter.php new file mode 100644 index 00000000000..f24e40ea059 --- /dev/null +++ b/tests/lib/share/searchresultsorter.php @@ -0,0 +1,40 @@ + +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see . +*/ + +class Test_Share_Search extends \PHPUnit_Framework_TestCase { + public function testSort() { + $search = 'lin'; + $sorter = new \OC\Share\SearchResultSorter($search, 'foobar'); + + $result = array( + array('foobar' => 'woot'), + array('foobar' => 'linux'), + array('foobar' => 'Linus'), + array('foobar' => 'Bicyclerepairwoman'), + ); + + usort($result, array($sorter, 'sort')); + $this->assertTrue($result[0]['foobar'] === 'Linus'); + $this->assertTrue($result[1]['foobar'] === 'linux'); + $this->assertTrue($result[2]['foobar'] === 'Bicyclerepairwoman'); + $this->assertTrue($result[3]['foobar'] === 'woot'); + } +} From 20bfbb0fd9316be0cbba9c2202a9b45ce7eea7f8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 16 Jan 2014 10:30:18 +0100 Subject: [PATCH 31/34] wrong tld --- lib/private/share/searchresultsorter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php index f64a4766ade..4f8799494f5 100644 --- a/lib/private/share/searchresultsorter.php +++ b/lib/private/share/searchresultsorter.php @@ -1,6 +1,6 @@ + * Copyright (c) 2014 Arthur Schiwon * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. From 32afdcbefec5793fb28162c456919d2b0be5cfe9 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 16 Jan 2014 11:00:22 +0100 Subject: [PATCH 32/34] Inject logger --- lib/private/share/searchresultsorter.php | 9 ++++++--- tests/lib/share/searchresultsorter.php | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php index 4f8799494f5..f81a94c749d 100644 --- a/lib/private/share/searchresultsorter.php +++ b/lib/private/share/searchresultsorter.php @@ -12,16 +12,19 @@ class SearchResultSorter { private $search; private $encoding; private $key; + private $log; /** * @param $search the search term as was given by the user * @param $key the array key containing the value that should be compared * against * @param $encoding optional, encoding to use, defaults to UTF-8 + * @param $log optional, an \OC\Log instance */ - public function __construct($search, $key, $encoding = 'UTF-8') { + public function __construct($search, $key, $encoding = 'UTF-8', \OC\Log $log = null) { $this->encoding = $encoding; $this->key = $key; + $this->log = is_null($log) ? new \OC\Log() : $log; $this->search = mb_strtolower($search, $this->encoding); } @@ -32,8 +35,8 @@ class SearchResultSorter { */ public function sort($a, $b) { if(!isset($a[$this->key]) || !isset($b[$this->key])) { - \OCP\Util::writeLog('core', 'Sharing: cannot sort due to missing'. - 'array key', \OC_Log::ERROR); + $this->log->error('Sharing dialogue: cannot sort due to missing array key', + array('app' => 'core')); return 0; } $nameA = mb_strtolower($a[$this->key], $this->encoding); diff --git a/tests/lib/share/searchresultsorter.php b/tests/lib/share/searchresultsorter.php index f24e40ea059..efc3e1b7aa3 100644 --- a/tests/lib/share/searchresultsorter.php +++ b/tests/lib/share/searchresultsorter.php @@ -37,4 +37,11 @@ class Test_Share_Search extends \PHPUnit_Framework_TestCase { $this->assertTrue($result[2]['foobar'] === 'Bicyclerepairwoman'); $this->assertTrue($result[3]['foobar'] === 'woot'); } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testSortWrongLog() { + $sorter = new \OC\Share\SearchResultSorter('foo', 'bar', 'UTF-8', 'foobar'); + } } From af781bdea7509c3ecd9a7b4902fb7a266dc62c80 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Feb 2014 17:05:56 +0100 Subject: [PATCH 33/34] fix DI --- core/ajax/share.php | 3 ++- lib/private/share/searchresultsorter.php | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 21e320a4732..c251f8e7bae 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -355,7 +355,8 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo } } $sorter = new \OC\Share\SearchResultSorter($_GET['search'], - 'label'); + 'label', + new \OC\Log()); usort($shareWith, array($sorter, 'sort')); OC_JSON::success(array('data' => $shareWith)); } diff --git a/lib/private/share/searchresultsorter.php b/lib/private/share/searchresultsorter.php index f81a94c749d..fbf77179097 100644 --- a/lib/private/share/searchresultsorter.php +++ b/lib/private/share/searchresultsorter.php @@ -21,10 +21,10 @@ class SearchResultSorter { * @param $encoding optional, encoding to use, defaults to UTF-8 * @param $log optional, an \OC\Log instance */ - public function __construct($search, $key, $encoding = 'UTF-8', \OC\Log $log = null) { + public function __construct($search, $key, \OC\Log $log = null, $encoding = 'UTF-8') { $this->encoding = $encoding; $this->key = $key; - $this->log = is_null($log) ? new \OC\Log() : $log; + $this->log = $log; $this->search = mb_strtolower($search, $this->encoding); } @@ -35,8 +35,10 @@ class SearchResultSorter { */ public function sort($a, $b) { if(!isset($a[$this->key]) || !isset($b[$this->key])) { - $this->log->error('Sharing dialogue: cannot sort due to missing array key', - array('app' => 'core')); + if(!is_null($this->log)) { + $this->log->error('Sharing dialogue: cannot sort due to ' . + 'missing array key', array('app' => 'core')); + } return 0; } $nameA = mb_strtolower($a[$this->key], $this->encoding); From 72f134cfce05eb089a6d8271e73d6eb95cbe94a4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Feb 2014 17:12:17 +0100 Subject: [PATCH 34/34] intendation --- tests/lib/share/searchresultsorter.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/lib/share/searchresultsorter.php b/tests/lib/share/searchresultsorter.php index efc3e1b7aa3..eaf93400a7d 100644 --- a/tests/lib/share/searchresultsorter.php +++ b/tests/lib/share/searchresultsorter.php @@ -25,11 +25,11 @@ class Test_Share_Search extends \PHPUnit_Framework_TestCase { $sorter = new \OC\Share\SearchResultSorter($search, 'foobar'); $result = array( - array('foobar' => 'woot'), - array('foobar' => 'linux'), - array('foobar' => 'Linus'), - array('foobar' => 'Bicyclerepairwoman'), - ); + array('foobar' => 'woot'), + array('foobar' => 'linux'), + array('foobar' => 'Linus'), + array('foobar' => 'Bicyclerepairwoman'), + ); usort($result, array($sorter, 'sort')); $this->assertTrue($result[0]['foobar'] === 'Linus');