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