diff --git a/includes/access-control.php b/includes/access-control.php index f02f8bc..c9f9b09 100644 --- a/includes/access-control.php +++ b/includes/access-control.php @@ -1,39 +1,8 @@ options; - - if (empty($options['enable_maintenance'])) return; - - if (is_user_logged_in()) { - $user = wp_get_current_user(); - foreach ($user->roles as $role) { - if (in_array($role, $options['excluded_roles'])) return; - } - } - - if (in_array($_SERVER['REMOTE_ADDR'], $options['excluded_ips'])) return; - - global $wp_query; - if (!$options['enable_maintenance'] && $wp_query->is_404()) return; - - $current_path = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/'); - $redirect_path = trim($options['redirect_url'], '/'); - - if ($current_path === $redirect_path) return; - - foreach ($options['excluded_slugs'] as $slug) { - if (stripos($current_path, $slug) !== false) return; - } - - if (!is_admin()) { - wp_redirect(home_url($options['redirect_url'])); - exit; - } - }); -} +// Intentionally left blank. The previous dynamic "add_method" logic was removed. diff --git a/includes/admin-ui.php b/includes/admin-ui.php index a013f75..361582c 100644 --- a/includes/admin-ui.php +++ b/includes/admin-ui.php @@ -1,15 +1,20 @@ '—']; global $wp_roles; $all_users = get_users(['fields' => ['user_login']]); @@ -17,7 +22,6 @@ add_action('pausera_render_ui', function () { return $u->user_login; }, $all_users); ?> -
Aktueller Status:
@@ -37,11 +41,6 @@ add_action('pausera_render_ui', function () {
- - - - -
/>
- - - - -

Weiterleitungsseite

@@ -63,29 +57,18 @@ add_action('pausera_render_ui', function () { ID)); $selected = selected($redirect_url, $slug, false); - echo ""; + echo ""; endforeach; ?>
- - - - - - - - - - -

Erlaubte Benutzer

@@ -95,12 +78,31 @@ add_action('pausera_render_ui', function () { +
+

Ausgeschlossene Seiten (Slugs/Paths)

+ + + +
+ + +

Ausgeschlossene IP-Adressen

@@ -111,20 +113,16 @@ add_action('pausera_render_ui', function () {
-
-
-

Einstellungen speichern?

-

Bitte bestätigen Sie, dass Sie die Änderungen speichern möchten.

-
- - -
-
-
- - - +
+

Einstellungen speichern?

+

Bitte bestätigen Sie, dass Sie die Änderungen speichern möchten.

+
+ + +
+
+
@@ -134,12 +132,12 @@ add_action('pausera_render_ui', function () {

Plugin-Links

diff --git a/includes/assets.php b/includes/assets.php index 8bc6ec6..ab1eb91 100644 --- a/includes/assets.php +++ b/includes/assets.php @@ -1,7 +1,12 @@ - jQuery(document).ready(function($){ + jQuery(function($){ $(".acf-style-select").select2(); + $(".js-tags").select2({ + tags: true, + tokenSeparators: [",", " "], + width: "100%", + placeholder: "Slug hinzufügen…", + createTag: function(params) { + var term = $.trim(params.term); + if (term === "") return null; + return { id: term, text: term, newTag: true }; + } + }); $(".nav-tab").on("mousedown", function(e){ e.preventDefault(); }); }); '; } + add_action('admin_enqueue_scripts', 'pausera_enqueue_assets'); diff --git a/pausera.php b/pausera.php index e02cc6e..f51ce77 100644 --- a/pausera.php +++ b/pausera.php @@ -1,25 +1,194 @@ false, + 'excluded_slugs' => [], // e.g. ["qr", "coming-soon", "shop/qr"] + 'excluded_ips' => [], + 'excluded_roles' => [], + 'allowed_users' => [], + 'redirect_url' => '/maintenance', + ]; + + $saved_options = get_option('pausera_settings', []); + $this->options = wp_parse_args($saved_options, $defaults); + + add_action('admin_menu', [$this, 'admin_menu']); + add_action('admin_init', [$this, 'register_settings']); + add_action('template_redirect', [$this, 'handle_redirect']); + add_action('admin_bar_menu', [$this, 'add_admin_bar_status'], 100); + } + + /************************************************************************************ + * settings registration + sanitization + ************************************************************************************/ + public function register_settings() + { + register_setting('pausera_group', 'pausera_settings', [ + 'sanitize_callback' => [$this, 'sanitize_settings'] + ]); + } + + public function sanitize_settings($input) + { + add_option('pausera_settings_saved', 1); + + // Keep nested paths like "shop/qr" clean + $sanitize_path = function ($val) { + $val = is_string($val) ? trim($val) : ''; + $val = trim($val, "/ \t\n\r\0\x0B"); + if ($val === '') return ''; + $parts = array_filter(explode('/', $val), 'strlen'); + $parts = array_map('sanitize_title', $parts); + return implode('/', $parts); + }; + + $excluded_slugs = []; + if (isset($input['excluded_slugs'])) { + $raw = is_array($input['excluded_slugs']) ? $input['excluded_slugs'] : [$input['excluded_slugs']]; + foreach ($raw as $r) { + $s = $sanitize_path($r); + if ($s !== '') $excluded_slugs[] = $s; + } + $excluded_slugs = array_values(array_unique($excluded_slugs)); + } + + return [ + 'enable_maintenance' => !empty($input['enable_maintenance']), + 'excluded_slugs' => $excluded_slugs, + 'excluded_ips' => array_filter(array_map('trim', explode(',', sanitize_text_field($input['excluded_ips'] ?? '')))), + 'excluded_roles' => isset($input['excluded_roles']) ? array_filter(array_map('sanitize_text_field', (array) $input['excluded_roles'])) : [], + 'redirect_url' => esc_url_raw($input['redirect_url'] ?? '/maintenance'), + 'allowed_users' => isset($input['allowed_users']) ? array_filter(array_map('sanitize_user', (array) $input['allowed_users'])) : [], + ]; + } + + /************************************************************************************ + * admin UI + notices + ************************************************************************************/ + public function admin_menu() + { + add_menu_page( + 'Pausera', + 'Pausera', + 'manage_options', + 'pausera', + [$this, 'settings_page'], + 'dashicons-shield-alt', + 80 + ); + } + + public function settings_page() + { + do_action('pausera_render_ui'); + } + + public function add_admin_bar_status($wp_admin_bar) + { + if (!current_user_can('manage_options')) return; + + $enabled = !empty($this->options['enable_maintenance']); + $label = 'Pausera: ' . ($enabled ? 'ON' : 'OFF'); + $color = $enabled ? 'orange' : '#999'; + + $wp_admin_bar->add_node([ + 'id' => 'pausera_status', + 'title' => '' . esc_html($label) . '', + 'href' => admin_url('admin.php?page=pausera'), + 'meta' => ['title' => 'Pausera Status'] + ]); + } + + /************************************************************************************ + * redirect logic + ************************************************************************************/ + private function path_matches($current_path, $slug) + { + $slug = trim($slug, "/ \t\n\r\0\x0B"); + if ($slug === '') return false; + if ($current_path === $slug) return true; // exact + if (strpos($current_path, $slug . '/') === 0) return true; // prefix segment + return false; + } + + private function is_public_system_request($current_path) + { + if (function_exists('wp_doing_ajax') && wp_doing_ajax()) return true; + if (defined('REST_REQUEST') && REST_REQUEST) return true; + if (strpos($current_path, 'wp-json') === 0) return true; + + $script = $_SERVER['SCRIPT_NAME'] ?? ''; + if (strpos($script, 'wp-login.php') !== false) return true; + if (strpos($script, 'wp-cron.php') !== false) return true; + + if (function_exists('is_customize_preview') && is_customize_preview()) return true; + if (is_feed()) return true; + + return false; + } + + public function handle_redirect() + { + if (empty($this->options['enable_maintenance'])) return; + + if (is_user_logged_in()) { + $user = wp_get_current_user(); + if (in_array($user->user_login, $this->options['allowed_users'] ?? [], true)) return; + foreach ((array) $user->roles as $role) { + if (in_array($role, (array) $this->options['excluded_roles'], true)) return; + } + } + + $remote_ip = $_SERVER['REMOTE_ADDR'] ?? ''; + if ($remote_ip && in_array($remote_ip, (array) $this->options['excluded_ips'], true)) return; + + $current_path = trim(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?? '', '/'); + $redirect_path = trim($this->options['redirect_url'] ?? '/maintenance', '/'); + + if ($this->is_public_system_request($current_path)) return; + if ($current_path === $redirect_path) return; + + foreach ((array) $this->options['excluded_slugs'] as $slug) { + if ($this->path_matches($current_path, $slug)) return; + } + + if (!is_admin()) { + wp_safe_redirect(home_url('/' . ltrim($redirect_path, '/'))); + exit; + } + } +} + +/************************************************************************************ + * bootstrap + ************************************************************************************/ +add_action('plugins_loaded', function () { + $GLOBALS['pausera_instance'] = new Pausera(); +});