xref: /plugin/deletepageguard/admin.php (revision 9a383d51b90310842e2a3f0f9d693178d0875b32)
1<?php
2/**
3 * Admin interface for Delete Page Guard pattern validation
4 *
5 * @license GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html) - see LICENSE.md
6 * @author  Johann Duscher <jonny.dee@posteo.net>
7 * @copyright 2025 Johann Duscher
8 */
9
10use dokuwiki\Extension\AdminPlugin;
11
12// Protect against direct call
13if (!defined('DOKU_INC')) die();
14
15/**
16 * Class admin_plugin_deletepageguard
17 *
18 * Provides an admin interface for validating Delete Page Guard patterns
19 * and offering configuration guidance to administrators.
20 */
21class admin_plugin_deletepageguard extends AdminPlugin {
22
23    /**
24     * Return sort order for position in admin menu
25     * @return int
26     */
27    public function getMenuSort() {
28        return 200;
29    }
30
31    /**
32     * Return the text to display in the admin menu
33     * @return string
34     */
35    public function getMenuText($language) {
36        return $this->getLang('menu');
37    }
38
39    /**
40     * Return true if access to this admin plugin is allowed
41     * @return bool
42     */
43    public function forAdminOnly() {
44        return true;
45    }
46
47    /**
48     * Handle user request
49     * @return void
50     */
51    public function handle() {
52        // Nothing to handle - validation is done in html() method
53    }
54
55    /**
56     * Render HTML output
57     * @return void
58     */
59    public function html() {
60        echo '<h1>' . $this->getLang('admin_title') . '</h1>';
61        echo '<div class="level1">';
62
63        // Determine which patterns to show - use POST data if available, otherwise config
64        $patterns = $_POST['test_patterns'] ?? $this->getConf('patterns');
65
66        // Show validation results if form was submitted
67        if (isset($_POST['validate_patterns'])) {
68            echo '<h2>' . $this->getLang('validation_results_title') . '</h2>';
69            $this->showPatternValidation($patterns);
70        } else {
71            // Show current config patterns on initial load
72            $this->showPatternValidation($patterns);
73        }
74
75        // Add validation form
76        echo '<h2>' . $this->getLang('test_patterns_title') . '</h2>';
77        echo '<form method="post" accept-charset="utf-8">';
78        echo '<p>' . $this->getLang('test_patterns_help') . '</p>';
79        echo '<textarea name="test_patterns" rows="10" cols="80" class="edit">' . hsc($patterns) . '</textarea><br>';
80        echo '<input type="submit" name="validate_patterns" value="' . $this->getLang('validate_button') . '" class="button">';
81        echo '</form>';
82
83        echo '</div>';
84    }
85
86    /**
87     * Display pattern validation results
88     * @param string $patterns The patterns to validate
89     * @return void
90     */
91    private function showPatternValidation($patterns) {
92        if (empty(trim($patterns))) {
93            echo '<div class="info">' . $this->getLang('no_patterns') . '</div>';
94            return;
95        }
96
97        $lines = preg_split('/\R+/', $patterns, -1, PREG_SPLIT_NO_EMPTY);
98        $hasErrors = false;
99        $validCount = 0;
100
101        echo '<div class="level2">';
102        echo '<h3>' . $this->getLang('validation_results') . '</h3>';
103        echo '<ul>';
104
105        foreach ($lines as $i => $line) {
106            $pattern = trim($line);
107            if ($pattern === '') continue;
108
109            $lineNum = $i + 1;
110            $status = $this->validateSinglePattern($pattern);
111
112            if ($status === true) {
113                echo '<li><span style="color: green; font-weight: bold;">✓</span> ';
114                echo '<strong>Line ' . $lineNum . ':</strong> <code>' . hsc($pattern) . '</code></li>';
115                $validCount++;
116            } else {
117                echo '<li><span style="color: red; font-weight: bold;">✗</span> ';
118                echo '<strong>Line ' . $lineNum . ':</strong> <code>' . hsc($pattern) . '</code><br>';
119                echo '&nbsp;&nbsp;&nbsp;<em style="color: red;">' . hsc($status) . '</em></li>';
120                $hasErrors = true;
121            }
122        }
123
124        echo '</ul>';
125
126        if (!$hasErrors && $validCount > 0) {
127            echo '<div class="success">' . sprintf($this->getLang('all_patterns_valid'), $validCount) . '</div>';
128        } elseif ($hasErrors) {
129            echo '<div class="error">' . $this->getLang('some_patterns_invalid') . '</div>';
130        }
131
132        echo '</div>';
133    }
134
135    /**
136     * Validate a single pattern by delegating to the action plugin's validator.
137     * This ensures consistent validation logic between admin UI and runtime checks.
138     *
139     * @param string $pattern The pattern to validate
140     * @return string|true True if valid, error message if invalid
141     */
142    private function validateSinglePattern($pattern) {
143        // Load the action plugin to use its centralized validation logic
144        $actionPlugin = plugin_load('action', 'deletepageguard');
145        if (!$actionPlugin) {
146            return 'Error: Could not load validation service';
147        }
148
149        // Use the action plugin's validateRegexPattern method (without line number)
150        $result = $actionPlugin->validateRegexPattern($pattern, 0);
151
152        // The action plugin returns true for valid, string for invalid
153        // We need to strip the "Line 0: " prefix if present
154        if (is_string($result)) {
155            $result = preg_replace('/^Line 0: /', '', $result);
156        }
157
158        return $result;
159    }
160}