xref: /plugin/approve/syntax/table.php (revision 4474ed8a8edd55319eb6dd1e4e69fdb09925ebf0)
1<?php
2
3use dokuwiki\plugin\approve\meta\ApproveConst;
4use dokuwiki\plugin\approve\meta\PageSearch;
5
6// must be run within DokuWiki
7if(!defined('DOKU_INC')) die();
8
9
10class syntax_plugin_approve_table extends DokuWiki_Syntax_Plugin {
11
12    protected $states = [];
13
14    public function __construct() {
15        $this->states = [$this->getConf('sum approved'),
16                         $this->getConf('sum ready for approval'),
17                         $this->getConf('sum draft')];
18    }
19
20    function getType() {
21        return 'substition';
22    }
23
24    function getSort() {
25        return 20;
26    }
27
28    function PType() {
29        return 'block';
30    }
31
32    function connectTo($mode) {
33        $this->Lexer->addSpecialPattern('----+ *approve table *-+\n.*?----+', $mode,'plugin_approve_table');
34    }
35
36    function handle($match, $state, $pos, Doku_Handler $handler){
37        $lines = explode("\n", $match);
38        array_shift($lines);
39        array_pop($lines);
40
41        $params = [];
42        foreach ($lines as $line) {
43            $pair = explode(':', $line, 2);
44            if (count($pair) < 2) {
45                continue;
46            }
47            $key = trim($pair[0]);
48            $value = trim($pair[1]);
49            if ($key == 'states') {
50                $value = array_map('trim', explode(',', $value));
51                //normalize
52                $value = array_map('strtolower', $value);
53                $value = array_map('ucfirst', $value);
54                foreach ($value as $state) {
55                    if (!in_array($state, $this->states)) {
56                        msg('approve plugin: unknown state "'.$state.'" should be: ' .
57                            implode(', ', $this->states), -1);
58                        return false;
59                    }
60                }
61            } elseif($key == 'filter' && preg_match($value, null) === false) {
62                msg('approve plugin: invalid filter regex', -1);
63                return false;
64            } elseif ($key == 'summarize') {
65                $value = $value == '0' ? false : true;
66            }
67            $params[$key] = $value;
68        }
69        return $params;
70    }
71
72    function render($mode, Doku_Renderer $renderer, $params) {
73        global $conf;
74
75        if ($mode != 'xhtml') return false;
76        if ($params === false) return false;
77
78        $pageSearch = new PageSearch();
79
80        $defaults = [
81            'namespace' => '',
82            'filter' => false,
83            'states' => $this->states,
84            'summarize' => true,
85        ];
86
87        $params = array_replace($defaults, $params);
88
89        $namespace = cleanID(getNS($params['namespace'] . ":*"));
90
91        $pages = $pageSearch->getPagesFromNamespace($namespace, $params['filter'], $params['states']);
92
93        usort($pages, array($pageSearch, 'pageSorter'));
94
95        // Output Table
96        $renderer->doc .= '<table><tr>';
97        $renderer->doc .= '<th>' . $this->getLang('hdr_page') . '</th>';
98        $renderer->doc .= '<th>' . $this->getLang('hdr_state') . '</th>';
99        $renderer->doc .= '<th>' . $this->getLang('hdr_updated') . '</th>';
100        $renderer->doc .= '</tr>';
101
102
103        $all_approved = 0;
104        $all_approved_ready = 0;
105        $all = 0;
106
107        $working_ns = null;
108        foreach($pages as $page) {
109            // $page: 0 -> pagename, 1 -> true -> approved else false, 2 -> last changed date
110            $this_ns = getNS($page[0]);
111
112            if($this_ns != $working_ns) {
113                $name_ns = $this_ns;
114                if($this_ns == '') { $name_ns = 'root'; }
115                $renderer->doc .= '<tr><td colspan="3"><a href="';
116                $renderer->doc .= wl($this_ns . ':' . $this->getConf('start'));
117                $renderer->doc .= '">';
118                $renderer->doc .= $name_ns;
119                $renderer->doc .= '</a> ';
120                $renderer->doc .= '</td></tr>';
121                $working_ns = $this_ns;
122            }
123
124            $updated = '<a href="' . wl($page[0]) . '">' . dformat($page[2]) . '</a>';
125
126            $class = 'plugin__approve_red';
127            $state = $this->getLang('draft');
128            $all += 1;
129
130            if ($page[1] === 'approved') {
131                $class = 'plugin__approve_green';
132                $state = $this->getLang('approved');
133                $all_approved += 1;
134            } elseif ($page[1] === 'ready for approval' && $this->getConf('ready_for_approval') === 1) {
135                $class = 'plugin__approve_ready';
136                $state = $this->getLang('marked_approve_ready');
137                $all_approved_ready += 1;
138            }
139
140            $renderer->doc .= '<tr class="'.$class.'">';
141            $renderer->doc .= '<td><a href="';
142            $renderer->doc .= wl($page[0]);
143            $renderer->doc .= '">';
144            if ($conf['useheading'] === '1') {
145                $heading = p_get_first_heading($page[0]);
146                if ($heading != '') {
147                    $renderer->doc .= $heading;
148                } else {
149                    $renderer->doc .= $page[0];
150                }
151
152            } else {
153                $renderer->doc .= $page[0];
154            }
155
156            $renderer->doc .= '</a></td><td>';
157            $renderer->doc .= '<strong>'.$state. '</strong> '. $this->getLang('by'). ' ' . $page[4];
158            $renderer->doc .= '</td><td>';
159            $renderer->doc .= $updated;
160            $renderer->doc .= '</td></tr>';
161        }
162
163        if ($params['summarize']) {
164            if($this->getConf('ready_for_approval') === 1) {
165                $renderer->doc .= '<tr><td><strong>';
166                $renderer->doc .= $this->getLang('all_approved_ready');
167                $renderer->doc .= '</strong></td>';
168
169                $renderer->doc .= '<td colspan="2">';
170                $percent       = 0;
171                if($all > 0) {
172                    $percent = $all_approved_ready * 100 / $all;
173                }
174                $renderer->doc .= $all_approved_ready . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
175                $renderer->doc .= '</td></tr>';
176            }
177
178            $renderer->doc .= '<tr><td><strong>';
179            $renderer->doc .= $this->getLang('all_approved');
180            $renderer->doc .= '</strong></td>';
181
182            $renderer->doc .= '<td colspan="2">';
183            $percent       = 0;
184            if($all > 0) {
185                $percent = $all_approved * 100 / $all;
186            }
187            $renderer->doc .= $all_approved . ' / ' . $all . sprintf(" (%.0f%%)", $percent);
188            $renderer->doc .= '</td></tr>';
189        }
190
191        $renderer->doc .= '</table>';
192        return true;
193    }
194}
195