1<?php 2 3namespace dokuwiki\Action; 4 5use dokuwiki\Action\Exception\ActionAbort; 6 7/** 8 * Class Search 9 * 10 * Search for pages and content 11 * 12 * @package dokuwiki\Action 13 */ 14class Search extends AbstractAction 15{ 16 protected $pageLookupResults = []; 17 protected $fullTextResults = []; 18 protected $highlight = []; 19 20 /** @inheritdoc */ 21 public function minimumPermission() 22 { 23 return AUTH_NONE; 24 } 25 26 /** 27 * we only search if a search word was given 28 * 29 * @inheritdoc 30 */ 31 public function checkPreconditions() 32 { 33 parent::checkPreconditions(); 34 } 35 36 public function preProcess() 37 { 38 global $QUERY, $ID, $conf, $INPUT; 39 $s = cleanID($QUERY); 40 41 if ($ID !== $conf['start'] && !$INPUT->has('q')) { 42 parse_str($INPUT->server->str('QUERY_STRING'), $urlParts); 43 $urlParts['q'] = $urlParts['id']; 44 unset($urlParts['id']); 45 $url = wl($ID, $urlParts, true, '&'); 46 send_redirect($url); 47 } 48 49 if ($s === '') throw new ActionAbort(); 50 $this->adjustGlobalQuery(); 51 } 52 53 /** @inheritdoc */ 54 public function tplContent() 55 { 56 $this->execute(); 57 58 $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight); 59 $search->show(); 60 } 61 62 63 /** 64 * run the search 65 */ 66 protected function execute() 67 { 68 global $INPUT, $QUERY; 69 $after = $INPUT->str('min'); 70 $before = $INPUT->str('max'); 71 $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'), $after, $before); 72 $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'), $after, $before); 73 $this->highlight = $highlight; 74 } 75 76 /** 77 * Adjust the global query accordingly to the config search_nslimit and search_fragment 78 * 79 * This will only do something if the search didn't originate from the form on the searchpage itself 80 */ 81 protected function adjustGlobalQuery() 82 { 83 global $conf, $INPUT, $QUERY, $ID; 84 85 if ($INPUT->bool('sf')) { 86 return; 87 } 88 89 $Indexer = idx_get_indexer(); 90 $parsedQuery = ft_queryParser($Indexer, $QUERY); 91 92 if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) { 93 if ($conf['search_nslimit'] > 0) { 94 if (getNS($ID) !== false) { 95 $nsParts = explode(':', getNS($ID)); 96 $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit'])); 97 $QUERY .= " @$ns"; 98 } 99 } 100 } 101 102 if ($conf['search_fragment'] !== 'exact') { 103 if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) { 104 if (strpos($QUERY, '*') === false) { 105 $queryParts = explode(' ', $QUERY); 106 $queryParts = array_map(function ($part) { 107 if (strpos($part, '@') === 0) { 108 return $part; 109 } 110 if (strpos($part, 'ns:') === 0) { 111 return $part; 112 } 113 if (strpos($part, '^') === 0) { 114 return $part; 115 } 116 if (strpos($part, '-ns:') === 0) { 117 return $part; 118 } 119 120 global $conf; 121 122 if ($conf['search_fragment'] === 'starts_with') { 123 return $part . '*'; 124 } 125 if ($conf['search_fragment'] === 'ends_with') { 126 return '*' . $part; 127 } 128 129 return '*' . $part . '*'; 130 }, $queryParts); 131 $QUERY = implode(' ', $queryParts); 132 } 133 } 134 } 135 } 136} 137