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