1<?php
2/**
3 * DokuWiki Plugin structrowcolor (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Szymon Olewniczak <it@rid.pl>
7 */
8
9
10use dokuwiki\plugin\struct\meta\SearchConfig;
11use dokuwiki\plugin\struct\meta\Value;
12
13// must be run within Dokuwiki
14if (!defined('DOKU_INC')) {
15    die();
16}
17
18class action_plugin_structrowcolor_struct extends DokuWiki_Action_Plugin
19{
20
21    protected $row_colors = [];
22
23    /**
24     * Registers a callback function for a given event
25     *
26     * @param Doku_Event_Handler $controller DokuWiki's event controller object
27     *
28     * @return void
29     */
30    public function register(Doku_Event_Handler $controller)
31    {
32        $controller->register_hook('PLUGIN_STRUCT_CONFIGPARSER_UNKNOWNKEY', 'BEFORE', $this, 'handle_plugin_struct_configparser_unknownkey');
33        $controller->register_hook('PLUGIN_STRUCT_AGGREGATIONTABLE_RENDERRESULTROW', 'BEFORE', $this, 'handle_plugin_struct_aggregationtable_renderresultrow_before');
34        $controller->register_hook('PLUGIN_STRUCT_AGGREGATIONTABLE_RENDERRESULTROW', 'AFTER', $this, 'handle_plugin_struct_aggregationtable_renderresultrow_after');
35
36    }
37
38    /**
39     * [Custom event handler which performs action]
40     *
41     * Called for event:
42     *
43     * @param Doku_Event $event  event object by reference
44     *
45     * @return void
46     */
47    public function handle_plugin_struct_configparser_unknownkey(Doku_Event $event)
48    {
49        $data = $event->data;
50        $key = $data['key'];
51        if ($key != 'rowcolor') return;
52
53        $event->preventDefault();
54        $event->stopPropagation();
55
56        $val = trim($data['val']);
57        $data['config'][$key] = $val;
58    }
59
60    /**
61     * [Custom event handler which performs action]
62     *
63     * Called for event:
64     *
65     * @param Doku_Event $event  event object by reference
66     *
67     * @return void
68     */
69    public function handle_plugin_struct_aggregationtable_renderresultrow_before(Doku_Event $event)
70    {
71        $mode = $event->data['mode'];
72        $renderer = $event->data['renderer'];
73        $data = $event->data['data'];
74
75        if ($mode != 'xhtml') return;
76
77        $rowcolor = $data['rowcolor'];
78        if (!$rowcolor) return;
79
80        /** @var SearchConfig $searchConfig */
81        $searchConfig = $event->data['searchConfig'];
82        $searchConfig_hash = spl_object_hash($searchConfig);
83        if (!isset($this->row_colors[$searchConfig_hash])) {
84            $this->row_colors[$searchConfig_hash] = [];
85
86            $rowcolor_column = $searchConfig->findColumn($rowcolor);
87
88            $searchConfig->addColumn('*');
89            $result = $searchConfig->execute();
90            foreach ($result as $rownum => $row) {
91                /** @var Value $value */
92                foreach ($row as $colnum => $value) {
93                    if ($value->getColumn() === $rowcolor_column) {
94                        $this->row_colors[$searchConfig_hash][$rownum] = $value->getRawValue();
95                        break;
96                    }
97                }
98            }
99
100        }
101
102        // save row start position
103        $event->data['rowstart']= mb_strlen($renderer->doc);
104    }
105
106    /**
107     * [Custom event handler which performs action]
108     *
109     * Called for event:
110     *
111     * @param Doku_Event $event  event object by reference
112     *
113     * @return void
114     */
115    public function handle_plugin_struct_aggregationtable_renderresultrow_after(Doku_Event $event)
116    {
117        $mode = $event->data['mode'];
118        if ($mode != 'xhtml') return;
119
120        $renderer = $event->data['renderer'];
121        /** @var SearchConfig $searchConfig */
122        $searchConfig = $event->data['searchConfig'];
123        $data = $event->data['data'];
124
125        $rownum  = $event->data['rownum'];
126
127        $rowstart = $event->data['rowstart'];
128        $rowcolor = $data['rowcolor'];
129
130        if (!$rowcolor) return;
131        if (!$rowstart) return;
132
133        $searchConfig_hash = spl_object_hash($searchConfig);
134        $bgcolor = $this->row_colors[$searchConfig_hash][$rownum];
135
136        if (!$bgcolor) return;
137
138        $rest = mb_substr($renderer->doc, 0,  $rowstart);
139        $row = mb_substr($renderer->doc, $rowstart);
140        $row = ltrim($row);
141        //check if we processing row
142        if (mb_substr($row, 0, 3) != '<tr') return;
143
144        $tr_tag = mb_substr($row, 0, 3);
145        $tr_rest = mb_substr($row, 3);
146
147        $renderer->doc = $rest . $tr_tag . ' style="background-color: '.$bgcolor.'" ' . $tr_rest;
148    }
149
150}
151
152