From a5f0f3f4f6eb5f212d6c5fa0bfa72a19c44b0c37 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 | 47 ++++++++++++------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index 6b3208dc28..8f44e650c4 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -427,6 +427,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 fc22cf5596..95dbda9933 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -451,20 +451,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 */ 'trashbin_retention_obligation' => 'auto', @@ -491,19 +491,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 */ 'versions_retention_obligation' => 'auto', @@ -1064,6 +1064,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 26c8f82ba23b202fcd120d1a525838294a66ecd1 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/js/sharedialogview.js | 52 +++++++++++++++++++++---- lib/private/Template/JSConfigHelper.php | 4 +- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index f5fff61b9a..21993aa3b6 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 f17c6a1619..701ca09a9b 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' => $this->config->getSystemValue('enable_avatars', true) === true, '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 fef75ff2c0257d66071079da20d700d240a1d6fa 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 8f44e650c4..5261fc8031 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -429,13 +429,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 21993aa3b6..552050f06b 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 701ca09a9b..010e7b1ca6 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -207,8 +207,8 @@ class JSConfigHelper { 'enable_avatars' => $this->config->getSystemValue('enable_avatars', true) === true, '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 decdb06e8923d52ea525d289c48f28283e41f85c 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 5261fc8031..d6b517f3c4 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; @@ -423,7 +423,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) { @@ -431,7 +431,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 @@ -507,7 +507,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) { @@ -559,7 +559,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 59f4ffb9a38b778519d8fd5e766d2039cee7275f 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 d6b517f3c4..2fb554f392 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -429,13 +429,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 187e76a184559f1b555c19377a146cf9dd330a5d 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 552050f06b..3cd6f2e246 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 }