xref: /plugin/approve/syntax/table.php (revision 9aebb49453f15d83c791d90e388ea7f985f16c4a)
1<?php
2
3// must be run within DokuWiki
4if(!defined('DOKU_INC')) die();
5
6
7class syntax_plugin_approve_table extends DokuWiki_Syntax_Plugin {
8
9    protected $states = ['approved', 'draft', 'ready for approval'];
10
11    function getType() {
12        return 'substition';
13    }
14
15    function getSort() {
16        return 20;
17    }
18
19    function PType() {
20        return 'block';
21    }
22
23    function connectTo($mode) {
24        $this->Lexer->addSpecialPattern('----+ *approve table *-+\n.*?----+', $mode,'plugin_approve_table');
25    }
26
27    function handle($match, $state, $pos, Doku_Handler $handler){
28        $lines = explode("\n", $match);
29        array_shift($lines);
30        array_pop($lines);
31
32        $params = [
33            'namespace' => '',
34            'filter' => false,
35            'states' => $this->states,
36            'summarize' => true,
37            'maintainer' => null
38        ];
39
40        foreach ($lines as $line) {
41            $pair = explode(':', $line, 2);
42            if (count($pair) < 2) {
43                continue;
44            }
45            $key = trim($pair[0]);
46            $value = trim($pair[1]);
47            if ($key == 'states') {
48                $value = array_map('trim', explode(',', $value));
49                //normalize
50                $value = array_map('strtolower', $value);
51                $value = array_map('ucfirst', $value);
52                foreach ($value as $state) {
53                    if (!in_array($state, $this->states)) {
54                        msg('approve plugin: unknown state "'.$state.'" should be: ' .
55                            implode(', ', $this->states), -1);
56                        return false;
57                    }
58                }
59            } elseif($key == 'filter') {
60                $value = trim($value, '/');
61                if (preg_match('/' . $value . '/', null) === false) {
62                    msg('approve plugin: invalid filter regex', -1);
63                    return false;
64                }
65            } elseif ($key == 'summarize') {
66                $value = $value == '0' ? false : true;
67            } elseif ($key == 'namespace') {
68                $value = trim(cleanID($value), ':');
69            }
70            $params[$key] = $value;
71        }
72        return $params;
73    }
74
75    /**
76     * Render xhtml output or metadata
77     *
78     * @param string        $mode     Renderer mode (supported modes: xhtml)
79     * @param Doku_Renderer $renderer The renderer
80     * @param array         $data     The data from the handler() function
81     *
82     * @return bool If rendering was successful.
83     */
84
85    public function render($mode, Doku_Renderer $renderer, $data)
86    {
87        $method = 'render' . ucfirst($mode);
88        if (method_exists($this, $method)) {
89            call_user_func([$this, $method], $renderer, $data);
90            return true;
91        }
92        return false;
93    }
94
95    /**
96     * Render metadata
97     *
98     * @param Doku_Renderer $renderer The renderer
99     * @param array         $data     The data from the handler() function
100     */
101    public function renderMetadata(Doku_Renderer $renderer, $params)
102    {
103        $plugin_name = $this->getPluginName();
104        $renderer->meta['plugin'][$plugin_name] = [];
105
106        if ($params['maintainer'] == '$USER$') {
107            $renderer->meta['plugin'][$plugin_name]['dynamic_maintainer'] = true;
108        }
109
110        $renderer->meta['plugin'][$plugin_name]['approve_table'] = true;
111    }
112
113    public function renderXhtml(Doku_Renderer $renderer, $params)
114    {
115        global $INFO;
116
117        global $conf;
118        /** @var DokuWiki_Auth_Plugin $auth */
119        global $auth;
120
121        /** @var \helper_plugin_ireadit_db $db_helper */
122        $db_helper = plugin_load('helper', 'approve_db');
123        $sqlite = $db_helper->getDB();
124
125        if ($params['maintainer'] == '$USER$') {
126            $params['maintainer'] = $INFO['client'];
127        }
128
129        $maintainer_query = '';
130        $query_args = [$params['namespace'].'%'];
131        if ($params['maintainer']) {
132            $maintainer_query .= " AND page.maintainer LIKE ?";
133            $query_args[] = $params['maintainer'];
134        }
135        if ($params['filter']) {
136            $maintainer_query .= " AND page.page REGEXP ?";
137            $query_args[] = $params['filter'];
138        }
139
140        $q = "SELECT page.page, page.maintainer, revision.rev, revision.approved, revision.approved_by,
141                    revision.ready_for_approval, revision.ready_for_approval_by,
142                    LENGTH(page.page) - LENGTH(REPLACE(page.page, ':', '')) AS colons
143                    FROM page INNER JOIN revision ON page.page = revision.page
144                    WHERE page.hidden = 0 AND revision.current=1 AND page.page LIKE ? ESCAPE '_'
145                            $maintainer_query
146                    ORDER BY colons, page.page";
147
148        $res = $sqlite->query($q, $query_args);
149        $pages = $sqlite->res2arr($res);
150
151        // Output Table
152        $renderer->doc .= '<table><tr>';
153        $renderer->doc .= '<th>' . $this->getLang('hdr_page') . '</th>';
154        $renderer->doc .= '<th>' . $this->getLang('hdr_state') . '</th>';
155        $renderer->doc .= '<th>' . $this->getLang('hdr_updated') . '</th>';
156        $renderer->doc .= '<th>' . $this->getLang('hdr_maintainer') . '</th>';
157        $renderer->doc .= '</tr>';
158
159
160        $all_approved = 0;
161        $all_approved_ready = 0;
162        $all = 0;
163
164        $curNS = '';
165        foreach($pages as $page) {
166            $id = $page['page'];
167            $maintainer = $page['maintainer'];
168            $rev = $page['rev'];
169            $approved = strtotime($page['approved']);
170            $approved_by = $page['approved_by'];
171            $ready_for_approval = strtotime($page['ready_for_approval']);
172            $ready_for_approval_by = $page['ready_for_approval_by'];
173
174            $pageNS = getNS($id);
175
176            if($pageNS != '' && $pageNS != $curNS) {
177                $curNS = $pageNS;
178
179                $renderer->doc .= '<tr><td colspan="4"><a href="';
180                $renderer->doc .= wl($curNS);
181                $renderer->doc .= '">';
182                $renderer->doc .= $curNS;
183                $renderer->doc .= '</a> ';
184                $renderer->doc .= '</td></tr>';
185            }
186
187            $all += 1;
188            if ($approved) {
189                $class = 'plugin__approve_green';
190                $state = $this->getLang('approved');
191                $date = $approved;
192                $by = $approved_by;
193
194                $all_approved += 1;
195            } elseif ($this->getConf('ready_for_approval') && $ready_for_approval) {
196                $class = 'plugin__approve_ready';
197                $state = $this->getLang('marked_approve_ready');
198                $date = $ready_for_approval;
199                $by = $ready_for_approval_by;
200
201                $all_approved_ready += 1;
202            } else {
203                $class = 'plugin__approve_red';
204                $state = $this->getLang('draft');
205                $date = $rev;
206                $by = p_get_metadata($id, 'last_change user');
207            }
208
209            $renderer->doc .= '<tr class="'.$class.'">';
210            $renderer->doc .= '<td><a href="';
211            $renderer->doc .= wl($id);
212            $renderer->doc .= '">';
213            if ($conf['useheading'] == '1') {
214                $heading = p_get_first_heading($id);
215                if ($heading != '') {
216                    $renderer->doc .= $heading;
217                } else {
218                    $renderer->doc .= $id;
219                }
220            } else {
221                $renderer->doc .= $id;
222            }
223
224            $renderer->doc .= '</a></td><td>';
225            $renderer->doc .= '<strong>'.$state. '</strong> ';
226
227            $user = $auth->getUserData($by);
228            if ($user) {
229                $renderer->doc .= $this->getLang('by'). ' ' . $user['name'];
230            }
231            $renderer->doc .= '</td><td>';
232            $renderer->doc .= '<a href="' . wl($id) . '">' . dformat($date) . '</a>';;
233            $renderer->doc .= '</td><td>';
234            if ($maintainer) {
235                $user = $auth->getUserData($maintainer);
236                if ($user) {
237                    $renderer->doc .= $user['name'];
238                } else {
239                    $renderer->doc .= $maintainer;
240                }
241            } else {
242                $renderer->doc .= '---';
243            }
244            $renderer->doc .= '</td></tr>';
245        }
246
247        if ($params['summarize']) {
248            if($this->getConf('ready_for_approval')) {
249                $renderer->doc .= '<tr><td><strong>';
250                $renderer->doc .= $this->getLang('all_approved_ready');
251                $renderer->doc .= '</strong></td>';
252
253                $renderer->doc .= '<td colspan="3">';
254                $percent       = 0;
255                if($all > 0) {
256                    $percent = $all_approved_ready * 100 / $all;
257                }
258                $renderer->doc .= $all_approved_ready . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
259                $renderer->doc .= '</td></tr>';
260            }
261
262            $renderer->doc .= '<tr><td><strong>';
263            $renderer->doc .= $this->getLang('all_approved');
264            $renderer->doc .= '</strong></td>';
265
266            $renderer->doc .= '<td colspan="3">';
267            $percent       = 0;
268            if($all > 0) {
269                $percent = $all_approved * 100 / $all;
270            }
271            $renderer->doc .= $all_approved . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
272            $renderer->doc .= '</td></tr>';
273        }
274
275        $renderer->doc .= '</table>';
276    }
277}
278