xref: /plugin/approve/syntax/table.php (revision d8ede06043d02e5697f43d6d5bd3619b9ec26549)
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        foreach ($lines as $line) {
40            $pair = explode(':', $line, 2);
41            if (count($pair) < 2) {
42                continue;
43            }
44            $key = trim($pair[0]);
45            $value = trim($pair[1]);
46            if ($key == 'states') {
47                $value = array_map('trim', explode(',', $value));
48                //normalize
49                $value = array_map('strtolower', $value);
50                $value = array_map('ucfirst', $value);
51                foreach ($value as $state) {
52                    if (!in_array($state, $this->states)) {
53                        msg('approve plugin: unknown state "'.$state.'" should be: ' .
54                            implode(', ', $this->states), -1);
55                        return false;
56                    }
57                }
58            } elseif($key == 'filter' && preg_match($value, null) === false) {
59                msg('approve plugin: invalid filter regex', -1);
60                return false;
61            } elseif ($key == 'summarize') {
62                $value = $value == '0' ? false : true;
63            } elseif ($key == 'namespace') {
64                $value = trim(cleanID($value), ':');
65            }
66            $params[$key] = $value;
67        }
68        return $params;
69    }
70
71    function render($mode, Doku_Renderer $renderer, $params) {
72        global $conf;
73        /** @var DokuWiki_Auth_Plugin $auth */
74        global $auth;
75
76        if ($mode != 'xhtml') return false;
77        if ($params === false) return false;
78
79        /** @var \helper_plugin_ireadit_db $db_helper */
80        $db_helper = plugin_load('helper', 'approve_db');
81        $sqlite = $db_helper->getDB();
82
83        $defaults = [
84            'namespace' => '',
85            'filter' => false,
86            'states' => $this->states,
87            'summarize' => true,
88        ];
89
90        $params = array_replace($defaults, $params);
91
92        $q = "SELECT page.page, page.maintainer, revision.rev, revision.approved, revision.approved_by,
93                    revision.ready_for_approval, revision.ready_for_approval_by,
94                    LENGTH(page.page) - LENGTH(REPLACE(page.page, ':', '')) AS colons
95                    FROM page INNER JOIN revision ON page.page = revision.page
96                    WHERE page.hidden = 0 AND revision.current=1 AND page.page LIKE ? ESCAPE '_'
97                    ORDER BY colons, page.page";
98        $res = $sqlite->query($q, $params['namespace'].'%');
99        $pages = $sqlite->res2arr($res);
100
101        // Output Table
102        $renderer->doc .= '<table><tr>';
103        $renderer->doc .= '<th>' . $this->getLang('hdr_page') . '</th>';
104        $renderer->doc .= '<th>' . $this->getLang('hdr_state') . '</th>';
105        $renderer->doc .= '<th>' . $this->getLang('hdr_updated') . '</th>';
106        $renderer->doc .= '<th>' . $this->getLang('hdr_maintainer') . '</th>';
107        $renderer->doc .= '</tr>';
108
109
110        $all_approved = 0;
111        $all_approved_ready = 0;
112        $all = 0;
113
114        $curNS = '';
115        foreach($pages as $page) {
116            $id = $page['page'];
117            $maintainer = $page['maintainer'];
118            $rev = $page['rev'];
119            $approved = strtotime($page['approved']);
120            $approved_by = $page['approved_by'];
121            $ready_for_approval = strtotime($page['ready_for_approval']);
122            $ready_for_approval_by = $page['ready_for_approval_by'];
123
124            $pageNS = getNS($id);
125
126            if($pageNS != '' && $pageNS != $curNS) {
127                $curNS = $pageNS;
128
129                $renderer->doc .= '<tr><td colspan="4"><a href="';
130                $renderer->doc .= wl($curNS);
131                $renderer->doc .= '">';
132                $renderer->doc .= $curNS;
133                $renderer->doc .= '</a> ';
134                $renderer->doc .= '</td></tr>';
135            }
136
137            $all += 1;
138            if ($approved) {
139                $class = 'plugin__approve_green';
140                $state = $this->getLang('approved');
141                $date = $approved;
142                $by = $approved_by;
143
144                $all_approved += 1;
145            } elseif ($this->getConf('ready_for_approval') && $ready_for_approval) {
146                $class = 'plugin__approve_ready';
147                $state = $this->getLang('marked_approve_ready');
148                $date = $ready_for_approval;
149                $by = $ready_for_approval_by;
150
151                $all_approved_ready += 1;
152            } else {
153                $class = 'plugin__approve_red';
154                $state = $this->getLang('draft');
155                $date = $rev;
156                $by = p_get_metadata($id, 'last_change user');
157            }
158
159            $renderer->doc .= '<tr class="'.$class.'">';
160            $renderer->doc .= '<td><a href="';
161            $renderer->doc .= wl($id);
162            $renderer->doc .= '">';
163            if ($conf['useheading'] == '1') {
164                $heading = p_get_first_heading($id);
165                if ($heading != '') {
166                    $renderer->doc .= $heading;
167                } else {
168                    $renderer->doc .= $id;
169                }
170            } else {
171                $renderer->doc .= $id;
172            }
173
174            $renderer->doc .= '</a></td><td>';
175            $renderer->doc .= '<strong>'.$state. '</strong> ';
176
177            $user = $auth->getUserData($by);
178            if ($user) {
179                $renderer->doc .= $this->getLang('by'). ' ' . $user['name'];
180            }
181            $renderer->doc .= '</td><td>';
182            $renderer->doc .= '<a href="' . wl($id) . '">' . dformat($date) . '</a>';;
183            $renderer->doc .= '</td><td>';
184            if ($maintainer) {
185                $user = $auth->getUserData($maintainer);
186                if ($user) {
187                    $renderer->doc .= $user['name'];
188                } else {
189                    $renderer->doc .= $maintainer;
190                }
191            } else {
192                $renderer->doc .= '---';
193            }
194            $renderer->doc .= '</td></tr>';
195        }
196
197        if ($params['summarize']) {
198            if($this->getConf('ready_for_approval')) {
199                $renderer->doc .= '<tr><td><strong>';
200                $renderer->doc .= $this->getLang('all_approved_ready');
201                $renderer->doc .= '</strong></td>';
202
203                $renderer->doc .= '<td colspan="3">';
204                $percent       = 0;
205                if($all > 0) {
206                    $percent = $all_approved_ready * 100 / $all;
207                }
208                $renderer->doc .= $all_approved_ready . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
209                $renderer->doc .= '</td></tr>';
210            }
211
212            $renderer->doc .= '<tr><td><strong>';
213            $renderer->doc .= $this->getLang('all_approved');
214            $renderer->doc .= '</strong></td>';
215
216            $renderer->doc .= '<td colspan="3">';
217            $percent       = 0;
218            if($all > 0) {
219                $percent = $all_approved * 100 / $all;
220            }
221            $renderer->doc .= $all_approved . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
222            $renderer->doc .= '</td></tr>';
223        }
224
225        $renderer->doc .= '</table>';
226        return true;
227    }
228}
229