$cookie_value ) { $hit = self::match_cookie_pattern( $cookie_name ); if ( $hit ) { return self::result( self::BYPASS, 'Session/personalization cookie present: ' . $hit ); } } $query = (array) ( $context['query'] ?? array() ); $meaningful_query = array_diff_key( $query, array_flip( self::IGNORABLE_QUERY_PARAMS ) ); if ( ! empty( $meaningful_query ) ) { return self::result( self::NEEDS_REVIEW, 'Request has query parameters beyond known tracking params: ' . implode( ', ', array_keys( $meaningful_query ) ) ); } return self::result( self::SAFE_TO_CACHE, 'GET request, anonymous, no protected path, no session cookies, no meaningful query string.' ); } public static function classify_response( array $context ) { $status = (int) ( $context['status_code'] ?? 0 ); if ( 200 !== $status ) { return self::result( self::FORCE_EXCLUDED, 'Response status ' . $status . ' is not 200 (redirects/errors are never cached).' ); } $content_type = (string) ( $context['content_type'] ?? '' ); if ( '' !== $content_type && false === stripos( $content_type, 'text/html' ) ) { return self::result( self::BYPASS, 'Response content-type is not text/html: ' . $content_type ); } $headers = array_change_key_case( (array) ( $context['headers'] ?? array() ), CASE_LOWER ); $cache_control = strtolower( (string) ( $headers['cache-control'] ?? '' ) ); if ( $cache_control ) { foreach ( array( 'no-store', 'private', 'no-cache' ) as $directive ) { if ( false !== strpos( $cache_control, $directive ) ) { return self::result( self::BYPASS, 'Origin response sent Cache-Control: ' . $directive ); } } } if ( ! empty( $headers['pragma'] ) && false !== stripos( (string) $headers['pragma'], 'no-cache' ) ) { return self::result( self::BYPASS, 'Origin response sent Pragma: no-cache.' ); } if ( ! empty( $headers['set-cookie'] ) ) { return self::result( self::BYPASS, 'Origin response set a new cookie during this request -- likely personalized (session/cart/comment identity).' ); } foreach ( (array) ( $context['new_cookies_set'] ?? array() ) as $cookie_name ) { if ( self::match_cookie_pattern( $cookie_name ) ) { return self::result( self::BYPASS, 'Origin response set a session/personalization cookie: ' . $cookie_name ); } } return self::result( self::SAFE_TO_CACHE, 'Response is a plain 200 text/html page with no private/session signal.' ); } protected static function match_cookie_pattern( $cookie_name ) { foreach ( self::cookie_patterns() as $pattern ) { if ( self::wildcard_match( $pattern, $cookie_name ) ) { return $pattern; } } return false; } protected static function wildcard_match( $pattern, $subject ) { $regex = '/^' . str_replace( '\*', '.*', preg_quote( $pattern, '/' ) ) . '$/i'; return (bool) preg_match( $regex, $subject ); } public static function cookie_patterns() { $defaults = array( 'wordpress_logged_in_*', 'wordpress_sec_*', 'wordpress_*', 'wp-settings-*', 'wp-settings-time-*', 'comment_author_*', 'comment_author_email_*', 'comment_author_url_*', 'woocommerce_items_in_cart', 'woocommerce_cart_hash', 'wp_woocommerce_session_*', ); return apply_filters( 'argus_wpd_cache_bypass_cookie_patterns', $defaults ); } public static function protected_paths() { $defaults = array( '/wp-admin', '/wp-login.php', '/wp-json', '/wp-cron.php', '/xmlrpc.php', ); if ( class_exists( 'WooCommerce' ) ) { $defaults = array_merge( $defaults, self::woocommerce_paths() ); } return apply_filters( 'argus_wpd_cache_protected_paths', $defaults ); } protected static function woocommerce_paths() { $paths = array(); $page_options = array( 'woocommerce_cart_page_id' => '/cart', 'woocommerce_checkout_page_id' => '/checkout', 'woocommerce_myaccount_page_id' => '/my-account', ); foreach ( $page_options as $option => $fallback ) { $page_id = (int) get_option( $option ); $path = $page_id ? wp_parse_url( get_permalink( $page_id ), PHP_URL_PATH ) : null; $paths[] = $path ? untrailingslashit( $path ) : $fallback; } return $paths; } public static function classify_url( $url ) { $parts = wp_parse_url( $url ); $query = array(); if ( ! empty( $parts['query'] ) ) { parse_str( $parts['query'], $query ); } return self::classify_request( array( 'method' => 'GET', 'path' => $parts['path'] ?? '/', 'query' => $query, 'is_admin' => false, 'is_logged_in' => false, 'cookies' => array(), ) ); } protected static function result( $status, $reason ) { return array( 'status' => $status, 'reason' => $reason ); } }