xref: /dokuwiki/inc/Action/Search.php (revision 1265b1930c74888a3474df6c6cf1e1c1c01f9c9e)
164ab5140SAndreas Gohr<?php
264ab5140SAndreas Gohr
364ab5140SAndreas Gohrnamespace dokuwiki\Action;
464ab5140SAndreas Gohr
564ab5140SAndreas Gohruse dokuwiki\Action\Exception\ActionAbort;
664ab5140SAndreas Gohr
7ab583a1bSAndreas Gohr/**
8ab583a1bSAndreas Gohr * Class Search
9ab583a1bSAndreas Gohr *
10ab583a1bSAndreas Gohr * Search for pages and content
11ab583a1bSAndreas Gohr *
12ab583a1bSAndreas Gohr * @package dokuwiki\Action
13ab583a1bSAndreas Gohr */
1464ab5140SAndreas Gohrclass Search extends AbstractAction {
1564ab5140SAndreas Gohr
166639a152SMichael Große    protected $pageLookupResults = array();
176639a152SMichael Große    protected $fullTextResults = array();
186639a152SMichael Große    protected $highlight = array();
196639a152SMichael Große
2064ab5140SAndreas Gohr    /** @inheritdoc */
21ec701221SAndreas Gohr    public function minimumPermission() {
2264ab5140SAndreas Gohr        return AUTH_NONE;
2364ab5140SAndreas Gohr    }
2464ab5140SAndreas Gohr
2564ab5140SAndreas Gohr    /**
2664ab5140SAndreas Gohr     * we only search if a search word was given
2764ab5140SAndreas Gohr     *
2864ab5140SAndreas Gohr     * @inheritdoc
2964ab5140SAndreas Gohr     */
3064ab5140SAndreas Gohr    public function checkPermissions() {
3164ab5140SAndreas Gohr        parent::checkPermissions();
3264ab5140SAndreas Gohr    }
3364ab5140SAndreas Gohr
34d09b5b64SMichael Große    public function preProcess()
35d09b5b64SMichael Große    {
36d22b78c8SMichael Große        global $QUERY, $ID, $conf, $INPUT;
37d22b78c8SMichael Große        $s = cleanID($QUERY);
38d22b78c8SMichael Große
39d22b78c8SMichael Große        if ($ID !== $conf['start'] && $s === '') {
40d22b78c8SMichael Große            parse_str($INPUT->server->str('QUERY_STRING'), $urlParts);
41d22b78c8SMichael Große            $urlParts['q'] = $urlParts['id'];
42d22b78c8SMichael Große            $urlParts['id'] = $conf['start'];
43d22b78c8SMichael Große            $url = DOKU_URL . DOKU_SCRIPT . '?' . http_build_query($urlParts, null, '&');
44d22b78c8SMichael Große            send_redirect($url);
45d22b78c8SMichael Große        }
46d22b78c8SMichael Große
47d22b78c8SMichael Große        if ($s === '') throw new ActionAbort();
48d09b5b64SMichael Große        $this->adjustGlobalQuery();
49d09b5b64SMichael Große    }
50d09b5b64SMichael Große
5164ab5140SAndreas Gohr    /** @inheritdoc */
52d09b5b64SMichael Große    public function tplContent()
53d09b5b64SMichael Große    {
546639a152SMichael Große        $this->execute();
556639a152SMichael Große
566639a152SMichael Große        $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight);
5721fcef82SMichael Große        $search->show();
5864ab5140SAndreas Gohr    }
59d09b5b64SMichael Große
606639a152SMichael Große
616639a152SMichael Große    /**
626639a152SMichael Große     * run the search
636639a152SMichael Große     */
646639a152SMichael Große    protected function execute()
656639a152SMichael Große    {
666639a152SMichael Große        global $INPUT, $QUERY;
676639a152SMichael Große        $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'));
68*1265b193SMichael Große        $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'));
696639a152SMichael Große        $this->highlight = $highlight;
706639a152SMichael Große    }
716639a152SMichael Große
72d09b5b64SMichael Große    /**
73d09b5b64SMichael Große     * Adjust the global query accordingly to the config search_limit_to_first_ns and search_default_fragment_behaviour
74d09b5b64SMichael Große     *
75d09b5b64SMichael Große     * This will only do something if the search didn't originate from the form on the searchpage itself
76d09b5b64SMichael Große     */
77d09b5b64SMichael Große    protected function adjustGlobalQuery()
78d09b5b64SMichael Große    {
79340f849aSMichael Große        global $conf, $INPUT, $QUERY, $ID;
80d09b5b64SMichael Große
81*1265b193SMichael Große        if ($INPUT->bool('sf')) {
82d09b5b64SMichael Große            return;
83d09b5b64SMichael Große        }
84d09b5b64SMichael Große
85d09b5b64SMichael Große        $Indexer = idx_get_indexer();
86d09b5b64SMichael Große        $parsedQuery = ft_queryParser($Indexer, $QUERY);
87d09b5b64SMichael Große
88d09b5b64SMichael Große        if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) {
89d09b5b64SMichael Große            if ($conf['search_limit_to_first_ns'] > 0) {
90340f849aSMichael Große                if (getNS($ID) !== false) {
91340f849aSMichael Große                    $nsParts = explode(':', getNS($ID));
92d09b5b64SMichael Große                    $ns = implode(':', array_slice($nsParts, 0, $conf['search_limit_to_first_ns']));
93d09b5b64SMichael Große                    $QUERY .= " @$ns";
94d09b5b64SMichael Große                }
95d09b5b64SMichael Große            }
96d09b5b64SMichael Große        }
97d09b5b64SMichael Große
98d09b5b64SMichael Große        if ($conf['search_default_fragment_behaviour'] !== 'exact') {
99d09b5b64SMichael Große            if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) {
100d09b5b64SMichael Große                if (strpos($QUERY, '*') === false) {
101d09b5b64SMichael Große                    $queryParts = explode(' ', $QUERY);
102d09b5b64SMichael Große                    $queryParts = array_map(function ($part) {
103d09b5b64SMichael Große                        if (strpos($part, '@') === 0) {
104d09b5b64SMichael Große                            return $part;
105d09b5b64SMichael Große                        }
106d09b5b64SMichael Große                        if (strpos($part, 'ns:') === 0) {
107d09b5b64SMichael Große                            return $part;
108d09b5b64SMichael Große                        }
109d09b5b64SMichael Große                        if (strpos($part, '^') === 0) {
110d09b5b64SMichael Große                            return $part;
111d09b5b64SMichael Große                        }
112d09b5b64SMichael Große                        if (strpos($part, '-ns:') === 0) {
113d09b5b64SMichael Große                            return $part;
114d09b5b64SMichael Große                        }
115d09b5b64SMichael Große
116d09b5b64SMichael Große                        global $conf;
117d09b5b64SMichael Große
118d09b5b64SMichael Große                        if ($conf['search_default_fragment_behaviour'] === 'starts_with') {
119d09b5b64SMichael Große                            return $part . '*';
120d09b5b64SMichael Große                        }
121d09b5b64SMichael Große                        if ($conf['search_default_fragment_behaviour'] === 'ends_with') {
122d09b5b64SMichael Große                            return '*' . $part;
123d09b5b64SMichael Große                        }
124d09b5b64SMichael Große
125d09b5b64SMichael Große                        return '*' . $part . '*';
126d09b5b64SMichael Große
127d09b5b64SMichael Große                    }, $queryParts);
128d09b5b64SMichael Große                    $QUERY = implode(' ', $queryParts);
129d09b5b64SMichael Große                }
130d09b5b64SMichael Große            }
131d09b5b64SMichael Große        }
132d09b5b64SMichael Große    }
13364ab5140SAndreas Gohr}
134