164ab5140SAndreas Gohr<?php 264ab5140SAndreas Gohr 364ab5140SAndreas Gohrnamespace dokuwiki\Action; 464ab5140SAndreas Gohr 564ab5140SAndreas Gohruse dokuwiki\Action\Exception\ActionAbort; 60cba610bSSatoshi Saharause dokuwiki\Search\FulltextSearch; 70cba610bSSatoshi Saharause dokuwiki\Search\MetadataSearch; 80cba610bSSatoshi Saharause dokuwiki\Search\QueryParser; 964ab5140SAndreas Gohr 10ab583a1bSAndreas Gohr/** 11ab583a1bSAndreas Gohr * Class Search 12ab583a1bSAndreas Gohr * 13ab583a1bSAndreas Gohr * Search for pages and content 14ab583a1bSAndreas Gohr * 15ab583a1bSAndreas Gohr * @package dokuwiki\Action 16ab583a1bSAndreas Gohr */ 1764ab5140SAndreas Gohrclass Search extends AbstractAction { 1864ab5140SAndreas Gohr 196639a152SMichael Große protected $pageLookupResults = array(); 206639a152SMichael Große protected $fullTextResults = array(); 216639a152SMichael Große protected $highlight = array(); 226639a152SMichael Große 2364ab5140SAndreas Gohr /** @inheritdoc */ 24ec701221SAndreas Gohr public function minimumPermission() { 2564ab5140SAndreas Gohr return AUTH_NONE; 2664ab5140SAndreas Gohr } 2764ab5140SAndreas Gohr 2864ab5140SAndreas Gohr /** 2964ab5140SAndreas Gohr * we only search if a search word was given 3064ab5140SAndreas Gohr * 3164ab5140SAndreas Gohr * @inheritdoc 3264ab5140SAndreas Gohr */ 33b2c9cd19SAndreas Gohr public function checkPreconditions() { 34b2c9cd19SAndreas Gohr parent::checkPreconditions(); 3564ab5140SAndreas Gohr } 3664ab5140SAndreas Gohr 37d09b5b64SMichael Große public function preProcess() 38d09b5b64SMichael Große { 39d22b78c8SMichael Große global $QUERY, $ID, $conf, $INPUT; 40d22b78c8SMichael Große $s = cleanID($QUERY); 41d22b78c8SMichael Große 423286c65dSMichael Große if ($ID !== $conf['start'] && !$INPUT->has('q')) { 43d22b78c8SMichael Große parse_str($INPUT->server->str('QUERY_STRING'), $urlParts); 44d22b78c8SMichael Große $urlParts['q'] = $urlParts['id']; 45918638dcSSchplurtz le Déboulonné unset($urlParts['id']); 46cc21cb50SAndreas Gohr $url = wl($ID, $urlParts, true, '&'); 47d22b78c8SMichael Große send_redirect($url); 48d22b78c8SMichael Große } 49d22b78c8SMichael Große 50d22b78c8SMichael Große if ($s === '') throw new ActionAbort(); 51d09b5b64SMichael Große $this->adjustGlobalQuery(); 52d09b5b64SMichael Große } 53d09b5b64SMichael Große 5464ab5140SAndreas Gohr /** @inheritdoc */ 55d09b5b64SMichael Große public function tplContent() 56d09b5b64SMichael Große { 576639a152SMichael Große $this->execute(); 586639a152SMichael Große 596639a152SMichael Große $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight); 6021fcef82SMichael Große $search->show(); 6164ab5140SAndreas Gohr } 62d09b5b64SMichael Große 636639a152SMichael Große 646639a152SMichael Große /** 656639a152SMichael Große * run the search 666639a152SMichael Große */ 676639a152SMichael Große protected function execute() 686639a152SMichael Große { 696639a152SMichael Große global $INPUT, $QUERY; 70422bbbc6SMichael Große $after = $INPUT->str('min'); 71422bbbc6SMichael Große $before = $INPUT->str('max'); 72*9329b002SSatoshi Sahara $MetadataSearch = MetadataSearch::getInstance(); 73*9329b002SSatoshi Sahara $this->pageLookupResults = $MetadataSearch->pageLookup( 74*9329b002SSatoshi Sahara $QUERY, true, useHeading('navigation'), $after, $before 75*9329b002SSatoshi Sahara ); 76*9329b002SSatoshi Sahara $FulltextSearch = FulltextSearch::getInstance(); 77*9329b002SSatoshi Sahara $this->fullTextResults = $FulltextSearch->pageSearch( 78*9329b002SSatoshi Sahara $QUERY, $highlight, $INPUT->str('srt'), $after, $before 79*9329b002SSatoshi Sahara ); 806639a152SMichael Große $this->highlight = $highlight; 816639a152SMichael Große } 826639a152SMichael Große 83d09b5b64SMichael Große /** 8413ce475dSAndreas Gohr * Adjust the global query accordingly to the config search_nslimit and search_fragment 85d09b5b64SMichael Große * 86d09b5b64SMichael Große * This will only do something if the search didn't originate from the form on the searchpage itself 87d09b5b64SMichael Große */ 88d09b5b64SMichael Große protected function adjustGlobalQuery() 89d09b5b64SMichael Große { 90340f849aSMichael Große global $conf, $INPUT, $QUERY, $ID; 91d09b5b64SMichael Große 921265b193SMichael Große if ($INPUT->bool('sf')) { 93d09b5b64SMichael Große return; 94d09b5b64SMichael Große } 95d09b5b64SMichael Große 96*9329b002SSatoshi Sahara $parsedQuery = (new QueryParser)->convert($QUERY); 97d09b5b64SMichael Große 98d09b5b64SMichael Große if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) { 9913ce475dSAndreas Gohr if ($conf['search_nslimit'] > 0) { 100340f849aSMichael Große if (getNS($ID) !== false) { 101340f849aSMichael Große $nsParts = explode(':', getNS($ID)); 10213ce475dSAndreas Gohr $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit'])); 103d09b5b64SMichael Große $QUERY .= " @$ns"; 104d09b5b64SMichael Große } 105d09b5b64SMichael Große } 106d09b5b64SMichael Große } 107d09b5b64SMichael Große 10813ce475dSAndreas Gohr if ($conf['search_fragment'] !== 'exact') { 109d09b5b64SMichael Große if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) { 110d09b5b64SMichael Große if (strpos($QUERY, '*') === false) { 111d09b5b64SMichael Große $queryParts = explode(' ', $QUERY); 112d09b5b64SMichael Große $queryParts = array_map(function ($part) { 113d09b5b64SMichael Große if (strpos($part, '@') === 0) { 114d09b5b64SMichael Große return $part; 115d09b5b64SMichael Große } 116d09b5b64SMichael Große if (strpos($part, 'ns:') === 0) { 117d09b5b64SMichael Große return $part; 118d09b5b64SMichael Große } 119d09b5b64SMichael Große if (strpos($part, '^') === 0) { 120d09b5b64SMichael Große return $part; 121d09b5b64SMichael Große } 122d09b5b64SMichael Große if (strpos($part, '-ns:') === 0) { 123d09b5b64SMichael Große return $part; 124d09b5b64SMichael Große } 125d09b5b64SMichael Große 126d09b5b64SMichael Große global $conf; 127d09b5b64SMichael Große 12813ce475dSAndreas Gohr if ($conf['search_fragment'] === 'starts_with') { 129d09b5b64SMichael Große return $part . '*'; 130d09b5b64SMichael Große } 13113ce475dSAndreas Gohr if ($conf['search_fragment'] === 'ends_with') { 132d09b5b64SMichael Große return '*' . $part; 133d09b5b64SMichael Große } 134d09b5b64SMichael Große 135d09b5b64SMichael Große return '*' . $part . '*'; 136d09b5b64SMichael Große 137d09b5b64SMichael Große }, $queryParts); 138d09b5b64SMichael Große $QUERY = implode(' ', $queryParts); 139d09b5b64SMichael Große } 140d09b5b64SMichael Große } 141d09b5b64SMichael Große } 142d09b5b64SMichael Große } 14364ab5140SAndreas Gohr} 144