save_configuration( $options, POWERED_CACHE_IS_NETWORK ); // drop object cache on backend changes if ( isset( $options['object_cache'] ) && $old_options['object_cache'] !== $options['object_cache'] ) { wp_cache_flush(); } // Flush cache when Dev Mode is turned OFF if ( ! empty( $old_options['dev_mode'] ) && empty( $options['dev_mode'] ) ) { wp_cache_flush(); } // maybe cancel preloading process when it turned off if ( $old_options['enable_cache_preload'] && ! $options['enable_cache_preload'] ) { cancel_preloading(); } // start the preloading process when it is turned on if ( ! $old_options['enable_cache_preload'] && $options['enable_cache_preload'] ) { start_preloading(); } if ( $old_options['async_cache_cleaning'] && ! $options['async_cache_cleaning'] ) { cancel_async_cache_cleaning(); } // cleanup existing cache on toggling cache option if ( $old_options['enable_page_cache'] && ! $options['enable_page_cache'] ) { clean_site_cache_dir(); } // cleanup existing cache due to optimized URL changes if ( $old_options['rewrite_file_optimizer'] && ! $options['rewrite_file_optimizer'] ) { clean_site_cache_dir(); } if ( $old_options['cache_timeout'] !== $options['cache_timeout'] ) { $timestamp = wp_next_scheduled( PURGE_CACHE_CRON_NAME ); wp_unschedule_event( $timestamp, PURGE_CACHE_CRON_NAME ); } /** * Fires after saving configurations. * * @hook powered_cache_settings_saved * * @param {array} $old_options Old settings. * @param {array} $options New settings. * * @since 1.0 */ do_action( 'powered_cache_settings_saved', $old_options, $options ); $redirect_url = wp_get_referer(); if ( empty( $redirect_url ) && isset( $_SERVER['REQUEST_URI'] ) ) { $redirect_url = wp_unslash( $_SERVER['REQUEST_URI'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } $redirect_url = add_query_arg( [ 'pc_action' => $action, ], $redirect_url ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } } /** * Sanitize options * * @param array $options Raw input, most likely $_POST request * * @return array|mixed Sanitized options */ function sanitize_options( $options ) { $sanitized_options = []; if ( isset( $options['object_cache'] ) && in_array( $options['object_cache'], get_available_object_caches(), true ) ) { $sanitized_options['object_cache'] = sanitize_text_field( $options['object_cache'] ); } else { $sanitized_options['object_cache'] = 'off'; } $sanitized_options['enable_page_cache'] = ! empty( $options['enable_page_cache'] ); $sanitized_options['cache_mobile'] = ! empty( $options['cache_mobile'] ); $sanitized_options['cache_mobile_separate_file'] = ! empty( $options['cache_mobile_separate_file'] ); $sanitized_options['loggedin_user_cache'] = ! empty( $options['loggedin_user_cache'] ); $sanitized_options['gzip_compression'] = ! empty( $options['gzip_compression'] ); $sanitized_options['cache_timeout'] = absint( $options['cache_timeout'] ); $sanitized_options['auto_configure_htaccess'] = ! empty( $options['auto_configure_htaccess'] ); $sanitized_options['rewrite_file_optimizer'] = ! empty( $options['rewrite_file_optimizer'] ); $sanitized_options['rejected_user_agents'] = sanitize_textarea_field( $options['rejected_user_agents'] ); $sanitized_options['rejected_cookies'] = sanitize_textarea_field( $options['rejected_cookies'] ); $sanitized_options['rejected_referrers'] = sanitize_textarea_field( $options['rejected_referrers'] ); $sanitized_options['vary_cookies'] = sanitize_textarea_field( $options['vary_cookies'] ); $sanitized_options['rejected_uri'] = sanitize_textarea_field( $options['rejected_uri'] ); $sanitized_options['cache_query_strings'] = sanitize_textarea_field( $options['cache_query_strings'] ); $sanitized_options['ignored_query_strings'] = sanitize_textarea_field( $options['ignored_query_strings'] ); $sanitized_options['purge_additional_pages'] = sanitize_textarea_field( $options['purge_additional_pages'] ); $sanitized_options['minify_html'] = ! empty( $options['minify_html'] ); $sanitized_options['minify_html_dom_optimization'] = ! empty( $options['minify_html_dom_optimization'] ); $sanitized_options['combine_google_fonts'] = ! empty( $options['combine_google_fonts'] ); $sanitized_options['swap_google_fonts_display'] = ! empty( $options['swap_google_fonts_display'] ); $sanitized_options['use_bunny_fonts'] = ! empty( $options['use_bunny_fonts'] ); $sanitized_options['minify_css'] = ! empty( $options['minify_css'] ); $sanitized_options['combine_css'] = ! empty( $options['combine_css'] ); $sanitized_options['critical_css'] = ! empty( $options['critical_css'] ); $sanitized_options['critical_css_additional_files'] = sanitize_textarea_field( $options['critical_css_additional_files'] ); $sanitized_options['critical_css_excluded_files'] = sanitize_textarea_field( $options['critical_css_excluded_files'] ); $sanitized_options['excluded_css_files'] = sanitize_textarea_field( $options['excluded_css_files'] ); $sanitized_options['remove_unused_css'] = ! empty( $options['remove_unused_css'] ); $sanitized_options['ucss_safelist'] = sanitize_textarea_field( $options['ucss_safelist'] ); $sanitized_options['ucss_excluded_files'] = sanitize_textarea_field( $options['ucss_excluded_files'] ); $sanitized_options['minify_js'] = ! empty( $options['minify_js'] ); $sanitized_options['combine_js'] = ! empty( $options['combine_js'] ); $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] ); $sanitized_options['js_defer'] = ! empty( $options['js_defer'] ); $sanitized_options['js_defer_exclusions'] = sanitize_textarea_field( $options['js_defer_exclusions'] ); $sanitized_options['js_delay'] = ! empty( $options['js_delay'] ); $sanitized_options['js_delay_exclusions'] = sanitize_textarea_field( $options['js_delay_exclusions'] ); $sanitized_options['js_delay_timeout'] = absint( $options['js_delay_timeout'] ); $sanitized_options['enable_image_optimization'] = ! empty( $options['enable_image_optimization'] ); $sanitized_options['image_optimizer_preferred_format'] = isset( $options['image_optimizer_preferred_format'] ) ? sanitize_text_field( wp_unslash( $options['image_optimizer_preferred_format'] ) ) : ''; $sanitized_options['enable_lazy_load'] = ! empty( $options['enable_lazy_load'] ); $sanitized_options['lazy_load_post_content'] = ! empty( $options['lazy_load_post_content'] ); $sanitized_options['lazy_load_images'] = ! empty( $options['lazy_load_images'] ); $sanitized_options['lazy_load_iframes'] = ! empty( $options['lazy_load_iframes'] ); $sanitized_options['lazy_load_widgets'] = ! empty( $options['lazy_load_widgets'] ); $sanitized_options['lazy_load_post_thumbnail'] = ! empty( $options['lazy_load_post_thumbnail'] ); $sanitized_options['lazy_load_avatars'] = ! empty( $options['lazy_load_avatars'] ); $sanitized_options['lazy_load_youtube'] = ! empty( $options['lazy_load_youtube'] ); $sanitized_options['lazy_load_exclusions'] = sanitize_textarea_field( $options['lazy_load_exclusions'] ); $sanitized_options['lazy_load_skip_first_nth_img'] = absint( $options['lazy_load_skip_first_nth_img'] ); $sanitized_options['disable_wp_lazy_load'] = ! empty( $options['disable_wp_lazy_load'] ); $sanitized_options['add_missing_image_dimensions'] = ! empty( $options['add_missing_image_dimensions'] ); $sanitized_options['disable_wp_embeds'] = ! empty( $options['disable_wp_embeds'] ); $sanitized_options['disable_emoji_scripts'] = ! empty( $options['disable_emoji_scripts'] ); $sanitized_options['enable_cdn'] = ! empty( $options['enable_cdn'] ); // convert TTL in minute if ( $options['cache_timeout'] > 0 && isset( $options['cache_timeout_interval'] ) ) { switch ( $options['cache_timeout_interval'] ) { case 'DAY': $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1440; break; case 'HOUR': $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 60; break; case 'MINUTE': default: $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1; } } $cdn_hostname = []; if ( isset( $options['cdn_hostname'] ) ) { foreach ( (array) $options['cdn_hostname'] as $hostname ) { $hostname = trim( $hostname ); if ( filter_var( $hostname, FILTER_VALIDATE_URL ) ) { $cdn_hostname[] = wp_parse_url( $hostname, PHP_URL_HOST ); } else { $cdn_hostname[] = $hostname; } } } $cdn_zone = []; if ( isset( $options['cdn_zone'] ) ) { foreach ( (array) $options['cdn_zone'] as $zone ) { $cdn_zone[] = sanitize_text_field( $zone ); } } if ( empty( $cdn_hostname ) ) { $cdn_hostname = [ '' ]; } if ( empty( $cdn_zone ) ) { $cdn_zone = [ '' ]; } $sanitized_options['cdn_hostname'] = $cdn_hostname; $sanitized_options['cdn_zone'] = $cdn_zone; $sanitized_options['cdn_rejected_files'] = sanitize_textarea_field( $options['cdn_rejected_files'] ); $sanitized_options['enable_cache_preload'] = ! empty( $options['enable_cache_preload'] ); $sanitized_options['preload_homepage'] = ! empty( $options['preload_homepage'] ); $sanitized_options['preload_public_posts'] = ! empty( $options['preload_public_posts'] ); $sanitized_options['preload_public_tax'] = ! empty( $options['preload_public_tax'] ); $sanitized_options['enable_sitemap_preload'] = ! empty( $options['enable_sitemap_preload'] ); $sanitized_options['preload_request_interval'] = absint( $options['preload_request_interval'] ); $sanitized_options['preload_sitemap'] = sanitize_textarea_field( $options['preload_sitemap'] ); $sanitized_options['prefetch_dns'] = sanitize_textarea_field( $options['prefetch_dns'] ); $sanitized_options['preconnect_resource'] = sanitize_textarea_field( $options['preconnect_resource'] ); $sanitized_options['prefetch_links'] = ! empty( $options['prefetch_links'] ); $sanitized_options['db_cleanup_post_revisions'] = ! empty( $options['db_cleanup_post_revisions'] ); $sanitized_options['db_cleanup_auto_drafts'] = ! empty( $options['db_cleanup_auto_drafts'] ); $sanitized_options['db_cleanup_trashed_posts'] = ! empty( $options['db_cleanup_trashed_posts'] ); $sanitized_options['db_cleanup_spam_comments'] = ! empty( $options['db_cleanup_spam_comments'] ); $sanitized_options['db_cleanup_trashed_comments'] = ! empty( $options['db_cleanup_trashed_comments'] ); $sanitized_options['db_cleanup_expired_transients'] = ! empty( $options['db_cleanup_expired_transients'] ); $sanitized_options['db_cleanup_all_transients'] = ! empty( $options['db_cleanup_all_transients'] ); $sanitized_options['db_cleanup_optimize_tables'] = ! empty( $options['db_cleanup_optimize_tables'] ); $sanitized_options['enable_scheduled_db_cleanup'] = ! empty( $options['enable_scheduled_db_cleanup'] ); $sanitized_options['scheduled_db_cleanup_frequency'] = sanitize_text_field( $options['scheduled_db_cleanup_frequency'] ); $sanitized_options['enable_cloudflare'] = ! empty( $options['enable_cloudflare'] ); $sanitized_options['cloudflare_email'] = sanitize_email( $options['cloudflare_email'] ); $sanitized_options['cloudflare_api_key'] = sanitize_text_field( $options['cloudflare_api_key'] ); $sanitized_options['cloudflare_api_token'] = sanitize_text_field( $options['cloudflare_api_token'] ); $sanitized_options['cloudflare_zone'] = sanitize_text_field( $options['cloudflare_zone'] ); $sanitized_options['enable_heartbeat'] = ! empty( $options['enable_heartbeat'] ); $sanitized_options['heartbeat_dashboard_status'] = sanitize_text_field( $options['heartbeat_dashboard_status'] ); $sanitized_options['heartbeat_editor_status'] = sanitize_text_field( $options['heartbeat_editor_status'] ); $sanitized_options['heartbeat_frontend_status'] = sanitize_text_field( $options['heartbeat_frontend_status'] ); $sanitized_options['heartbeat_dashboard_interval'] = absint( $options['heartbeat_dashboard_interval'] ); $sanitized_options['heartbeat_editor_interval'] = absint( $options['heartbeat_editor_interval'] ); $sanitized_options['heartbeat_frontend_interval'] = absint( $options['heartbeat_frontend_interval'] ); $sanitized_options['enable_varnish'] = ! empty( $options['enable_varnish'] ); $sanitized_options['varnish_ip'] = sanitize_text_field( $options['varnish_ip'] ); $sanitized_options['cache_footprint'] = ! empty( $options['cache_footprint'] ); $sanitized_options['async_cache_cleaning'] = ! empty( $options['async_cache_cleaning'] ); $sanitized_options['dev_mode'] = ! empty( $options['dev_mode'] ); $sanitized_options['enable_google_tracking'] = ! empty( $options['enable_google_tracking'] ); $sanitized_options['enable_fb_tracking'] = ! empty( $options['enable_fb_tracking'] ); if ( isset( $options['critical_css_appended_content'] ) ) { $sanitized_options['critical_css_appended_content'] = sanitize_css( $options['critical_css_appended_content'] ); } if ( isset( $options['critical_css_fallback'] ) ) { $sanitized_options['critical_css_fallback'] = sanitize_css( $options['critical_css_fallback'] ); } /** * Filters sanitized options. * * @hook powered_cache_sanitized_options * * @param {array} $sanitized_options Sanitized options. * @param {array} $options raw input. * * @return {array} New value. * * @since 2.0 */ return apply_filters( 'powered_cache_sanitized_options', $sanitized_options, $options ); } /** * Add base admin bar menu * * @param object $wp_admin_bar Admin bar object * * @since 2.0 */ function admin_bar_menu( $wp_admin_bar ) { $href = admin_url( 'admin.php?page=powered-cache' ); if ( POWERED_CACHE_IS_NETWORK && current_user_can( 'manage_network' ) ) { $href = network_admin_url( 'admin.php?page=powered-cache' ); } if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) { $href = '#'; } if ( current_user_can( 'manage_options' ) ) { $wp_admin_bar->add_menu( array( 'id' => MENU_SLUG, 'title' => __( 'Powered Cache', 'powered-cache' ), 'href' => $href, ) ); } } /** * Maybe display feedback messages when certain action is taken * * @since 2.0 */ function maybe_display_message() { // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( ! isset( $_GET['pc_action'] ) ) { return; } /** * Dont display multiple message when saving the options while having the query_params */ if ( ! empty( $_POST ) ) { return; } $screen = get_current_screen(); $success_messages = [ 'purge_image_optimizer_cache' => esc_html__( 'Image optimizer cache purged successfully!', 'powered-cache' ), 'flush_page_cache_network' => esc_html__( 'Page cache deleted for all websites!', 'powered-cache' ), 'flush_page_cache' => esc_html__( 'Page cache deleted successfully!', 'powered-cache' ), 'flush_object_cache' => esc_html__( 'Object cache deleted successfully!', 'powered-cache' ), 'flush_all_cache' => esc_html__( 'All cached items flushed successfully!', 'powered-cache' ), 'start_preload' => esc_html__( 'The cache preloading has been initialized!', 'powered-cache' ), 'generate_critical' => esc_html__( 'The Critical CSS generation process has been initialized!', 'powered-cache' ), 'generate_critical_network' => esc_html__( 'The Critical CSS generation process has been initialized for all sites! This might take a while, depending on the network size.', 'powered-cache' ), 'generate_ucss' => esc_html__( 'The UCSS generation process has been initialized!', 'powered-cache' ), 'generate_ucss_network' => esc_html__( 'The UCSS generation process has been initialized for all sites! This might take a while, depending on the network size.', 'powered-cache' ), 'flush_cf_cache' => esc_html__( 'Cloudflare cache flushed, it can take up to 30 seconds to delete all cache from Cloudflare!', 'powered-cache' ), 'reset_settings' => esc_html__( 'Settings have been reset!', 'powered-cache' ), 'import_settings' => esc_html__( 'Settings have been imported!', 'powered-cache' ), 'save_settings_and_optimize' => esc_html__( 'Settings saved and database being optimized...', 'powered-cache' ), 'save_settings_and_clear_cache' => esc_html__( 'Settings have been successfully saved, and all cache has been cleared.', 'powered-cache' ), 'save_settings' => esc_html__( 'Settings saved.', 'powered-cache' ), ]; if ( isset( $_GET['language'] ) ) { $success_messages['flush_lang_cache'] = sprintf( esc_html__( 'Page cache for %s language has been deleted!', 'powered-cache' ), esc_attr( urldecode_deep( $_GET['language'] ) ) ); // phpcs:ignore } $err_messages = [ 'purge_image_optimizer_cache_failed' => esc_html__( 'Could not purge image optimizer cache. Please try again later and ensure your license key is activated!', 'powered-cache' ), 'generic_permission_err' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'flush_page_cache_network_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'flush_page_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'flush_object_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'flush_all_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'start_preload_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'start_critical_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'start_ucss_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ), 'start_critical_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for the Critical CSS!', 'powered-cache' ), 'start_ucss_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for removing unused CSS!', 'powered-cache' ), 'flush_cf_cache_failed' => esc_html__( 'Could not flush Cloudflare cache. Please make sure you entered the correct credentials and zone id!', 'powered-cache' ), ]; if ( isset( $success_messages[ $_GET['pc_action'] ] ) ) { if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page add_settings_error( $screen->parent_file, MENU_SLUG, $success_messages[ $_GET['pc_action'] ], 'success' ); // phpcs:ignore return; } printf( '

%s

', $success_messages[ $_GET['pc_action'] ] ); // phpcs:ignore } if ( isset( $err_messages[ $_GET['pc_action'] ] ) ) { if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page add_settings_error( $screen->parent_file, MENU_SLUG, $err_messages[ $_GET['pc_action'] ], 'error' ); // phpcs:ignore return; } printf( '

%s

', $err_messages[ $_GET['pc_action'] ] ); // phpcs:ignore } // phpcs:enable WordPress.Security.NonceVerification.Recommended } /** * Adds `Purge All Cache` menu bar item * * @param object $wp_admin_bar Admin bar object * * @since 1.1 */ function purge_all_admin_bar_menu( $wp_admin_bar ) { // Only available for the network admins on multisite. if ( is_multisite() && ! current_user_can( 'manage_network' ) ) { return; } $wp_admin_bar->add_menu( array( 'id' => 'all-cache-purge', 'title' => __( 'Purge All Cache', 'powered-cache' ), 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_all_cache' ), 'powered_cache_purge_all_cache' ), 'parent' => 'powered-cache', ) ); } /** * Purges all cache related things * * @since 1.1 */ function purge_all_cache_action() { if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_purge_all_cache' ) ) { // phpcs:ignore wp_nonce_ays( '' ); } if ( is_multisite() && ! current_user_can( 'manage_network' ) ) { $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } if ( ! current_user_can( 'manage_options' ) ) { $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } purge_all_cache(); $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache', wp_get_referer() ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } /** * Purge all cache * * @param array $settings plugin settings * * @return void */ function purge_all_cache( $settings = array() ) { $cache_purger = CachePurger::factory(); if ( empty( $settings ) ) { $settings = \PoweredCache\Utils\get_settings(); } if ( $settings['async_cache_cleaning'] ) { if ( function_exists( 'wp_cache_flush' ) ) { wp_cache_flush(); } $cache_purger->push_to_queue( [ 'call' => 'powered_cache_flush' ] ); $cache_purger->save()->dispatch(); } else { powered_cache_flush();// cleans object cache + page cache dir } /** * Fires after purging all cache * * @hook powered_cache_purge_all_cache * @since 1.1 */ do_action( 'powered_cache_purge_all_cache' ); if ( POWERED_CACHE_IS_NETWORK ) { delete_site_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT ); } else { delete_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT ); } } /** * Downloads proper configuration file * * @since 1.1 */ function download_rewrite_config() { if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_download_rewrite' ) ) { // phpcs:ignore wp_nonce_ays( '' ); } if ( ! can_control_all_settings() ) { $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } if ( ! empty( $_GET['server'] ) ) { $server = sanitize_text_field( wp_unslash( $_GET['server'] ) ); Config::factory()->download_rewrite_rules( $server ); } wp_safe_redirect( wp_get_referer() ); die(); } /** * Run DB optimization * * @param array $options plugin settings */ function db_optimize( $options ) { $powered_cache_db_optimizer = DatabaseOptimizer::factory(); $supported_options = $powered_cache_db_optimizer->get_supported_options(); if ( POWERED_CACHE_IS_NETWORK ) { $sites = get_sites(); foreach ( $sites as $site ) { switch_to_blog( $site->blog_id ); foreach ( $supported_options as $optimization_item ) { if ( $options[ $optimization_item ] ) { $powered_cache_db_optimizer->push_to_queue( $optimization_item ); } } $powered_cache_db_optimizer->save()->dispatch(); restore_current_blog(); } } else { foreach ( $supported_options as $optimization_item ) { if ( $options[ $optimization_item ] ) { $powered_cache_db_optimizer->push_to_queue( $optimization_item ); } } $powered_cache_db_optimizer->save()->dispatch(); } } /** * Cancel preloading process on toggling preload option */ function cancel_preloading() { \PoweredCache\Utils\log( 'Cancel preload process - Settings toggle' ); $cache_preloader = CachePreloader::factory(); $cache_preloader->cancel_process(); $cache_preloader->delete_all(); } /** * Kick-start preloading process * * @return void */ function start_preloading() { \PoweredCache\Utils\log( 'Enable Preloader - Settings toggle' ); Preloader::factory()->setup_preload_queue(); // kickstart the preloading process Preloader::factory()->dispatch_preload_queue(); } /** * Cancel async cache purging processes * * @since 2.3 */ function cancel_async_cache_cleaning() { \PoweredCache\Utils\log( 'Cancel CachePurger process' ); $cache_preloader = CachePurger::factory(); $cache_preloader->cancel_process(); } /** * Perform diagnostic checks */ function run_diagnostic() { global $is_apache; $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( wp_verify_nonce( $nonce, 'powered_cache_run_diagnostic' ) ) { $settings = \PoweredCache\Utils\get_settings(); $checks = array(); // check config file $config_file = Config::factory()->find_wp_config_file(); $config_file_status = is_writeable( $config_file ); if ( $config_file_status ) { $config_file_desc = esc_html__( 'wp-config.php is writable.', 'powered-cache' ); } else { $config_file_desc = sprintf( __( 'wp-config.php is not writable. Please make sure the file writable or you can manually define %s constant.', 'powered-cache' ), 'WP_CACHE' ); } $checks[] = array( 'check' => 'config', 'status' => $config_file_status, 'description' => $config_file_desc, ); // check cache directory $cache_dir = get_cache_dir(); $cache_dir_status = false; if ( ! file_exists( $cache_dir ) ) { $cache_dir_desc = sprintf( __( 'Cache directory %s is not exist!', 'powered-cache' ), '' . $cache_dir . '' ); } elseif ( ! is_writeable( $cache_dir ) ) { $cache_dir_desc = sprintf( __( 'Cache directory %s is not writeable!', 'powered-cache' ), '' . $cache_dir . '' ); } else { $cache_dir_status = true; $cache_dir_desc = sprintf( __( 'Cache directory %s exist and writable!', 'powered-cache' ), '' . $cache_dir . '' ); } $checks[] = array( 'check' => 'cache-dir', 'status' => $cache_dir_status, 'description' => $cache_dir_desc, ); // check .htaccess file if ( $is_apache && $settings['auto_configure_htaccess'] ) { $htaccess_file = get_home_path() . '.htaccess'; $htaccess_file_status = false; if ( ! file_exists( $htaccess_file ) ) { $htaccess_file_desc = sprintf( __( '.htaccess file %s is not exist!', 'powered-cache' ), '' . $htaccess_file . '' ); } elseif ( ! is_writeable( $htaccess_file ) ) { $htaccess_file_desc = sprintf( __( '.htaccess file %s is not writeable!', 'powered-cache' ), '' . $htaccess_file . '' ); } else { $htaccess_file_status = true; $htaccess_file_desc = sprintf( __( '.htaccess file %s exist and writable!', 'powered-cache' ), '' . $htaccess_file . '' ); } $checks[] = array( 'check' => 'htaccess', 'status' => $htaccess_file_status, 'description' => $htaccess_file_desc, ); } // check page cache if ( $settings['enable_page_cache'] ) { $advanced_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php'; $advanced_cache_file_status = false; if ( ! file_exists( $advanced_cache_file ) ) { $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not exist!', 'powered-cache' ), '' . $advanced_cache_file . '' ); } elseif ( ! is_writeable( $advanced_cache_file ) ) { $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not writeable!', 'powered-cache' ), '' . $advanced_cache_file . '' ); } else { $advanced_cache_file_status = true; $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s exist and writable!', 'powered-cache' ), '' . $advanced_cache_file . '' ); } $checks[] = array( 'check' => 'advanced-cache', 'status' => $advanced_cache_file_status, 'description' => $advanced_cache_file_desc, ); } // check object cache if ( 'off' !== $settings['object_cache'] ) { $object_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php'; $object_cache_file_status = false; if ( ! file_exists( $object_cache_file ) ) { $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not exist!', 'powered-cache' ), '' . $object_cache_file . '' ); } elseif ( ! is_writeable( $object_cache_file ) ) { $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not writeable!', 'powered-cache' ), '' . $object_cache_file . '' ); } else { $object_cache_file_status = true; $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s exist and writable!', 'powered-cache' ), '' . $object_cache_file . '' ); } $checks[] = array( 'check' => 'object-cache', 'status' => $object_cache_file_status, 'description' => $object_cache_file_desc, ); } wp_send_json_success( $checks ); } wp_send_json_error( [ esc_html__( 'Invalid request', 'powered-cache' ) ] ); } /** * Check alloptions size like performance lab does. * It's critical to know this before enabling memcached based persistent object cache backends. * When alloptions size is too big (1mb in this case), it will cause performance degradation instead of improvement. * * @return void * @since 3.4 */ function check_alloptions() { $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'powered_cache_update_settings' ) || ! can_configure_object_cache() ) { wp_send_json_error( [ 'message' => esc_html__( 'Invalid request', 'powered-cache' ) ] ); return; } $autoload_option_size = \PoweredCache\Utils\autoloaded_options_size(); $autoload_option_count = count( wp_load_alloptions() ); if ( $autoload_option_size > ALLOPTIONS_CRITICAL_THRESHOLD ) { $status = 'critical'; } elseif ( $autoload_option_size > ALLOPTIONS_WARNING_THRESHOLD && $autoload_option_size <= ALLOPTIONS_CRITICAL_THRESHOLD ) { $status = 'warning'; } else { $status = 'good'; } $message = '

' . esc_html__( 'Autoloaded options could affect performance:', 'powered-cache' ) . ' ' . sprintf( esc_html__( /* translators: 1: Number of autoloaded options. 2: Size of autoloaded options. */ 'Your site has %1$s autoloaded options (size: %2$s) in the options table, which could cause your site to be slow. You can reduce the number of autoloaded options by cleaning up your site\'s options table.', 'powered-cache' ), esc_html( number_format_i18n( $autoload_option_count ) ), esc_html( size_format( $autoload_option_size ) ) ) . '

'; wp_send_json_success( [ 'status' => $status, 'message' => $message, ] ); } /** * Deactivate incompatible plugins * * @since 1.0 */ function deactivate_plugin() { if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'deactivate_plugin' ) ) { // phpcs:ignore wp_nonce_ays( '' ); } if ( ! current_user_can( 'activate_plugins' ) ) { $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() ); wp_safe_redirect( esc_url_raw( $redirect_url ) ); exit; } if ( isset( $_GET['plugin'] ) ) { $plugin = sanitize_text_field( wp_unslash( $_GET['plugin'] ) ); deactivate_plugins( $plugin ); } wp_safe_redirect( wp_get_referer() ); die(); } /** * Adds settings link to plugin actions * * @param array $actions Plugin actions. * * @return array * @since 1.0 */ function action_links( $actions ) { $settings_url = POWERED_CACHE_IS_NETWORK ? network_admin_url( 'admin.php?page=powered-cache' ) : admin_url( 'admin.php?page=powered-cache' ); $powered_cache_url = 'https://poweredcache.com/?utm_source=wp_admin&utm_medium=plugin&utm_campaign=plugin_action_links'; $actions['powered_settings'] = sprintf( '%s', esc_url( $settings_url ), esc_html__( 'Settings', 'powered-cache' ) ); if ( ! is_premium() ) { $actions['get_premium'] = sprintf( '%s', esc_url( $powered_cache_url ), esc_html__( 'Get Premium', 'powered-cache' ) ); } return array_reverse( $actions ); } /** * Conditionally process Cloudflare API key and token settings based on the form input. * * @param array $options The form options submitted by the user. * * @return array Updated options with processed Cloudflare settings. */ function maybe_process_cloudflare_settings( $options ) { // Retrieve the previous Cloudflare API key and token values. $prev_cf_api_key = \PoweredCache\Extensions\Cloudflare\Cloudflare::get_cf_api_key(); $prev_cf_api_token = \PoweredCache\Extensions\Cloudflare\Cloudflare::get_cf_api_token(); // Check if the submitted Cloudflare API key matches the masked version of the previous key. if ( isset( $options['cloudflare_api_key'] ) && mask_string( $prev_cf_api_key, UNMASK_CHARACTER_LENGTH ) === $options['cloudflare_api_key'] ) { $options['cloudflare_api_key'] = $prev_cf_api_key; // Use the unmasked value. } if ( isset( $options['cloudflare_api_token'] ) && mask_string( $prev_cf_api_token, UNMASK_CHARACTER_LENGTH ) === $options['cloudflare_api_token'] ) { $options['cloudflare_api_token'] = $prev_cf_api_token; // Use the unmasked value. } $encryption = new Encryption(); // Encrypt sensitive data if it's not empty. if ( ! empty( $options['cloudflare_api_key'] ) ) { $options['cloudflare_api_key'] = $encryption->encrypt( $options['cloudflare_api_key'] ); } if ( ! empty( $options['cloudflare_api_token'] ) ) { $options['cloudflare_api_token'] = $encryption->encrypt( $options['cloudflare_api_token'] ); } // Override with empty values if constants are defined. if ( defined( 'POWERED_CACHE_CF_API_KEY' ) && POWERED_CACHE_CF_API_KEY ) { $options['cloudflare_api_key'] = ''; } if ( defined( 'POWERED_CACHE_CF_API_TOKEN' ) && POWERED_CACHE_CF_API_TOKEN ) { $options['cloudflare_api_token'] = ''; } return $options; }