1<?php 2// must be run within Dokuwiki 3use ComboStrap\LogUtility; 4use ComboStrap\PageRules; 5use ComboStrap\PluginUtility; 6use ComboStrap\Sqlite; 7 8if (!defined('DOKU_INC')) die(); 9 10if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); 11 12require_once(DOKU_PLUGIN . 'admin.php'); 13require_once(DOKU_INC . 'inc/parser/xhtml.php'); 14require_once(__DIR__ . '/../class/PageRules.php'); 15require_once(__DIR__ . '/../class/PluginUtility.php'); 16 17/** 18 * The admin pages 19 * need to inherit from this class 20 * 21 * 22 * ! important ! 23 * The suffix of the class name should: 24 * * be equal to the name of the file 25 * * and have only letters 26 */ 27class admin_plugin_combo_pagerules extends DokuWiki_Admin_Plugin 28{ 29 30 31 32 /** 33 * @var array|string[] 34 */ 35 private $infoPlugin; 36 37 /** 38 * @var PageRules 39 */ 40 private $pageRuleManager; 41 42 43 /** 44 * admin_plugin_combo constructor. 45 * 46 * Use the get function instead 47 */ 48 public function __construct() 49 { 50 51 // enable direct access to language strings 52 // of use of $this->getLang 53 $this->setupLocale(); 54 $this->currentDate = date("c"); 55 $this->infoPlugin = $this->getInfo(); 56 57 58 } 59 60 /** 61 * Handle Sqlite instantiation here and not in the constructor 62 * to not make sqlite mandatory everywhere 63 */ 64 private function initiatePageRuleManager() 65 { 66 67 if ($this->pageRuleManager == null) { 68 69 $sqlite = Sqlite::getSqlite(); 70 if ($sqlite == null) { 71 // A message should have already been send by the getSqlite function 72 return; 73 } 74 $this->pageRuleManager = new PageRules($sqlite); 75 76 } 77 } 78 79 80 /** 81 * Access for managers allowed 82 */ 83 function forAdminOnly() 84 { 85 return false; 86 } 87 88 /** 89 * return sort order for position in admin menu 90 */ 91 function getMenuSort() 92 { 93 return 140; 94 } 95 96 /** 97 * return prompt for admin menu 98 * @param string $language 99 * @return string 100 */ 101 function getMenuText($language) 102 { 103 return ucfirst(PluginUtility::$PLUGIN_NAME) . " - " . $this->lang['PageRules']; 104 } 105 106 public function getMenuIcon() 107 { 108 return DOKU_PLUGIN . $this->getPluginName() . '/images/page-next.svg'; 109 } 110 111 112 /** 113 * handle user request 114 */ 115 function handle() 116 { 117 118 $this->initiatePageRuleManager(); 119 120 /** 121 * If one of the form submit has the add key 122 */ 123 if ($_POST['save'] && checkSecurityToken()) { 124 125 $id = $_POST[PageRules::ID_NAME]; 126 $matcher = $_POST[PageRules::MATCHER_NAME]; 127 $target = $_POST[PageRules::TARGET_NAME]; 128 $priority = $_POST[PageRules::PRIORITY_NAME]; 129 130 if ($matcher == null) { 131 msg('Matcher can not be null', LogUtility::LVL_MSG_ERROR); 132 return; 133 } 134 if ($target == null) { 135 msg('Target can not be null', LogUtility::LVL_MSG_ERROR); 136 return; 137 } 138 139 if ($matcher == $target) { 140 msg($this->lang['SameSourceAndTargetAndPage'] . ': ' . $matcher . '', LogUtility::LVL_MSG_ERROR); 141 return; 142 } 143 144 if ($id == null) { 145 if (!$this->pageRuleManager->patternExists($matcher)) { 146 $this->pageRuleManager->addRule($matcher, $target, $priority); 147 msg($this->lang['Saved'], LogUtility::LVL_MSG_INFO); 148 } else { 149 msg("The matcher pattern ($matcher) already exists. The page rule was not inserted.", LogUtility::LVL_MSG_ERROR); 150 } 151 } else { 152 $this->pageRuleManager->updateRule($id, $matcher, $target, $priority); 153 msg($this->lang['Saved'], LogUtility::LVL_MSG_INFO); 154 } 155 156 157 158 } 159 160 if ($_POST['Delete'] && checkSecurityToken()) { 161 162 $ruleId = $_POST[PageRules::ID_NAME]; 163 $this->pageRuleManager->deleteRule($ruleId); 164 msg($this->lang['Deleted'], LogUtility::LVL_MSG_INFO); 165 166 } 167 168 } 169 170 /** 171 * output appropriate html 172 * TODO: Add variable parsing where the key is the key of the lang object ?? 173 */ 174 function html() 175 { 176 177 $this->initiatePageRuleManager(); 178 179 ptln('<h1>' . ucfirst(PluginUtility::$PLUGIN_NAME) . ' - ' . ucfirst($this->getPluginComponent()) . '</a></h1>'); 180 $relativePath = 'admin/' . $this->getPluginComponent() . '_intro'; 181 echo $this->locale_xhtml($relativePath); 182 183 // Forms 184 if ($_POST['upsert']) { 185 186 $matcher = null; 187 $target = null; 188 $priority = 1; 189 190 // Update ? 191 $id = $_POST[PageRules::ID_NAME]; 192 if ($id != null){ 193 $rule = $this->pageRuleManager->getRule($id); 194 $matcher = $rule[PageRules::MATCHER_NAME]; 195 $target = $rule[PageRules::TARGET_NAME]; 196 $priority = $rule[PageRules::PRIORITY_NAME]; 197 } 198 199 200 // Forms 201 ptln('<div class="level2" >'); 202 ptln('<div id="form_container" style="max-width: 600px;">'); 203 ptln('<form action="" method="post">'); 204 ptln('<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'); 205 ptln('<p><b>If the Dokuwiki ID matches the following pattern:</b></p>'); 206 $matcherDefault = ""; 207 if ($matcher != null) { 208 $matcherDefault = 'value="' . $matcher . '"'; 209 } 210 ptln('<label for="' . PageRules::MATCHER_NAME . '">(You can use the asterisk (*) character)</label>'); 211 ptln('<p><input type="text" style="width: 100%;" id="' . PageRules::MATCHER_NAME . '" required="required" name="' . PageRules::MATCHER_NAME . '" ' . $matcherDefault . ' class="edit" placeholder="pattern"/> </p>'); 212 ptln('<p><b>Then applies this redirect settings:</b></p>'); 213 $targetDefault = ""; 214 if ($matcher != null) { 215 $targetDefault = 'value="' . $target . '"'; 216 } 217 ptln('<label for="' . PageRules::TARGET_NAME . '">Target: (A DokuWiki Id or an URL where you can use the ($) group character)</label>'); 218 ptln('<p><input type="text" style="width: 100%;" required="required" id="' . PageRules::TARGET_NAME . '" name="' . PageRules::TARGET_NAME . '" ' . $targetDefault . ' class="edit" placeholder="target" /></p>'); 219 ptln('<label for="' . PageRules::PRIORITY_NAME . '">Priority: (The order in which rules are applied)</label>'); 220 ptln('<p><input type="id" id="' . PageRules::PRIORITY_NAME . '." style="width: 100%;" required="required" placeholder="priority" name="' . PageRules::PRIORITY_NAME . '" value="' . $priority . '" class="edit" /></p>'); 221 ptln('<input type="hidden" name="do" value="admin" />'); 222 if ($id != null) { 223 ptln('<input type="hidden" name="' . PageRules::ID_NAME . '" value="' . $id . '" />'); 224 } 225 ptln('<input type="hidden" name="page" value="' . $this->getPluginName() . '_' . $this->getPluginComponent() . '" />'); 226 ptln('<p>'); 227 ptln('<a class="btn btn-light" href="?do=admin&page=webcomponent_pagerules" > ' . 'Cancel' . ' <a/>'); 228 ptln('<input class="btn btn-primary" type="submit" name="save" class="button" value="' . 'Save' . '" />'); 229 ptln('</p>'); 230 ptln('</form>'); 231 ptln('</div>'); 232 233 ptln('</div>'); 234 235 236 } else { 237 238 ptln('<h2><a name="" id="pagerules_list">' . 'Rules' . '</a></h2>'); 239 ptln('<div class="level2">'); 240 241 ptln('<form class="pt-3 pb-3" action="" method="post">'); 242 ptln('<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'); 243 ptln(' <input type="hidden" name="do" value="admin" />'); 244 ptln(' <input type="hidden" name="page" value="' . $this->getPluginName() . '_' . $this->getPluginComponent() . '" />'); 245 ptln(' <input type="submit" name="upsert" name="Create a page rule" class="button" value="' . $this->getLangOrDefault('AddNewRule','Add a new rule') . '" />'); 246 ptln('</form>'); 247 248 // List of redirection 249 $rules = $this->pageRuleManager->getRules(); 250 251 if (sizeof($rules)==0){ 252 ptln('<p>No Rules found</p>'); 253 } else { 254 ptln('<div class="table-responsive">'); 255 256 ptln('<table class="table table-hover">'); 257 ptln(' <thead>'); 258 ptln(' <tr>'); 259 ptln(' <th> </th>'); 260 ptln(' <th>' . $this->getLangOrDefault('Priority', 'Priority') . '</th>'); 261 ptln(' <th>' . $this->getLangOrDefault('Matcher', 'Matcher') . '</th>'); 262 ptln(' <th>' . $this->getLangOrDefault('Target', 'Target') . '</th>'); 263 ptln(' <th>' . $this->getLangOrDefault('NDate', 'Date') . '</th>'); 264 ptln(' </tr>'); 265 ptln(' </thead>'); 266 ptln(' <tbody>'); 267 268 269 foreach ($rules as $key => $row) { 270 271 $id = $row[PageRules::ID_NAME]; 272 $matcher = $row[PageRules::MATCHER_NAME]; 273 $target = $row[PageRules::TARGET_NAME]; 274 $timestamp = $row[PageRules::TIMESTAMP_NAME]; 275 $priority = $row[PageRules::PRIORITY_NAME]; 276 277 278 ptln(' <tr class="redirect_info">'); 279 ptln(' <td>'); 280 ptln(' <form action="" method="post" style="display: inline-block">'); 281 ptln('<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'); 282 ptln('<button style="background: none;border: 0;">'); 283 ptln(inlineSVG(DOKU_PLUGIN . $this->getPluginName() . '/images/delete.svg')); 284 ptln('</button>'); 285 ptln(' <input type="hidden" name="Delete" value="Yes" />'); 286 ptln(' <input type="hidden" name="' . PageRules::ID_NAME . '" value="' . $id . '" />'); 287 ptln(' </form>'); 288 ptln(' <form action="" method="post" style="display: inline-block">'); 289 ptln('<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'); 290 ptln('<button style="background: none;border: 0;">'); 291 ptln(inlineSVG(DOKU_PLUGIN . $this->getPluginName() . '/images/file-document-edit-outline.svg')); 292 ptln('</button>'); 293 ptln(' <input type="hidden" name="upsert" value="Yes" />'); 294 ptln(' <input type="hidden" name="' . PageRules::ID_NAME . '" value="' . $id . '" />'); 295 ptln(' </form>'); 296 297 ptln(' </td>'); 298 ptln(' <td>' . $priority . '</td>'); 299 ptln(' <td>' . $matcher . '</td>'); 300 ptln(' <td>' . $target . '</td>'); 301 ptln(' <td>' . $timestamp . '</td>'); 302 ptln(' </tr>'); 303 } 304 ptln(' </tbody>'); 305 ptln('</table>'); 306 ptln('</div>'); //End Table responsive 307 } 308 309 ptln('</div>'); // End level 2 310 311 312 } 313 314 315 } 316 317 /** 318 * An utility function to return the plugin translation or a default value 319 * @param $id 320 * @param $default 321 * @return mixed|string 322 */ 323 private function getLangOrDefault($id, $default) 324 { 325 $lang = $this->getLang($id); 326 return $lang !='' ? $lang : $default; 327 } 328 329 330 static function getAdminPageName(){ 331 return PluginUtility::getAdminPageName(get_called_class()); 332 } 333 334} 335