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