: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( !isset( $wp_super_cache_front_page_check ) || ( isset( $wp_super_cache_front_page_check ) && $wp_super_cache_front_page_check == 0 ) ) {
if ( function_exists( "wp_remote_get" ) == false ) {
$front_page = wp_remote_get( site_url(), array('timeout' => 60, 'blocking' => true ) );
if( is_array( $front_page ) ) {
// Check for gzipped front page
if ( $front_page[ 'headers' ][ 'content-type' ] == 'application/x-gzip' ) {
if ( !isset( $wp_super_cache_front_page_clear ) || ( isset( $wp_super_cache_front_page_clear ) && $wp_super_cache_front_page_clear == 0 ) ) {
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Front page is gzipped! Please clear cache!', 'wp-super-cache' ), home_url() ), sprintf( __( "Please visit %s to clear the cache as the front page of your site is now downloading!", 'wp-super-cache' ), admin_url( 'options-general.php?page=wpsupercache' ) ) );
wp_cache_clear_cache( $wpdb->blogid );
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Front page is gzipped! Cache Cleared!', 'wp-super-cache' ), home_url() ), sprintf( __( "The cache on your blog has been cleared because the front page of your site is now downloading. Please visit %s to verify the cache has been cleared.", 'wp-super-cache' ), admin_url( 'options-general.php?page=wpsupercache' ) ) );
// Check for broken front page
! empty( $wp_super_cache_front_page_text )
&& ! str_contains( $front_page['body'], $wp_super_cache_front_page_text )
if ( !isset( $wp_super_cache_front_page_clear ) || ( isset( $wp_super_cache_front_page_clear ) && $wp_super_cache_front_page_clear == 0 ) ) {
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Front page is not correct! Please clear cache!', 'wp-super-cache' ), home_url() ), sprintf( __( 'Please visit %1$s to clear the cache as the front page of your site is not correct and missing the text, "%2$s"!', 'wp-super-cache' ), admin_url( 'options-general.php?page=wpsupercache' ), $wp_super_cache_front_page_text ) );
wp_cache_clear_cache( $wpdb->blogid );
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Front page is not correct! Cache Cleared!', 'wp-super-cache' ), home_url() ), sprintf( __( 'The cache on your blog has been cleared because the front page of your site is missing the text "%2$s". Please visit %1$s to verify the cache has been cleared.', 'wp-super-cache' ), admin_url( 'options-general.php?page=wpsupercache' ), $wp_super_cache_front_page_text ) );
if ( isset( $wp_super_cache_front_page_notification ) && $wp_super_cache_front_page_notification == 1 ) {
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Front page check!', 'wp-super-cache' ), home_url() ), sprintf( __( "WP Super Cache has checked the front page of your blog. Please visit %s if you would like to disable this.", 'wp-super-cache' ) . "\n\n", admin_url( 'options-general.php?page=wpsupercache' ) ) );
if ( !wp_next_scheduled( 'wp_cache_check_site_hook' ) ) {
wp_schedule_single_event( time() + 360 , 'wp_cache_check_site_hook' );
wp_cache_debug( 'scheduled wp_cache_check_site_hook for 360 seconds time.', 2 );
add_action( 'wp_cache_check_site_hook', 'wp_cache_check_site' );
function update_cached_mobile_ua_list( $mobile_browsers, $mobile_prefixes = 0, $mobile_groups = 0 ) {
global $wp_cache_config_file, $wp_cache_mobile_browsers, $wp_cache_mobile_prefixes, $wp_cache_mobile_groups;
wp_cache_setting( 'wp_cache_mobile_browsers', $mobile_browsers );
wp_cache_setting( 'wp_cache_mobile_prefixes', $mobile_prefixes );
if ( is_array( $mobile_groups ) ) {
$wp_cache_mobile_groups = $mobile_groups;
wp_cache_replace_line('^ *\$wp_cache_mobile_groups', "\$wp_cache_mobile_groups = '" . implode( ', ', $mobile_groups ) . "';", $wp_cache_config_file);
function wpsc_update_htaccess() {
extract( wpsc_get_htaccess_info() ); // $document_root, $apache_root, $home_path, $home_root, $home_root_lc, $inst_root, $wprules, $scrules, $condition_rules, $rules, $gziprules
wpsc_remove_marker( $home_path.'.htaccess', 'WordPress' ); // remove original WP rules so SuperCache rules go on top
if( insert_with_markers( $home_path.'.htaccess', 'WPSuperCache', explode( "\n", $rules ) ) && insert_with_markers( $home_path.'.htaccess', 'WordPress', explode( "\n", $wprules ) ) ) {
function wpsc_update_htaccess_form( $short_form = true ) {
$admin_url = admin_url( 'options-general.php?page=wpsupercache' );
extract( wpsc_get_htaccess_info() ); // $document_root, $apache_root, $home_path, $home_root, $home_root_lc, $inst_root, $wprules, $scrules, $condition_rules, $rules, $gziprules
if( !is_writeable_ACLSafe( $home_path . ".htaccess" ) ) {
echo "<div style='padding:0 8px;color:#9f6000;background-color:#feefb3;border:1px solid #9f6000;'><h5>" . __( 'Cannot update .htaccess', 'wp-super-cache' ) . "</h5><p>" . sprintf( __( 'The file <code>%s.htaccess</code> cannot be modified by the web server. Please correct this using the chmod command or your ftp client.', 'wp-super-cache' ), $home_path ) . "</p><p>" . __( 'Refresh this page when the file permissions have been modified.' ) . "</p><p>" . sprintf( __( 'Alternatively, you can edit your <code>%s.htaccess</code> file manually and add the following code (before any WordPress rules):', 'wp-super-cache' ), $home_path ) . "</p>";
echo "<p><pre># BEGIN WPSuperCache\n" . esc_html( $rules ) . "# END WPSuperCache</pre></p></div>";
if ( $short_form == false ) {
echo "<p>" . sprintf( __( 'To serve static html files your server must have the correct mod_rewrite rules added to a file called <code>%s.htaccess</code>', 'wp-super-cache' ), $home_path ) . " ";
_e( "You can edit the file yourself. Add the following rules.", 'wp-super-cache' );
echo __( " Make sure they appear before any existing WordPress rules. ", 'wp-super-cache' ) . "</p>";
echo "<div style='overflow: auto; width: 800px; height: 400px; padding:0 8px;color:#9f6000;background-color:#feefb3;border:1px solid #9f6000;'>";
echo "<pre># BEGIN WPSuperCache\n" . esc_html( $rules ) . "# END WPSuperCache</pre></p>";
echo "<h5>" . sprintf( __( 'Rules must be added to %s too:', 'wp-super-cache' ), WP_CONTENT_DIR . "/cache/.htaccess" ) . "</h5>";
echo "<div style='overflow: auto; width: 800px; height: 400px; padding:0 8px;color:#9f6000;background-color:#feefb3;border:1px solid #9f6000;'>";
echo "<pre># BEGIN supercache\n" . esc_html( $gziprules ) . "# END supercache</pre></p>";
if ( !isset( $wpmu_version ) || $wpmu_version == '' ) {
echo '<form name="updatehtaccess" action="' . esc_url_raw( add_query_arg( 'tab', 'settings', $admin_url ) . '#modrewrite' ) . '" method="post">';
echo '<input type="hidden" name="updatehtaccess" value="1" />';
echo '<div class="submit"><input class="button-primary" type="submit" ' . SUBMITDISABLED . 'id="updatehtaccess" value="' . __( 'Update Mod_Rewrite Rules', 'wp-super-cache' ) . '" /></div>';
wp_nonce_field('wp-cache');
* Return LOGGED_IN_COOKIE if it doesn't begin with wordpress_logged_in
* to avoid having people update their .htaccess file
function wpsc_get_logged_in_cookie() {
$logged_in_cookie = 'wordpress_logged_in';
if ( defined( 'LOGGED_IN_COOKIE' ) && substr( constant( 'LOGGED_IN_COOKIE' ), 0, 19 ) != 'wordpress_logged_in' )
$logged_in_cookie = constant( 'LOGGED_IN_COOKIE' );
return $logged_in_cookie;
function wpsc_get_htaccess_info() {
global $wp_cache_mobile_enabled, $wp_cache_mobile_prefixes, $wp_cache_mobile_browsers, $wp_cache_disable_utf8;
if ( isset( $_SERVER[ "PHP_DOCUMENT_ROOT" ] ) ) {
$document_root = $_SERVER[ "PHP_DOCUMENT_ROOT" ];
$apache_root = $_SERVER[ "PHP_DOCUMENT_ROOT" ];
$document_root = $_SERVER[ "DOCUMENT_ROOT" ];
$apache_root = '%{DOCUMENT_ROOT}';
$content_dir_root = $document_root;
if ( strpos( $document_root, '/kunden/homepages/' ) === 0 ) {
// https://wordpress.org/support/topic/plugin-wp-super-cache-how-to-get-mod_rewrite-working-on-1and1-shared-hosting?replies=1
// On 1and1, PHP's directory structure starts with '/homepages'. The
// Apache directory structure has an extra '/kunden' before it.
// Also 1and1 does not support the %{DOCUMENT_ROOT} variable in
// This prevents the $inst_root from being calculated correctly and
// means that the $apache_root is wrong.
// e.g. This is an example of how Apache and PHP see the directory
// Apache: /kunden/homepages/xx/dxxxxxxxx/htdocs/site1/index.html
// PHP: /homepages/xx/dxxxxxxxx/htdocs/site1/index.html
// Here we fix up the paths to make mode_rewrite work on 1and1 shared hosting.
$content_dir_root = substr( $content_dir_root, 7 );
$apache_root = $document_root;
$home_path = get_home_path();
$home_root = parse_url(get_bloginfo('url'));
$home_root = isset( $home_root[ 'path' ] ) ? trailingslashit( $home_root[ 'path' ] ) : '/';
if ( isset( $htaccess_path ) ) {
$home_path = $htaccess_path;
$home_path != $_SERVER[ 'DOCUMENT_ROOT' ]
$home_path = $_SERVER[ 'DOCUMENT_ROOT' ];
$home_path != str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ) &&
is_dir( $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root )
$home_path = str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root );
$home_path = trailingslashit( $home_path );
$home_root_lc = str_replace( '//', '/', strtolower( $home_root ) );
$inst_root = str_replace( '//', '/', '/' . trailingslashit( str_replace( $content_dir_root, '', str_replace( '\\', '/', WP_CONTENT_DIR ) ) ) );
$wprules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WordPress' ) );
$wprules = str_replace( "RewriteEngine On\n", '', $wprules );
$wprules = str_replace( "RewriteBase $home_root\n", '', $wprules );
$scrules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WPSuperCache' ) );
if( substr( get_option( 'permalink_structure' ), -1 ) == '/' ) {
$condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*[^/]$";
$condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*//.*$";
$condition_rules[] = "RewriteCond %{REQUEST_METHOD} !POST";
$condition_rules[] = "RewriteCond %{QUERY_STRING} ^$";
$condition_rules[] = "RewriteCond %{HTTP:Cookie} !^.*(comment_author_|" . wpsc_get_logged_in_cookie() . wpsc_get_extra_cookies() . "|wp-postpass_).*$";
$condition_rules[] = "RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\\\"]+ [NC]";
$condition_rules[] = "RewriteCond %{HTTP:Profile} !^[a-z0-9\\\"]+ [NC]";
if ( $wp_cache_mobile_enabled ) {
if ( isset( $wp_cache_mobile_browsers ) && "" != $wp_cache_mobile_browsers )
$condition_rules[] = "RewriteCond %{HTTP_USER_AGENT} !^.*(" . addcslashes( str_replace( ', ', '|', $wp_cache_mobile_browsers ), ' ' ) . ").* [NC]";
if ( isset( $wp_cache_mobile_prefixes ) && "" != $wp_cache_mobile_prefixes )
$condition_rules[] = "RewriteCond %{HTTP_USER_AGENT} !^(" . addcslashes( str_replace( ', ', '|', $wp_cache_mobile_prefixes ), ' ' ) . ").* [NC]";
$condition_rules = apply_filters( 'supercacherewriteconditions', $condition_rules );
$rules = "<IfModule mod_rewrite.c>\n";
$rules .= "RewriteEngine On\n";
$rules .= "RewriteBase $home_root\n"; // props Chris Messina
$rules .= "#If you serve pages from behind a proxy you may want to change 'RewriteCond %{HTTPS} on' to something more sensible\n";
if ( isset( $wp_cache_disable_utf8 ) == false || $wp_cache_disable_utf8 == 0 ) {
$charset = get_option('blog_charset') == '' ? 'UTF-8' : get_option('blog_charset');
$rules .= "AddDefaultCharset {$charset}\n";
$rules .= "CONDITION_RULES";
$rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n";
$rules .= "RewriteCond %{HTTPS} on\n";
$rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html.gz -f\n";
$rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html.gz\" [L]\n\n";
$rules .= "CONDITION_RULES";
$rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n";
$rules .= "RewriteCond %{HTTPS} !on\n";
$rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html.gz -f\n";
$rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html.gz\" [L]\n\n";
$rules .= "CONDITION_RULES";
$rules .= "RewriteCond %{HTTPS} on\n";
$rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html -f\n";
$rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html\" [L]\n\n";
$rules .= "CONDITION_RULES";
$rules .= "RewriteCond %{HTTPS} !on\n";
$rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html -f\n";
$rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html\" [L]\n";
$rules .= "</IfModule>\n";
$rules = apply_filters( 'supercacherewriterules', $rules );
$rules = str_replace( "CONDITION_RULES", implode( "\n", $condition_rules ) . "\n", $rules );
$gziprules = "<IfModule mod_mime.c>\n <FilesMatch \"\\.html\\.gz\$\">\n ForceType text/html\n FileETag None\n </FilesMatch>\n AddEncoding gzip .gz\n AddType text/html .gz\n</IfModule>\n";
$gziprules .= "<IfModule mod_deflate.c>\n SetEnvIfNoCase Request_URI \.gz$ no-gzip\n</IfModule>\n";
'Vary' => 'Accept-Encoding, Cookie',
'Cache-Control' => 'max-age=3, must-revalidate',
// Allow users to override the Vary header with WPSC_VARY_HEADER.
if ( defined( 'WPSC_VARY_HEADER' ) && ! empty( WPSC_VARY_HEADER ) ) {
$headers['Vary'] = WPSC_VARY_HEADER;
// Allow users to override Cache-control header with WPSC_CACHE_CONTROL_HEADER
if ( defined( 'WPSC_CACHE_CONTROL_HEADER' ) && ! empty( WPSC_CACHE_CONTROL_HEADER ) ) {
$headers['Cache-Control'] = WPSC_CACHE_CONTROL_HEADER;
// Allow overriding headers with a filter.
$headers = apply_filters( 'wpsc_htaccess_mod_headers', $headers );
// Combine headers into a block of text.
function ( $key, $value ) {
return " Header set $key '" . addcslashes( $value, "'" ) . "'";
// Pack headers into gziprules (for historic reasons) - TODO refactor the values
// returned to better reflect the blocks being written.
if ( $headers_text != '' ) {
$gziprules .= "<IfModule mod_headers.c>\n$headers_text\n</IfModule>\n";
// Deafult mod_expires rules.
'ExpiresByType text/html A3',
// Allow overriding mod_expires rules with a filter.
$expires_rules = apply_filters( 'wpsc_htaccess_mod_expires', $expires_rules );
$gziprules .= "<IfModule mod_expires.c>\n";
$gziprules .= "\n</IfModule>\n";
$gziprules .= "Options -Indexes\n";
'document_root' => $document_root,
'apache_root' => $apache_root,
'home_path' => $home_path,
'home_root' => $home_root,
'home_root_lc' => $home_root_lc,
'inst_root' => $inst_root,
'condition_rules' => $condition_rules,
'gziprules' => $gziprules,
function clear_post_supercache( $post_id ) {
$dir = get_current_url_supercache_dir( $post_id );
if ( false == @is_dir( $dir ) )
if ( get_supercache_dir() == $dir ) {
wp_cache_debug( "clear_post_supercache: not deleting post_id $post_id as it points at homepage: $dir" );
wp_cache_debug( "clear_post_supercache: post_id: $post_id. deleting files in $dir" );
if ( get_post_type( $post_id ) != 'page') { // don't delete child pages if they exist
prune_super_cache( $dir, true );
wpsc_delete_files( $dir );
* Serves an AJAX endpoint to return the current state of the preload process.
function wpsc_ajax_get_preload_status() {
$preload_status = wpsc_get_preload_status( true );
wp_send_json_success( $preload_status );
add_action( 'wp_ajax_wpsc_get_preload_status', 'wpsc_ajax_get_preload_status' );
* Returns the location of the preload status file.
function wpsc_get_preload_status_file_path() {
return $cache_path . 'preload_permalink.txt';
* Get the timestamp of the next preload.
function wpsc_get_next_preload_time() {
$next = wp_next_scheduled( 'wp_cache_preload_hook' );
$next = wp_next_scheduled( 'wp_cache_full_preload_hook' );
* Read the preload status. Caches the result in a static variable.
function wpsc_get_preload_status( $include_next = false ) {
$filename = wpsc_get_preload_status_file_path();
if ( file_exists( $filename ) ) {
$data = wp_json_file_decode( $filename, array( 'associative' => true ) );
if ( is_array( $data ) ) {
$status['next'] = wpsc_get_next_preload_time();
* Update the preload status file during a preload.
function wpsc_update_active_preload( $group = null, $progress = null, $url = null ) {
$preload_status = wpsc_get_preload_status();
$preload_status['running'] = true;
// Add the new entry to the history.
$preload_status['history'],
// Limit to 5 in the history.
$preload_status['history'] = array_slice( $preload_status['history'], 0, 5 );
$filename = wpsc_get_preload_status_file_path();
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
if ( false === file_put_contents( $filename, wp_json_encode( $preload_status ) ) ) {
wp_cache_debug( "wpsc_update_active_preload: failed to write to $filename" );
* Update the preload status to indicate it is idle. If a finish time is specified, store it.
function wpsc_update_idle_preload( $finish_time = null ) {
$preload_status = wpsc_get_preload_status();
$preload_status['running'] = false;
$preload_status['history'] = array();
if ( ! empty( $finish_time ) ) {
$preload_status['previous'] = $finish_time;
$filename = wpsc_get_preload_status_file_path();
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
if ( false === file_put_contents( $filename, wp_json_encode( $preload_status ) ) ) {
wp_cache_debug( "wpsc_update_idle_preload: failed to write to $filename" );
function wp_cron_preload_cache() {
global $wpdb, $wp_cache_preload_interval, $wp_cache_preload_posts, $wp_cache_preload_email_me, $wp_cache_preload_email_volume, $cache_path, $wp_cache_preload_taxonomies;
// check if stop_preload.txt exists and preload should be stopped.
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
if ( @file_exists( $cache_path . 'stop_preload.txt' ) ) {
wp_cache_debug( 'wp_cron_preload_cache: preload cancelled. Aborting preload.' );
wpsc_reset_preload_settings();
* The mutex file is used to prevent multiple preload processes from running at the same time.
* If the mutex file is found, the preload process will wait 3-8 seconds and then check again.
* If the mutex file is still found, the preload process will abort.
* If the mutex file is not found, the preload process will create the mutex file and continue.
* The mutex file is deleted at the end of the preload process.
* The mutex file is deleted if it is more than 10 minutes old.
* The mutex file should only be deleted by the preload process that created it.
* If the mutex file is deleted by another process, another preload process may start.
$mutex = $cache_path . "preload_mutex.tmp";
if ( @file_exists( $mutex ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
sleep( 3 + wp_rand( 1, 5 ) );
// check again just in case another preload process is still running.
if ( @file_exists( $mutex ) && @filemtime( $mutex ) > ( time() - 600 ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
wp_cache_debug( 'wp_cron_preload_cache: preload mutex found and less than 600 seconds old. Aborting preload.', 1 );
wp_cache_debug( 'wp_cron_preload_cache: old preload mutex found and deleted. Preload continues.', 1 );
$fp = @fopen( $mutex, 'w' );
$counter = get_option( 'preload_cache_counter' );
if ( $wp_cache_preload_email_volume == 'none' && $wp_cache_preload_email_me == 1 ) {
$wp_cache_preload_email_me = 0;
wp_cache_setting( 'wp_cache_preload_email_me', 0 );
$just_started_preloading = false;
* Preload taxonomies first.
if ( isset( $wp_cache_preload_taxonomies ) && $wp_cache_preload_taxonomies ) {
wp_cache_debug( 'wp_cron_preload_cache: doing taxonomy preload.', 5 );
$taxonomies = apply_filters(
'wp_cache_preload_taxonomies',
'category' => 'category',
$preload_more_taxonomies = false;
foreach ( $taxonomies as $taxonomy => $path ) {
$taxonomy_filename = $cache_path . 'taxonomy_' . $taxonomy . '.txt';
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
if ( false === @file_exists( $taxonomy_filename ) ) {
if ( ! $just_started_preloading && $wp_cache_preload_email_me ) {
// translators: 1: site url
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%1$s] Cache Preload Started', 'wp-super-cache' ), home_url(), '' ), ' ' );
$just_started_preloading = true;
$records = get_terms( $taxonomy );
foreach ( $records as $term ) {
$out .= get_term_link( $term ) . "\n";
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
$fp = fopen( $taxonomy_filename, 'w' );
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose