From d09b5b6441fa2464fba24f84eff22348b879676c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= <grosse@cosmocode.de> Date: Thu, 22 Mar 2018 14:22:41 +0100 Subject: [PATCH] feat(search): add config options to adjust default behavior This adds two new config options: `search_limit_to_first_ns`: Limit the search to the current X namespaces. When a search is executed from a page within a deeper namespace, the first X namespaces will be added as filter. Possible use case could be with language namespaces to ensure that the default search is initially within the current language. `search_default_fragment_behaviour`: Option to specify the default fragment search behavior --- conf/dokuwiki.php | 2 + inc/Action/Search.php | 74 ++++++++++++++++++- inc/Ui/Search.php | 13 +++- lib/plugins/config/lang/en/lang.php | 6 ++ .../config/settings/config.metadata.php | 2 + 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php index c87a7cd0c..97f396ed6 100644 --- a/conf/dokuwiki.php +++ b/conf/dokuwiki.php @@ -156,6 +156,8 @@ $conf['broken_iua'] = 0; //Platform with broken ignore_user_abor $conf['xsendfile'] = 0; //Use X-Sendfile (1 = lighttpd, 2 = standard) $conf['renderer_xhtml'] = 'xhtml'; //renderer to use for main page generation $conf['readdircache'] = 0; //time cache in second for the readdir operation, 0 to deactivate. +$conf['search_limit_to_first_ns'] = 0; //Option to limit the search to the current X namespaces +$conf['search_default_fragment_behaviour'] = 'exact'; // Option to specify the default fragment search behavior /* Network Settings */ $conf['dnslookups'] = 1; //disable to disallow IP to hostname lookups diff --git a/inc/Action/Search.php b/inc/Action/Search.php index 1fa19d889..f848d8752 100644 --- a/inc/Action/Search.php +++ b/inc/Action/Search.php @@ -30,11 +30,79 @@ class Search extends AbstractAction { if($s === '') throw new ActionAbort(); } + public function preProcess() + { + $this->adjustGlobalQuery(); + } + /** @inheritdoc */ - public function tplContent() { - global $QUERY; - $search = new \dokuwiki\Ui\Search($QUERY); + public function tplContent() + { + $search = new \dokuwiki\Ui\Search(); $search->execute(); $search->show(); } + + /** + * Adjust the global query accordingly to the config search_limit_to_first_ns and search_default_fragment_behaviour + * + * This will only do something if the search didn't originate from the form on the searchpage itself + */ + protected function adjustGlobalQuery() + { + global $conf, $INPUT, $QUERY; + + if ($INPUT->bool('searchPageForm')) { + return; + } + + $Indexer = idx_get_indexer(); + $parsedQuery = ft_queryParser($Indexer, $QUERY); + + if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) { + if ($conf['search_limit_to_first_ns'] > 0) { + $searchOriginPage = $INPUT->str('from'); + if (getNS($searchOriginPage) !== false) { + $nsParts = explode(':', getNS($searchOriginPage)); + $ns = implode(':', array_slice($nsParts, 0, $conf['search_limit_to_first_ns'])); + $QUERY .= " @$ns"; + } + } + } + + if ($conf['search_default_fragment_behaviour'] !== 'exact') { + if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) { + if (strpos($QUERY, '*') === false) { + $queryParts = explode(' ', $QUERY); + $queryParts = array_map(function ($part) { + if (strpos($part, '@') === 0) { + return $part; + } + if (strpos($part, 'ns:') === 0) { + return $part; + } + if (strpos($part, '^') === 0) { + return $part; + } + if (strpos($part, '-ns:') === 0) { + return $part; + } + + global $conf; + + if ($conf['search_default_fragment_behaviour'] === 'starts_with') { + return $part . '*'; + } + if ($conf['search_default_fragment_behaviour'] === 'ends_with') { + return '*' . $part; + } + + return '*' . $part . '*'; + + }, $queryParts); + $QUERY = implode(' ', $queryParts); + } + } + } + } } diff --git a/inc/Ui/Search.php b/inc/Ui/Search.php index 2e09ee935..0fab58db4 100644 --- a/inc/Ui/Search.php +++ b/inc/Ui/Search.php @@ -17,11 +17,15 @@ class Search extends Ui * * @param string $query the search query */ - public function __construct($query) + public function __construct() { - $this->query = $query; + global $QUERY; + $Indexer = idx_get_indexer(); - $this->parsedQuery = ft_queryParser($Indexer, $query); + $parsedQuery = ft_queryParser($Indexer, $QUERY); + + $this->query = $QUERY; + $this->parsedQuery = $parsedQuery; } /** @@ -68,8 +72,9 @@ class Search extends Ui $searchForm = (new Form())->attrs(['method' => 'get'])->addClass('search-results-form'); $searchForm->setHiddenField('do', 'search'); $searchForm->setHiddenField('from', $ID); + $searchForm->setHiddenField('searchPageForm', '1'); $searchForm->addFieldsetOpen()->addClass('search-results-form__fieldset'); - $searchForm->addTextInput('id')->val($query); + $searchForm->addTextInput('id')->val($query)->useInput(false); $searchForm->addButton('', $lang['btn_search'])->attr('type', 'submit'); if ($this->isSearchAssistanceAvailable($this->parsedQuery)) { diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php index 269d24f4c..cee84604c 100644 --- a/lib/plugins/config/lang/en/lang.php +++ b/lib/plugins/config/lang/en/lang.php @@ -178,6 +178,12 @@ $lang['xsendfile'] = 'Use the X-Sendfile header to let the webserver deliver s $lang['renderer_xhtml'] = 'Renderer to use for main (xhtml) wiki output'; $lang['renderer__core'] = '%s (dokuwiki core)'; $lang['renderer__plugin'] = '%s (plugin)'; +$lang['search_limit_to_first_ns'] = 'Limit the search to the current X namespaces. When a search is executed from a page within a deeper namespace, the first X namespaces will be added as filter'; +$lang['search_default_fragment_behaviour'] = 'Specify the default fragment search behavior'; +$lang['search_default_fragment_behaviour_o_exact'] = 'exact'; +$lang['search_default_fragment_behaviour_o_starts_with'] = 'starts with'; +$lang['search_default_fragment_behaviour_o_ends_with'] = 'ends with'; +$lang['search_default_fragment_behaviour_o_contains'] = 'contains'; /* Network Options */ $lang['dnslookups'] = 'DokuWiki will lookup hostnames for remote IP addresses of users editing pages. If you have a slow or non working DNS server or don\'t want this feature, disable this option'; diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php index 0527bb9c3..750245957 100644 --- a/lib/plugins/config/settings/config.metadata.php +++ b/lib/plugins/config/settings/config.metadata.php @@ -219,6 +219,8 @@ $meta['broken_iua'] = array('onoff'); $meta['xsendfile'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'warning'); $meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'),'_caution' => 'warning'); $meta['readdircache'] = array('numeric'); +$meta['search_limit_to_first_ns'] = array('numeric', '_min' => 0); +$meta['search_default_fragment_behaviour'] = array('multichoice','_choices' => array('exact', 'starts_with', 'ends_with', 'contains'),); $meta['_network'] = array('fieldset'); $meta['dnslookups'] = array('onoff'); -- GitLab