=' ) && is_readable( $php_pack ) ) ? $official : ESCUDER_MAINTENANCE_PATH . 'languages/escuder-maintenance-' . $locale . '.mo'; load_textdomain( 'escuder-maintenance', $path, $locale ); } public function allowed() { if ( current_user_can( 'manage_options' ) ) { return true; } $ip = Ip_Address::visitor(); $options = Settings::all(); return '' !== $ip && is_array( $options['allowed_ips'] ) && in_array( $ip, $options['allowed_ips'], true ); } public function should_block() { global $pagenow; if ( ! Settings::enabled() || ( defined( 'WP_CLI' ) && WP_CLI ) || wp_doing_cron() ) { return false; } // Test the actual entry point, never a substring of the requested URL. $script = isset( $_SERVER['SCRIPT_FILENAME'] ) ? realpath( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_FILENAME'] ) ) ) : false; if ( 'wp-login.php' === $pagenow && $script && $script === realpath( ABSPATH . 'wp-login.php' ) ) { return false; } // Ordinary administration retains WordPress authentication and permissions. // admin-post and admin-ajax can expose public handlers and are gated as well. if ( is_admin() && ! wp_doing_ajax() && 'admin-post.php' !== $pagenow ) { return false; } return ! $this->allowed(); } public function enforce() { if ( ! Settings::enabled() ) { return; } if ( ! headers_sent() ) { nocache_headers(); header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0, private', true ); } if ( ! $this->should_block() ) { return; } $this->render( false ); exit; } public function menu() { add_options_page( 'Escuder Maintenance', 'Escuder Maintenance', 'manage_options', 'escuder-maintenance', array( $this, 'settings_page' ) ); } public function assets( $hook ) { if ( 'settings_page_escuder-maintenance' !== $hook ) { return; } wp_enqueue_media(); wp_enqueue_style( 'escuder-maintenance-admin', ESCUDER_MAINTENANCE_URL . 'assets/admin.css', array(), ESCUDER_MAINTENANCE_VERSION ); wp_enqueue_script( 'escuder-maintenance-admin', ESCUDER_MAINTENANCE_URL . 'assets/admin.js', array( 'media-views' ), ESCUDER_MAINTENANCE_VERSION, true ); wp_localize_script( 'escuder-maintenance-admin', 'escuderMaintenance', array( 'ip' => Ip_Address::visitor(), 'logoTitle' => __( 'Choose a logo', 'escuder-maintenance' ), 'logoButton' => __( 'Use this image', 'escuder-maintenance' ), 'ipAdded' => __( 'IP address added. Save changes to apply it.', 'escuder-maintenance' ), 'ipExists' => __( 'This IP address is already in the list.', 'escuder-maintenance' ), ) ); } public function settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $options = Settings::all(); $preview_url = wp_nonce_url( admin_url( 'admin-post.php?action=escuder_maintenance_preview' ), 'escuder_maintenance_preview' ); require ESCUDER_MAINTENANCE_PATH . 'views/settings.php'; } public function save() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You are not allowed to change these settings.', 'escuder-maintenance' ), '', array( 'response' => 403 ) ); } if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) { wp_die( esc_html__( 'Use the settings form to save changes.', 'escuder-maintenance' ), '', array( 'response' => 405 ) ); } check_admin_referer( 'escuder_maintenance_save' ); $input = isset( $_POST['escuder_maintenance'] ) ? map_deep( wp_unslash( $_POST['escuder_maintenance'] ), 'sanitize_textarea_field' ) : null; $result = Settings::sanitize( $input ); if ( is_wp_error( $result ) ) { wp_die( esc_html( $result->get_error_message() ), esc_html__( 'Settings not saved', 'escuder-maintenance' ), array( 'response' => 400, 'back_link' => true ) ); } update_option( Settings::OPTION, $result, false ); // Purging arbitrary server/CDN caches is deliberately left to their owner. wp_safe_redirect( add_query_arg( array( 'page' => 'escuder-maintenance', 'saved' => '1', '_wpnonce' => wp_create_nonce( 'escuder_maintenance_feedback' ) ), admin_url( 'options-general.php' ) ) ); exit; } public function preview() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You are not allowed to preview this page.', 'escuder-maintenance' ), '', array( 'response' => 403 ) ); } check_admin_referer( 'escuder_maintenance_preview' ); $this->render( true ); exit; } public function render( $preview ) { $options = Settings::all(); nocache_headers(); header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0, private', true ); status_header( $preview ? 200 : 503 ); header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); header( 'X-Robots-Tag: noindex, nofollow', true ); header( 'X-Content-Type-Options: nosniff', true ); if ( ! $preview ) { header( 'Retry-After: 3600', true ); } // A HEAD response carries identical headers without an HTML body. if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'HEAD' === $_SERVER['REQUEST_METHOD'] ) { return; } wp_enqueue_style( 'escuder-maintenance-page', ESCUDER_MAINTENANCE_URL . 'assets/maintenance.css', array(), ESCUDER_MAINTENANCE_VERSION ); require ESCUDER_MAINTENANCE_PATH . 'views/maintenance.php'; } public function notice() { if ( ! current_user_can( 'manage_options' ) || ! Settings::enabled() ) { return; } echo '
Escuder Maintenance: ' . esc_html__( 'Maintenance is active. Visitors without an authorized IP cannot view the site.', 'escuder-maintenance' ) . ' ' . esc_html__( 'Settings', 'escuder-maintenance' ) . '