summaryrefslogtreecommitdiff
path: root/platform/www/inc/Action/Search.php
blob: 88bd0baa306ab8380e52cfce635b986c7aa814d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php

namespace dokuwiki\Action;

use dokuwiki\Action\Exception\ActionAbort;

/**
 * Class Search
 *
 * Search for pages and content
 *
 * @package dokuwiki\Action
 */
class Search extends AbstractAction {

    protected $pageLookupResults = array();
    protected $fullTextResults = array();
    protected $highlight = array();

    /** @inheritdoc */
    public function minimumPermission() {
        return AUTH_NONE;
    }

    /**
     * we only search if a search word was given
     *
     * @inheritdoc
     */
    public function checkPreconditions() {
        parent::checkPreconditions();
    }

    public function preProcess()
    {
        global $QUERY, $ID, $conf, $INPUT;
        $s = cleanID($QUERY);

        if ($ID !== $conf['start'] && !$INPUT->has('q')) {
            parse_str($INPUT->server->str('QUERY_STRING'), $urlParts);
            $urlParts['q'] = $urlParts['id'];
            unset($urlParts['id']);
            $url = wl($ID, $urlParts, true, '&');
            send_redirect($url);
        }

        if ($s === '') throw new ActionAbort();
        $this->adjustGlobalQuery();
    }

    /** @inheritdoc */
    public function tplContent()
    {
        $this->execute();

        $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight);
        $search->show();
    }


    /**
     * run the search
     */
    protected function execute()
    {
        global $INPUT, $QUERY;
        $after = $INPUT->str('min');
        $before = $INPUT->str('max');
        $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'), $after, $before);
        $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'), $after, $before);
        $this->highlight = $highlight;
    }

    /**
     * Adjust the global query accordingly to the config search_nslimit and search_fragment
     *
     * 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, $ID;

        if ($INPUT->bool('sf')) {
            return;
        }

        $Indexer = idx_get_indexer();
        $parsedQuery = ft_queryParser($Indexer, $QUERY);

        if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) {
            if ($conf['search_nslimit'] > 0) {
                if (getNS($ID) !== false) {
                    $nsParts = explode(':', getNS($ID));
                    $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit']));
                    $QUERY .= " @$ns";
                }
            }
        }

        if ($conf['search_fragment'] !== '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_fragment'] === 'starts_with') {
                            return $part . '*';
                        }
                        if ($conf['search_fragment'] === 'ends_with') {
                            return '*' . $part;
                        }

                        return '*' . $part . '*';

                    }, $queryParts);
                    $QUERY = implode(' ', $queryParts);
                }
            }
        }
    }
}