1<?php
2
3/**
4 * DokuWiki Plugin struct (Syntax Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8 */
9
10use dokuwiki\plugin\struct\meta\AggregationTable;
11use dokuwiki\plugin\struct\meta\ConfigParser;
12use dokuwiki\plugin\struct\meta\SearchConfig;
13use dokuwiki\plugin\struct\meta\StructException;
14use dokuwiki\plugin\struct\meta\Value;
15
16// must be run within Dokuwiki
17if (!defined('DOKU_INC')) die();
18
19class syntax_plugin_structgroupby_one extends syntax_plugin_struct_table
20{
21    /**
22     * Connect lookup pattern to lexer.
23     *
24     * @param string $mode Parser mode
25     */
26    public function connectTo($mode)
27    {
28        $this->Lexer->addSpecialPattern('----+ *struct one *-+\n.*?\n----+', $mode, 'plugin_structgroupby_one');
29    }
30
31    /**
32     * Render xhtml output or metadata
33     *
34     * @param string $mode Renderer mode (supported modes: xhtml)
35     * @param Doku_Renderer $renderer The renderer
36     * @param array $data The data from the handler() function
37     * @return bool If rendering was successful.
38     */
39    public function render($mode, Doku_Renderer $renderer, $data)
40    {
41        if (!$data) return false;
42        global $INFO;
43        global $conf;
44
45        if (count($data['cols']) > 1) {
46            $renderer->cdata('The syntax accepts only one column.');
47            return true;
48        }
49
50        try {
51            foreach ($data['cols'] as &$col) {
52                $col = trim($col);
53                $match = 'SUM(';
54                if (substr($col, 0, strlen($match)) == $match) {
55                    $col = substr($col, strlen($match), -1);
56                    $sum_col = $col;
57                }
58            }
59
60            if (!$sum_col) {
61                $renderer->cdata('No aggregation function provided or incorrect function name.');
62                return true;
63            }
64
65            $search = new SearchConfig($data);
66            $search->setLimit(0);
67            $search->setOffset(0);
68
69            $sum = 0;
70            $result = $search->execute();
71            foreach ($result as $rownum => $row) {
72                /** @var Value $value */
73                foreach ($row as $colnum => $value) {
74                    // summarize
75                    if ($colnum == $sum_col && is_numeric($value->getValue())) {
76                        $sum += $value->getValue();
77                    }
78                }
79            }
80            $renderer->cdata($sum);
81
82            if ($mode == 'metadata') {
83                /** @var Doku_Renderer_metadata $renderer */
84                $renderer->meta['plugin']['struct']['hasaggregation'] = $search->getCacheFlag();
85            }
86        } catch (StructException $e) {
87            msg($e->getMessage(), -1, $e->getLine(), $e->getFile());
88            if ($conf['allowdebug']) msg('<pre>' . hsc($e->getTraceAsString()) . '</pre>', -1);
89        }
90
91        return true;
92    }
93}
94