_config = Dispatcher::config();
}
/**
* Runs plugin
*/
public function run() {
$this->is_w3tc_page = Util_Admin::is_w3tc_admin_page();
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetAccount', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetSettings', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetPartners', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetServices', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetBoldGrid', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Generic_WidgetStats', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_init_w3tc_dashboard', array( '\W3TC\Extension_ImageService_Widget', 'admin_init_w3tc_dashboard' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'admin_print_styles-toplevel_page_w3tc_dashboard', array( '\W3TC\Generic_Page_Dashboard', 'admin_print_styles_w3tc_dashboard' ) );
add_action( 'wp_ajax_w3tc_ajax', array( $this, 'wp_ajax_w3tc_ajax' ) );
add_action( 'admin_head', array( $this, 'admin_head' ) );
add_action( 'admin_footer', array( $this, 'admin_footer' ) );
if ( is_network_admin() ) {
add_action( 'network_admin_menu', array( $this, 'network_admin_menu' ) );
add_filter( 'network_admin_plugin_action_links_' . W3TC_FILE, array( $this, 'plugin_action_links' ) );
add_action( 'network_admin_notices', array( $this, 'top_nav_bar' ), 0 );
} else {
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_filter( 'plugin_action_links_' . W3TC_FILE, array( $this, 'plugin_action_links' ) );
add_action( 'admin_notices', array( $this, 'top_nav_bar' ), 0 );
}
add_filter( 'favorite_actions', array( $this, 'favorite_actions' ) );
add_action( 'in_plugin_update_message-' . W3TC_FILE, array( $this, 'in_plugin_update_message' ) );
if ( $this->_config->get_boolean( 'pgcache.enabled' ) || $this->_config->get_boolean( 'minify.enabled' ) ) {
add_filter( 'pre_update_option_active_plugins', array( $this, 'pre_update_option_active_plugins' ) );
}
$config_labels = new Generic_ConfigLabels();
add_filter( 'w3tc_config_labels', array( $config_labels, 'config_labels' ) );
$admin_notes = new Generic_AdminNotes();
add_filter( 'w3tc_notes', array( $admin_notes, 'w3tc_notes' ) );
add_filter( 'w3tc_errors', array( $admin_notes, 'w3tc_errors' ), 1000 );
add_action( 'w3tc_ajax_faq', array( $this, 'w3tc_ajax_faq' ) );
// Load w3tc_message.
$message_id = Util_Request::get_string( 'w3tc_message' );
if ( $message_id ) {
$v = get_option( 'w3tc_message' );
if ( isset( $v[ $message_id ] ) ) {
$this->w3tc_message = $v[ $message_id ];
delete_option( 'w3tc_message' );
}
}
}
/**
* Load action
*
* @return void
*/
public function load() {
$this->add_help_tabs();
$this->_page = Util_Admin::get_current_page();
// Run plugin action.
$action = false;
foreach ( $_REQUEST as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( 'w3tc_' === substr( $key, 0, 5 ) ) {
$action = $key;
break;
}
}
$executor = new Root_AdminActions();
if ( $action && $executor->exists( $action ) ) {
if ( ! wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) ) {
wp_nonce_ays( 'w3tc' );
}
try {
$executor->execute( $action );
} catch ( \Exception $e ) {
$key = 'admin_action_failed_' . $action;
Util_Admin::redirect_with_custom_messages( array(), array( $key => $e->getMessage() ) );
}
exit();
}
}
/**
* Load action
*
* @throws \Exception Exception.
*
* @return void
*/
public function wp_ajax_w3tc_ajax() {
if ( ! wp_verify_nonce( Util_Request::get_string( '_wpnonce' ), 'w3tc' ) ) {
wp_nonce_ays( 'w3tc' );
}
try {
$base_capability = apply_filters( 'w3tc_ajax_base_capability_', 'manage_options' );
$capability = apply_filters( 'w3tc_ajax_capability_' . Util_Request::get_string( 'w3tc_action' ), $base_capability );
if ( ! empty( $capability ) && ! current_user_can( $capability ) ) {
throw new \Exception( 'no permissions' );
}
do_action( 'w3tc_ajax' );
do_action( 'w3tc_ajax_' . Util_Request::get_string( 'w3tc_action' ) );
} catch ( \Exception $e ) {
echo esc_html( $e->getMessage() );
}
exit();
}
/**
* Admin init.
*/
public function admin_init() {
// Special handling for deactivation link, it's plugins.php file.
if ( 'w3tc_deactivate_plugin' === Util_Request::get_string( 'action' ) ) {
Util_Activation::deactivate_plugin();
}
/**
* These have been moved here as the admin_print_scripts-{$suffix} hook with translations won't take the user locale setting
* into account if it's called too soon, resulting in JS not loading.
*
* Translations are needed as the "prefix" used is based on the menu/page title, which is translated (11+ year old WP bug).
*/
// Support page.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_support',
array( '\W3TC\Support_Page', 'admin_print_scripts_w3tc_support' )
);
// Minify.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_general',
array( '\W3TC\Minify_Plugin_Admin', 'admin_print_scripts_w3tc_general' )
);
// PageCache.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_pgcache',
array( '\W3TC\PgCache_Page', 'admin_print_scripts_w3tc_pgcache' )
);
// Extensions.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_extensions',
array( '\W3TC\Extension_CloudFlare_Page', 'admin_print_scripts_performance_page_w3tc_cdn' )
);
// Usage Statistics.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_stats',
array( '\W3TC\UsageStatistics_Page', 'admin_print_scripts_w3tc_stats' )
);
$c = Dispatcher::config();
// CDN.
switch ( $c->get_string( 'cdn.engine' ) ) {
case 'bunnycdn':
$cdn_class = '\W3TC\Cdn_BunnyCdn_Page';
break;
case 'google_drive':
$cdn_class = '\W3TC\Cdn_GoogleDrive_Page';
break;
case 'highwinds':
$cdn_class = '\W3TC\Cdn_Highwinds_Page';
break;
case 'limelight':
$cdn_class = '\W3TC\Cdn_LimeLight_Page';
break;
case 'rackspace_cdn':
$cdn_class = '\W3TC\Cdn_RackSpaceCdn_Page';
break;
case 'rscf':
$cdn_class = '\W3TC\Cdn_RackSpaceCloudFiles_Page';
break;
case 'stackpath':
$cdn_class = '\W3TC\Cdn_StackPath_Page';
break;
case 'stackpath2':
$cdn_class = '\W3TC\Cdn_StackPath2_Page';
break;
default:
break;
}
if ( ! empty( $cdn_class ) ) {
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn',
array( $cdn_class, 'admin_print_scripts_w3tc_cdn' )
);
}
// CDNFSD.
switch ( $c->get_string( 'cdnfsd.engine' ) ) {
case 'bunnycdn':
$cdnfsd_class = '\W3TC\Cdnfsd_BunnyCdn_Page';
break;
case 'cloudflare':
$cdnfsd_class = '\W3TC\Extension_CloudFlare_Page';
break;
case 'cloudfront':
$cdnfsd_class = '\W3TC\Cdnfsd_CloudFront_Page';
break;
case 'limelight':
$cdnfsd_class = '\W3TC\Cdnfsd_LimeLight_Page';
break;
case 'stackpath':
$cdnfsd_class = '\W3TC\Cdnfsd_StackPath_Page';
break;
case 'stackpath2':
$cdnfsd_class = '\W3TC\Cdnfsd_StackPath2_Page';
break;
default:
break;
}
if ( ! empty( $cdnfsd_class ) ) {
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_cdn',
array( $cdnfsd_class, 'admin_print_scripts_performance_page_w3tc_cdn' )
);
}
// PageSpeed page/widget.
add_action(
'admin_print_scripts-' . sanitize_title( __( 'Performance', 'w3-total-cache' ) ) . '_page_w3tc_pagespeed',
array( '\W3TC\PageSpeed_Page', 'admin_print_scripts_w3tc_pagespeed' )
);
add_action(
'admin_print_scripts-toplevel_page_w3tc_dashboard',
array( '\W3TC\PageSpeed_Widget', 'admin_print_scripts_w3tc_pagespeed_widget' )
);
$page_val = Util_Request::get_string( 'page' );
if ( ! empty( $page_val ) ) {
do_action( 'admin_init_' . $page_val );
}
}
/**
* Enqueue admin scripts.
*/
public function admin_enqueue_scripts() {
wp_register_style( 'w3tc-options', plugins_url( 'pub/css/options.css', W3TC_FILE ), array(), W3TC_VERSION );
wp_register_style( 'w3tc-lightbox', plugins_url( 'pub/css/lightbox.css', W3TC_FILE ), array(), W3TC_VERSION );
wp_register_style( 'w3tc-bootstrap-css', plugins_url( 'pub/css/bootstrap-buttons.css', W3TC_FILE ), array(), W3TC_VERSION );
wp_register_style( 'w3tc-widget', plugins_url( 'pub/css/widget.css', W3TC_FILE ), array(), W3TC_VERSION );
wp_register_script( 'w3tc-metadata', plugins_url( 'pub/js/metadata.js', W3TC_FILE ), array(), W3TC_VERSION, false );
wp_register_script( 'w3tc-options', plugins_url( 'pub/js/options.js', W3TC_FILE ), array(), W3TC_VERSION, false );
wp_register_script( 'w3tc-lightbox', plugins_url( 'pub/js/lightbox.js', W3TC_FILE ), array(), W3TC_VERSION, false );
wp_register_script( 'w3tc-widget', plugins_url( 'pub/js/widget.js', W3TC_FILE ), array(), W3TC_VERSION, false );
wp_register_script( 'w3tc-jquery-masonry', plugins_url( 'pub/js/jquery.masonry.min.js', W3TC_FILE ), array( 'jquery' ), W3TC_VERSION, false );
// New feature count for the Feature Showcase.
wp_register_script( 'w3tc-feature-counter', plugins_url( 'pub/js/feature-counter.js', W3TC_FILE ), array(), W3TC_VERSION, true );
wp_localize_script(
'w3tc-feature-counter',
'W3TCFeatureShowcaseData',
array( 'unseenCount' => FeatureShowcase_Plugin_Admin::get_unseen_count() )
);
wp_enqueue_script( 'w3tc-feature-counter' );
// Messages.
if ( ! is_null( $this->w3tc_message ) && isset( $this->w3tc_message['actions'] ) && is_array( $this->w3tc_message['actions'] ) ) {
foreach ( $this->w3tc_message['actions'] as $action ) {
do_action( 'w3tc_message_action_' . $action );
}
}
// For testing.
$w3tc_message_action_val = Util_Request::get_string( 'w3tc_message_action' );
if ( ! empty( $w3tc_message_action_val ) ) {
do_action( 'w3tc_message_action_' . $w3tc_message_action_val );
}
}
/**
* Render sticky top navigation bar on all W3TC admin pages.
*/
public function top_nav_bar() {
if ( Util_Admin::is_w3tc_admin_page() ) {
require W3TC_INC_DIR . '/options/common/top_nav_bar.php';
}
}
/**
* Define icon styles for the custom post type.
*
* @throws \Exception Exception.
*/
public function admin_head() {
global $wp_version;
global $wpdb;
$page = Util_Request::get_string( 'page', null );
if ( ( ! is_multisite() || is_super_admin() ) && false !== strpos( $page, 'w3tc' ) && 'w3tc_setup_guide' !== $page && ! get_site_option( 'w3tc_setupguide_completed' ) ) {
$state_master = Dispatcher::config_state_master();
if ( ! $this->_config->get_boolean( 'pgcache.enabled' ) && $state_master->get_integer( 'common.install' ) > strtotime( 'NOW - 1 WEEK' ) ) {
wp_safe_redirect( esc_url( network_admin_url( 'admin.php?page=w3tc_setup_guide' ) ) );
}
}
if ( empty( $this->_config->get_integer( 'pgcache.migrated.qsexempts' ) ) ) {
$pgcache_accept_qs = array_unique( array_merge( $this->_config->get_array( 'pgcache.accept.qs' ), PgCache_QsExempts::get_qs_exempts() ) );
sort( $pgcache_accept_qs );
$this->_config->set( 'pgcache.accept.qs', $pgcache_accept_qs );
$this->_config->set( 'pgcache.migrated.qsexempts', time() );
// Save the config if the environment is ready; filesystem needs to be writable.
try {
$this->_config->save();
} catch ( \Exception $e ) {
$this->_config->set( 'pgcache.migrated.qsexempts', null );
}
}
if ( $this->_config->get_boolean( 'common.track_usage' ) && $this->is_w3tc_page ) {
$current_user = wp_get_current_user();
$page = Util_Request::get_string( 'page' );
if ( 'w3tc_extensions' === $page ) {
$page = 'extensions/' . Util_Request::get_string( 'extension' );
}
if ( defined( 'W3TC_DEVELOPER' ) && W3TC_DEVELOPER ) {
$profile = 'G-Q3CHQJWERM';
} else {
$profile = 'G-5TFS8M5TTY';
}
$state = Dispatcher::config_state();
wp_enqueue_script(
'w3tc_ga',
'https://www.googletagmanager.com/gtag/js?id=' . esc_attr( $profile ),
array(),
W3TC_VERSION,
true
);
?>
is_w3tc_page ) {
require W3TC_INC_DIR . '/options/common/footer.php';
}
}
/**
* Render network admin menu.
*/
public function network_admin_menu() {
$this->_admin_menu( 'manage_network_options' );
}
/**
* Render admin menu.
*/
public function admin_menu() {
$this->_admin_menu( 'manage_options' );
}
/**
* Admin menu
*
* @param string $base_capability Base compatibility.
*
* @return void
*/
private function _admin_menu( $base_capability ) {
$base_capability = apply_filters( 'w3tc_capability_menu', $base_capability );
if ( current_user_can( $base_capability ) ) {
$menus = Dispatcher::component( 'Root_AdminMenu' );
$submenu_pages = $menus->generate( $base_capability );
/**
* Only admin can modify W3TC settings
*/
foreach ( $submenu_pages as $submenu_page ) {
add_action( 'load-' . $submenu_page, array( $this, 'load' ) );
add_action( 'admin_print_styles-' . $submenu_page, array( $this, 'admin_print_styles' ) );
add_action( 'admin_print_scripts-' . $submenu_page, array( $this, 'admin_print_scripts' ) );
}
global $pagenow;
if ( 'plugins.php' === $pagenow ) {
add_action( 'admin_print_scripts', array( $this, 'load_plugins_page_js' ) );
add_action( 'admin_print_styles', array( $this, 'print_plugins_page_css' ) );
}
global $pagenow;
if ( 'plugins.php' === $pagenow || $this->is_w3tc_page ||
! empty( Util_Request::get_string( 'w3tc_note' ) ) ||
! empty( Util_Request::get_string( 'w3tc_error' ) ) ||
! empty( Util_Request::get_string( 'w3tc_message' ) ) ) {
// Only admin can see W3TC notices and errors.
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
add_action( 'network_admin_notices', array( $this, 'admin_notices' ) );
}
global $pagenow;
if ( ! $this->is_w3tc_page &&
(
! empty( Util_Request::get_string( 'w3tc_note' ) ) ||
! empty( Util_Request::get_string( 'w3tc_error' ) ) ||
! empty( Util_Request::get_string( 'w3tc_message' ) )
)
) {
// This is needed for admin notice buttons displayed on non-w3tc pages after actions via admin top menu.
add_action( 'admin_print_scripts-' . $pagenow, array( $this, 'admin_print_scripts' ) );
}
}
}
/**
* Print styles
*
* @return void
*/
public function admin_print_styles() {
wp_enqueue_style( 'w3tc-options' );
wp_enqueue_style( 'w3tc-bootstrap-css' );
wp_enqueue_style( 'w3tc-lightbox' );
}
/**
* Print scripts.
*/
public function admin_print_scripts() {
wp_enqueue_script( 'w3tc-metadata' );
wp_enqueue_script( 'w3tc-options' );
wp_enqueue_script( 'w3tc-lightbox' );
if ( $this->is_w3tc_page ) {
wp_localize_script(
'w3tc-options',
'w3tc_nonce',
array( wp_create_nonce( 'w3tc' ) )
);
wp_localize_script(
'w3tc-options',
'w3tcData',
array(
'cdnEnabled' => $this->_config->get_boolean( 'cdn.enabled' ),
'cdnEngine' => $this->_config->get_string( 'cdn.engine' ),
'cdnFlushManually' => $this->_config->get_boolean(
'cdn.flush_manually',
Cdn_Util::get_flush_manually_default_override( $this->_config->get_string( 'cdn.engine' ) )
),
'cdnfsdEnabled' => $this->_config->get_boolean( 'cdnfsd.enabled' ),
'cdnfsdEngine' => $this->_config->get_string( 'cdnfsd.engine' ),
'cfWarning' => wp_kses(
sprintf(
// translators: 1: HTML opening a tag to docs.aws.amazon.com for invalidation payments, 2: HTML closing a tag followed by HTML line break tag,
// translators: 4: HTML line break tag, 5: HTML opening a tag to purge CDN manually, 6: HTML closing a tag.
__(
'Please see %1$sAmazon\'s CloudFront documentation -- Paying for file invalidation%2$sThe first 1,000 invalidation paths that you submit per month are free; you pay for each invalidation path over 1,000 in a month.%3$sYou can disable automatic purging by enabling %4$sOnly purge CDN manually%5$s.',
'w3-total-cache'
),
'',
'.
',
'
',
'',
''
),
array(
'a' => array(
'target' => array(),
'href' => array(),
),
'br' => array(),
)
),
'bunnyCdnWarning' => esc_html__(
'Bunny CDN should only be enabled as either a CDN for objects or full-site delivery, not both at the same time. The CDN settings have been reverted.',
'w3-total-cache'
),
)
);
}
switch ( $this->_page ) {
case 'w3tc_minify':
case 'w3tc_cachegroups':
wp_enqueue_script(
'w3tc_cachegroups',
plugins_url( 'CacheGroups_Plugin_Admin_View.js', W3TC_FILE ),
array(
'jquery',
'jquery-ui-sortable',
),
W3TC_VERSION,
true
);
// No break.
case 'w3tc_userexperience':
if ( UserExperience_Remove_CssJs_Extension::is_enabled() ) {
wp_enqueue_script(
'w3tc_remove_cssjs',
plugins_url( 'UserExperience_Remove_CssJs_Page_View.js', W3TC_FILE ),
array(
'jquery',
),
W3TC_VERSION,
true
);
}
// No break.
case 'w3tc_cdn':
wp_enqueue_script( 'jquery-ui-sortable' );
break;
}
if ( 'w3tc_cdn' === $this->_page ) {
wp_enqueue_script( 'jquery-ui-dialog' );
}
if ( 'w3tc_dashboard' === $this->_page ) {
wp_enqueue_script( 'w3tc-jquery-masonry' );
}
}
/**
* Load plugins page JS.
*/
public function load_plugins_page_js() {
wp_enqueue_script( 'w3tc-options' );
}
/**
* Load plugins page CSS.
*/
public function print_plugins_page_css() {
?>
$data ) {
$content = '