From 869ea38ffe77e92b9a5651fe07020b4035d1f1d3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 21 Feb 2017 18:10:38 +0100 Subject: [PATCH 1/6] allow to configure a min-length of search strings for auto-compeltion and a max number for of results returned Signed-off-by: Bjoern Schiessle --- .../lib/Controller/ShareesAPIController.php | 12 +++++ config/config.sample.php | 49 ++++++++++++------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 40a9b272bc..171fac4dbd 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -413,6 +413,18 @@ class ShareesAPIController extends OCSController { * @throws OCSBadRequestException */ public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) { + + // only search for string larger than a given threshold + $threshold = $this->config->getSystemValue('sharing.minSearchStringLength', 0); + if (strlen($search) < $threshold) { + return new Http\DataResponse($this->result); + } + + // never return more than the max. number of results configured in the config.php + $maxResults = $this->config->getSystemValue('sharing.maxAutocompleteResults', 0); + if ($maxResults > 0) { + $perPage = min($perPage, $maxResults); + } if ($perPage <= 0) { throw new OCSBadRequestException('Invalid perPage argument'); } diff --git a/config/config.sample.php b/config/config.sample.php index 2a1387cecd..3ad8ffc832 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -188,7 +188,7 @@ $CONFIG = array( /** * Lifetime of the remember login cookie, which is set when the user clicks - * the ``remember`` checkbox on the login screen. + * the ``remember`` checkbox on the login screen. * * Defaults to ``60*60*24*15`` seconds (15 days) */ @@ -497,20 +497,20 @@ $CONFIG = array( * * Available values: * - * * ``auto`` - * default setting. keeps files and folders in the trash bin for 30 days - * and automatically deletes anytime after that if space is needed (note: + * * ``auto`` + * default setting. keeps files and folders in the trash bin for 30 days + * and automatically deletes anytime after that if space is needed (note: * files may not be deleted if space is not needed). - * * ``D, auto`` - * keeps files and folders in the trash bin for D+ days, delete anytime if + * * ``D, auto`` + * keeps files and folders in the trash bin for D+ days, delete anytime if * space needed (note: files may not be deleted if space is not needed) - * * ``auto, D`` - * delete all files in the trash bin that are older than D days + * * ``auto, D`` + * delete all files in the trash bin that are older than D days * automatically, delete other files anytime if space needed - * * ``D1, D2`` - * keep files and folders in the trash bin for at least D1 days and + * * ``D1, D2`` + * keep files and folders in the trash bin for at least D1 days and * delete when exceeds D2 days - * * ``disabled`` + * * ``disabled`` * trash bin auto clean disabled, files and folders will be kept forever * * Defaults to ``auto`` @@ -539,19 +539,19 @@ $CONFIG = array( * * Available values: * - * * ``auto`` - * default setting. Automatically expire versions according to expire + * * ``auto`` + * default setting. Automatically expire versions according to expire * rules. Please refer to :doc:`../configuration_files/file_versioning` for * more information. - * * ``D, auto`` - * keep versions at least for D days, apply expire rules to all versions + * * ``D, auto`` + * keep versions at least for D days, apply expire rules to all versions * that are older than D days - * * ``auto, D`` - * delete all versions that are older than D days automatically, delete + * * ``auto, D`` + * delete all versions that are older than D days automatically, delete * other versions according to expire rules - * * ``D1, D2`` + * * ``D1, D2`` * keep versions for at least D1 days and delete when exceeds D2 days - * * ``disabled`` + * * ``disabled`` * versions auto clean disabled, versions will be kept forever * * Defaults to ``auto`` @@ -1185,6 +1185,17 @@ $CONFIG = array( */ 'sharing.managerFactory' => '\OC\Share20\ProviderFactory', +/** + * Define max number of results returned by the user search for auto-completion + * Default is unlimited (value set to 0). + */ +'sharing.maxAutocompleteResults' => 0, + +/** + * Define the minimum length of the search string before we start auto-completion + * Default is no limit (value set to 0) + */ +'sharing.minSearchStringLength' => 0, /** From 3284efd1996854df0252d3e40574759e698b812d Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 21 Feb 2017 17:07:07 -0600 Subject: [PATCH 2/6] Improve the UX for sharing settings * shows a info when list is potentially truncated * shows a warning when characters length is not enough Signed-off-by: Morris Jobke --- core/css/share.scss | 5 +++ core/js/sharedialogview.js | 52 +++++++++++++++++++++---- lib/private/Template/JSConfigHelper.php | 4 +- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/core/css/share.scss b/core/css/share.scss index 8852ad2748..6d98dc7494 100644 --- a/core/css/share.scss +++ b/core/css/share.scss @@ -78,6 +78,11 @@ } } +.ui-autocomplete .autocomplete-note { + padding: 5px 10px; + color: rgba(0, 0, 0, .3); +} + #shareWithList { list-style-type: none; padding: 8px; diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 60cd97fb57..bbc40c9c8d 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -130,18 +130,46 @@ }, autocompleteHandler: function (search, response) { - var view = this; - var $loading = this.$el.find('.shareWithLoading'); + var $shareWithField = $('.shareWithField'), + view = this, + $loading = this.$el.find('.shareWithLoading'), + $remoteShareInfo = this.$el.find('.shareWithRemoteInfo'); + + var count = oc_config['sharing.minSearchStringLength']; + if (search.term.trim().length < count) { + var title = n('core', + 'At least {count} character are needed for autocompletion', + 'At least {count} characters are needed for autocompletion', + count, + { count: count } + ); + $shareWithField.addClass('error') + .attr('data-original-title', title) + .tooltip('hide') + .tooltip({ + placement: 'bottom', + trigger: 'manual' + }) + .tooltip('fixTitle') + .tooltip('show'); + response(); + return; + } + $loading.removeClass('hidden'); $loading.addClass('inlineblock'); - var $remoteShareInfo = this.$el.find('.shareWithRemoteInfo'); $remoteShareInfo.addClass('hidden'); + + $shareWithField.removeClass('error') + .tooltip('hide'); + + var perPage = 200; $.get( OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', { format: 'json', search: search.term.trim(), - perPage: 200, + perPage: perPage, itemType: view.model.get('itemType') }, function (result) { @@ -232,16 +260,24 @@ var suggestions = users.concat(groups).concat(remotes).concat(emails).concat(lookup); if (suggestions.length > 0) { - $('.shareWithField').removeClass('error') - .tooltip('hide') + $shareWithField .autocomplete("option", "autoFocus", true); + response(suggestions); + + // show a notice that the list is truncated + // this is the case if one of the search results is at least as long as the max result config option + if(Math.min(perPage, oc_config['sharing.maxAutocompleteResults']) <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) { + var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.'); + $('.ui-autocomplete').append('
  • ' + message + '
  • '); + } + } else { - var title = t('core', 'No users or groups found for {search}', {search: $('.shareWithField').val()}); + var title = t('core', 'No users or groups found for {search}', {search: $shareWithField.val()}); if (!view.configModel.get('allowGroupSharing')) { title = t('core', 'No users found for {search}', {search: $('.shareWithField').val()}); } - $('.shareWithField').addClass('error') + $shareWithField.addClass('error') .attr('data-original-title', title) .tooltip('hide') .tooltip({ diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index 1c241989fd..7a4e8415e7 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -206,7 +206,9 @@ class JSConfigHelper { 'versionstring' => \OC_Util::getVersionString(), 'enable_avatars' => true, // here for legacy reasons - to not crash existing code that relies on this value 'lost_password_link'=> $this->config->getSystemValue('lost_password_link', null), - 'modRewriteWorking' => (\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'), + 'modRewriteWorking' => ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'), + 'sharing.maxAutocompleteResults' => $this->config->getSystemValue('sharing.maxAutocompleteResults', 0), + 'sharing.minSearchStringLength' => $this->config->getSystemValue('sharing.minSearchStringLength', 0), ]), "oc_appconfig" => json_encode([ 'core' => [ From 8e3d0fecd237a457fe66e00bc293923dae9a5adf Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 21 Feb 2017 17:22:06 -0600 Subject: [PATCH 3/6] Use intval() for validation of config options Signed-off-by: Morris Jobke --- apps/files_sharing/lib/Controller/ShareesAPIController.php | 4 ++-- core/js/sharedialogview.js | 5 ++++- lib/private/Template/JSConfigHelper.php | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 171fac4dbd..73f804faac 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -415,13 +415,13 @@ class ShareesAPIController extends OCSController { public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) { // only search for string larger than a given threshold - $threshold = $this->config->getSystemValue('sharing.minSearchStringLength', 0); + $threshold = intval($this->config->getSystemValue('sharing.minSearchStringLength', 0)); if (strlen($search) < $threshold) { return new Http\DataResponse($this->result); } // never return more than the max. number of results configured in the config.php - $maxResults = $this->config->getSystemValue('sharing.maxAutocompleteResults', 0); + $maxResults = intval($this->config->getSystemValue('sharing.maxAutocompleteResults', 0)); if ($maxResults > 0) { $perPage = min($perPage, $maxResults); } diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index bbc40c9c8d..6a92c6a8dd 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -267,7 +267,10 @@ // show a notice that the list is truncated // this is the case if one of the search results is at least as long as the max result config option - if(Math.min(perPage, oc_config['sharing.maxAutocompleteResults']) <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) { + if(oc_config['sharing.maxAutocompleteResults'] > 0 && + Math.min(perPage, oc_config['sharing.maxAutocompleteResults']) + <= Math.max(users.length, groups.length, remotes.length, emails.length, lookup.length)) { + var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.'); $('.ui-autocomplete').append('
  • ' + message + '
  • '); } diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index 7a4e8415e7..6bf08dcdad 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -207,8 +207,8 @@ class JSConfigHelper { 'enable_avatars' => true, // here for legacy reasons - to not crash existing code that relies on this value 'lost_password_link'=> $this->config->getSystemValue('lost_password_link', null), 'modRewriteWorking' => ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true'), - 'sharing.maxAutocompleteResults' => $this->config->getSystemValue('sharing.maxAutocompleteResults', 0), - 'sharing.minSearchStringLength' => $this->config->getSystemValue('sharing.minSearchStringLength', 0), + 'sharing.maxAutocompleteResults' => intval($this->config->getSystemValue('sharing.maxAutocompleteResults', 0)), + 'sharing.minSearchStringLength' => intval($this->config->getSystemValue('sharing.minSearchStringLength', 0)), ]), "oc_appconfig" => json_encode([ 'core' => [ From 02ea84f50f79ff6df8bada46d7c1fe0287cbd636 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Tue, 21 Feb 2017 17:24:40 -0600 Subject: [PATCH 4/6] properly include class Signed-off-by: Morris Jobke --- .../lib/Controller/ShareesAPIController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 73f804faac..838dd1adf9 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -24,7 +24,7 @@ */ namespace OCA\Files_Sharing\Controller; -use OCP\AppFramework\Http; +use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCSController; use OCP\Contacts\IManager; @@ -409,7 +409,7 @@ class ShareesAPIController extends OCSController { * @param int $perPage * @param int|int[] $shareType * @param bool $lookup - * @return Http\DataResponse + * @return DataResponse * @throws OCSBadRequestException */ public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) { @@ -417,7 +417,7 @@ class ShareesAPIController extends OCSController { // only search for string larger than a given threshold $threshold = intval($this->config->getSystemValue('sharing.minSearchStringLength', 0)); if (strlen($search) < $threshold) { - return new Http\DataResponse($this->result); + return new DataResponse($this->result); } // never return more than the max. number of results configured in the config.php @@ -493,7 +493,7 @@ class ShareesAPIController extends OCSController { * @param int $page * @param int $perPage * @param bool $lookup - * @return Http\DataResponse + * @return DataResponse * @throws OCSBadRequestException */ protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) { @@ -545,7 +545,7 @@ class ShareesAPIController extends OCSController { $this->result['exact']['emails'] = $mailResults['exact']; } - $response = new Http\DataResponse($this->result); + $response = new DataResponse($this->result); if (sizeof($this->reachedEndFor) < 3) { $response->addHeader('Link', $this->getPaginationLink($page, [ From fe46c6f7439de71b33de21f937627a29f27a4844 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 22 Feb 2017 15:14:36 +0100 Subject: [PATCH 5/6] use (int) instead of intval for performance reasons Signed-off-by: Bjoern Schiessle --- apps/files_sharing/lib/Controller/ShareesAPIController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 838dd1adf9..e4b5b0ce19 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -415,13 +415,13 @@ class ShareesAPIController extends OCSController { public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) { // only search for string larger than a given threshold - $threshold = intval($this->config->getSystemValue('sharing.minSearchStringLength', 0)); + $threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0); if (strlen($search) < $threshold) { return new DataResponse($this->result); } // never return more than the max. number of results configured in the config.php - $maxResults = intval($this->config->getSystemValue('sharing.maxAutocompleteResults', 0)); + $maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0); if ($maxResults > 0) { $perPage = min($perPage, $maxResults); } From 11e5a3dcf4767149a3f7e14deb8e684bb6500276 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 22 Feb 2017 16:28:42 +0100 Subject: [PATCH 6/6] fix typo Signed-off-by: Bjoern Schiessle --- core/js/sharedialogview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 6a92c6a8dd..a63960da2b 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -138,7 +138,7 @@ var count = oc_config['sharing.minSearchStringLength']; if (search.term.trim().length < count) { var title = n('core', - 'At least {count} character are needed for autocompletion', + 'At least {count} character is needed for autocompletion', 'At least {count} characters are needed for autocompletion', count, { count: count }