xref: /plugin/dbquery/syntax/query.php (revision 1b7b5e661908b8d7ad42f44f453d6eceae4a998d)
1c64c1748SAndreas Gohr<?php
2c64c1748SAndreas Gohr
3c64c1748SAndreas Gohr/**
4c64c1748SAndreas Gohr * DokuWiki Plugin dbquery (Syntax Component)
5c64c1748SAndreas Gohr *
6c64c1748SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7c64c1748SAndreas Gohr * @author  Andreas Gohr <dokuwiki@cosmocode.de>
8c64c1748SAndreas Gohr */
9c64c1748SAndreas Gohrclass syntax_plugin_dbquery_query extends DokuWiki_Syntax_Plugin
10c64c1748SAndreas Gohr{
11c64c1748SAndreas Gohr    /** @inheritDoc */
12c64c1748SAndreas Gohr    public function getType()
13c64c1748SAndreas Gohr    {
14c64c1748SAndreas Gohr        return 'substition';
15c64c1748SAndreas Gohr    }
16c64c1748SAndreas Gohr
17c64c1748SAndreas Gohr    /** @inheritDoc */
18c64c1748SAndreas Gohr    public function getPType()
19c64c1748SAndreas Gohr    {
20c64c1748SAndreas Gohr        return 'block';
21c64c1748SAndreas Gohr    }
22c64c1748SAndreas Gohr
23c64c1748SAndreas Gohr    /** @inheritDoc */
24c64c1748SAndreas Gohr    public function getSort()
25c64c1748SAndreas Gohr    {
26c64c1748SAndreas Gohr        return 135;
27c64c1748SAndreas Gohr    }
28c64c1748SAndreas Gohr
29c64c1748SAndreas Gohr    /** @inheritDoc */
30c64c1748SAndreas Gohr    public function connectTo($mode)
31c64c1748SAndreas Gohr    {
32c64c1748SAndreas Gohr        $this->Lexer->addSpecialPattern('{{QUERY:\w+}}', $mode, 'plugin_dbquery_query');
33c64c1748SAndreas Gohr    }
34c64c1748SAndreas Gohr
35c64c1748SAndreas Gohr    /** @inheritDoc */
36c64c1748SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
37c64c1748SAndreas Gohr    {
38c64c1748SAndreas Gohr        return ['name' => substr($match, 8, -2)];
39c64c1748SAndreas Gohr    }
40c64c1748SAndreas Gohr
41c64c1748SAndreas Gohr    /** @inheritDoc */
42c64c1748SAndreas Gohr    public function render($mode, Doku_Renderer $renderer, $data)
43c64c1748SAndreas Gohr    {
44c64c1748SAndreas Gohr        if ($mode !== 'xhtml') {
45c64c1748SAndreas Gohr            return false;
46c64c1748SAndreas Gohr        }
47c64c1748SAndreas Gohr
48c64c1748SAndreas Gohr        /** @var helper_plugin_dbquery $hlp */
49c64c1748SAndreas Gohr        $hlp = plugin_load('helper', 'dbquery');
50c64c1748SAndreas Gohr        try {
51c64c1748SAndreas Gohr            $qdata = $hlp->loadDataFromPage($data['name']);
52c64c1748SAndreas Gohr            $result = $hlp->executeQuery($qdata['codeblocks']['_']);
53c64c1748SAndreas Gohr        } catch (\Exception $e) {
54c64c1748SAndreas Gohr            msg(hsc($e->getMessage()), -1);
55c64c1748SAndreas Gohr            return true;
56c64c1748SAndreas Gohr        }
57c64c1748SAndreas Gohr
58c64c1748SAndreas Gohr        if (count($result) === 1 && isset($result[0]['status']) && isset($qdata['codeblocks'][$result[0]['status']])) {
59c64c1748SAndreas Gohr            $this->renderStatus($result, $qdata['codeblocks'][$result[0]['status']], $renderer);
60c64c1748SAndreas Gohr        } else {
61c64c1748SAndreas Gohr            if ($qdata['macros']['transpose']) {
62c64c1748SAndreas Gohr                $this->renderTransposedResultTable($result, $renderer);
63c64c1748SAndreas Gohr            } else {
64c64c1748SAndreas Gohr                $this->renderResultTable($result, $renderer);
65c64c1748SAndreas Gohr            }
66c64c1748SAndreas Gohr        }
67c64c1748SAndreas Gohr
68c64c1748SAndreas Gohr        return true;
69c64c1748SAndreas Gohr    }
70c64c1748SAndreas Gohr
71c64c1748SAndreas Gohr    /**
72c64c1748SAndreas Gohr     * Render given result via the given status HTML
73c64c1748SAndreas Gohr     *
74c64c1748SAndreas Gohr     * @param string[][] $result
75c64c1748SAndreas Gohr     * @param string $html
76c64c1748SAndreas Gohr     * @param Doku_Renderer $R
77c64c1748SAndreas Gohr     */
78c64c1748SAndreas Gohr    public function renderStatus($result, $html, Doku_Renderer $R)
79c64c1748SAndreas Gohr    {
80c64c1748SAndreas Gohr        $value = isset($result[0]['result']) ? $result[0]['result'] : '';
81c64c1748SAndreas Gohr        $html = str_replace(':result', hsc($value), $html);
82c64c1748SAndreas Gohr        $R->doc .= $html;
83c64c1748SAndreas Gohr    }
84c64c1748SAndreas Gohr
85c64c1748SAndreas Gohr    /**
86c64c1748SAndreas Gohr     * Render the given result as a table
87c64c1748SAndreas Gohr     *
88c64c1748SAndreas Gohr     * @param string[][] $result
89c64c1748SAndreas Gohr     * @param Doku_Renderer $R
90c64c1748SAndreas Gohr     */
91c64c1748SAndreas Gohr    public function renderResultTable($result, Doku_Renderer $R)
92c64c1748SAndreas Gohr    {
93c64c1748SAndreas Gohr        global $lang;
94c64c1748SAndreas Gohr
95c64c1748SAndreas Gohr        if (!count($result)) {
96c64c1748SAndreas Gohr            $R->cdata($lang['nothingfound']);
97c64c1748SAndreas Gohr            return;
98c64c1748SAndreas Gohr        }
99c64c1748SAndreas Gohr
100c64c1748SAndreas Gohr        $R->table_open();
101c64c1748SAndreas Gohr        $R->tablerow_open();
102c64c1748SAndreas Gohr        foreach (array_keys($result[0]) as $header) {
103c64c1748SAndreas Gohr            $R->tableheader_open();
104c64c1748SAndreas Gohr            $R->cdata($header);
105c64c1748SAndreas Gohr            $R->tableheader_close();
106c64c1748SAndreas Gohr        }
107c64c1748SAndreas Gohr        $R->tablerow_close();
108c64c1748SAndreas Gohr
109c64c1748SAndreas Gohr        foreach ($result as $row) {
110c64c1748SAndreas Gohr            $R->tablerow_open();
111c64c1748SAndreas Gohr            foreach ($row as $cell) {
112c64c1748SAndreas Gohr                $R->tablecell_open();
113*1b7b5e66SAndreas Gohr                $this->cellFormat($cell, $R);
114c64c1748SAndreas Gohr                $R->tablecell_close();
115c64c1748SAndreas Gohr            }
116c64c1748SAndreas Gohr            $R->tablerow_close();
117c64c1748SAndreas Gohr        }
118c64c1748SAndreas Gohr        $R->table_close();
119c64c1748SAndreas Gohr    }
120c64c1748SAndreas Gohr
121c64c1748SAndreas Gohr    /**
122c64c1748SAndreas Gohr     * Render the given result as a table, but turned 90 degrees
123c64c1748SAndreas Gohr     *
124c64c1748SAndreas Gohr     * @param string[][] $result
125c64c1748SAndreas Gohr     * @param Doku_Renderer $R
126c64c1748SAndreas Gohr     */
127c64c1748SAndreas Gohr    public function renderTransposedResultTable($result, Doku_Renderer $R)
128c64c1748SAndreas Gohr    {
129c64c1748SAndreas Gohr        global $lang;
130c64c1748SAndreas Gohr
131c64c1748SAndreas Gohr        if (!count($result)) {
132c64c1748SAndreas Gohr            $R->cdata($lang['nothingfound']);
133c64c1748SAndreas Gohr            return;
134c64c1748SAndreas Gohr        }
135c64c1748SAndreas Gohr
136c64c1748SAndreas Gohr        $width = count($result[0]);
137c64c1748SAndreas Gohr        $height = count($result);
138c64c1748SAndreas Gohr
139c64c1748SAndreas Gohr        $R->table_open();
140c64c1748SAndreas Gohr        for ($x = 0; $x < $width; $x++) {
141c64c1748SAndreas Gohr            $R->tablerow_open();
142c64c1748SAndreas Gohr            $R->tableheader_open();
143c64c1748SAndreas Gohr            $R->cdata(array_keys($result[0])[$x]);
144c64c1748SAndreas Gohr            $R->tableheader_close();
145c64c1748SAndreas Gohr
146c64c1748SAndreas Gohr            for ($y = 0; $y < $height; $y++) {
147c64c1748SAndreas Gohr                $R->tablecell_open();
148*1b7b5e66SAndreas Gohr                $this->cellFormat(array_values($result[$y])[$x], $R);
149c64c1748SAndreas Gohr                $R->tablecell_close();
150c64c1748SAndreas Gohr            }
151c64c1748SAndreas Gohr            $R->tablerow_close();
152c64c1748SAndreas Gohr        }
153c64c1748SAndreas Gohr        $R->table_close();
154c64c1748SAndreas Gohr    }
155c64c1748SAndreas Gohr
156*1b7b5e66SAndreas Gohr    /**
157*1b7b5e66SAndreas Gohr     * Pass the given cell content to the correct renderer call
158*1b7b5e66SAndreas Gohr     *
159*1b7b5e66SAndreas Gohr     * Detects a subset of the wiki link syntax
160*1b7b5e66SAndreas Gohr     *
161*1b7b5e66SAndreas Gohr     * @param string $content
162*1b7b5e66SAndreas Gohr     * @param Doku_Renderer $R
163*1b7b5e66SAndreas Gohr     * @return void
164*1b7b5e66SAndreas Gohr     */
165*1b7b5e66SAndreas Gohr    protected function cellFormat($content, Doku_Renderer $R)
166*1b7b5e66SAndreas Gohr    {
167*1b7b5e66SAndreas Gohr        // external urls
168*1b7b5e66SAndreas Gohr        if (preg_match('/^\[\[(https?:\/\/[^|\]]+)(|.*?)?]]$/', $content, $m)) {
169*1b7b5e66SAndreas Gohr            $url = $m[1];
170*1b7b5e66SAndreas Gohr            $title = $m[2] ?? '';
171*1b7b5e66SAndreas Gohr            $title = trim($title,'|');
172*1b7b5e66SAndreas Gohr            $R->externallink($url, $title);
173*1b7b5e66SAndreas Gohr            return;
174*1b7b5e66SAndreas Gohr        }
175*1b7b5e66SAndreas Gohr
176*1b7b5e66SAndreas Gohr        // internal urls
177*1b7b5e66SAndreas Gohr        if (preg_match('/^\[\[([^|\]]+)(|.*?)?]]$/', $content, $m)) {
178*1b7b5e66SAndreas Gohr            $page = cleanID($m[1]);
179*1b7b5e66SAndreas Gohr            $title = $m[2] ?? '';
180*1b7b5e66SAndreas Gohr            $title = trim($title,'|');
181*1b7b5e66SAndreas Gohr            $R->internallink($page, $title);
182*1b7b5e66SAndreas Gohr            return;
183*1b7b5e66SAndreas Gohr        }
184*1b7b5e66SAndreas Gohr
185*1b7b5e66SAndreas Gohr        $R->cdata($content);
186*1b7b5e66SAndreas Gohr    }
187c64c1748SAndreas Gohr}
188c64c1748SAndreas Gohr
189