_config = Dispatcher::config(); } /** * Runs plugin */ function run() { add_filter( 'cron_schedules', array( $this, 'cron_schedules' ), 5 ); /* need this to run before wp-cron to issue w3tc redirect */ add_action( 'init', array( $this, 'init' ), 1 ); if ( Util_Environment::is_w3tc_pro_dev() && Util_Environment::is_w3tc_pro( $this->_config ) ) { add_action( 'wp_footer', array( $this, 'pro_dev_mode' ) ); } add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 150 ); add_action( 'admin_bar_init', array( $this, 'admin_bar_init' ) ); $http_user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : ''; if ( ! empty( Util_Request::get_string( 'w3tc_theme' ) ) && stristr( $http_user_agent, W3TC_POWERED_BY ) !== false ) { add_filter( 'template', array( $this, 'template_preview' ) ); add_filter( 'stylesheet', array( $this, 'stylesheet_preview' ) ); } elseif ( $this->_config->get_boolean( 'mobile.enabled' ) || $this->_config->get_boolean( 'referrer.enabled' ) ) { add_filter( 'template', array( $this, 'template' ) ); add_filter( 'stylesheet', array( $this, 'stylesheet' ) ); } /** * Create cookies to flag if a pgcache role was loggedin */ if ( ! $this->_config->get_boolean( 'pgcache.reject.logged' ) && $this->_config->get_array( 'pgcache.reject.logged_roles' ) ) { add_action( 'set_logged_in_cookie', array( $this, 'check_login_action' ), 0, 5 ); add_action( 'clear_auth_cookie', array( $this, 'check_login_action' ), 0, 5 ); } if ( $this->can_ob() ) { add_filter( 'wp_die_xml_handler', array( $this, 'wp_die_handler' ) ); add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) ); ob_start( array( $this, 'ob_callback' ) ); } } /** * Marks wp_die was called so response is system message **/ public function wp_die_handler( $v ) { $this->is_wp_die = true; return $v; } /** * Cron schedules filter * * @param array $schedules * @return array */ function cron_schedules( $schedules ) { // Sets default values which are overriden by apropriate plugins // if they are enabled // // absense of keys (if e.g. pgcaching became disabled, but there is // cron event scheduled in db) causes PHP notices. return array_merge( $schedules, array( 'w3_cdn_cron_queue_process' => array( 'interval' => 0, 'display' => '[W3TC] CDN queue process (disabled)', ), 'w3_cdn_cron_upload' => array( 'interval' => 0, 'display' => '[W3TC] CDN auto upload (disabled)', ), 'w3_dbcache_cleanup' => array( 'interval' => 0, 'display' => '[W3TC] Database Cache file GC (disabled)', ), 'w3_fragmentcache_cleanup' => array( 'interval' => 0, 'display' => '[W3TC] Fragment Cache file GC (disabled)', ), 'w3_minify_cleanup' => array( 'interval' => 0, 'display' => '[W3TC] Minify file GC (disabled)', ), 'w3_objectcache_cleanup' => array( 'interval' => 0, 'display' => '[W3TC] Object Cache file GC (disabled)', ), 'w3_pgcache_cleanup' => array( 'interval' => 0, 'display' => '[W3TC] Page Cache file GC (disabled)', ), 'w3_pgcache_prime' => array( 'interval' => 0, 'display' => '[W3TC] Page Cache file GC (disabled)', ), ) ); } /** * Init action * * @return void */ function init() { // Load W3TC textdomain for translations. $this->reset_l10n(); load_plugin_textdomain( W3TC_TEXT_DOMAIN, false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); if ( is_multisite() && ! is_network_admin() ) { global $w3_current_blog_id, $current_blog; if ( $w3_current_blog_id !== $current_blog->blog_id && ! isset( $GLOBALS['w3tc_blogmap_register_new_item'] ) ) { $url = Util_Environment::host_port() . ( isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ); $pos = strpos( $url, '?' ); if ( false !== $pos ) { $url = substr( $url, 0, $pos ); } $GLOBALS['w3tc_blogmap_register_new_item'] = $url; } } if ( isset( $GLOBALS['w3tc_blogmap_register_new_item'] ) ) { $do_redirect = Util_WpmuBlogmap::register_new_item( $this->_config ); // reset cache of blog_id. Util_Environment::reset_microcache(); Dispatcher::reset_config(); // change config to actual blog, it was master before. $this->_config = new Config(); // fix environment, potentially it's first request to a specific blog. $environment = Dispatcher::component( 'Root_Environment' ); $environment->fix_on_event( $this->_config, 'first_frontend', $this->_config ); // need to repeat request processing, since we was not able to realize // blog_id before so we are running with master config now. // redirect to the same url causes "redirect loop" error in browser, // so need to redirect to something a bit different. if ( $do_redirect ) { if ( ( defined( 'WP_CLI' ) && WP_CLI ) || php_sapi_name() === 'cli' ) { // command-line mode, no real requests made, // try to switch context in-request. } else { $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; if ( strpos( $request_uri, '?' ) === false ) { Util_Environment::safe_redirect_temp( $request_uri . '?repeat=w3tc' ); } else { if ( strpos( $request_uri, 'repeat=w3tc' ) === false ) { Util_Environment::safe_redirect_temp( $request_uri . '&repeat=w3tc' ); } } } } } /** * Check for rewrite test request */ $rewrite_test = Util_Request::get_boolean( 'w3tc_rewrite_test' ); if ( $rewrite_test ) { echo 'OK'; exit(); } $admin_bar = false; if ( function_exists( 'is_admin_bar_showing' ) ) { $admin_bar = is_admin_bar_showing(); } if ( $admin_bar ) { add_action( 'wp_print_scripts', array( $this, 'popup_script' ) ); } // dont add system stuff to search results. $repeat_val = Util_Request::get_string( 'repeat' ); if ( ( ! empty( $repeat_val ) && 'w3tc' === $repeat_val ) || Util_Environment::is_preview_mode() ) { header( 'X-Robots-Tag: noindex' ); } } public function admin_bar_init() { $font_base = plugins_url( 'pub/fonts/w3tc', W3TC_FILE ); $css = " @font-face { font-family: 'w3tc'; src: url('$font_base.eot'); src: url('$font_base.eot?#iefix') format('embedded-opentype'), url('$font_base.woff') format('woff'), url('$font_base.ttf') format('truetype'), url('$font_base.svg#w3tc') format('svg'); font-weight: normal; font-style: normal; } .w3tc-icon:before{ content:'\\0041'; top: 2px; font-family: 'w3tc'; }"; wp_add_inline_style( 'admin-bar', $css); } /** * Admin bar menu * * @return void */ function admin_bar_menu() { global $wp_admin_bar; $base_capability = apply_filters( 'w3tc_capability_admin_bar', 'manage_options' ); if ( current_user_can( $base_capability ) ) { $modules = Dispatcher::component( 'ModuleStatus' ); $menu_items = array(); $menu_items['00010.generic'] = array( 'id' => 'w3tc', 'title' => sprintf( '%s', __( 'Performance', 'w3-total-cache' ) ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_dashboard' ), 'w3tc' ), ); if ( $modules->plugin_is_enabled() ) { $menu_items['10010.generic'] = array( 'id' => 'w3tc_flush_all', 'parent' => 'w3tc', 'title' => __( 'Purge All Caches', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_dashboard&w3tc_flush_all' ), 'w3tc' ), ); // Add menu item to flush all cached except Bunny CDN. if ( 0 && // @todo Revisit this item. Cdn_BunnyCdn_Page::is_active() && ( $modules->can_empty_memcache() || $modules->can_empty_opcode() || $modules->can_empty_file() || $modules->can_empty_varnish() ) ) { $menu_items['10012.generic'] = array( 'id' => 'w3tc_flush_all_except_bunnycdn', 'parent' => 'w3tc', 'title' => __( 'Purge All Caches Except Bunny CDN', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_dashboard&w3tc_bunnycdn_flush_all_except_bunnycdn' ), 'w3tc' ), ); } // Add menu item to flush all cached except Cloudflare. if ( ! empty( $this->_config->get_string( array( 'cloudflare', 'email' ) ) ) && ! empty( $this->_config->get_string( array( 'cloudflare', 'key' ) ) ) && ( $modules->can_empty_memcache() || $modules->can_empty_opcode() || $modules->can_empty_file() || $modules->can_empty_varnish() ) ) { $menu_items['10015.generic'] = array( 'id' => 'w3tc_flush_all_except_cf', 'parent' => 'w3tc', 'title' => __( 'Purge All Caches Except CloudFlare', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_dashboard&w3tc_cloudflare_flush_all_except_cf' ), 'w3tc' ), ); } if ( ! is_admin() ) { $menu_items['10020.generic'] = array( 'id' => 'w3tc_flush_current_page', 'parent' => 'w3tc', 'title' => __( 'Purge Current Page', 'w3-total-cache' ), 'href' => wp_nonce_url( admin_url( 'admin.php?page=w3tc_dashboard&w3tc_flush_post&post_id=' . Util_Environment::detect_post_id() . '&force=true' ), 'w3tc' ), ); } $menu_items['20010.generic'] = array( 'id' => 'w3tc_flush', 'parent' => 'w3tc', 'title' => __( 'Purge Modules', 'w3-total-cache' ), ); } $menu_items['30000.generic'] = array( 'id' => 'w3tc_feature_showcase', 'parent' => 'w3tc', 'title' => __( 'Feature Showcase', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_feature_showcase' ), 'w3tc' ), ); $menu_items['40010.generic'] = array( 'id' => 'w3tc_settings_general', 'parent' => 'w3tc', 'title' => __( 'General Settings', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_general' ), 'w3tc' ), ); $menu_items['40020.generic'] = array( 'id' => 'w3tc_settings_extensions', 'parent' => 'w3tc', 'title' => __( 'Manage Extensions', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_extensions' ), 'w3tc' ), ); $menu_items['40030.generic'] = array( 'id' => 'w3tc_settings_faq', 'parent' => 'w3tc', 'title' => __( 'FAQ', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_faq' ), 'w3tc' ), ); $menu_items['60010.generic'] = array( 'id' => 'w3tc_support', 'parent' => 'w3tc', 'title' => __( 'Support', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_support' ), 'w3tc' ), ); if ( defined( 'W3TC_DEBUG' ) && W3TC_DEBUG ) { $menu_items['90010.generic'] = array( 'id' => 'w3tc_debug_overlays', 'parent' => 'w3tc', 'title' => __( 'Debug: Overlays', 'w3-total-cache' ), ); $menu_items['90020.generic'] = array( 'id' => 'w3tc_overlay_support_us', 'parent' => 'w3tc_debug_overlays', 'title' => __( 'Support Us', 'w3-total-cache' ), 'href' => wp_nonce_url( network_admin_url( 'admin.php?page=w3tc_dashboard&w3tc_message_action=generic_support_us' ), 'w3tc' ), ); } $menu_items = apply_filters( 'w3tc_admin_bar_menu', $menu_items ); $keys = array_keys( $menu_items ); asort( $keys ); foreach ( $keys as $key ) { $capability = apply_filters( 'w3tc_capability_admin_bar_' . $menu_items[ $key ]['id'], $base_capability ); if ( current_user_can( $capability ) ) { $wp_admin_bar->add_menu( $menu_items[ $key ] ); } } } } /** * Template filter * * @param unknown $template * @return string */ function template( $template ) { $w3_mobile = Dispatcher::component( 'Mobile_UserAgent' ); $mobile_template = $w3_mobile->get_template(); if ( $mobile_template ) { return $mobile_template; } else { $w3_referrer = Dispatcher::component( 'Mobile_Referrer' ); $referrer_template = $w3_referrer->get_template(); if ( $referrer_template ) { return $referrer_template; } } return $template; } /** * Stylesheet filter * * @param unknown $stylesheet * @return string */ function stylesheet( $stylesheet ) { $w3_mobile = Dispatcher::component( 'Mobile_UserAgent' ); $mobile_stylesheet = $w3_mobile->get_stylesheet(); if ( $mobile_stylesheet ) { return $mobile_stylesheet; } else { $w3_referrer = Dispatcher::component( 'Mobile_Referrer' ); $referrer_stylesheet = $w3_referrer->get_stylesheet(); if ( $referrer_stylesheet ) { return $referrer_stylesheet; } } return $stylesheet; } /** * Template filter * * @param unknown $template * @return string */ function template_preview( $template ) { $theme_name = Util_Request::get_string( 'w3tc_theme' ); $theme = Util_Theme::get( $theme_name ); if ( $theme ) { return $theme['Template']; } return $template; } /** * Stylesheet filter * * @param unknown $stylesheet * @return string */ function stylesheet_preview( $stylesheet ) { $theme_name = Util_Request::get_string( 'w3tc_theme' ); $theme = Util_Theme::get( $theme_name ); if ( $theme ) { return $theme['Stylesheet']; } return $stylesheet; } /** * Output buffering callback * * @param string $buffer * @return string */ function ob_callback( $buffer ) { global $wpdb; global $w3_late_caching_succeeded; if ( $w3_late_caching_succeeded ) { return $buffer; } if ( $this->is_wp_die && ! apply_filters( 'w3tc_process_wp_die', false, $buffer ) ) { // wp_die is dynamic output (usually fatal errors), dont process it } else { $buffer = apply_filters( 'w3tc_process_content', $buffer ); if ( Util_Content::can_print_comment( $buffer ) ) { /** * Add footer comment */ $date = date_i18n( 'Y-m-d H:i:s' ); $host = ( ! empty( $_SERVER['SERVER_NAME'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) : 'localhost' ); if ( Util_Environment::is_preview_mode() ) { $buffer .= "\r\n"; } $strings = array(); if ( ! $this->_config->get_boolean( 'common.tweeted' ) ) { $strings[] = 'Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/'; $strings[] = ''; } $strings = apply_filters( 'w3tc_footer_comment', $strings ); if ( count( $strings ) ) { $strings[] = ''; $strings[] = sprintf( 'Served from: %1$s @ %2$s by W3 Total Cache', Util_Content::escape_comment( $host ), $date ); $buffer .= "\r\n"; } } $buffer = Util_Bus::do_ob_callbacks( array( 'swarmify', 'lazyload', 'removecssjs', 'deferscripts', 'minify', 'newrelic', 'cdn', 'browsercache', ), $buffer ); $buffer = apply_filters( 'w3tc_processed_content', $buffer ); // Apply the w3tc_processed_content filter before pagecache callback. $buffer = Util_Bus::do_ob_callbacks( array( 'pagecache' ), $buffer ); } return $buffer; } /** * Check if we can do modify contents * * @return boolean */ function can_ob() { global $w3_late_init; if ( $w3_late_init ) { return false; } /** * Skip if doing AJAX */ if ( defined( 'DOING_AJAX' ) ) { return false; } /** * Skip if doing cron */ if ( defined( 'DOING_CRON' ) ) { return false; } /** * Skip if APP request */ if ( defined( 'APP_REQUEST' ) ) { return false; } /** * Skip if XMLRPC request */ if ( defined( 'XMLRPC_REQUEST' ) ) { return false; } /** * Check for WPMU's and WP's 3.0 short init */ if ( defined( 'SHORTINIT' ) && SHORTINIT ) { return false; } /** * Check User Agent */ $http_user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : ''; if ( stristr( $http_user_agent, W3TC_POWERED_BY ) !== false ) { return false; } return true; } /** * User login hook * Check if current user is not listed in pgcache.reject.* rules * If so, set a role cookie so the requests wont be cached */ function check_login_action( $logged_in_cookie = false, $expire = ' ', $expiration = 0, $user_id = 0, $action = 'logged_out' ) { $current_user = wp_get_current_user(); if ( isset( $current_user->ID ) && ! $current_user->ID ) { $user_id = new \WP_User( $user_id ); } else { $user_id = $current_user; } if ( is_string( $user_id->roles ) ) { $roles = array( $user_id->roles ); } elseif ( ! is_array( $user_id->roles ) || count( $user_id->roles ) <= 0 ) { return; } else { $roles = $user_id->roles; } $rejected_roles = $this->_config->get_array( 'pgcache.reject.roles' ); if ( 'logged_out' === $action ) { foreach ( $rejected_roles as $role ) { $role_hash = md5( NONCE_KEY . $role ); setcookie( 'w3tc_logged_' . $role_hash, $expire, time() - 31536000, COOKIEPATH, COOKIE_DOMAIN ); } return; } if ( 'logged_in' !== $action ) { return; } foreach ( $roles as $role ) { if ( in_array( $role, $rejected_roles, true ) ) { $role_hash = md5( NONCE_KEY . $role ); setcookie( 'w3tc_logged_' . $role_hash, true, $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true ); } } } function popup_script() { if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) { return; } ?> _config->get_boolean( 'pgcache.enabled' ) && $this->_config->get_boolean( 'pgcache.debug' ); $debug = $debug || ( $this->_config->get_boolean( 'dbcache.enabled' ) && $this->_config->get_boolean( 'dbcache.debug' ) ); $debug = $debug || ( $this->_config->getf_boolean( 'objectcache.enabled' ) && $this->_config->get_boolean( 'objectcache.debug' ) ); $debug = $debug || ( $this->_config->get_boolean( 'browsercache.enabled' ) && $this->_config->get_boolean( 'browsercache.debug' ) ); $debug = $debug || ( $this->_config->get_boolean( 'minify.enabled' ) && $this->_config->get_boolean( 'minify.debug' ) ); $debug = $debug || ( $this->_config->get_boolean( 'cdn.enabled' ) && $this->_config->get_boolean( 'cdn.debug' ) ); return $debug; } public function pro_dev_mode() { echo '
W3 Total Cache is currently running in Pro version Development mode.