1b81b1128SSzymon Olewniczak<?php 2b81b1128SSzymon Olewniczak 3*f7568302SSzymon Olewniczakuse dokuwiki\Extension\SyntaxPlugin; 4b664e7d8SSzymon Olewniczak 5*f7568302SSzymon Olewniczakclass syntax_plugin_approve_table extends SyntaxPlugin { 6b81b1128SSzymon Olewniczak 7058bad72SSzymon Olewniczak protected $states = ['approved', 'draft', 'ready_for_approval']; 8b81b1128SSzymon Olewniczak 9b81b1128SSzymon Olewniczak function getType() { 10b81b1128SSzymon Olewniczak return 'substition'; 11b81b1128SSzymon Olewniczak } 12b81b1128SSzymon Olewniczak 13b81b1128SSzymon Olewniczak function getSort() { 14b81b1128SSzymon Olewniczak return 20; 15b81b1128SSzymon Olewniczak } 16b81b1128SSzymon Olewniczak 17b81b1128SSzymon Olewniczak function PType() { 18b81b1128SSzymon Olewniczak return 'block'; 19b81b1128SSzymon Olewniczak } 20b81b1128SSzymon Olewniczak 21b81b1128SSzymon Olewniczak function connectTo($mode) { 22b81b1128SSzymon Olewniczak $this->Lexer->addSpecialPattern('----+ *approve table *-+\n.*?----+', $mode,'plugin_approve_table'); 23b81b1128SSzymon Olewniczak } 24b81b1128SSzymon Olewniczak 25b81b1128SSzymon Olewniczak function handle($match, $state, $pos, Doku_Handler $handler){ 26b81b1128SSzymon Olewniczak $lines = explode("\n", $match); 27b81b1128SSzymon Olewniczak array_shift($lines); 28b81b1128SSzymon Olewniczak array_pop($lines); 29b81b1128SSzymon Olewniczak 30b1ff32a1SSzymon Olewniczak $params = [ 31b1ff32a1SSzymon Olewniczak 'namespace' => '', 32b1ff32a1SSzymon Olewniczak 'filter' => false, 33b664e7d8SSzymon Olewniczak 'states' => $this->states, 34b1ff32a1SSzymon Olewniczak 'summarize' => true, 35*f7568302SSzymon Olewniczak 'approver' => '' 36b1ff32a1SSzymon Olewniczak ]; 37b1ff32a1SSzymon Olewniczak 38b81b1128SSzymon Olewniczak foreach ($lines as $line) { 39b81b1128SSzymon Olewniczak $pair = explode(':', $line, 2); 40b81b1128SSzymon Olewniczak if (count($pair) < 2) { 41b81b1128SSzymon Olewniczak continue; 42b81b1128SSzymon Olewniczak } 43b81b1128SSzymon Olewniczak $key = trim($pair[0]); 44b81b1128SSzymon Olewniczak $value = trim($pair[1]); 45b81b1128SSzymon Olewniczak if ($key == 'states') { 46b81b1128SSzymon Olewniczak $value = array_map('trim', explode(',', $value)); 47b81b1128SSzymon Olewniczak //normalize 48b81b1128SSzymon Olewniczak $value = array_map('strtolower', $value); 49b81b1128SSzymon Olewniczak foreach ($value as $state) { 5099eaf3e2SSzymon Olewniczak if (!in_array($state, $this->states)) { 51b81b1128SSzymon Olewniczak msg('approve plugin: unknown state "'.$state.'" should be: ' . 5299eaf3e2SSzymon Olewniczak implode(', ', $this->states), -1); 53b81b1128SSzymon Olewniczak return false; 54b81b1128SSzymon Olewniczak } 55b81b1128SSzymon Olewniczak } 569aebb494SSzymon Olewniczak } elseif($key == 'filter') { 579aebb494SSzymon Olewniczak $value = trim($value, '/'); 589aebb494SSzymon Olewniczak if (preg_match('/' . $value . '/', null) === false) { 59b81b1128SSzymon Olewniczak msg('approve plugin: invalid filter regex', -1); 60b81b1128SSzymon Olewniczak return false; 619aebb494SSzymon Olewniczak } 625f33cda2SSzymon Olewniczak } elseif ($key == 'summarize') { 635f33cda2SSzymon Olewniczak $value = $value == '0' ? false : true; 64c7d53eabSSzymon Olewniczak } elseif ($key == 'namespace') { 65c7d53eabSSzymon Olewniczak $value = trim(cleanID($value), ':'); 66b81b1128SSzymon Olewniczak } 67b81b1128SSzymon Olewniczak $params[$key] = $value; 68b81b1128SSzymon Olewniczak } 69b81b1128SSzymon Olewniczak return $params; 70b81b1128SSzymon Olewniczak } 71b81b1128SSzymon Olewniczak 72b1ff32a1SSzymon Olewniczak /** 73b1ff32a1SSzymon Olewniczak * Render xhtml output or metadata 74b1ff32a1SSzymon Olewniczak * 75b1ff32a1SSzymon Olewniczak * @param string $mode Renderer mode (supported modes: xhtml) 76b1ff32a1SSzymon Olewniczak * @param Doku_Renderer $renderer The renderer 77b1ff32a1SSzymon Olewniczak * @param array $data The data from the handler() function 78b1ff32a1SSzymon Olewniczak * 79b1ff32a1SSzymon Olewniczak * @return bool If rendering was successful. 80b1ff32a1SSzymon Olewniczak */ 81b1ff32a1SSzymon Olewniczak 82b1ff32a1SSzymon Olewniczak public function render($mode, Doku_Renderer $renderer, $data) 83b1ff32a1SSzymon Olewniczak { 84b1ff32a1SSzymon Olewniczak $method = 'render' . ucfirst($mode); 85b1ff32a1SSzymon Olewniczak if (method_exists($this, $method)) { 86b1ff32a1SSzymon Olewniczak call_user_func([$this, $method], $renderer, $data); 87b1ff32a1SSzymon Olewniczak return true; 88b1ff32a1SSzymon Olewniczak } 89b1ff32a1SSzymon Olewniczak return false; 90b1ff32a1SSzymon Olewniczak } 91b1ff32a1SSzymon Olewniczak 92b1ff32a1SSzymon Olewniczak /** 93b1ff32a1SSzymon Olewniczak * Render metadata 94b1ff32a1SSzymon Olewniczak * 95b1ff32a1SSzymon Olewniczak * @param Doku_Renderer $renderer The renderer 96b1ff32a1SSzymon Olewniczak * @param array $data The data from the handler() function 97b1ff32a1SSzymon Olewniczak */ 98b1ff32a1SSzymon Olewniczak public function renderMetadata(Doku_Renderer $renderer, $params) 99b1ff32a1SSzymon Olewniczak { 100b1ff32a1SSzymon Olewniczak $plugin_name = $this->getPluginName(); 101b1ff32a1SSzymon Olewniczak $renderer->meta['plugin'][$plugin_name] = []; 102b1ff32a1SSzymon Olewniczak 103*f7568302SSzymon Olewniczak $renderer->meta['plugin'][$plugin_name]['dynamic_approver'] = $params['approver'] == '$USER$'; 104b1ff32a1SSzymon Olewniczak $renderer->meta['plugin'][$plugin_name]['approve_table'] = true; 105b1ff32a1SSzymon Olewniczak } 106b1ff32a1SSzymon Olewniczak 107058bad72SSzymon Olewniczak protected function array_equal($a, $b) { 108058bad72SSzymon Olewniczak return ( 109058bad72SSzymon Olewniczak is_array($a) 110058bad72SSzymon Olewniczak && is_array($b) 111058bad72SSzymon Olewniczak && count($a) == count($b) 112058bad72SSzymon Olewniczak && array_diff($a, $b) === array_diff($b, $a) 113058bad72SSzymon Olewniczak ); 114058bad72SSzymon Olewniczak } 115058bad72SSzymon 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 124*f7568302SSzymon Olewniczak 1254474ed8aSSzymon Olewniczak 1262ce523c6SSzymon Olewniczak if ($params['approver'] == '$USER$') { 1272ce523c6SSzymon Olewniczak $params['approver'] = $INFO['client']; 128a27fc412SSzymon Olewniczak } 129a27fc412SSzymon Olewniczak 130b81b1128SSzymon Olewniczak // Output Table 131b81b1128SSzymon Olewniczak $renderer->doc .= '<table><tr>'; 132b81b1128SSzymon Olewniczak $renderer->doc .= '<th>' . $this->getLang('hdr_page') . '</th>'; 133b81b1128SSzymon Olewniczak $renderer->doc .= '<th>' . $this->getLang('hdr_state') . '</th>'; 134b81b1128SSzymon Olewniczak $renderer->doc .= '<th>' . $this->getLang('hdr_updated') . '</th>'; 1352ce523c6SSzymon Olewniczak $renderer->doc .= '<th>' . $this->getLang('hdr_approver') . '</th>'; 136b81b1128SSzymon Olewniczak $renderer->doc .= '</tr>'; 137b81b1128SSzymon Olewniczak 138b81b1128SSzymon Olewniczak 139b81b1128SSzymon Olewniczak $all_approved = 0; 140b81b1128SSzymon Olewniczak $all_approved_ready = 0; 141b81b1128SSzymon Olewniczak $all = 0; 142b81b1128SSzymon Olewniczak 143c7d53eabSSzymon Olewniczak $curNS = ''; 144*f7568302SSzymon Olewniczak 145*f7568302SSzymon Olewniczak /** @var helper_plugin_approve_db $db */ 146*f7568302SSzymon Olewniczak $db = $this->loadHelper('approve_db'); 147*f7568302SSzymon Olewniczak $pages = $db->getPages($params['approver'], $params['states'], $params['namespace'], $params['filter']); 148b81b1128SSzymon Olewniczak foreach($pages as $page) { 149*f7568302SSzymon Olewniczak $id = $page['id']; 1502ce523c6SSzymon Olewniczak $approver = $page['approver']; 151c7d53eabSSzymon Olewniczak $rev = $page['rev']; 152c7d53eabSSzymon Olewniczak $approved = strtotime($page['approved']); 153c7d53eabSSzymon Olewniczak $approved_by = $page['approved_by']; 154c7d53eabSSzymon Olewniczak $ready_for_approval = strtotime($page['ready_for_approval']); 155c7d53eabSSzymon Olewniczak $ready_for_approval_by = $page['ready_for_approval_by']; 156b81b1128SSzymon Olewniczak 157c7d53eabSSzymon Olewniczak $pageNS = getNS($id); 158c7d53eabSSzymon Olewniczak 159c7d53eabSSzymon Olewniczak if($pageNS != '' && $pageNS != $curNS) { 160c7d53eabSSzymon Olewniczak $curNS = $pageNS; 161c7d53eabSSzymon Olewniczak 162c7d53eabSSzymon Olewniczak $renderer->doc .= '<tr><td colspan="4"><a href="'; 163c7d53eabSSzymon Olewniczak $renderer->doc .= wl($curNS); 164b81b1128SSzymon Olewniczak $renderer->doc .= '">'; 165c7d53eabSSzymon Olewniczak $renderer->doc .= $curNS; 166b81b1128SSzymon Olewniczak $renderer->doc .= '</a> '; 167b81b1128SSzymon Olewniczak $renderer->doc .= '</td></tr>'; 168b81b1128SSzymon Olewniczak } 169b81b1128SSzymon Olewniczak 170b81b1128SSzymon Olewniczak $all += 1; 171c7d53eabSSzymon Olewniczak if ($approved) { 17215e5c2ddSSzymon Olewniczak $class = 'plugin__approve_approved'; 173b81b1128SSzymon Olewniczak $state = $this->getLang('approved'); 174c7d53eabSSzymon Olewniczak $date = $approved; 175c7d53eabSSzymon Olewniczak $by = $approved_by; 176c7d53eabSSzymon Olewniczak 177b81b1128SSzymon Olewniczak $all_approved += 1; 178c7d53eabSSzymon Olewniczak } elseif ($this->getConf('ready_for_approval') && $ready_for_approval) { 179b81b1128SSzymon Olewniczak $class = 'plugin__approve_ready'; 180b81b1128SSzymon Olewniczak $state = $this->getLang('marked_approve_ready'); 181c7d53eabSSzymon Olewniczak $date = $ready_for_approval; 182c7d53eabSSzymon Olewniczak $by = $ready_for_approval_by; 183c7d53eabSSzymon Olewniczak 184b81b1128SSzymon Olewniczak $all_approved_ready += 1; 185c7d53eabSSzymon Olewniczak } else { 18615e5c2ddSSzymon Olewniczak $class = 'plugin__approve_draft'; 187c7d53eabSSzymon Olewniczak $state = $this->getLang('draft'); 188c7d53eabSSzymon Olewniczak $date = $rev; 189c7d53eabSSzymon Olewniczak $by = p_get_metadata($id, 'last_change user'); 190b81b1128SSzymon Olewniczak } 191b81b1128SSzymon Olewniczak 192b81b1128SSzymon Olewniczak $renderer->doc .= '<tr class="'.$class.'">'; 193b81b1128SSzymon Olewniczak $renderer->doc .= '<td><a href="'; 194c7d53eabSSzymon Olewniczak $renderer->doc .= wl($id); 195b81b1128SSzymon Olewniczak $renderer->doc .= '">'; 196c7d53eabSSzymon Olewniczak if ($conf['useheading'] == '1') { 197c7d53eabSSzymon Olewniczak $heading = p_get_first_heading($id); 198b81b1128SSzymon Olewniczak if ($heading != '') { 199b81b1128SSzymon Olewniczak $renderer->doc .= $heading; 200b81b1128SSzymon Olewniczak } else { 201c7d53eabSSzymon Olewniczak $renderer->doc .= $id; 202b81b1128SSzymon Olewniczak } 203b81b1128SSzymon Olewniczak } else { 204c7d53eabSSzymon Olewniczak $renderer->doc .= $id; 205b81b1128SSzymon Olewniczak } 206b81b1128SSzymon Olewniczak 207b81b1128SSzymon Olewniczak $renderer->doc .= '</a></td><td>'; 208c7d53eabSSzymon Olewniczak $renderer->doc .= '<strong>'.$state. '</strong> '; 209c7d53eabSSzymon Olewniczak 210c7d53eabSSzymon Olewniczak $user = $auth->getUserData($by); 211c7d53eabSSzymon Olewniczak if ($user) { 212c7d53eabSSzymon Olewniczak $renderer->doc .= $this->getLang('by'). ' ' . $user['name']; 213c7d53eabSSzymon Olewniczak } 214b81b1128SSzymon Olewniczak $renderer->doc .= '</td><td>'; 215c7d53eabSSzymon Olewniczak $renderer->doc .= '<a href="' . wl($id) . '">' . dformat($date) . '</a>';; 216c7d53eabSSzymon Olewniczak $renderer->doc .= '</td><td>'; 2172ce523c6SSzymon Olewniczak if ($approver) { 2182ce523c6SSzymon Olewniczak $user = $auth->getUserData($approver); 219c7d53eabSSzymon Olewniczak if ($user) { 220c7d53eabSSzymon Olewniczak $renderer->doc .= $user['name']; 221c7d53eabSSzymon Olewniczak } else { 2222ce523c6SSzymon Olewniczak $renderer->doc .= $approver; 223c7d53eabSSzymon Olewniczak } 224c7d53eabSSzymon Olewniczak } else { 225c7d53eabSSzymon Olewniczak $renderer->doc .= '---'; 226c7d53eabSSzymon Olewniczak } 227b81b1128SSzymon Olewniczak $renderer->doc .= '</td></tr>'; 228b81b1128SSzymon Olewniczak } 229b81b1128SSzymon Olewniczak 2305f33cda2SSzymon Olewniczak if ($params['summarize']) { 231c7d53eabSSzymon Olewniczak if($this->getConf('ready_for_approval')) { 232b81b1128SSzymon Olewniczak $renderer->doc .= '<tr><td><strong>'; 233b81b1128SSzymon Olewniczak $renderer->doc .= $this->getLang('all_approved_ready'); 234b81b1128SSzymon Olewniczak $renderer->doc .= '</strong></td>'; 235b81b1128SSzymon Olewniczak 236c7d53eabSSzymon Olewniczak $renderer->doc .= '<td colspan="3">'; 237b81b1128SSzymon Olewniczak $percent = 0; 238b81b1128SSzymon Olewniczak if($all > 0) { 239b81b1128SSzymon Olewniczak $percent = $all_approved_ready * 100 / $all; 240b81b1128SSzymon Olewniczak } 241b81b1128SSzymon Olewniczak $renderer->doc .= $all_approved_ready . ' / ' . $all . sprintf(" (%.0f%%)", $percent); 242b81b1128SSzymon Olewniczak $renderer->doc .= '</td></tr>'; 243b81b1128SSzymon Olewniczak } 244b81b1128SSzymon Olewniczak 245b81b1128SSzymon Olewniczak $renderer->doc .= '<tr><td><strong>'; 246b81b1128SSzymon Olewniczak $renderer->doc .= $this->getLang('all_approved'); 247b81b1128SSzymon Olewniczak $renderer->doc .= '</strong></td>'; 248b81b1128SSzymon Olewniczak 249c7d53eabSSzymon Olewniczak $renderer->doc .= '<td colspan="3">'; 250b81b1128SSzymon Olewniczak $percent = 0; 251b81b1128SSzymon Olewniczak if($all > 0) { 252b81b1128SSzymon Olewniczak $percent = $all_approved * 100 / $all; 253b81b1128SSzymon Olewniczak } 254b81b1128SSzymon Olewniczak $renderer->doc .= $all_approved . ' / ' . $all . sprintf(" (%.0f%%)", $percent); 255b81b1128SSzymon Olewniczak $renderer->doc .= '</td></tr>'; 2565f33cda2SSzymon Olewniczak } 257b81b1128SSzymon Olewniczak 258b81b1128SSzymon Olewniczak $renderer->doc .= '</table>'; 259b81b1128SSzymon Olewniczak } 260b81b1128SSzymon Olewniczak} 261