diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php index c87a7cd0cf678cea41af8d6acb0727758c7d9ceb..97f396ed6f8f645047f69af7d7167ffd294135da 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 1fa19d88914bb30e39a525004a37b07934fc2edb..f848d87524354dfdc6f312c65ec6701bb6398de1 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 2e09ee935ad5fea31549ee72d377b87a3d01680b..0fab58db46cc099889427ebc9b3f5b8856508f45 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 269d24f4c96a601abc3906e8d4daf74d1af75695..cee84604cfde26e843993a83a4bf3a81084bb657 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 0527bb9c3ea730947f5ad323880f1985f979ecd9..750245957dbd38a4fd7a67b396ceed91a6652f80 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');