xref: /plugin/dbquery/syntax/query.php (revision 9730265cac55f032a41e08c80cc41610b870373b)
1c64c1748SAndreas Gohr<?php
2c64c1748SAndreas Gohr
3*9730265cSAndreas Gohruse dokuwiki\Extension\SyntaxPlugin;
4*9730265cSAndreas Gohr
5c64c1748SAndreas Gohr/**
6c64c1748SAndreas Gohr * DokuWiki Plugin dbquery (Syntax Component)
7c64c1748SAndreas Gohr *
8c64c1748SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
9c64c1748SAndreas Gohr * @author  Andreas Gohr <dokuwiki@cosmocode.de>
10c64c1748SAndreas Gohr */
11*9730265cSAndreas Gohrclass syntax_plugin_dbquery_query extends SyntaxPlugin
12c64c1748SAndreas Gohr{
13c64c1748SAndreas Gohr    /** @inheritDoc */
14c64c1748SAndreas Gohr    public function getType()
15c64c1748SAndreas Gohr    {
16c64c1748SAndreas Gohr        return 'substition';
17c64c1748SAndreas Gohr    }
18c64c1748SAndreas Gohr
19c64c1748SAndreas Gohr    /** @inheritDoc */
20c64c1748SAndreas Gohr    public function getPType()
21c64c1748SAndreas Gohr    {
22c64c1748SAndreas Gohr        return 'block';
23c64c1748SAndreas Gohr    }
24c64c1748SAndreas Gohr
25c64c1748SAndreas Gohr    /** @inheritDoc */
26c64c1748SAndreas Gohr    public function getSort()
27c64c1748SAndreas Gohr    {
28c64c1748SAndreas Gohr        return 135;
29c64c1748SAndreas Gohr    }
30c64c1748SAndreas Gohr
31c64c1748SAndreas Gohr    /** @inheritDoc */
32c64c1748SAndreas Gohr    public function connectTo($mode)
33c64c1748SAndreas Gohr    {
34c64c1748SAndreas Gohr        $this->Lexer->addSpecialPattern('{{QUERY:\w+}}', $mode, 'plugin_dbquery_query');
35c64c1748SAndreas Gohr    }
36c64c1748SAndreas Gohr
37c64c1748SAndreas Gohr    /** @inheritDoc */
38c64c1748SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
39c64c1748SAndreas Gohr    {
40c64c1748SAndreas Gohr        return ['name' => substr($match, 8, -2)];
41c64c1748SAndreas Gohr    }
42c64c1748SAndreas Gohr
43c64c1748SAndreas Gohr    /** @inheritDoc */
44c64c1748SAndreas Gohr    public function render($mode, Doku_Renderer $renderer, $data)
45c64c1748SAndreas Gohr    {
46c64c1748SAndreas Gohr        if ($mode !== 'xhtml') {
47c64c1748SAndreas Gohr            return false;
48c64c1748SAndreas Gohr        }
49c64c1748SAndreas Gohr
50c64c1748SAndreas Gohr        /** @var helper_plugin_dbquery $hlp */
51c64c1748SAndreas Gohr        $hlp = plugin_load('helper', 'dbquery');
52c64c1748SAndreas Gohr        try {
53c64c1748SAndreas Gohr            $qdata = $hlp->loadDataFromPage($data['name']);
543113520cSAndreas Gohr            $result = $hlp->executeQuery($qdata['codeblocks']['_'], $qdata['macros']['dsn'] ?? null);
55c64c1748SAndreas Gohr        } catch (\Exception $e) {
56c64c1748SAndreas Gohr            msg(hsc($e->getMessage()), -1);
57c64c1748SAndreas Gohr            return true;
58c64c1748SAndreas Gohr        }
59c64c1748SAndreas Gohr
60c64c1748SAndreas Gohr        if (count($result) === 1 && isset($result[0]['status']) && isset($qdata['codeblocks'][$result[0]['status']])) {
61c64c1748SAndreas Gohr            $this->renderStatus($result, $qdata['codeblocks'][$result[0]['status']], $renderer);
62*9730265cSAndreas Gohr        } elseif ($qdata['macros']['transpose']) {
63c64c1748SAndreas Gohr            $this->renderTransposedResultTable($result, $renderer);
64c64c1748SAndreas Gohr        } else {
65c64c1748SAndreas Gohr            $this->renderResultTable($result, $renderer);
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    {
80*9730265cSAndreas Gohr        $value = $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();
10104ef7616SAndreas Gohr        $R->tablethead_open();
102c64c1748SAndreas Gohr        $R->tablerow_open();
103c64c1748SAndreas Gohr        foreach (array_keys($result[0]) as $header) {
104c64c1748SAndreas Gohr            $R->tableheader_open();
105c64c1748SAndreas Gohr            $R->cdata($header);
106c64c1748SAndreas Gohr            $R->tableheader_close();
107c64c1748SAndreas Gohr        }
108c64c1748SAndreas Gohr        $R->tablerow_close();
10904ef7616SAndreas Gohr        $R->tablethead_close();
110c64c1748SAndreas Gohr
11104ef7616SAndreas Gohr        $R->tabletbody_open();
112c64c1748SAndreas Gohr        foreach ($result as $row) {
113c64c1748SAndreas Gohr            $R->tablerow_open();
114c64c1748SAndreas Gohr            foreach ($row as $cell) {
115c64c1748SAndreas Gohr                $R->tablecell_open();
1161b7b5e66SAndreas Gohr                $this->cellFormat($cell, $R);
117c64c1748SAndreas Gohr                $R->tablecell_close();
118c64c1748SAndreas Gohr            }
119c64c1748SAndreas Gohr            $R->tablerow_close();
120c64c1748SAndreas Gohr        }
12104ef7616SAndreas Gohr        $R->tabletbody_close();
122c64c1748SAndreas Gohr        $R->table_close();
123c64c1748SAndreas Gohr    }
124c64c1748SAndreas Gohr
125c64c1748SAndreas Gohr    /**
126c64c1748SAndreas Gohr     * Render the given result as a table, but turned 90 degrees
127c64c1748SAndreas Gohr     *
128c64c1748SAndreas Gohr     * @param string[][] $result
129c64c1748SAndreas Gohr     * @param Doku_Renderer $R
130c64c1748SAndreas Gohr     */
131c64c1748SAndreas Gohr    public function renderTransposedResultTable($result, Doku_Renderer $R)
132c64c1748SAndreas Gohr    {
133c64c1748SAndreas Gohr        global $lang;
134c64c1748SAndreas Gohr
135c64c1748SAndreas Gohr        if (!count($result)) {
136c64c1748SAndreas Gohr            $R->cdata($lang['nothingfound']);
137c64c1748SAndreas Gohr            return;
138c64c1748SAndreas Gohr        }
139c64c1748SAndreas Gohr
140c64c1748SAndreas Gohr        $width = count($result[0]);
141c64c1748SAndreas Gohr        $height = count($result);
142c64c1748SAndreas Gohr
143c64c1748SAndreas Gohr        $R->table_open();
144c64c1748SAndreas Gohr        for ($x = 0; $x < $width; $x++) {
145c64c1748SAndreas Gohr            $R->tablerow_open();
146c64c1748SAndreas Gohr            $R->tableheader_open();
147c64c1748SAndreas Gohr            $R->cdata(array_keys($result[0])[$x]);
148c64c1748SAndreas Gohr            $R->tableheader_close();
149c64c1748SAndreas Gohr
150c64c1748SAndreas Gohr            for ($y = 0; $y < $height; $y++) {
151c64c1748SAndreas Gohr                $R->tablecell_open();
1521b7b5e66SAndreas Gohr                $this->cellFormat(array_values($result[$y])[$x], $R);
153c64c1748SAndreas Gohr                $R->tablecell_close();
154c64c1748SAndreas Gohr            }
155c64c1748SAndreas Gohr            $R->tablerow_close();
156c64c1748SAndreas Gohr        }
157c64c1748SAndreas Gohr        $R->table_close();
158c64c1748SAndreas Gohr    }
159c64c1748SAndreas Gohr
1601b7b5e66SAndreas Gohr    /**
1611b7b5e66SAndreas Gohr     * Pass the given cell content to the correct renderer call
1621b7b5e66SAndreas Gohr     *
1631b7b5e66SAndreas Gohr     * Detects a subset of the wiki link syntax
1641b7b5e66SAndreas Gohr     *
1651b7b5e66SAndreas Gohr     * @param string $content
1661b7b5e66SAndreas Gohr     * @param Doku_Renderer $R
1671b7b5e66SAndreas Gohr     * @return void
1681b7b5e66SAndreas Gohr     */
1691b7b5e66SAndreas Gohr    protected function cellFormat($content, Doku_Renderer $R)
1701b7b5e66SAndreas Gohr    {
1711b7b5e66SAndreas Gohr        // external urls
1721b7b5e66SAndreas Gohr        if (preg_match('/^\[\[(https?:\/\/[^|\]]+)(|.*?)?]]$/', $content, $m)) {
1731b7b5e66SAndreas Gohr            $url = $m[1];
1741b7b5e66SAndreas Gohr            $title = $m[2] ?? '';
1751b7b5e66SAndreas Gohr            $title = trim($title, '|');
1761b7b5e66SAndreas Gohr            $R->externallink($url, $title);
1771b7b5e66SAndreas Gohr            return;
1781b7b5e66SAndreas Gohr        }
1791b7b5e66SAndreas Gohr
1801b7b5e66SAndreas Gohr        // internal urls
1811b7b5e66SAndreas Gohr        if (preg_match('/^\[\[([^|\]]+)(|.*?)?]]$/', $content, $m)) {
1821b7b5e66SAndreas Gohr            $page = cleanID($m[1]);
1831b7b5e66SAndreas Gohr            $title = $m[2] ?? '';
1841b7b5e66SAndreas Gohr            $title = trim($title, '|');
1851b7b5e66SAndreas Gohr            $R->internallink($page, $title);
1861b7b5e66SAndreas Gohr            return;
1871b7b5e66SAndreas Gohr        }
1881b7b5e66SAndreas Gohr
1891b7b5e66SAndreas Gohr        $R->cdata($content);
1901b7b5e66SAndreas Gohr    }
191c64c1748SAndreas Gohr}
192