_config = Dispatcher::config(); } /** * Runs the plugin, setting up various hooks and filters for extensions. * * @return void */ public function run() { // Attach w3tc-bundled extensions. add_filter( 'w3tc_extensions', array( '\W3TC\Extension_CloudFlare_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_FragmentCache_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_Genesis_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions_hooks', array( '\W3TC\Extension_Genesis_Plugin_Admin', 'w3tc_extensions_hooks' ) ); add_filter( 'w3tc_notes_genesis_theme', array( '\W3TC\Extension_Genesis_Plugin_Admin', 'w3tc_notes_genesis_theme' ) ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_AlwaysCached_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_MaxCache_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_notes', array( '\W3TC\Extension_MaxCache_Plugin_Admin', 'w3tc_notes' ) ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_NewRelic_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_Swarmify_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_WordPressSeo_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions_hooks', array( '\W3TC\Extension_WordPressSeo_Plugin_Admin', 'w3tc_extensions_hooks' ) ); add_action( 'w3tc_notes_wordpress_seo', array( '\W3TC\Extension_WordPressSeo_Plugin_Admin', 'w3tc_notes_wordpress_seo' ) ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_Wpml_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_Amp_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_filter( 'w3tc_extensions_hooks', array( '\W3TC\Extension_Wpml_Plugin_Admin', 'w3tc_extensions_hooks' ) ); add_action( 'w3tc_notes_wpml', array( '\W3TC\Extension_Wpml_Plugin_Admin', 'w3tc_notes_wpml' ) ); add_filter( 'w3tc_extensions', array( '\W3TC\Extension_ImageService_Plugin_Admin', 'w3tc_extensions' ), 10, 2 ); add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); add_filter( 'pre_update_option_active_plugins', array( $this, 'pre_update_option_active_plugins' ) ); add_filter( 'w3tc_admin_menu', array( $this, 'w3tc_admin_menu' ), 10000 ); add_action( 'w3tc_settings_page-w3tc_extensions', array( $this, 'w3tc_settings_page_w3tc_extensions' ) ); if ( Util_Admin::is_w3tc_admin_page() ) { add_action( 'admin_notices', array( $this, 'admin_notices' ) ); $action_val = Util_Request::get_string( 'action' ); if ( ! empty( Util_Request::get_string( 'extension' ) ) && ! empty( $action_val ) ) { if ( in_array( $action_val, array( 'activate', 'deactivate' ), true ) ) { add_action( 'admin_init', array( $this, 'change_extension_status' ) ); } } elseif ( ! empty( Util_Request::get_array( 'checked' ) ) ) { add_action( 'admin_init', array( $this, 'change_extensions_status' ) ); } } } /** * Modifies the admin menu based on the active extension. * * @param array $menu Existing menu array to be modified. * * @return array Modified menu array. */ public function w3tc_admin_menu( $menu ) { if ( ! \user_can( \get_current_user_id(), 'manage_options' ) ) { return $menu; } $extension_val = Util_Request::get_string( 'extension' ); $w3tc_extension = ( ! empty( $extension_val ) ? esc_attr( $extension_val ) : '' ); $page_title = ''; switch ( $w3tc_extension ) { case 'alwayscached': $page_title = __( 'Always Cached Extension Settings', 'w3-total-cache' ); break; case 'amp': $page_title = __( 'AMP Extension Settings', 'w3-total-cache' ); break; case 'cloudflare': $page_title = __( 'Cloudflare Extension Settings', 'w3-total-cache' ); break; case 'swarmify': $page_title = __( 'Swarmify Extension Settings', 'w3-total-cache' ); break; case 'genesis.theme': $page_title = __( 'Genesis Extension Settings', 'w3-total-cache' ); break; default: $page_title = __( 'Extensions', 'w3-total-cache' ); } $menu['w3tc_extensions'] = array( 'page_title' => $page_title, 'menu_text' => __( 'Extensions', 'w3-total-cache' ), 'visible_always' => false, 'order' => 1900, ); return $menu; } /** * Renders the settings page for extensions. * * @return void */ public function w3tc_settings_page_w3tc_extensions() { $w3tc_o = new Extensions_Page(); $w3tc_o->render_content(); } /** * Pre-processes the update of the active plugins option. * * @param mixed $w3tc_o Option value to be updated. * * @return mixed Modified option value. */ public function pre_update_option_active_plugins( $w3tc_o ) { delete_option( 'w3tc_extensions_hooks' ); return $w3tc_o; } /** * Initializes settings for the admin interface (administrators only). * * @return void */ public function admin_init() { if ( ! \user_can( \get_current_user_id(), 'manage_options' ) ) { return; } // Used to load even inactive extensions if they want to. $s = get_option( 'w3tc_extensions_hooks' ); $w3tc_hooks = @json_decode( $s, true ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( ! isset( $w3tc_hooks['next_check_date'] ) || $w3tc_hooks['next_check_date'] < time() ) { $w3tc_hooks = array( 'actions' => array(), 'filters' => array(), 'next_check_date' => time() + 24 * 60 * 60, ); $w3tc_hooks = apply_filters( 'w3tc_extensions_hooks', $w3tc_hooks ); update_option( 'w3tc_extensions_hooks', wp_json_encode( $w3tc_hooks ) ); } if ( isset( $w3tc_hooks['actions'] ) ) { foreach ( $w3tc_hooks['actions'] as $w3tc_hook => $actions_to_call ) { if ( is_array( $actions_to_call ) ) { add_action( $w3tc_hook, function () use ( $actions_to_call ) { foreach ( $actions_to_call as $action ) { do_action( $action ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound } } ); } } } if ( isset( $w3tc_hooks['filters'] ) ) { foreach ( $w3tc_hooks['filters'] as $w3tc_hook => $filters_to_call ) { if ( is_array( $filters_to_call ) ) { add_filter( $w3tc_hook, function ( $v ) use ( $filters_to_call ) { foreach ( $filters_to_call as $filter ) { $v = apply_filters( $filter, $v ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound } return $v; } ); } } } } /** * Changes the status of selected extensions (activate/deactivate and administrators only). * * @return void */ public function change_extensions_status() { $extensions = Util_Request::get_array( 'checked' ); $action = Util_Request::get( 'action' ); if ( '-1' === $action ) { $action = Util_Request::get( 'action2' ); // Dropdown at bottom. } if ( ! \in_array( $action, array( 'activate-selected', 'deactivate-selected' ), true ) ) { return; } /** * The bulk activate/deactivate dispatcher previously had no * nonce verification at all. Verify a * per-action nonce keyed `w3tc_extensions_bulk` rendered by the * bulk-action form in `inc/options/extensions/list.php`. * * Nonce is checked before capability so unauthenticated or * cross-site requests fail without revealing authorization state. * * @since 2.10.0 */ if ( ! Util_Nonce::verify_admin( 'w3tc_extensions_bulk' ) ) { \wp_die( \esc_html__( 'Nonce verification failed for bulk extension action.', 'w3-total-cache' ), '', array( 'response' => 403 ) ); } if ( ! \user_can( \get_current_user_id(), 'manage_options' ) ) { \wp_die( \esc_html__( 'You do not have sufficient permissions to manage extensions.', 'w3-total-cache' ), '', array( 'response' => 403 ) ); } $w3tc_message = ''; if ( 'activate-selected' === $action ) { foreach ( $extensions as $w3tc_extension ) { if ( Extensions_Util::activate_extension( $w3tc_extension, $this->_config ) ) { $w3tc_message .= '&activated=' . $w3tc_extension; } } wp_safe_redirect( Util_Ui::admin_url( sprintf( 'admin.php?page=w3tc_extensions%s', $w3tc_message ) ) ); exit; } foreach ( $extensions as $w3tc_extension ) { if ( Extensions_Util::deactivate_extension( $w3tc_extension, $this->_config ) ) { $w3tc_message .= '&deactivated=' . $w3tc_extension; } } wp_safe_redirect( Util_Ui::admin_url( sprintf( 'admin.php?page=w3tc_extensions%s', $w3tc_message ) ) ); exit; } /** * Changes the status of a specific extension (activate/deactivate and administrators only). * * @return void */ public function change_extension_status() { $action = Util_Request::get_string( 'action' ); $w3tc_extension = Util_Request::get_string( 'extension' ); /** * Per-action nonce keyed `w3tc_extension__`. * Single-link minters in `inc/options/extensions/list.php` render * the matching per-action token via `Util_Nonce::admin_nonce_url()`. * * Nonce is checked before capability so unauthenticated or * cross-site requests fail without revealing authorization state. * * @since 2.10.0 */ if ( ! in_array( $action, array( 'activate', 'deactivate' ), true ) || '' === $w3tc_extension ) { return; } $primary_action = 'w3tc_extension_' . $action . '_' . $w3tc_extension; if ( ! Util_Nonce::verify_admin( $primary_action ) ) { \wp_die( \esc_html__( 'Nonce verification failed for extension action.', 'w3-total-cache' ), '', array( 'response' => 403 ) ); } if ( ! \user_can( \get_current_user_id(), 'manage_options' ) ) { \wp_die( \esc_html__( 'You do not have sufficient permissions to manage extensions.', 'w3-total-cache' ), '', array( 'response' => 403 ) ); } if ( 'activate' === $action ) { Extensions_Util::activate_extension( $w3tc_extension, $this->_config ); wp_safe_redirect( Util_Ui::admin_url( sprintf( 'admin.php?page=w3tc_extensions&activated=%s', $w3tc_extension ) ) ); exit; } elseif ( 'deactivate' === $action ) { Extensions_Util::deactivate_extension( $w3tc_extension, $this->_config ); wp_safe_redirect( Util_Ui::admin_url( sprintf( 'admin.php?page=w3tc_extensions&deactivated=%s', $w3tc_extension ) ) ); exit; } } /** * Displays admin notices related to active extensions (administrators only). * * @see Extensions_Util::get_active_extensions() * * @return void */ public function admin_notices() { if ( ! \user_can( \get_current_user_id(), 'manage_options' ) ) { return; } $extensions_active = Extensions_Util::get_active_extensions( $this->_config ); foreach ( $extensions_active as $id => $info ) { $transient_name = 'w3tc_activation_' . $id; $action_name = 'w3tc_' . $id . '_action'; $action_val = Util_Request::get_string( $action_name ); if ( ! empty( $action_val ) && 'dismiss_activation_notice' === $action_val ) { delete_transient( $transient_name ); } if ( isset( $info['notice'] ) && get_transient( $transient_name ) ) { ?>

array( 'class' => array(), 'href' => array(), 'target' => array(), ), ) ); ?>