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