plugin_name = is_string( $plugin_name ) && '' !== $plugin_name ? $plugin_name : 'ajax-loading'; if ( ! is_string( $version ) || '' === $version ) { $version = defined( 'WPAJXL_PLUGIN_VERSION' ) ? WPAJXL_PLUGIN_VERSION : '2.0.0'; } $this->version = $version; } /** * Register all admin hooks. * * @return void */ public function register() { if ( ! class_exists( 'WPAJXL_Settings' ) ) { return; } add_action( 'admin_menu', array( $this, 'add_menu' ) ); add_action( 'admin_init', array( $this, 'register_settings' ) ); add_action( 'admin_page_access_denied', array( $this, 'maybe_redirect_legacy_slug' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'admin_post_' . self::ACTION, array( $this, 'handle_action' ) ); add_action( 'admin_notices', array( $this, 'admin_notices' ) ); add_filter( 'plugin_action_links_' . $this->plugin_basename(), array( $this, 'action_links' ) ); add_filter( 'removable_query_args', array( $this, 'removable_query_args' ) ); } /* * --------------------------------------------------------------------- * Hooks * --------------------------------------------------------------------- */ /** * Add Settings → AJAX Loading. * * @return void */ public function add_menu() { $suffix = add_options_page( __( 'AJAX Loading', 'ajax-loading' ), __( 'AJAX Loading', 'ajax-loading' ), self::CAPABILITY, self::PAGE_SLUG, array( $this, 'render_page' ) ); $this->hook_suffix = is_string( $suffix ) ? $suffix : ''; } /** * Register the option with the Settings API (options.php handles saving). * * @return void */ public function register_settings() { register_setting( self::OPTION_GROUP, self::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( WPAJXL_Settings::instance(), 'sanitize_option_input' ), 'show_in_rest' => false, ) ); } /** * Redirect the 0.x page slug to the current settings screen. * * Runs on 'admin_page_access_denied', which WordPress fires for the * unregistered legacy slug right before it would show "not allowed". * * @return void */ public function maybe_redirect_legacy_slug() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only routing. $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; if ( self::LEGACY_PAGE_SLUG !== $page || ! current_user_can( self::CAPABILITY ) ) { return; } wp_safe_redirect( $this->page_url() ); exit; } /** * Enqueue admin assets on the plugin screen only. * * @param string $hook_suffix Current admin page hook suffix. * @return void */ public function enqueue_assets( $hook_suffix ) { if ( '' === $this->hook_suffix || $hook_suffix !== $this->hook_suffix ) { return; } $tab = $this->current_tab(); wp_enqueue_style( 'wp-color-picker' ); if ( 'loading' === $tab ) { // Logo picker and live preview are only on the Loading Experience tab. wp_enqueue_media(); wp_enqueue_style( 'ajax-loading-preview', $this->asset_url( 'frontend', 'css' ), array(), $this->asset_version( 'frontend', 'css' ) ); } wp_enqueue_style( 'ajax-loading-admin', $this->asset_url( 'admin', 'css' ), array( 'wp-color-picker' ), $this->asset_version( 'admin', 'css' ) ); wp_enqueue_script( 'ajax-loading-admin', $this->asset_url( 'admin', 'js' ), array( 'jquery', 'wp-color-picker' ), $this->asset_version( 'admin', 'js' ), array( 'in_footer' => true ) ); $json = wp_json_encode( $this->script_data( $tab ), JSON_HEX_TAG | JSON_HEX_AMP | JSON_UNESCAPED_SLASHES ); wp_add_inline_script( 'ajax-loading-admin', 'window.ajaxLoadingAdmin = ' . ( false === $json ? '{}' : $json ) . ';', 'before' ); } /** * Quick actions (admin-post.php?action=ajax_loading_action). * * @return void */ public function handle_action() { if ( ! current_user_can( self::CAPABILITY ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to manage AJAX Loading.', 'ajax-loading' ), esc_html__( 'Forbidden', 'ajax-loading' ), array( 'response' => 403, 'back_link' => true, ) ); } $method = isset( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) ) : ''; if ( 'POST' !== $method ) { wp_die( esc_html__( 'This action must be submitted from the AJAX Loading settings screen.', 'ajax-loading' ), esc_html__( 'Method not allowed', 'ajax-loading' ), array( 'response' => 405, 'back_link' => true, ) ); } check_admin_referer( self::NONCE_ACTION ); $do = ''; if ( isset( $_POST['do'] ) ) { $do = sanitize_key( wp_unslash( $_POST['do'] ) ); } elseif ( isset( $_GET['do'] ) ) { $do = sanitize_key( wp_unslash( $_GET['do'] ) ); } $tab = isset( $_POST['ajxl_tab'] ) ? sanitize_key( wp_unslash( $_POST['ajxl_tab'] ) ) : 'overview'; $return = ( isset( $_POST['ajxl_return'] ) && 'plugins' === sanitize_key( wp_unslash( $_POST['ajxl_return'] ) ) ) ? 'plugins' : 'page'; if ( 'export' === $do ) { $this->send_export( $tab ); } $notice = 'action_failed'; try { $notice = $this->run_action( $do ); } catch ( Throwable $e ) { self::debug_log( 'quick action "' . $do . '" failed: ' . $e->getMessage() ); $notice = 'action_failed'; } $this->redirect_after_action( $tab, $notice, $return ); } /** * Admin notices: action results and state warnings (own screen + Plugins screen). * * @return void */ public function admin_notices() { if ( ! current_user_can( self::CAPABILITY ) || ! function_exists( 'get_current_screen' ) ) { return; } $screen = get_current_screen(); if ( ! $screen ) { return; } $own = ( '' !== $this->hook_suffix && $screen->id === $this->hook_suffix ); $plugins = ( 'plugins' === $screen->id ); if ( ! $own && ! $plugins ) { return; } $code = $this->notice_code(); if ( '' !== $code ) { $this->print_result_notice( $code ); } elseif ( $own && $this->settings_were_saved() && class_exists( 'WPAJXL_Compat' ) && method_exists( 'WPAJXL_Compat', 'has_page_cache' ) && WPAJXL_Compat::has_page_cache() ) { printf( '
%s