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