1<?php
2/**
3 * Plugin Search Form: Inserts a search form in any page
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Adolfo González Blázquez <code@infinicode.org>
7 */
8
9use dokuwiki\Extension\SyntaxPlugin;
10
11/**
12 * All DokuWiki plugins to extend the parser/rendering mechanism
13 * need to inherit from this class
14 */
15class syntax_plugin_searchform extends SyntaxPlugin {
16
17    /**
18     * Syntax Type
19     *
20     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
21     * @return string
22     */
23    public function getType() {
24        return 'substition';
25    }
26
27    /**
28     * Sort order when overlapping syntax
29     * @return int
30     */
31    public function getSort() {
32        return 138;
33    }
34
35    /**
36     * @param $mode
37     */
38    public function connectTo($mode) {
39        $this->Lexer->addSpecialPattern('\{searchform\b.*?\}', $mode, 'plugin_searchform');
40    }
41
42    /**
43     * Handler to prepare matched data for the rendering process
44     *
45     * @param   string $match   The text matched by the patterns
46     * @param   int $state   The lexer state for the match
47     * @param   int $pos     The character position of the matched text
48     * @param   Doku_Handler $handler Reference to the Doku_Handler object
49     * @return  array Return an array with all data you want to use in render
50     */
51    public function handle($match, $state, $pos, Doku_Handler $handler) {
52        $match = trim(substr($match,11,-1)); //strip {searchform from start and } from end
53        list($key, $value) = array_pad(explode('=', $match, 2), 2, null);
54
55        $options = ['namespace' => null, 'excludens' => false];
56
57        if(isset($key) && ($key == 'ns' || $key == '-ns')) {
58            $options['namespace'] = cleanID($value);
59            $options['excludens'] = $key === '-ns';
60        }
61        return array($options, $state, $pos);
62    }
63
64    /**
65     * The actual output creation.
66     *
67     * @param string $format output format being rendered
68     * @param Doku_Renderer $renderer reference to the current renderer object
69     * @param array $data data created by handler()
70     * @return  boolean                 rendered correctly?
71     */
72    public function render($format, Doku_Renderer $renderer, $data) {
73        global $lang, $INFO, $ACT, $QUERY, $ID;
74
75        if($format == 'xhtml') {
76            list($options,,) = $data;
77
78            // don't print the search form if search action has been disabled
79            if(!actionOK('search')) return true;
80
81            $ns = $options['namespace'];
82            $notns = '';
83            if($ns === null) {
84                $ns = $INFO['namespace'];
85            }
86            if($options['excludens']) {
87                $notns = $ns;
88                $ns = '';
89            }
90            /** based on  tpl_searchform() */
91            $autocomplete=true;
92            $ajax=true;
93
94            $searchForm = new dokuwiki\Form\Form([
95                                                     'action' => wl(),
96                                                     'method' => 'get',
97                                                     'role' => 'search',
98                                                     'class' => 'search',
99                                                 ], true);
100            $searchForm->addTagOpen('div')->addClass('no');
101            $searchForm->setHiddenField('do', 'search');
102            $searchForm->setHiddenField('id', $ID);
103            $searchForm->setHiddenField('ns', $ns)->addClass('searchform__ns');
104            $searchForm->setHiddenField('-ns', $notns)->addClass('searchform__notns');
105            $searchForm->addTextInput('q')
106                       ->addClass('edit searchform__qsearch_in')
107                       ->attrs([
108                                   'title' => '[F]',
109                                   'accesskey' => 'f',
110                                   'placeholder' => $lang['btn_search'],
111                                   'autocomplete' => $autocomplete ? 'on' : 'off',
112                               ])
113                       ->val($ACT === 'search' ? $QUERY : '')
114                       ->useInput(false);
115
116            $searchForm->addButton('', $lang['btn_search'])->attrs([
117                                                                       'type' => 'submit',
118                                                                       'title' => $lang['btn_search'],
119                                                                   ]);
120            if ($ajax) {
121                $searchForm->addTagOpen('div')->addClass('ajax_qsearch JSpopup searchform__qsearch_out');
122                $searchForm->addTagClose('div');
123            }
124            $searchForm->addTagClose('div');
125
126            $renderer->doc .= '<div class="searchform__form">';
127            $renderer->doc .= $searchForm->toHTML('quicksearch');
128            $renderer->doc .= '</div>';
129
130            return true;
131        }
132        return false;
133    }
134}
135