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