: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* WP Super Cache Phase 2 file.
* This file is included by the files wp-cache.php and wp-cache-phase1.php
* It has all the code for caching and serving requests.
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- TODO: Fix or determine for sure that these should not be fixed.
// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- TODO: Fix or determine for sure that these should not be fixed.
function gzip_accepted() {
if ( 1 == ini_get( 'zlib.output_compression' ) || 'on' == strtolower( ini_get( 'zlib.output_compression' ) ) ) { // don't compress WP-Cache data files when PHP is already doing it
if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) || ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) && strpos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) === false ) ) {
function setup_blog_cache_dir() {
global $blog_cache_dir, $cache_path;
if ( false == @is_dir( $blog_cache_dir ) ) {
@mkdir( $cache_path . 'blogs' );
@mkdir( $blog_cache_dir );
if ( false == @is_dir( $blog_cache_dir . 'meta' ) ) {
@mkdir( $blog_cache_dir . 'meta' );
function get_wp_cache_key( $url = false ) {
global $wp_cache_request_uri, $wp_cache_gzip_encoding, $WPSC_HTTP_HOST;
$url = $wp_cache_request_uri;
$server_port = isset( $_SERVER['SERVER_PORT'] ) ? intval( $_SERVER['SERVER_PORT'] ) : 0;
// Prepare a tag to include in the cache key if the request is anything other than text/html
$accept = wpsc_get_accept_header();
if ( $accept === 'text/html' ) {
$accept_tag = '-' . $accept;
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
wp_cache_check_mobile( $WPSC_HTTP_HOST . $server_port . preg_replace( '/#.*$/', '', str_replace( '/index.php', '/', $url ) ) . $wp_cache_gzip_encoding . wp_cache_get_cookies_values() . '-' . wpsc_get_accept_header() . $accept_tag )
* Parse a partial URL (only the path and query components).
* @param string $partial_uri - The path and query component of a URI to parse.
function wpsc_parse_partial_url( $partial_uri ) {
$scheme = wpsc_is_https() ? 'https://' : 'http://';
return parse_url( $scheme . $WPSC_HTTP_HOST . $partial_uri );
function wpsc_remove_tracking_params_from_uri( $uri ) {
global $wpsc_tracking_parameters, $wpsc_ignore_tracking_parameters;
if ( ! isset( $wpsc_ignore_tracking_parameters ) || ! $wpsc_ignore_tracking_parameters ) {
if ( ! isset( $wpsc_tracking_parameters ) || empty( $wpsc_tracking_parameters ) ) {
$parsed_url = wpsc_parse_partial_url( $uri );
if ( isset( $parsed_url['query'] ) ) {
parse_str( $parsed_url['query'], $query );
foreach ( $wpsc_tracking_parameters as $param_name ) {
unset( $query[ $param_name ] );
unset( $_GET[ $param_name ] );
$path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
$query = ! empty( $query ) ? '?' . http_build_query( $query ) : '';
$_SERVER['REQUEST_URI'] = strtok( $_SERVER['REQUEST_URI'], '?' );
if ( $uri !== $path . $query ) {
wp_cache_debug( 'Removed tracking parameters from URL. Returning ' . $path . $query );
function wp_super_cache_init() {
global $wp_cache_key, $key, $blogcacheid, $file_prefix, $blog_cache_dir, $meta_file, $cache_file, $cache_filename, $meta_pathname;
$wp_cache_key = get_wp_cache_key();
$key = $blogcacheid . md5( $wp_cache_key );
$wp_cache_key = $blogcacheid . $wp_cache_key;
$cache_filename = $file_prefix . $key . '.php';
$meta_file = $file_prefix . $key . '.php';
$cache_file = wpsc_get_realpath( $blog_cache_dir );
$cache_file .= '/' . $cache_filename;
$meta_pathname = wpsc_get_realpath( $blog_cache_dir . 'meta/' );
$meta_pathname .= '/' . $meta_file;
return compact( 'key', 'cache_filename', 'meta_file', 'cache_file', 'meta_pathname' );
function wp_cache_serve_cache_file() {
global $key, $blogcacheid, $wp_cache_request_uri, $file_prefix, $blog_cache_dir, $meta_file, $cache_file, $cache_filename, $meta_pathname, $wp_cache_gzip_encoding, $meta;
global $cache_compression, $wp_cache_slash_check, $wp_supercache_304, $wp_cache_home_path, $wp_cache_no_cache_for_get;
global $wp_cache_disable_utf8, $wp_cache_mfunc_enabled, $wpsc_served_header;
if ( wpsc_is_backend() ) {
wp_cache_debug( 'Not serving wp-admin requests.', 5 );
if ( $wp_cache_no_cache_for_get && wpsc_is_get_query() ) {
wp_cache_debug( 'Non empty GET request. Caching disabled on settings page. ' . wpsc_dump_get_request(), 1 );
if ( defined( 'WPSC_SERVE_DISABLED' ) ) {
wp_cache_debug( 'wp_cache_serve_cache_file: WPSC_SERVE_DISABLED defined. Not serving cached files.' );
if ( wpsc_get_accept_header() !== 'text/html' ) {
wp_cache_debug( 'wp_cache_serve_cache_file: visitor does not accept text/html. Not serving cached file.' );
extract( wp_super_cache_init() ); // $key, $cache_filename, $meta_file, $cache_file, $meta_pathname
// Look for wp-cache file + meta file for the current URL
// If we can't find them, we will look for supercache html files. These files don't have any meta data
// which is why the code below does more work setting up the headers, etc.
! defined( 'WPSC_SUPERCACHE_ONLY' ) &&
( $cache_file && file_exists( $cache_file ) ) ||
file_exists( get_current_url_supercache_dir() . 'meta-' . $cache_filename )
if ( file_exists( get_current_url_supercache_dir() . 'meta-' . $cache_filename ) ) {
$cache_file = get_current_url_supercache_dir() . $cache_filename;
$meta_pathname = get_current_url_supercache_dir() . 'meta-' . $cache_filename;
} elseif ( ! file_exists( $cache_file ) ) {
wp_cache_debug( 'wp_cache_serve_cache_file: found cache file but then it disappeared!' );
if ( ! $meta_pathname ) {
wp_cache_debug( 'wp_cache_serve_cache_file: meta pathname is empty. Could not load wp-cache meta file.' );
wp_cache_debug( "wp-cache file exists: $cache_file", 5 );
if ( ! ( $meta = json_decode( wp_cache_get_legacy_cache( $meta_pathname ), true ) ) ) {
wp_cache_debug( "couldn't load wp-cache meta file", 5 );
if ( is_array( $meta ) == false ) {
wp_cache_debug( "meta array corrupt, deleting $meta_pathname and $cache_file", 1 );
@unlink( $meta_pathname );
} else { // no wp-cache file, look for a supercache file
global $wpsc_save_headers;
// last chance, check if a supercache file exists. Just in case .htaccess rules don't work on this host
$file = get_current_url_supercache_dir() . supercache_filename();
if ( false == file_exists( $file ) ) {
wp_cache_debug( "No Super Cache file found for current URL: $file" );
} elseif ( wpsc_is_get_query() ) {
wp_cache_debug( 'GET array not empty. Cannot serve a supercache file. ' . wpsc_dump_get_request() );
} elseif ( wp_cache_get_cookies_values() != '' ) {
wp_cache_debug( 'Cookies found. Cannot serve a supercache file. ' . wp_cache_get_cookies_values() );
} elseif ( wpsc_get_accept_header() !== 'text/html' ) {
wp_cache_debug( 'Accept header is not text/html. Cannot serve supercache file.' . wp_cache_get_cookies_values() );
} elseif ( isset( $wpsc_save_headers ) && $wpsc_save_headers ) {
wp_cache_debug( 'Saving headers. Cannot serve a supercache file.' );
} elseif ( $cache_max_time > 0 && ( filemtime( $file ) + $cache_max_time ) < time() ) {
wp_cache_debug( sprintf( 'Cache has expired and is older than %d seconds old.', $cache_max_time ) );
if ( isset( $wp_cache_mfunc_enabled ) == false ) {
$wp_cache_mfunc_enabled = 0;
if ( false == isset( $wp_cache_home_path ) ) {
$wp_cache_home_path = '/';
// make sure ending slashes are ok
if ( $wp_cache_request_uri == $wp_cache_home_path || ( $wp_cache_slash_check && substr( $wp_cache_request_uri, -1 ) == '/' ) || ( $wp_cache_slash_check == 0 && substr( $wp_cache_request_uri, -1 ) != '/' ) ) {
if ( $wp_cache_mfunc_enabled == 0 ) {
if ( $wp_cache_gzip_encoding ) {
if ( file_exists( $file . '.gz' ) ) {
$cachefiledata = file_get_contents( $file . '.gz' );
wp_cache_debug( "Fetched gzip static page data from supercache file using PHP. File: $file.gz" );
$cachefiledata = gzencode( file_get_contents( $file ), 6, FORCE_GZIP );
wp_cache_debug( "Fetched static page data from supercache file using PHP and gzipped it. File: $file" );
$cachefiledata = file_get_contents( $file );
wp_cache_debug( "Fetched static page data from supercache file using PHP. File: $file" );
// get dynamic data from filtered file
$cachefiledata = do_cacheaction( 'wpsc_cachedata', file_get_contents( $file ) );
if ( $wp_cache_gzip_encoding ) {
$cachefiledata = gzencode( $cachefiledata, 6, FORCE_GZIP );
wp_cache_debug( "Fetched dynamic page data from supercache file using PHP and gzipped it. File: $file" );
wp_cache_debug( "Fetched dynamic page data from supercache file using PHP. File: $file" );
if ( isset( $wp_cache_disable_utf8 ) == false || $wp_cache_disable_utf8 == 0 ) {
header( 'Content-type: text/html; charset=UTF-8' );
if ( defined( 'WPSC_VARY_HEADER' ) ) {
if ( WPSC_VARY_HEADER != '' ) {
header( 'Vary: ' . WPSC_VARY_HEADER );
header( 'Vary: Accept-Encoding, Cookie' );
if ( defined( 'WPSC_CACHE_CONTROL_HEADER' ) ) {
if ( WPSC_CACHE_CONTROL_HEADER != '' ) {
header( 'Cache-Control: ' . WPSC_CACHE_CONTROL_HEADER );
header( 'Cache-Control: max-age=3, must-revalidate' );
$size = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $cachefiledata, '8bit' ) : strlen( $cachefiledata );
if ( $wp_cache_gzip_encoding ) {
if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
header( 'X-WP-Super-Cache: Served supercache gzip file from PHP' );
header( 'Content-Encoding: ' . $wp_cache_gzip_encoding );
header( 'Content-Length: ' . $size );
} elseif ( $wp_supercache_304 ) {
if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
header( 'X-WP-Super-Cache: Served supercache 304 file from PHP' );
header( 'Content-Length: ' . $size );
} elseif ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
header( 'X-WP-Super-Cache: Served supercache file from PHP' );
// don't try to match modified dates if using dynamic code.
if ( $wp_cache_mfunc_enabled == 0 && $wp_supercache_304 ) {
wp_cache_debug( 'wp_cache_serve_cache_file: checking age of cached vs served files.' );
$headers = apache_request_headers();
$remote_mod_time = isset( $headers['If-Modified-Since'] ) ? $headers['If-Modified-Since'] : null;
if ( $remote_mod_time === null && isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
$remote_mod_time = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
$local_mod_time = gmdate( 'D, d M Y H:i:s', filemtime( $file ) ) . ' GMT';
if ( $remote_mod_time !== null && $remote_mod_time == $local_mod_time ) {
wp_cache_debug( 'wp_cache_serve_cache_file: Send 304 Not Modified header.' );
header( $_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified' );
wp_cache_debug( 'wp_cache_serve_cache_file: 304 browser caching not possible as timestamps differ.' );
header( 'Last-Modified: ' . $local_mod_time );
wp_cache_debug( 'No wp-cache file exists. Must generate a new one.' );
$cache_file = do_cacheaction( 'wp_cache_served_cache_file', $cache_file );
// Sometimes the gzip headers are lost. Make sure html returned isn't compressed!
$do_not_serve_gzip_data = true;
if ( $cache_compression && $wp_cache_gzip_encoding ) {
if ( ! in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $meta['headers'], true ) ) {
wp_cache_debug( 'GZIP headers not found. Force uncompressed output.' );
$do_not_serve_gzip_data = false;
if ( isset( $meta['dynamic'] ) ) {
unset( $meta['headers']['Content-Length'] ); // this is set later after the output data is compressed
wp_cache_debug( 'GZIP headers found. Serving compressed output.' );
foreach ( $meta['headers'] as $t => $header ) {
// godaddy fix, via http://blog.gneu.org/2008/05/wp-supercache-on-godaddy/ and http://www.littleredrails.com/blog/2007/09/08/using-wp-cache-on-godaddy-500-error/
if ( strpos( $header, 'Last-Modified:' ) === false ) {
wp_cache_debug( 'Sending Header: ' . $header );
if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
header( 'X-WP-Super-Cache: Served WPCache cache file' );
if ( isset( $meta['dynamic'] ) ) {
wp_cache_debug( 'Serving wp-cache dynamic file', 5 );
if ( $do_not_serve_gzip_data ) {
// attempt to uncompress the cached file just in case it's gzipped
$cache = wp_cache_get_legacy_cache( $cache_file );
$uncompressed = @gzuncompress( $cache );
wp_cache_debug( 'Uncompressed gzipped cache from wp-cache: ' . $cache_file );
$cache = do_cacheaction( 'wpsc_cachedata', $cache );
wp_cache_debug( 'Compressed cache data from wp-cache: ' . $cache_file );
wp_cache_get_legacy_cache( $cache_file )
$size = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $cache, '8bit' ) : strlen( $cache );
wp_cache_debug( 'Sending Header: Content-Length: ' . $size );
header( 'Content-Length: ' . $size );
} elseif ( $do_not_serve_gzip_data ) {
$cache = wp_cache_get_legacy_cache( $cache_file );
$uncompressed = @gzuncompress( $cache ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- there is a small chance the cache isn't gzipped despite being configured to be.
wp_cache_debug( 'Uncompressed gzipped cache data from wp-cache file: ' . $cache_file );
wp_cache_debug( 'Sending already uncompressed cache file from wp-cache to browser: ' . $cache_file );
wp_cache_debug( 'Sending wp-cache file to browser: ' . $cache_file );
$cache = wp_cache_get_legacy_cache( $cache_file );
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- this is the cached version of the current page. It will have been escaped already.
wp_cache_debug( 'exit request', 5 );
function wp_cache_get_legacy_cache( $cache_file ) {
return substr( @file_get_contents( $cache_file ), 15 );
function wp_cache_postload() {
global $cache_enabled, $wp_super_cache_late_init;
global $wp_cache_request_uri;
if ( empty( $wp_cache_request_uri ) ) {
wp_cache_debug( 'wp_cache_postload: no request uri configured. Not running.' );
// have to sanitize here because formatting.php is loaded after wp_cache_request_uri is set
$wp_cache_request_uri = esc_url_raw( wp_unslash( $wp_cache_request_uri ) );
if ( ! $cache_enabled ) {
if ( isset( $wp_super_cache_late_init ) && true == $wp_super_cache_late_init ) {
wp_cache_debug( 'Supercache Late Init: add wp_cache_serve_cache_file to init', 3 );
add_action( 'init', 'wp_cache_late_loader', 9999 );
function wp_cache_late_loader() {
wp_cache_debug( 'Supercache Late Loader running on init', 3 );
wp_cache_serve_cache_file();
function wpsc_get_auth_cookies() {
if ( isset( $cached_cookies ) && is_array( $cached_cookies ) ) {
$cookies = array_keys( $_COOKIE );
if ( empty( $cookies ) ) {
$duplicate_cookies = array();
'AUTH_COOKIE' => 'wordpress_',
'SECURE_AUTH_COOKIE' => 'wordpress_sec_',
'LOGGED_IN_COOKIE' => 'wordpress_logged_in_',
foreach ( $wp_cookies as $cookie_const => $cookie_prefix ) {
$cookie_key = strtolower( $cookie_const );
if ( defined( $cookie_const ) ) {
if ( in_array( constant( $cookie_const ), $cookies, true ) ) {
$auth_cookies[ $cookie_key ] = constant( $cookie_const );
$found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
if ( count( $found_cookies ) === 1 ) {
$auth_cookies[ $cookie_key ] = reset( $found_cookies );
} elseif ( count( $found_cookies ) > 1 ) {
$duplicate_cookies = array_merge( $duplicate_cookies, $found_cookies );
$auth_cookies[ $cookie_key ] = $found_cookies;
$cookie_hash = defined( 'COOKIEHASH' ) ? COOKIEHASH : '';
'comment_cookie' => 'comment_author_',
'postpass_cookie' => 'wp-postpass_',
foreach ( $other_cookies as $cookie_key => $cookie_prefix ) {
if ( in_array( $cookie_prefix . $cookie_hash, $cookies, true ) ) {
$auth_cookies[ $cookie_key ] = $cookie_prefix . $cookie_hash;
$found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
if ( count( $found_cookies ) === 1 ) {
$auth_cookies[ $cookie_key ] = reset( $found_cookies );
} elseif ( count( $found_cookies ) > 1 ) {
$duplicate_cookies = array_merge( $duplicate_cookies, $found_cookies );
$auth_cookies[ $cookie_key ] = $found_cookies;
if ( ! $duplicate_cookies ) {
$cached_cookies = $auth_cookies;
if ( empty( $auth_cookies ) ) {
wp_cache_debug( 'wpsc_get_auth_cookies: no auth cookies detected', 5 );
} elseif ( $duplicate_cookies ) {
wp_cache_debug( 'wpsc_get_auth_cookies: duplicate cookies detected( ' . implode( ', ', $duplicate_cookies ) . ' )', 5 );
wp_cache_debug( 'wpsc_get_auth_cookies: cookies detected: ' . implode( ', ', $auth_cookies ), 5 );