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__ . '/../ComboStrap/PageRules.php');
15require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
16require_once(__DIR__ . '/../ComboStrap/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>&nbsp;</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