1<?php 2/** 3 * DokuWiki Plugin watchcycle (Admin Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Szymon Olewniczak <dokuwiki@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if (!defined('DOKU_INC')) { 11 die(); 12} 13 14class admin_plugin_approve extends DokuWiki_Admin_Plugin 15{ 16 17 /** @var helper_plugin_sqlite */ 18 protected $sqlite; 19 20 /** @var helper_plugin_approve */ 21 protected $helper; 22 23 /** 24 * @return helper_plugin_sqlite 25 */ 26 protected function sqlite() { 27 if (!$this->sqlite) { 28 /** @var helper_plugin_approve_db $db_helper */ 29 $db_helper = plugin_load('helper', 'approve_db'); 30 $this->sqlite = $db_helper->getDB(); 31 } 32 return $this->sqlite; 33 } 34 35 /** 36 * @return helper_plugin_approve 37 */ 38 protected function helper() { 39 if (!$this->helper) { 40 $helper = plugin_load('helper', 'approve'); 41 $this->helper = $helper; 42 } 43 return $this->helper; 44 } 45 46 /** 47 * @return int sort number in admin menu 48 */ 49 public function getMenuSort() 50 { 51 return 1; 52 } 53 54 protected function getPages() { 55 global $conf; 56 $datadir = $conf['datadir']; 57 if (substr($datadir, -1) != '/') { 58 $datadir .= '/'; 59 } 60 61 $directory = new RecursiveDirectoryIterator($datadir, FilesystemIterator::SKIP_DOTS); 62 $iterator = new RecursiveIteratorIterator($directory); 63 64 $pages = []; 65 /** @var SplFileInfo $fileinfo */ 66 foreach ($iterator as $fileinfo) { 67 if (!$fileinfo->isFile()) continue; 68 69 $path = $fileinfo->getPathname(); 70 //remove .txt 71 $id = str_replace('/', ':', substr($path, strlen($datadir), -4)); 72 $pages[] = $id; 73 } 74 75 return $pages; 76 } 77 78 protected function updatePage() 79 { 80 $res = $this->sqlite()->query('SELECT * FROM maintainer'); 81 $assignments = $this->sqlite()->res2arr($res); 82 83 $weighted_assigments = []; 84 foreach ($assignments as $assignment) { 85 $ns = $assignment['namespace']; 86 //more general namespaces are overridden by more specific ones. 87 if (substr($ns, -1) == '*') { 88 $weight = substr_count($ns, ':'); 89 } else { 90 $weight = PHP_INT_MAX; 91 } 92 93 $assignment['weight'] = $weight; 94 $weighted_assigments[] = $assignment; 95 } 96 array_multisort(array_column($weighted_assigments, 'weight'), $weighted_assigments); 97 98 $approvePages = []; 99 $wikiPages = $this->getPages(); 100 foreach ($weighted_assigments as $assignment) { 101 $ns = ltrim($assignment['namespace'], ':'); 102 $maintainer = $assignment['maintainer']; 103 if (substr($ns, -2) == '**') { 104 //remove '**' 105 $ns = substr($ns, 0, -2); 106 foreach ($wikiPages as $id) { 107 if (substr($id, 0, strlen($ns)) == $ns) { 108 $approvePages[$id] = $maintainer; 109 } 110 } 111 } elseif (substr($ns, -1) == '*') { 112 //remove '*' 113 $ns = substr($ns, 0, -1); 114 foreach ($wikiPages as $id) { 115 $noNS = substr($id, strlen($id)); 116 if (strpos($noNS, ':') === FALSE && 117 substr($id, 0, strlen($ns)) == $ns) { 118 $approvePages[$id] = $maintainer; 119 } 120 } 121 } else { 122 $approvePages[$ns] = $maintainer; 123 } 124 } 125 126 //clean current settings 127 $this->sqlite()->query('DELETE FROM page'); 128 $no_apr_namespace = $this->helper()->no_apr_namespace(); 129 foreach ($approvePages as $id => $maintainer) { 130 $in_hidden_namespace = $this->helper()->in_hidden_namespace($id, $no_apr_namespace); 131 $hidden = $in_hidden_namespace ? '1' : '0'; 132 if (blank($maintainer)) { 133 $q = 'INSERT INTO page(page,hidden) VALUES (?,?)'; 134 $this->sqlite()->query($q, $id, $hidden); 135 } else { 136 $q = 'INSERT INTO page(page,maintainer,hidden) VALUES (?,?,?)'; 137 $this->sqlite()->query($q, $id, $maintainer, $hidden); 138 } 139 } 140 141 } 142 143 /** 144 * Should carry out any processing required by the plugin. 145 */ 146 public function handle() 147 { 148 global $ID; 149 150 /* @var Input */ 151 global $INPUT; 152 153 if($INPUT->str('action') && $INPUT->arr('assignment') && checkSecurityToken()) { 154 $assignment = $INPUT->arr('assignment'); 155 //insert empty string as NULL 156 if ($INPUT->str('action') === 'delete') { 157 $this->sqlite()->query('DELETE FROM maintainer WHERE id=?', $assignment['id']); 158 $this->updatePage(); 159 } else if ($INPUT->str('action') === 'add' && !blank($assignment['assign'])) { 160 if (blank($assignment['maintainer'])) { 161 $q = 'INSERT INTO maintainer(namespace) VALUES (?)'; 162 $this->sqlite()->query($q, $assignment['assign']); 163 } else { 164 $q = 'INSERT INTO maintainer(namespace,maintainer) VALUES (?,?)'; 165 $this->sqlite()->query($q, $assignment['assign'], $assignment['maintainer']); 166 } 167 $this->updatePage(); 168 } 169 170 send_redirect(wl($ID, array('do' => 'admin', 'page' => 'approve'), true, '&')); 171 } 172 } 173 174 /** 175 * Render HTML output, e.g. helpful text and a form 176 */ 177 public function html() 178 { 179 global $ID; 180 /* @var DokuWiki_Auth_Plugin $auth */ 181 global $auth; 182 183 $res = $this->sqlite()->query('SELECT * FROM maintainer'); 184 $assignments = $this->sqlite()->res2arr($res); 185 186 echo $this->locale_xhtml('assignments_intro'); 187 188 echo '<form action="' . wl($ID) . '" action="post">'; 189 echo '<input type="hidden" name="do" value="admin" />'; 190 echo '<input type="hidden" name="page" value="approve" />'; 191 echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />'; 192 echo '<table class="inline">'; 193 194 // header 195 echo '<tr>'; 196 echo '<th>'.$this->getLang('admin h_assignment_namespace').'</th>'; 197 echo '<th>'.$this->getLang('admin h_assignment_maintainer').'</th>'; 198 echo '<th></th>'; 199 echo '</tr>'; 200 201 // existing assignments 202 foreach($assignments as $assignment) { 203 $id = $assignment['id']; 204 $namespace = $assignment['namespace']; 205 $maintainer = $assignment['maintainer'] ? $assignment['maintainer'] : '---'; 206 207 $link = wl( 208 $ID, array( 209 'do' => 'admin', 210 'page' => 'approve', 211 'action' => 'delete', 212 'sectok' => getSecurityToken(), 213 'assignment[id]' => $id 214 ) 215 ); 216 217 echo '<tr>'; 218 echo '<td>' . hsc($namespace) . '</td>'; 219 $user = $auth->getUserData($maintainer); 220 if ($user) { 221 echo '<td>' . hsc($user['name']) . '</td>'; 222 } else { 223 echo '<td>' . hsc($maintainer) . '</td>'; 224 } 225 echo '<td><a href="' . $link . '">'.$this->getLang('admin btn_delete').'</a></td>'; 226 echo '</tr>'; 227 } 228 229 // new assignment form 230 echo '<tr>'; 231 echo '<td><input type="text" name="assignment[assign]" /></td>'; 232 echo '<td>'; 233 echo '<select name="assignment[maintainer]">'; 234 echo '<option value="">---</option>'; 235 foreach($auth->retrieveUsers() as $login => $data) { 236 echo '<option value="' . hsc($login) . '">' . hsc($data['name']) . '</option>'; 237 } 238 echo '</select>'; 239 echo '</td>'; 240 echo '<td><button type="submit" name="action" value="add">'.$this->getLang('admin btn_add').'</button></td>'; 241 echo '</tr>'; 242 243 echo '</table>'; 244 } 245} 246 247// vim:ts=4:sw=4:et: 248