options = get_option( 'aio_options', [] ); $upload_dir = wp_upload_dir(); $this->cache_dir = trailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . 'aio-cache/'; if ( ! $register_hooks ) { return; } $maintenance_enabled = ! empty( $this->options['optEnableMaintenance'] ); $this->is_caching_active = ! empty( $this->options['optEnablePageCache'] ) && ! $maintenance_enabled && ! aio_is_speed_safe_mode(); if ( $this->is_caching_active ) { add_action( 'plugins_loaded', [ $this, 'serve_cache' ], 0 ); add_action( 'template_redirect', [ $this, 'start_buffer' ], -9999 ); add_action( 'save_post', [ $this, 'purge_on_post_change' ], 20, 2 ); add_action( 'deleted_post', [ $this, 'clear_all_cache' ] ); add_action( 'switch_theme', [ $this, 'clear_all_cache' ] ); add_action( 'wp_update_nav_menu', [ $this, 'clear_all_cache' ] ); add_action( 'woocommerce_new_order', [ $this, 'clear_all_cache' ] ); add_action( 'comment_post', [ $this, 'purge_on_comment' ], 20, 2 ); add_action( 'init', [ $this, 'maybe_schedule_gc_cron' ] ); } add_action( 'aio_page_cache_gc_cron', [ $this, 'cleanup_expired_cache' ] ); add_action( 'aio_cache_preload_batch', [ $this, 'process_preload_batch' ] ); add_action( 'aio_tools_settings_updated', [ $this, 'on_settings_updated' ], 10, 1 ); add_action( 'wp_head', [ $this, 'output_preload_tags' ], 1 ); // AJAX endpoints add_action( 'wp_ajax_aio_clear_page_cache', [ $this, 'ajax_clear_cache' ] ); add_action( 'wp_ajax_aio_get_page_cache_stats', [ $this, 'ajax_get_cache_stats' ] ); add_action( 'wp_ajax_aio_start_cache_preload', [ $this, 'ajax_start_preload' ] ); add_action( 'wp_ajax_aio_reinstall_adv_cache', [ $this, 'ajax_reinstall_adv_cache' ] ); } /** * Detect any other active page cache plugins so UI can alert admin without disabling AIO Tools. */ public static function detect_competing_cache_plugins() { $found = []; if ( defined( 'WP_ROCKET_VERSION' ) ) { $found[] = 'WP Rocket'; } if ( defined( 'LSCACHE_V' ) || class_exists( 'LiteSpeed_Cache' ) ) { $found[] = 'LiteSpeed Cache'; } if ( defined( 'W3TC' ) ) { $found[] = 'W3 Total Cache'; } if ( function_exists( 'wp_cache_phase2' ) || defined( 'WPCACHEHOME' ) ) { $found[] = 'WP Super Cache'; } if ( class_exists( 'WpFastestCache' ) ) { $found[] = 'WP Fastest Cache'; } if ( defined( 'AUTOPTIMIZE_PLUGIN_VERSION' ) ) { $found[] = 'Autoptimize'; } return $found; } private function is_excluded_cookie_present() { if ( empty( $_COOKIE ) ) { return false; } $prefixes = [ 'wordpress_logged_in_', 'wp-postpass_', 'woocommerce_items_in_cart', 'wp_woocommerce_session_', 'aio_maint_bypass', 'comment_author_', ]; if ( ! empty( $this->options['optCacheExcludeCookies'] ) ) { foreach ( preg_split( '/[\r\n]+/', (string) $this->options['optCacheExcludeCookies'] ) as $c ) { $c = trim( $c ); if ( $c !== '' ) { $prefixes[] = $c; } } } foreach ( array_keys( $_COOKIE ) as $key ) { foreach ( $prefixes as $pref ) { if ( $pref !== '' && stripos( (string) $key, $pref ) !== false ) { return true; } } } return false; } private function has_disallowed_query_args() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( empty( $_GET ) ) { return false; } $ignore_tracking = ! isset( $this->options['optCacheIgnoreTracking'] ) || ! empty( $this->options['optCacheIgnoreTracking'] ); if ( ! $ignore_tracking ) { return true; } $ignored = [ 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_id', 'fbclid', 'gclid', 'dclid', 'msclkid', 'ttclid', 'twclid', 'yclid', 'zarsrc', '_ga', '_gl', 'mc_cid', 'mc_eid', ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended foreach ( array_keys( $_GET ) as $qkey ) { if ( ! in_array( strtolower( (string) $qkey ), $ignored, true ) ) { return true; } } return false; } private function is_mobile_visitor() { if ( empty( $this->options['optCacheSeparateMobile'] ) ) { return false; } $ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? (string) wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) : ''; return (bool) preg_match( '/Mobile|Android|Silk\/|Kindle|BlackBerry|Opera (?:Mini|Mobi)|iPhone|iPod/i', $ua ); } /** * Safely build cache file path while preventing Host Header Poisoning and Path Traversal. */ private function get_cache_filepath( $custom_url = '' ) { $expected_host = strtolower( (string) wp_parse_url( home_url(), PHP_URL_HOST ) ); if ( empty( $expected_host ) ) { return false; } if ( $custom_url !== '' ) { $uri_path = (string) wp_parse_url( $custom_url, PHP_URL_PATH ); $scheme = strtolower( (string) wp_parse_url( $custom_url, PHP_URL_SCHEME ) ); $is_https = ( $scheme === 'https' ); } else { $raw_host = isset( $_SERVER['HTTP_HOST'] ) ? strtolower( sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) ) : ''; $req_host = preg_replace( '/:\d+$/', '', $raw_host ); if ( $req_host !== $expected_host ) { return false; } $raw_uri = isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_unslash( $_SERVER['REQUEST_URI'] ) : '/'; if ( strpos( $raw_uri, "\0" ) !== false || strpos( $raw_uri, '\\' ) !== false || strpos( $raw_uri, '..' ) !== false ) { return false; } $uri_path = (string) wp_parse_url( $raw_uri, PHP_URL_PATH ); $is_https = is_ssl(); } if ( preg_match( '/\.(?:xml|txt|json|php|ico|css|js)$/i', $uri_path ) ) { return false; } if ( ! empty( $this->options['optCacheExcludeUrls'] ) ) { foreach ( preg_split( '/[\r\n]+/', (string) $this->options['optCacheExcludeUrls'] ) as $ex ) { $ex = trim( $ex ); if ( $ex !== '' && stripos( $uri_path, $ex ) !== false ) { return false; } } } $segments = array_filter( explode( '/', trim( $uri_path, '/' ) ), 'strlen' ); $safe_segments = []; foreach ( $segments as $seg ) { $clean = preg_replace( '/[^A-Za-z0-9._~%-]/', '_', $seg ); if ( $clean === '' || $clean === '.' || $clean === '..' ) { return false; } $safe_segments[] = substr( $clean, 0, 120 ); } $scheme_prefix = $is_https ? 'https-' : 'http-'; $sub_path = ! empty( $safe_segments ) ? implode( '/', $safe_segments ) . '/' : ''; $file_name = ( $custom_url === '' && $this->is_mobile_visitor() ) ? 'index-mobile.html' : 'index.html'; $full_path = wp_normalize_path( $this->cache_dir . $scheme_prefix . $expected_host . '/' . $sub_path . $file_name ); if ( strpos( $full_path, $this->cache_dir ) !== 0 ) { return false; } return $full_path; } private function get_ttl_seconds() { $hours = isset( $this->options['optCacheTtlHours'] ) ? absint( $this->options['optCacheTtlHours'] ) : 24; return $hours > 0 ? ( $hours * HOUR_IN_SECONDS ) : 0; } public function serve_cache() { if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || $_SERVER['REQUEST_METHOD'] !== 'GET' ) { return; } if ( aio_is_speed_safe_mode() || $this->has_disallowed_query_args() || $this->is_excluded_cookie_present() ) { return; } $cache_file = $this->get_cache_filepath(); if ( ! $cache_file || ! file_exists( $cache_file ) ) { return; } $ttl = $this->get_ttl_seconds(); if ( $ttl > 0 && ( time() - filemtime( $cache_file ) ) > $ttl ) { @unlink( $cache_file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( file_exists( $cache_file . '.gz' ) ) { @unlink( $cache_file . '.gz' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } return; } $accept_enc = isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ? strtolower( (string) wp_unslash( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) : ''; $gz_file = $cache_file . '.gz'; $can_gzip = ( strpos( $accept_enc, 'gzip' ) !== false ) && ! ini_get( 'zlib.output_compression' ) && file_exists( $gz_file ); header( 'Content-Type: text/html; charset=UTF-8' ); header( 'Vary: Accept-Encoding' ); if ( $can_gzip ) { header( 'Content-Encoding: gzip' ); header( 'Content-Length: ' . filesize( $gz_file ) ); header( 'X-AIO-Cache: HIT-GZIP' ); readfile( $gz_file ); exit; } header( 'X-AIO-Cache: HIT' ); readfile( $cache_file ); exit; } public function start_buffer() { if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || $_SERVER['REQUEST_METHOD'] !== 'GET' ) { return; } if ( aio_is_speed_safe_mode() || $this->has_disallowed_query_args() || is_user_logged_in() ) { return; } if ( defined( 'DONOTCACHEPAGE' ) && DONOTCACHEPAGE ) { return; } if ( is_404() || is_search() || is_feed() || is_trackback() || is_preview() ) { return; } if ( function_exists( 'is_cart' ) && ( is_cart() || is_checkout() || is_account_page() ) ) { return; } if ( $this->is_excluded_cookie_present() ) { return; } ob_start( [ $this, 'cache_callback' ] ); } public function cache_callback( $buffer ) { if ( empty( $buffer ) || strlen( $buffer ) < 255 ) { return $buffer; } if ( http_response_code() !== 200 || stripos( $buffer, '' ) === false ) { return $buffer; } if ( defined( 'DONOTCACHEPAGE' ) && DONOTCACHEPAGE ) { return $buffer; } $cache_file = $this->get_cache_filepath(); if ( ! $cache_file ) { return $buffer; } if ( ! file_exists( $this->cache_dir ) ) { wp_mkdir_p( $this->cache_dir ); } if ( ! file_exists( $this->cache_dir . 'index.php' ) ) { if ( class_exists( 'AIO_Dropin_Manager' ) ) { AIO_Dropin_Manager::write_runtime_config( $this->options ); } else { @file_put_contents( $this->cache_dir . 'index.php', "'; $payload = $buffer . $signature; @file_put_contents( $cache_file, $payload ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( function_exists( 'gzencode' ) ) { $gz_payload = @gzencode( $payload, 6 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( $gz_payload !== false ) { @file_put_contents( $cache_file . '.gz', $gz_payload ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } if ( ! headers_sent() ) { header( 'X-AIO-Cache: MISS' ); } return $buffer; } /** * Granular cache invalidation when a post/page/product is updated. */ public function purge_on_post_change( $post_id, $post = null ) { if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) { return; } if ( is_object( $post ) && ! in_array( $post->post_status, [ 'publish', 'trash', 'private' ], true ) ) { return; } $urls_to_purge = [ home_url( '/' ) ]; $permalink = get_permalink( $post_id ); if ( $permalink ) { $urls_to_purge[] = $permalink; } $posts_page = get_option( 'page_for_posts' ); if ( $posts_page ) { $urls_to_purge[] = get_permalink( $posts_page ); } if ( function_exists( 'wc_get_page_permalink' ) ) { $shop_url = wc_get_page_permalink( 'shop' ); if ( $shop_url ) { $urls_to_purge[] = $shop_url; } } $taxonomies = get_object_taxonomies( get_post_type( $post_id ) ); if ( is_array( $taxonomies ) ) { foreach ( $taxonomies as $tax ) { $terms = get_the_terms( $post_id, $tax ); if ( is_array( $terms ) ) { foreach ( array_slice( $terms, 0, 10 ) as $term ) { $tlink = get_term_link( $term ); if ( ! is_wp_error( $tlink ) ) { $urls_to_purge[] = $tlink; } } } } } foreach ( array_unique( $urls_to_purge ) as $u ) { $this->purge_single_url( $u ); } } public function purge_on_comment( $comment_id, $comment_approved ) { if ( $comment_approved === 1 || $comment_approved === '1' ) { $comment = get_comment( $comment_id ); if ( $comment && ! empty( $comment->comment_post_ID ) ) { $this->purge_single_url( get_permalink( (int) $comment->comment_post_ID ) ); } } } public function maybe_schedule_gc_cron() { if ( ! wp_next_scheduled( 'aio_page_cache_gc_cron' ) ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'hourly', 'aio_page_cache_gc_cron' ); } } public static function purge_single_url_static( $url ) { $inst = new self( false ); $inst->purge_single_url( $url ); } public function purge_single_url( $url ) { if ( empty( $url ) ) { return; } $file = $this->get_cache_filepath( $url ); if ( ! $file ) { return; } $dir = dirname( $file ); foreach ( [ 'index.html', 'index.html.gz', 'index-mobile.html', 'index-mobile.html.gz' ] as $fn ) { $target = $dir . '/' . $fn; if ( is_file( $target ) ) { @unlink( $target ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } public function on_settings_updated( $new_options = [] ) { if ( is_array( $new_options ) ) { $this->options = $new_options; } $this->clear_all_cache(); if ( ! empty( $this->options['optEnablePageCache'] ) && ! empty( $this->options['optEnableCachePreload'] ) ) { $this->schedule_cache_preload(); } } public function clear_all_cache() { if ( file_exists( $this->cache_dir ) ) { $this->delete_cached_html_only( $this->cache_dir ); } } /** * Static helper to purge all cached HTML files without re-registering hooks. */ public static function purge_all_static() { $upload_dir = wp_upload_dir(); $cache_dir = trailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . 'aio-cache/'; if ( ! is_dir( $cache_dir ) ) { return; } $files = glob( $cache_dir . '*', GLOB_MARK ); if ( ! is_array( $files ) ) { return; } foreach ( $files as $file ) { if ( is_dir( $file ) ) { self::remove_dir_static( $file ); } else { $base = basename( $file ); if ( ! in_array( $base, [ 'index.php', '.htaccess', 'cache-config.php', 'object-cache-config.php' ], true ) ) { @unlink( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } } private static function remove_dir_static( $dir_path ) { if ( ! is_dir( $dir_path ) ) { return; } $dir_path = trailingslashit( $dir_path ); $files = glob( $dir_path . '*', GLOB_MARK ); if ( is_array( $files ) ) { foreach ( $files as $file ) { if ( is_dir( $file ) ) { self::remove_dir_static( $file ); } else { @unlink( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } @rmdir( $dir_path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } /** * Delete cached HTML subdirectories while preserving cache-config.php & object-cache-config.php. */ private function delete_cached_html_only( $dir_path ) { if ( ! is_dir( $dir_path ) ) { return; } $dir_path = trailingslashit( $dir_path ); $files = glob( $dir_path . '*', GLOB_MARK ); if ( is_array( $files ) ) { foreach ( $files as $file ) { if ( is_dir( $file ) ) { $this->delete_dir_recursive( $file ); } else { $base = basename( $file ); if ( ! in_array( $base, [ 'index.php', '.htaccess', 'cache-config.php', 'object-cache-config.php' ], true ) ) { @unlink( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } } } /** * Hourly WP-Cron Garbage Collector: removes expired .html / .html.gz files on disk * so Tier 1 .htaccess Zero-PHP rewrite never serves stale cached pages past TTL. */ public function cleanup_expired_cache() { $ttl = $this->get_ttl_seconds(); if ( $ttl <= 0 || ! is_dir( $this->cache_dir ) ) { return; } $now = time(); $this->gc_walk_dir( $this->cache_dir, $ttl, $now, true ); } private function gc_walk_dir( $dir_path, $ttl, $now, $is_root = false ) { if ( ! is_dir( $dir_path ) ) { return; } $dir_path = trailingslashit( $dir_path ); $items = glob( $dir_path . '*', GLOB_MARK ); if ( is_array( $items ) ) { foreach ( $items as $item ) { if ( is_dir( $item ) ) { $this->gc_walk_dir( $item, $ttl, $now, false ); } else { $base = basename( $item ); if ( substr( $base, -5 ) === '.html' || substr( $base, -8 ) === '.html.gz' ) { $mtime = (int) @filemtime( $item ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( $mtime > 0 && ( $now - $mtime ) > $ttl ) { @unlink( $item ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } } } if ( ! $is_root ) { $remaining = glob( $dir_path . '*' ); if ( is_array( $remaining ) && empty( $remaining ) ) { @rmdir( $dir_path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } private function delete_dir_recursive( $dir_path ) { if ( ! is_dir( $dir_path ) ) { return; } $dir_path = trailingslashit( $dir_path ); $files = glob( $dir_path . '*', GLOB_MARK ); if ( is_array( $files ) ) { foreach ( $files as $file ) { if ( is_dir( $file ) ) { $this->delete_dir_recursive( $file ); } else { @unlink( $file ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } } } @rmdir( $dir_path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged } /** * Compute live statistics (number of cached HTML pages & total bytes on disk). */ public function get_disk_stats() { $pages = 0; $bytes = 0; if ( is_dir( $this->cache_dir ) ) { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->cache_dir, FilesystemIterator::SKIP_DOTS ) ); foreach ( $iterator as $file_info ) { if ( $file_info->isFile() ) { $name = $file_info->getFilename(); if ( substr( $name, -5 ) === '.html' ) { $pages++; } if ( substr( $name, -5 ) === '.html' || substr( $name, -8 ) === '.html.gz' ) { $bytes += (int) $file_info->getSize(); } } } } $preload_state = get_option( 'aio_cache_preload_state', [] ); return [ 'pages' => $pages, 'bytes' => $bytes, 'size_human' => size_format( $bytes, 1 ), 'preloading' => ! empty( $preload_state['running'] ), 'preload_done' => isset( $preload_state['done'] ) ? (int) $preload_state['done'] : 0, 'preload_total' => isset( $preload_state['total'] ) ? (int) $preload_state['total'] : 0, ]; } /** * Build queue of top public URLs (Homepage + recent Pages, Posts, Products, Categories) and schedule preloader. */ public function schedule_cache_preload() { $urls = [ home_url( '/' ) ]; $post_types = [ 'page', 'post' ]; if ( post_type_exists( 'product' ) ) { $post_types[] = 'product'; } $q = new WP_Query( [ 'post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => 45, 'orderby' => 'modified', 'order' => 'DESC', 'fields' => 'ids', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ] ); if ( ! empty( $q->posts ) ) { foreach ( $q->posts as $pid ) { $link = get_permalink( $pid ); if ( $link ) { $urls[] = $link; } } } $cats = get_terms( [ 'taxonomy' => 'category', 'hide_empty' => true, 'number' => 10, ] ); if ( is_array( $cats ) ) { foreach ( $cats as $c ) { $clink = get_term_link( $c ); if ( ! is_wp_error( $clink ) ) { $urls[] = $clink; } } } $urls = array_values( array_unique( array_filter( $urls ) ) ); $state = [ 'running' => true, 'queue' => $urls, 'done' => 0, 'total' => count( $urls ), ]; update_option( 'aio_cache_preload_state', $state, false ); if ( ! wp_next_scheduled( 'aio_cache_preload_batch' ) ) { wp_schedule_single_event( time() + 1, 'aio_cache_preload_batch' ); } return $state; } /** * Background batch warmer: visits up to 8 URLs per batch anonymously to build .html + .html.gz files. */ public function process_preload_batch() { $state = get_option( 'aio_cache_preload_state', [] ); if ( empty( $state['running'] ) || empty( $state['queue'] ) || ! is_array( $state['queue'] ) ) { $state['running'] = false; update_option( 'aio_cache_preload_state', $state, false ); return; } $batch = array_splice( $state['queue'], 0, 8 ); foreach ( $batch as $url ) { wp_remote_get( $url, [ 'timeout' => 6, 'redirection' => 2, 'sslverify' => false, 'cookies' => [], 'headers' => [ 'Accept-Encoding' => 'gzip', 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0 AIO-Cache-Preloader/3.0.9', ], ] ); $state['done'] = isset( $state['done'] ) ? ( (int) $state['done'] + 1 ) : 1; } if ( empty( $state['queue'] ) ) { $state['running'] = false; } else { wp_schedule_single_event( time() + 3, 'aio_cache_preload_batch' ); } update_option( 'aio_cache_preload_state', $state, false ); } public function ajax_clear_cache() { check_ajax_referer( 'aio-settings-nonce', 'security' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) ); } $this->clear_all_cache(); delete_transient( 'aio_img_dims_cache' ); if ( class_exists( 'AIO_Asset_Optimizer' ) ) { AIO_Asset_Optimizer::clear_minified_assets(); } wp_send_json_success( [ 'message' => __( 'Page cache and minified assets cleared successfully!', 'aio-tools' ), 'stats' => $this->get_disk_stats(), ] ); } public function ajax_get_cache_stats() { check_ajax_referer( 'aio-settings-nonce', 'security' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) ); } wp_send_json_success( $this->get_disk_stats() ); } public function ajax_start_preload() { check_ajax_referer( 'aio-settings-nonce', 'security' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) ); } $state = $this->schedule_cache_preload(); // Process first batch immediately so homepage & top pages are warm right away! $this->process_preload_batch(); wp_send_json_success( [ 'message' => __( 'Cache preloader started! Homepage and top pages are now warm.', 'aio-tools' ), 'stats' => $this->get_disk_stats(), ] ); } public function ajax_reinstall_adv_cache() { check_ajax_referer( 'aio-settings-nonce', 'security' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'Unauthorized', 'aio-tools' ) ); } if ( ! class_exists( 'AIO_Dropin_Manager' ) ) { require_once AIO_MODULES_PATH . 'performance/class-aio-dropin-manager.php'; } $ok = AIO_Dropin_Manager::sync_advanced_cache( true, true, $this->options ); if ( $ok ) { wp_send_json_success( __( 'Installed advanced-cache.php Drop-in & enabled WP_CACHE successfully!', 'aio-tools' ) ); } else { wp_send_json_error( __( 'Could not write wp-content/advanced-cache.php. Please check directory permissions.', 'aio-tools' ) ); } } public function output_preload_tags() { if ( aio_is_speed_safe_mode() ) { return; } if ( ! empty( $this->options['optPrefetchDomains'] ) ) { $raw_items = preg_split( '/[\r\n,\s]+/', (string) $this->options['optPrefetchDomains'] ); $seen = []; foreach ( $raw_items as $domain ) { $domain = trim( $domain ); if ( empty( $domain ) ) { continue; } if ( strpos( $domain, '//' ) === 0 ) { $domain = 'https:' . $domain; } elseif ( ! preg_match( '#^https?://#i', $domain ) ) { $domain = 'https://' . ltrim( $domain, '/' ); } $parsed = wp_parse_url( $domain ); if ( empty( $parsed['host'] ) ) { continue; } $origin = ( ! empty( $parsed['scheme'] ) ? strtolower( $parsed['scheme'] ) : 'https' ) . '://' . strtolower( $parsed['host'] ); if ( isset( $seen[ $origin ] ) ) { continue; } $seen[ $origin ] = true; echo '' . "\n"; echo '' . "\n"; } } if ( ! empty( $this->options['optPreloadAssets'] ) ) { $assets = preg_split( '/[\r\n\s]+/', (string) $this->options['optPreloadAssets'] ); $seen = []; foreach ( $assets as $asset ) { $asset = trim( $asset ); if ( empty( $asset ) || isset( $seen[ $asset ] ) ) { continue; } $seen[ $asset ] = true; $lower = strtolower( (string) wp_parse_url( $asset, PHP_URL_PATH ) ); if ( substr( $lower, -6 ) === '.woff2' ) { echo '' . "\n"; } elseif ( substr( $lower, -5 ) === '.woff' ) { echo '' . "\n"; } elseif ( substr( $lower, -4 ) === '.ttf' ) { echo '' . "\n"; } elseif ( substr( $lower, -4 ) === '.css' ) { echo '' . "\n"; } elseif ( substr( $lower, -3 ) === '.js' ) { echo '' . "\n"; } elseif ( preg_match( '/\.(?:jpe?g|png|webp|avif|gif|svg)$/', $lower ) ) { echo '' . "\n"; } else { echo '' . "\n"; } } } } }