Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 2099
0.00% covered (danger)
0.00%
0 / 88
CRAP
n/a
0 / 0
gzip_accepted
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
setup_blog_cache_dir
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
get_wp_cache_key
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
wpsc_parse_partial_url
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
wpsc_remove_tracking_params_from_uri
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
132
wp_super_cache_init
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
wp_cache_serve_cache_file
0.00% covered (danger)
0.00%
0 / 180
0.00% covered (danger)
0.00%
0 / 1
5852
wp_cache_get_legacy_cache
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_postload
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
wp_cache_late_loader
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
wpsc_get_auth_cookies
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 1
342
wpsc_get_accept_header
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
42
wp_cache_get_cookies_values
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
132
add_cacheaction
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
do_cacheaction
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
42
wp_cache_mobile_group
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
30
wp_cache_check_mobile
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
342
wp_cache_debug
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
240
wpsc_dump_get_request
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
wpsc_is_backend
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
132
get_supercache_dir
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
get_current_url_supercache_dir
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
240
wpsc_rebuild_files
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wpsc_get_realpath
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
30
wpsc_is_in_cache_directory
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
wpsc_delete_files
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
272
get_all_supercache_filenames
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
156
wpsc_is_https
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
20
supercache_filename
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
get_oc_version
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
reset_oc_version
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
get_oc_key
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wp_supercache_cache_for_admins
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
110
wpsc_is_caching_user_disabled
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
wp_cache_confirm_delete
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
72
wpsc_deep_replace
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
wpsc_get_protected_directories
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
wpsc_debug_username
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
wpsc_create_debug_log
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
30
wpsc_delete_url_cache
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
is_writeable_ACLSafe
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
90
wp_cache_setting
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
42
wp_cache_replace_line
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
812
wpsc_shutdown_message
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
wp_cache_phase2
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
380
wpsc_register_post_hooks
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
30
wpcache_do_rebuild
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
342
wpcache_logged_in_message
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_user_agent_is_rejected
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
56
wp_cache_get_response_headers
0.00% covered (danger)
0.00%
0 / 66
0.00% covered (danger)
0.00%
0 / 1
56
wpsc_is_rejected_cookie
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
wp_cache_is_rejected
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
72
wp_cache_mutex_init
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
72
wp_cache_writers_entry
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
42
wp_cache_writers_exit
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
56
wp_super_cache_query_vars
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
552
wpsc_catch_status_header
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
wpsc_catch_http_status_code
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
wpsc_is_fatal_error
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
wp_cache_ob_callback
0.00% covered (danger)
0.00%
0 / 102
0.00% covered (danger)
0.00%
0 / 1
4970
wp_cache_append_tag
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
42
wp_cache_add_to_buffer
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
wp_cache_maybe_dynamic
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
wp_cache_get_ob
0.00% covered (danger)
0.00%
0 / 229
0.00% covered (danger)
0.00%
0 / 1
8010
wp_cache_phase2_clean_cache
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
56
prune_super_cache
0.00% covered (danger)
0.00%
0 / 66
0.00% covered (danger)
0.00%
0 / 1
1190
wp_cache_rebuild_or_delete
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
210
wp_cache_phase2_clean_expired
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
272
wp_cache_shutdown_callback
0.00% covered (danger)
0.00%
0 / 90
0.00% covered (danger)
0.00%
0 / 1
1332
wp_cache_no_postid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_get_postid_from_comment
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
380
wp_cache_clear_cache_on_menu
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_clear_cache
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
wpsc_delete_post_archives
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
210
wpsc_delete_cats_tags
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
wpsc_post_transition
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
156
wp_cache_post_edit
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
72
wp_cache_post_id_gc
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
wp_cache_post_change
0.00% covered (danger)
0.00%
0 / 89
0.00% covered (danger)
0.00%
0 / 1
1260
wp_cache_microtime_diff
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_post_id
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
110
maybe_stop_gc
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
get_gc_flag
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
wp_cache_gc_cron
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
72
schedule_wp_gc
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
210
wp_cache_gc_watcher
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
wpsc_is_get_query
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
wpsc_apache_request_headers
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2/*
3 * WP Super Cache Phase 2 file.
4 * This file is included by the files wp-cache.php and wp-cache-phase1.php
5 * It has all the code for caching and serving requests.
6 */
7
8// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- TODO: Fix or determine for sure that these should not be fixed.
9// phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- TODO: Fix or determine for sure that these should not be fixed.
10
11function gzip_accepted() {
12    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
13        return false;
14    }
15
16    if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) || ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) && strpos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) === false ) ) {
17        return false;
18    }
19    return 'gzip';
20}
21
22function setup_blog_cache_dir() {
23    global $blog_cache_dir, $cache_path;
24    if ( false == @is_dir( $blog_cache_dir ) ) {
25        @mkdir( $cache_path . 'blogs' );
26        @mkdir( $blog_cache_dir );
27    }
28
29    if ( false == @is_dir( $blog_cache_dir . 'meta' ) ) {
30        @mkdir( $blog_cache_dir . 'meta' );
31    }
32}
33
34function get_wp_cache_key( $url = false ) {
35    global $wp_cache_request_uri, $wp_cache_gzip_encoding, $WPSC_HTTP_HOST;
36    if ( ! $url ) {
37        $url = $wp_cache_request_uri;
38    }
39    $server_port = isset( $_SERVER['SERVER_PORT'] ) ? intval( $_SERVER['SERVER_PORT'] ) : 0;
40
41    // Prepare a tag to include in the cache key if the request is anything other than text/html
42    $accept = wpsc_get_accept_header();
43    if ( $accept === 'text/html' ) {
44        $accept_tag = '';
45    } else {
46        $accept_tag = '-' . $accept;
47    }
48
49    return do_cacheaction(
50        'wp_cache_key',
51        // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
52        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 )
53    );
54}
55
56/**
57 * Parse a partial URL (only the path and query components).
58 *
59 * @param string $partial_uri - The path and query component of a URI to parse.
60 */
61function wpsc_parse_partial_url( $partial_uri ) {
62    global $WPSC_HTTP_HOST;
63
64    $scheme = wpsc_is_https() ? 'https://' : 'http://';
65    return parse_url( $scheme . $WPSC_HTTP_HOST . $partial_uri );
66}
67
68function wpsc_remove_tracking_params_from_uri( $uri ) {
69    global $wpsc_tracking_parameters, $wpsc_ignore_tracking_parameters;
70
71    if ( ! isset( $wpsc_ignore_tracking_parameters ) || ! $wpsc_ignore_tracking_parameters ) {
72        return $uri;
73    }
74
75    if ( ! isset( $wpsc_tracking_parameters ) || empty( $wpsc_tracking_parameters ) ) {
76        return $uri;
77    }
78
79    $parsed_url = wpsc_parse_partial_url( $uri );
80    $query      = array();
81
82    if ( isset( $parsed_url['query'] ) ) {
83        parse_str( $parsed_url['query'], $query );
84        foreach ( $wpsc_tracking_parameters as $param_name ) {
85            unset( $query[ $param_name ] );
86            unset( $_GET[ $param_name ] );
87        }
88    }
89    $path  = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
90    $query = ! empty( $query ) ? '?' . http_build_query( $query ) : '';
91
92    if ( empty( $_GET ) ) {
93        $_SERVER['REQUEST_URI'] = strtok( $_SERVER['REQUEST_URI'], '?' );
94    }
95
96    if ( $uri !== $path . $query ) {
97        wp_cache_debug( 'Removed tracking parameters from URL. Returning ' . $path . $query );
98    }
99
100    return $path . $query;
101}
102
103function wp_super_cache_init() {
104    global $wp_cache_key, $key, $blogcacheid, $file_prefix, $blog_cache_dir, $meta_file, $cache_file, $cache_filename, $meta_pathname;
105
106    $wp_cache_key = get_wp_cache_key();
107    $key          = $blogcacheid . md5( $wp_cache_key );
108    $wp_cache_key = $blogcacheid . $wp_cache_key;
109
110    $cache_filename = $file_prefix . $key . '.php';
111    $meta_file      = $file_prefix . $key . '.php';
112
113    $cache_file = wpsc_get_realpath( $blog_cache_dir );
114
115    if ( $cache_file ) {
116        $cache_file .= '/' . $cache_filename;
117    }
118
119    $meta_pathname = wpsc_get_realpath( $blog_cache_dir . 'meta/' );
120
121    if ( $meta_pathname ) {
122        $meta_pathname .= '/' . $meta_file;
123    }
124
125    return compact( 'key', 'cache_filename', 'meta_file', 'cache_file', 'meta_pathname' );
126}
127
128function wp_cache_serve_cache_file() {
129    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;
130    global $cache_compression, $wp_cache_slash_check, $wp_supercache_304, $wp_cache_home_path, $wp_cache_no_cache_for_get;
131    global $wp_cache_disable_utf8, $wp_cache_mfunc_enabled, $wpsc_served_header;
132
133    if ( wpsc_is_backend() ) {
134        wp_cache_debug( 'Not serving wp-admin requests.', 5 );
135        return false;
136    }
137
138    if ( $wp_cache_no_cache_for_get && wpsc_is_get_query() ) {
139        wp_cache_debug( 'Non empty GET request. Caching disabled on settings page. ' . wpsc_dump_get_request(), 1 );
140        return false;
141    }
142
143    if ( defined( 'WPSC_SERVE_DISABLED' ) ) {
144        wp_cache_debug( 'wp_cache_serve_cache_file: WPSC_SERVE_DISABLED defined. Not serving cached files.' );
145        return false;
146    }
147
148    if ( wpsc_get_accept_header() !== 'text/html' ) {
149        wp_cache_debug( 'wp_cache_serve_cache_file: visitor does not accept text/html. Not serving cached file.' );
150        return false;
151    }
152
153    extract( wp_super_cache_init() ); // $key, $cache_filename, $meta_file, $cache_file, $meta_pathname
154
155    // Look for wp-cache file + meta file for the current URL
156    // If we can't find them, we will look for supercache html files. These files don't have any meta data
157    // which is why the code below does more work setting up the headers, etc.
158    if (
159        ! defined( 'WPSC_SUPERCACHE_ONLY' ) &&
160        (
161            ( $cache_file && file_exists( $cache_file ) ) ||
162            file_exists( get_current_url_supercache_dir() . 'meta-' . $cache_filename )
163        )
164    ) {
165        if ( file_exists( get_current_url_supercache_dir() . 'meta-' . $cache_filename ) ) {
166            $cache_file    = get_current_url_supercache_dir() . $cache_filename;
167            $meta_pathname = get_current_url_supercache_dir() . 'meta-' . $cache_filename;
168        } elseif ( ! file_exists( $cache_file ) ) {
169            wp_cache_debug( 'wp_cache_serve_cache_file: found cache file but then it disappeared!' );
170            return false;
171        }
172
173        if ( ! $meta_pathname ) {
174            wp_cache_debug( 'wp_cache_serve_cache_file: meta pathname is empty. Could not load wp-cache meta file.' );
175            return true;
176        }
177
178        wp_cache_debug( "wp-cache file exists: $cache_file", 5 );
179        if ( ! ( $meta = json_decode( wp_cache_get_legacy_cache( $meta_pathname ), true ) ) ) {
180            wp_cache_debug( "couldn't load wp-cache meta file", 5 );
181            return true;
182        }
183        if ( is_array( $meta ) == false ) {
184            wp_cache_debug( "meta array corrupt, deleting $meta_pathname and $cache_file", 1 );
185            @unlink( $meta_pathname );
186            @unlink( $cache_file );
187            return true;
188        }
189    } else { // no wp-cache file, look for a supercache file
190        global $wpsc_save_headers;
191        global $cache_max_time;
192        // last chance, check if a supercache file exists. Just in case .htaccess rules don't work on this host
193        $file = get_current_url_supercache_dir() . supercache_filename();
194        if ( false == file_exists( $file ) ) {
195            wp_cache_debug( "No Super Cache file found for current URL: $file" );
196            return false;
197        } elseif ( wpsc_is_get_query() ) {
198            wp_cache_debug( 'GET array not empty. Cannot serve a supercache file. ' . wpsc_dump_get_request() );
199            return false;
200        } elseif ( wp_cache_get_cookies_values() != '' ) {
201            wp_cache_debug( 'Cookies found. Cannot serve a supercache file. ' . wp_cache_get_cookies_values() );
202            return false;
203        } elseif ( wpsc_get_accept_header() !== 'text/html' ) {
204            wp_cache_debug( 'Accept header is not text/html. Cannot serve supercache file.' . wp_cache_get_cookies_values() );
205            return false;
206        } elseif ( isset( $wpsc_save_headers ) && $wpsc_save_headers ) {
207            wp_cache_debug( 'Saving headers. Cannot serve a supercache file.' );
208            return false;
209        } elseif ( $cache_max_time > 0 && ( filemtime( $file ) + $cache_max_time ) < time() ) {
210            wp_cache_debug( sprintf( 'Cache has expired and is older than %d seconds old.', $cache_max_time ) );
211            return false;
212        }
213
214        if ( isset( $wp_cache_mfunc_enabled ) == false ) {
215            $wp_cache_mfunc_enabled = 0;
216        }
217
218        if ( false == isset( $wp_cache_home_path ) ) {
219            $wp_cache_home_path = '/';
220        }
221
222        // make sure ending slashes are ok
223        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 ) != '/' ) ) {
224
225            if ( $wp_cache_mfunc_enabled == 0 ) {
226                // get data from file
227                if ( $wp_cache_gzip_encoding ) {
228                    if ( file_exists( $file . '.gz' ) ) {
229                        $cachefiledata = file_get_contents( $file . '.gz' );
230
231                        if ( false === $cachefiledata ) {
232                            wp_cache_debug( 'The cached gzip file could not be read. Must generate a new one.' );
233                            return false;
234                        }
235
236                        wp_cache_debug( "Fetched gzip static page data from supercache file using PHP. File: $file.gz" );
237                    } else {
238                        $cachefiledata = file_get_contents( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
239
240                        if ( false === $cachefiledata ) {
241                            wp_cache_debug( 'The cached file could not be read. Must generate a new one.' );
242                            return false;
243                        }
244
245                        $cachefiledata = gzencode( $cachefiledata, 6, FORCE_GZIP );
246                        wp_cache_debug( "Fetched static page data from supercache file using PHP and gzipped it. File: $file" );
247                    }
248                } else {
249                    $cachefiledata = file_get_contents( $file );
250
251                    if ( false === $cachefiledata ) {
252                        wp_cache_debug( 'The cached file could not be read. Must generate a new one.' );
253                        return false;
254                    }
255
256                    wp_cache_debug( "Fetched static page data from supercache file using PHP. File: $file" );
257                }
258            } else {
259                // get dynamic data from filtered file
260                $cachefiledata = file_get_contents( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
261
262                if ( false === $cachefiledata ) {
263                    wp_cache_debug( 'The cached file could not be read. Must generate a new one.' );
264                    return false;
265                }
266
267                $cachefiledata = do_cacheaction( 'wpsc_cachedata', $cachefiledata );
268                if ( $wp_cache_gzip_encoding ) {
269                    $cachefiledata = gzencode( $cachefiledata, 6, FORCE_GZIP );
270                    wp_cache_debug( "Fetched dynamic page data from supercache file using PHP and gzipped it. File: $file" );
271                } else {
272                    wp_cache_debug( "Fetched dynamic page data from supercache file using PHP. File: $file" );
273                }
274            }
275
276            if ( isset( $wp_cache_disable_utf8 ) == false || $wp_cache_disable_utf8 == 0 ) {
277                header( 'Content-type: text/html; charset=UTF-8' );
278            }
279
280            if ( defined( 'WPSC_VARY_HEADER' ) ) {
281                if ( WPSC_VARY_HEADER != '' ) {
282                    header( 'Vary: ' . WPSC_VARY_HEADER );
283                }
284            } else {
285                header( 'Vary: Accept-Encoding, Cookie' );
286            }
287            if ( defined( 'WPSC_CACHE_CONTROL_HEADER' ) ) {
288                if ( WPSC_CACHE_CONTROL_HEADER != '' ) {
289                    header( 'Cache-Control: ' . WPSC_CACHE_CONTROL_HEADER );
290                }
291            } else {
292                header( 'Cache-Control: max-age=3, must-revalidate' );
293            }
294            $size = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $cachefiledata, '8bit' ) : strlen( $cachefiledata );
295            if ( $wp_cache_gzip_encoding ) {
296                if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
297                    header( 'X-WP-Super-Cache: Served supercache gzip file from PHP' );
298                }
299                header( 'Content-Encoding: ' . $wp_cache_gzip_encoding );
300                header( 'Content-Length: ' . $size );
301            } elseif ( $wp_supercache_304 ) {
302                if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
303                    header( 'X-WP-Super-Cache: Served supercache 304 file from PHP' );
304                }
305                header( 'Content-Length: ' . $size );
306            } elseif ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
307                header( 'X-WP-Super-Cache: Served supercache file from PHP' );
308            }
309
310            // don't try to match modified dates if using dynamic code.
311            if ( $wp_cache_mfunc_enabled == 0 && $wp_supercache_304 ) {
312                wp_cache_debug( 'wp_cache_serve_cache_file: checking age of cached vs served files.' );
313                $headers         = wpsc_apache_request_headers();
314                $remote_mod_time = isset( $headers['If-Modified-Since'] ) ? $headers['If-Modified-Since'] : null;
315
316                if ( $remote_mod_time === null && isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
317                    $remote_mod_time = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
318                }
319
320                $local_mod_time = gmdate( 'D, d M Y H:i:s', filemtime( $file ) ) . ' GMT';
321                if ( $remote_mod_time !== null && $remote_mod_time == $local_mod_time ) {
322                    wp_cache_debug( 'wp_cache_serve_cache_file: Send 304 Not Modified header.' );
323                    header( $_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified' );
324                    exit( 0 );
325                } else {
326                    wp_cache_debug( 'wp_cache_serve_cache_file: 304 browser caching not possible as timestamps differ.' );
327                }
328                header( 'Last-Modified: ' . $local_mod_time );
329            }
330
331            echo $cachefiledata;
332            exit( 0 );
333        } else {
334            wp_cache_debug( 'No wp-cache file exists. Must generate a new one.' );
335            return false;
336        }
337    }
338
339    $cache_file = do_cacheaction( 'wp_cache_served_cache_file', $cache_file );
340    // Sometimes the gzip headers are lost. Make sure html returned isn't compressed!
341    $do_not_serve_gzip_data = true;
342    if ( $cache_compression && $wp_cache_gzip_encoding ) {
343        if ( ! in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $meta['headers'], true ) ) {
344            wp_cache_debug( 'GZIP headers not found. Force uncompressed output.' );
345        } else {
346            $do_not_serve_gzip_data = false;
347            if ( isset( $meta['dynamic'] ) ) {
348                unset( $meta['headers']['Content-Length'] ); // this is set later after the output data is compressed
349            }
350            wp_cache_debug( 'GZIP headers found. Serving compressed output.' );
351        }
352    }
353
354    foreach ( $meta['headers'] as $t => $header ) {
355        // 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/
356        if ( strpos( $header, 'Last-Modified:' ) === false ) {
357            header( $header );
358            wp_cache_debug( 'Sending Header: ' . $header );
359        }
360    }
361    if ( isset( $wpsc_served_header ) && $wpsc_served_header ) {
362        header( 'X-WP-Super-Cache: Served WPCache cache file' );
363    }
364    if ( isset( $meta['dynamic'] ) ) {
365        wp_cache_debug( 'Serving wp-cache dynamic file', 5 );
366        if ( $do_not_serve_gzip_data ) {
367            // attempt to uncompress the cached file just in case it's gzipped
368            $cache        = wp_cache_get_legacy_cache( $cache_file );
369            $uncompressed = @gzuncompress( $cache );
370            if ( $uncompressed ) {
371                wp_cache_debug( 'Uncompressed gzipped cache from wp-cache: ' . $cache_file );
372                $cache = $uncompressed;
373                unset( $uncompressed );
374            }
375            $cache = do_cacheaction( 'wpsc_cachedata', $cache );
376        } else {
377            wp_cache_debug( 'Compressed cache data from wp-cache: ' . $cache_file );
378            $cache = gzencode(
379                do_cacheaction(
380                    'wpsc_cachedata',
381                    wp_cache_get_legacy_cache( $cache_file )
382                ),
383                6,
384                FORCE_GZIP
385            );
386            $size  = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $cache, '8bit' ) : strlen( $cache );
387            wp_cache_debug( 'Sending Header: Content-Length: ' . $size );
388            header( 'Content-Length: ' . $size );
389        }
390    } elseif ( $do_not_serve_gzip_data ) {
391        $cache        = wp_cache_get_legacy_cache( $cache_file );
392        $uncompressed = @gzuncompress( $cache ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- there is a small chance the cache isn't gzipped despite being configured to be.
393        if ( $uncompressed ) {
394            $cache = $uncompressed;
395            unset( $uncompressed );
396            wp_cache_debug( 'Uncompressed gzipped cache data from wp-cache file: ' . $cache_file );
397        } else {
398            wp_cache_debug( 'Sending already uncompressed cache file from wp-cache to browser: ' . $cache_file );
399        }
400    } else {
401        wp_cache_debug( 'Sending wp-cache file to browser: ' . $cache_file );
402        $cache = wp_cache_get_legacy_cache( $cache_file );
403    }
404    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- this is the cached version of the current page. It will have been escaped already.
405    echo $cache;
406    wp_cache_debug( 'exit request', 5 );
407    die( 0 );
408}
409
410function wp_cache_get_legacy_cache( $cache_file ) {
411    return substr( @file_get_contents( $cache_file ), 15 );
412}
413
414function wp_cache_postload() {
415    global $cache_enabled, $wp_super_cache_late_init;
416    global $wp_cache_request_uri;
417
418    if ( empty( $wp_cache_request_uri ) ) {
419        wp_cache_debug( 'wp_cache_postload: no request uri configured. Not running.' );
420        return false;
421    }
422
423    // have to sanitize here because formatting.php is loaded after wp_cache_request_uri is set
424    $wp_cache_request_uri = esc_url_raw( wp_unslash( $wp_cache_request_uri ) );
425
426    if ( ! $cache_enabled ) {
427        return true;
428    }
429
430    if ( isset( $wp_super_cache_late_init ) && true == $wp_super_cache_late_init ) {
431        wp_cache_debug( 'Supercache Late Init: add wp_cache_serve_cache_file to init', 3 );
432        add_action( 'init', 'wp_cache_late_loader', 9999 );
433    } else {
434        wp_super_cache_init();
435        wp_cache_phase2();
436    }
437}
438
439function wp_cache_late_loader() {
440    wp_cache_debug( 'Supercache Late Loader running on init', 3 );
441    wp_cache_serve_cache_file();
442    wp_cache_phase2();
443}
444
445function wpsc_get_auth_cookies() {
446    static $cached_cookies;
447
448    if ( isset( $cached_cookies ) && is_array( $cached_cookies ) ) {
449        return $cached_cookies;
450    }
451
452    $cookies = array_keys( $_COOKIE );
453    if ( empty( $cookies ) ) {
454        return array();
455    }
456
457    $auth_cookies      = array();
458    $duplicate_cookies = array();
459
460    $wp_cookies = array(
461        'AUTH_COOKIE'        => 'wordpress_',
462        'SECURE_AUTH_COOKIE' => 'wordpress_sec_',
463        'LOGGED_IN_COOKIE'   => 'wordpress_logged_in_',
464    );
465
466    foreach ( $wp_cookies as $cookie_const => $cookie_prefix ) {
467        $cookie_key = strtolower( $cookie_const );
468
469        if ( defined( $cookie_const ) ) {
470            if ( in_array( constant( $cookie_const ), $cookies, true ) ) {
471                $auth_cookies[ $cookie_key ] = constant( $cookie_const );
472            }
473
474            continue;
475        }
476
477        $found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
478
479        if ( count( $found_cookies ) === 1 ) {
480            $auth_cookies[ $cookie_key ] = reset( $found_cookies );
481        } elseif ( count( $found_cookies ) > 1 ) {
482            $duplicate_cookies           = array_merge( $duplicate_cookies, $found_cookies );
483            $auth_cookies[ $cookie_key ] = $found_cookies;
484        }
485    }
486
487    $cookie_hash   = defined( 'COOKIEHASH' ) ? COOKIEHASH : '';
488    $other_cookies = array(
489        'comment_cookie'  => 'comment_author_',
490        'postpass_cookie' => 'wp-postpass_',
491    );
492
493    foreach ( $other_cookies as $cookie_key => $cookie_prefix ) {
494
495        if ( $cookie_hash ) {
496            if ( in_array( $cookie_prefix . $cookie_hash, $cookies, true ) ) {
497                $auth_cookies[ $cookie_key ] = $cookie_prefix . $cookie_hash;
498            }
499
500            continue;
501        }
502
503        $found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
504
505        if ( count( $found_cookies ) === 1 ) {
506            $auth_cookies[ $cookie_key ] = reset( $found_cookies );
507        } elseif ( count( $found_cookies ) > 1 ) {
508            $duplicate_cookies           = array_merge( $duplicate_cookies, $found_cookies );
509            $auth_cookies[ $cookie_key ] = $found_cookies;
510        }
511    }
512
513    if ( ! $duplicate_cookies ) {
514        $cached_cookies = $auth_cookies;
515    }
516
517    if ( empty( $auth_cookies ) ) {
518        wp_cache_debug( 'wpsc_get_auth_cookies: no auth cookies detected', 5 );
519    } elseif ( $duplicate_cookies ) {
520        wp_cache_debug( 'wpsc_get_auth_cookies: duplicate cookies detected( ' . implode( ', ', $duplicate_cookies ) . ' )', 5 );
521    } else {
522        wp_cache_debug( 'wpsc_get_auth_cookies: cookies detected: ' . implode( ', ', $auth_cookies ), 5 );
523    }
524
525    return $auth_cookies;
526}
527
528/**
529 * Returns a string containing a sanitized version of the Accept header.
530 * For now, this can only respond with `text/html` or `application/json` -
531 * used to differentiate between pages which may or may not be cacheable.
532 */
533function wpsc_get_accept_header() {
534    static $accept = 'N/A';
535
536    if ( $accept === 'N/A' ) {
537        $accept_headers = apply_filters( 'wpsc_accept_headers', array( 'application/json', 'application/activity+json', 'application/ld+json' ) );
538        $accept_headers = array_map( 'strtolower', $accept_headers );
539        // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
540        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- $accept is checked and set below.
541        $accept = isset( $_SERVER['HTTP_ACCEPT'] ) ? strtolower( filter_var( $_SERVER['HTTP_ACCEPT'] ) ) : '';
542
543        foreach ( $accept_headers as $header ) {
544            if ( str_contains( $accept, $header ) ) {
545                $accept = 'application/json';
546            }
547        }
548
549        if ( $accept !== 'application/json' ) {
550            $accept = 'text/html';
551        }
552
553        wp_cache_debug( 'ACCEPT: ' . $accept );
554    }
555
556    return $accept;
557}
558
559function wp_cache_get_cookies_values() {
560    global $wpsc_cookies;
561    static $string = '';
562
563    if ( $string != '' ) {
564        wp_cache_debug( "wp_cache_get_cookies_values: cached: $string" );
565        return $string;
566    }
567
568    if ( defined( 'COOKIEHASH' ) ) {
569        $cookiehash = preg_quote( constant( 'COOKIEHASH' ) );
570    } else {
571        $cookiehash = '';
572    }
573    $regex = "/^wp-postpass_$cookiehash|^comment_author_$cookiehash";
574    if ( defined( 'LOGGED_IN_COOKIE' ) ) {
575        $regex .= '|^' . preg_quote( constant( 'LOGGED_IN_COOKIE' ) );
576    } else {
577        $regex .= "|^wordpress_logged_in_$cookiehash";
578    }
579    $regex .= '/';
580    while ( $key = key( $_COOKIE ) ) {
581        if ( preg_match( $regex, $key ) ) {
582            wp_cache_debug( 'wp_cache_get_cookies_values: Login/postpass cookie detected' );
583            $string .= $_COOKIE[ $key ] . ',';
584        }
585        next( $_COOKIE );
586    }
587    reset( $_COOKIE );
588
589    // If you use this hook, make sure you update your .htaccess rules with the same conditions
590    $string = do_cacheaction( 'wp_cache_get_cookies_values', $string );
591
592    if (
593        isset( $wpsc_cookies ) &&
594        is_array( $wpsc_cookies )
595    ) {
596        foreach ( $wpsc_cookies as $name ) {
597            if ( isset( $_COOKIE[ $name ] ) ) {
598                wp_cache_debug( "wp_cache_get_cookies_values - found extra cookie: $name" );
599                $string .= $name . '=' . $_COOKIE[ $name ] . ',';
600            }
601        }
602    }
603
604    if ( $string != '' ) {
605        $string = md5( $string );
606    }
607
608    wp_cache_debug( "wp_cache_get_cookies_values: return: $string", 5 );
609    return $string;
610}
611
612function add_cacheaction( $action, $func ) {
613    global $wp_supercache_actions;
614    $wp_supercache_actions[ $action ][] = $func;
615}
616
617function do_cacheaction( $action, $value = '' ) {
618    global $wp_supercache_actions;
619
620    if ( ! isset( $wp_supercache_actions ) || ! is_array( $wp_supercache_actions ) ) {
621        return $value;
622    }
623
624    if ( array_key_exists( $action, $wp_supercache_actions ) && is_array( $wp_supercache_actions[ $action ] ) ) {
625        $actions = $wp_supercache_actions[ $action ];
626        foreach ( $actions as $func ) {
627            $value = call_user_func_array( $func, array( $value ) );
628        }
629    }
630
631    return $value;
632}
633
634function wp_cache_mobile_group( $user_agent ) {
635    global $wp_cache_mobile_groups;
636    foreach ( (array) $wp_cache_mobile_groups as $name => $group ) {
637        foreach ( (array) $group as $browser ) {
638            $browser = trim( strtolower( $browser ) );
639            if ( $browser != '' && strstr( $user_agent, $browser ) ) {
640                return $browser;
641            }
642        }
643    }
644    return 'mobile';
645}
646
647// From https://wordpress.org/plugins/wordpress-mobile-edition/ by Alex King
648function wp_cache_check_mobile( $cache_key ) {
649    global $wp_cache_mobile_enabled, $wp_cache_mobile_browsers, $wp_cache_mobile_prefixes;
650    if ( ! isset( $wp_cache_mobile_enabled ) || false == $wp_cache_mobile_enabled ) {
651        return $cache_key;
652    }
653
654    // a check of wp_is_mobile() should be added here, but if the Jetpack WPSC plugin
655    // is enabled, jetpack_is_mobile() is used through the wp_cache_check_mobile action.
656
657    wp_cache_debug( "wp_cache_check_mobile: $cache_key" );
658
659    // allow plugins to short circuit mobile check. Cookie, extra UA checks?
660    switch ( do_cacheaction( 'wp_cache_check_mobile', $cache_key ) ) {
661        case 'normal':
662            wp_cache_debug( 'wp_cache_check_mobile: desktop user agent detected by wp_cache_check_mobile action' );
663            return $cache_key;
664        break;
665        case 'mobile':
666            wp_cache_debug( 'wp_cache_check_mobile: mobile user agent detected by wp_cache_check_mobile action' );
667            return $cache_key . '-mobile';
668        break;
669    }
670
671    if ( ! isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
672        return $cache_key;
673    }
674
675    if ( do_cacheaction( 'disable_mobile_check', false ) ) {
676        wp_cache_debug( 'wp_cache_check_mobile: disable_mobile_check disabled mobile check' );
677        return $cache_key;
678    }
679
680    $browsers   = explode( ',', $wp_cache_mobile_browsers );
681    $user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
682    foreach ( $browsers as $browser ) {
683        if ( strstr( $user_agent, trim( strtolower( $browser ) ) ) ) {
684            wp_cache_debug( 'mobile browser detected: ' . $browser );
685            return $cache_key . '-' . wp_cache_mobile_group( $user_agent );
686        }
687    }
688    if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
689        return $cache_key . '-' . $_SERVER['HTTP_X_WAP_PROFILE'];
690    }
691    if ( isset( $_SERVER['HTTP_PROFILE'] ) ) {
692        return $cache_key . '-' . $_SERVER['HTTP_PROFILE'];
693    }
694
695    if ( isset( $wp_cache_mobile_prefixes ) ) {
696        $browsers = explode( ',', $wp_cache_mobile_prefixes );
697        foreach ( $browsers as $browser_prefix ) {
698            if ( substr( $user_agent, 0, 4 ) == $browser_prefix ) {
699                wp_cache_debug( 'mobile browser (prefix) detected: ' . $browser_prefix );
700                return $cache_key . '-' . $browser_prefix;
701            }
702        }
703    }
704    $accept = isset( $_SERVER['HTTP_ACCEPT'] ) ? strtolower( $_SERVER['HTTP_ACCEPT'] ) : '';
705    if ( str_contains( $accept, 'wap' ) ) {
706        return $cache_key . '-' . 'wap';
707    }
708
709    if ( isset( $_SERVER['ALL_HTTP'] ) && strpos( strtolower( $_SERVER['ALL_HTTP'] ), 'operamini' ) !== false ) {
710        return $cache_key . '-' . 'operamini';
711    }
712
713    return $cache_key;
714}
715
716/**
717 * Add a log message to the file, if debugging is turned on
718 *
719 * @param $message string The message that should be added to the log
720 * @param $level   int
721 */
722function wp_cache_debug( $message, $level = 1 ) {
723    global $wp_cache_debug_log, $cache_path, $wp_cache_debug_ip, $wp_super_cache_debug;
724    static $last_message = '';
725
726    if ( $last_message == $message ) {
727        return false;
728    }
729    $last_message = $message;
730
731    // If either of the debug or log globals aren't set, then we can stop
732    if ( ! isset( $wp_super_cache_debug )
733        || ! isset( $wp_cache_debug_log ) ) {
734        return false;
735    }
736
737    // If either the debug or log globals are false or empty, we can stop
738    if ( $wp_super_cache_debug == false
739        || $wp_cache_debug_log === '' ) {
740        return false;
741    }
742
743    // If the debug_ip has been set, but it doesn't match the ip of the requester
744    // then we can stop.
745    if ( isset( $wp_cache_debug_ip )
746        && $wp_cache_debug_ip !== ''
747        && ( ! isset( $_SERVER['REMOTE_ADDR'] ) || $wp_cache_debug_ip !== $_SERVER['REMOTE_ADDR'] ) ) {
748        return false;
749    }
750
751    // if cache path is gone, then don't log anything
752    if ( empty( $cache_path ) || ! is_dir( $cache_path ) ) {
753        return;
754    }
755
756    // Log message: Date URI Message
757    $log_message = date( 'H:i:s' ) . ' ' . getmypid() . " {$_SERVER['REQUEST_URI']} {$message}" . PHP_EOL;
758    // path to the log file in the cache folder
759    $log_file = $cache_path . str_replace( '/', '', str_replace( '..', '', $wp_cache_debug_log ) );
760
761    if ( ! file_exists( $log_file ) && function_exists( 'wpsc_create_debug_log' ) ) {
762        global $wp_cache_debug_username;
763        if ( ! isset( $wp_cache_debug_username ) ) {
764            $wp_cache_debug_username = '';
765        }
766
767        wpsc_create_debug_log( $wp_cache_debug_log, $wp_cache_debug_username );
768    }
769
770    error_log( $log_message, 3, $log_file );
771}
772
773function wpsc_dump_get_request() {
774    static $string;
775
776    if ( isset( $string ) ) {
777        return $string;
778    }
779
780    if ( function_exists( 'wp_json_encode' ) ) {
781        $string = wp_json_encode( $_GET, JSON_UNESCAPED_SLASHES ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
782    } else {
783        $string = json_encode( $_GET, JSON_UNESCAPED_SLASHES ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.WP.AlternativeFunctions.json_encode_json_encode
784    }
785
786    return $string;
787}
788
789function wpsc_is_backend() {
790    static $is_backend;
791
792    if ( isset( $is_backend ) ) {
793        return $is_backend;
794    }
795
796    $is_backend = is_admin();
797    if ( $is_backend ) {
798        return $is_backend;
799    }
800
801    $script = isset( $_SERVER['PHP_SELF'] ) ? basename( $_SERVER['PHP_SELF'] ) : '';
802    if ( $script !== 'index.php' ) {
803        if ( in_array( $script, array( 'wp-login.php', 'xmlrpc.php', 'wp-cron.php' ) ) ) {
804            $is_backend = true;
805        } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
806            $is_backend = true;
807        } elseif ( PHP_SAPI == 'cli' || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
808            $is_backend = true;
809        }
810    }
811
812    return $is_backend;
813}
814
815function get_supercache_dir( $blog_id = 0 ) {
816    global $cache_path;
817    if ( $blog_id == 0 ) {
818        $home = get_option( 'home' );
819    } else {
820        $home = get_blog_option( $blog_id, 'home' );
821    }
822    return trailingslashit( apply_filters( 'wp_super_cache_supercachedir', $cache_path . 'supercache/' . trailingslashit( strtolower( preg_replace( '/:.*$/', '', str_replace( 'http://', '', str_replace( 'https://', '', $home ) ) ) ) ) ) );
823}
824function get_current_url_supercache_dir( $post_id = 0 ) {
825    global $cached_direct_pages, $cache_path, $wp_cache_request_uri, $WPSC_HTTP_HOST, $wp_cache_home_path;
826    static $saved_supercache_dir = array();
827
828    if ( isset( $saved_supercache_dir[ $post_id ] ) ) {
829        return $saved_supercache_dir[ $post_id ];
830    }
831
832    $DONOTREMEMBER = 0;
833    if ( $post_id != 0 ) {
834        $site_url  = site_url();
835        $permalink = get_permalink( $post_id );
836        if ( ! str_contains( $permalink, $site_url ) ) {
837            /*
838             * Sometimes site_url doesn't return the siteurl. See https://wordpress.org/support/topic/wp-super-cache-not-refreshing-post-after-comments-made
839             */
840            $DONOTREMEMBER = 1;
841            wp_cache_debug( "get_current_url_supercache_dir: WARNING! site_url ($site_url) not found in permalink ($permalink).", 1 );
842            if ( preg_match( '`^(https?:)?//([^/]+)(/.*)?$`i', $permalink, $matches ) ) {
843                if ( $WPSC_HTTP_HOST != $matches[2] ) {
844                    wp_cache_debug( "get_current_url_supercache_dir: WARNING! SERVER_NAME ({$WPSC_HTTP_HOST}) not found in permalink ($permalink).", 1 );
845                }
846                wp_cache_debug( "get_current_url_supercache_dir: Removing SERVER_NAME ({$matches[2]}) from permalink ($permalink). Is the url right?", 1 );
847                $uri = isset( $matches[3] ) ? $matches[3] : '';
848            } elseif ( preg_match( '`^/([^/]+)(/.*)?$`i', $permalink, $matches ) ) {
849                wp_cache_debug( "get_current_url_supercache_dir: WARNING! Permalink ($permalink) looks as absolute path. Is the url right?", 1 );
850                $uri = $permalink;
851            } else {
852                wp_cache_debug( "get_current_url_supercache_dir: WARNING! Permalink ($permalink) could not be understood by parsing url. Using front page.", 1 );
853                $uri = '';
854            }
855        } else {
856            $uri = str_replace( $site_url, '', $permalink );
857            if ( ! str_starts_with( $uri, $wp_cache_home_path ) ) {
858                $uri = rtrim( $wp_cache_home_path, '/' ) . $uri;
859            }
860        }
861    } else {
862        $uri = strtolower( $wp_cache_request_uri );
863        $uri = preg_replace_callback(
864            '/%[a-f0-9]{2}/',
865            function ( $matches ) {
866                return strtoupper( $matches[0] );
867            },
868            $uri
869        );
870    }
871    $uri      = wpsc_deep_replace( array( '..', '\\', 'index.php' ), preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', preg_replace( '/(\?.*)?(#.*)?$/', '', $uri ) ) );
872    $hostname = $WPSC_HTTP_HOST;
873    // Get hostname from wp options for wp-cron, wp-cli and similar requests.
874    if ( empty( $hostname ) && function_exists( 'get_option' ) ) {
875        $hostname = (string) parse_url( get_option( 'home' ), PHP_URL_HOST );
876    }
877    $dir = preg_replace( '/:.*$/', '', $hostname ) . $uri; // To avoid XSS attacks
878    if ( function_exists( 'apply_filters' ) ) {
879        $dir = apply_filters( 'supercache_dir', $dir );
880    } else {
881        $dir = do_cacheaction( 'supercache_dir', $dir );
882    }
883    $dir = $cache_path . 'supercache/' . $dir . '/';
884    if ( is_array( $cached_direct_pages ) && in_array( $_SERVER['REQUEST_URI'], $cached_direct_pages ) ) {
885        $dir = ABSPATH . $uri . '/';
886    }
887    $dir = str_replace( '..', '', str_replace( '//', '/', $dir ) );
888    wp_cache_debug( "supercache dir: $dir", 5 );
889    if ( $DONOTREMEMBER == 0 ) {
890        $saved_supercache_dir[ $post_id ] = $dir;
891    }
892    return $dir;
893}
894
895/*
896 * Delete (or rebuild) all the files in one directory.
897 * Checks if it is in the cache directory but doesn't allow files in the following directories to be deleted:
898 * wp-content/cache/
899 * wp-content/cache/blogs/
900 * wp-content/cache/supercache/
901 *
902 */
903function wpsc_rebuild_files( $dir ) {
904    return wpsc_delete_files( $dir, false );
905}
906
907// realpath() doesn't always remove the trailing slash
908function wpsc_get_realpath( $directory ) {
909    if ( $directory == '/' ) {
910        wp_cache_debug( "wpsc_get_realpath: cannot get realpath of '/'" );
911        return false;
912    }
913
914    $original_dir = $directory;
915    $directory    = realpath( $directory );
916
917    if ( ! $directory ) {
918        wp_cache_debug( "wpsc_get_realpath: directory does not exist - $original_dir" );
919        return false;
920    }
921
922    if ( substr( $directory, -1 ) == '/' || substr( $directory, -1 ) == '\\' ) {
923        $directory = substr( $directory, 0, -1 ); // remove trailing slash
924    }
925
926    return $directory;
927}
928
929// return true if directory is in the cache directory
930function wpsc_is_in_cache_directory( $directory ) {
931    global $cache_path;
932    static $rp_cache_path = '';
933
934    if ( $directory == '' ) {
935        wp_cache_debug( 'wpsc_is_in_cache_directory: exiting as directory is blank' );
936        return false;
937    }
938
939    if ( $cache_path == '' ) {
940        wp_cache_debug( 'wpsc_is_in_cache_directory: exiting as cache_path is blank' );
941        return false;
942    }
943
944    if ( $rp_cache_path == '' ) {
945        $rp_cache_path = wpsc_get_realpath( $cache_path );
946    }
947
948    if ( ! $rp_cache_path ) {
949        wp_cache_debug( 'wpsc_is_in_cache_directory: exiting as cache_path directory does not exist' );
950        return false;
951    }
952
953    $directory = wpsc_get_realpath( $directory );
954
955    if ( ! $directory ) {
956        wp_cache_debug( 'wpsc_is_in_cache_directory: directory does not exist' );
957        return false;
958    }
959
960    if ( substr( $directory, 0, strlen( $rp_cache_path ) ) == $rp_cache_path ) {
961        return true;
962    } else {
963        return false;
964    }
965}
966
967function wpsc_delete_files( $dir, $delete = true ) {
968    global $cache_path;
969    static $protected = '';
970
971    if ( $dir == '' ) {
972        wp_cache_debug( 'wpsc_delete_files: directory is blank' );
973        return false;
974    }
975    wp_cache_debug( 'wpsc_delete_files: deleting ' . $dir );
976
977    // only do this once, this function will be called many times
978    if ( $protected == '' ) {
979        $protected = array( $cache_path, $cache_path . 'blogs/', $cache_path . 'supercache' );
980        foreach ( $protected as $id => $directory ) {
981            $protected[ $id ] = trailingslashit( wpsc_get_realpath( $directory ) );
982        }
983    }
984
985    $orig_dir = $dir;
986    $dir      = wpsc_get_realpath( $dir );
987    if ( ! $dir ) {
988        wp_cache_debug( 'wpsc_delete_files: directory does not exist: ' . $orig_dir );
989        return false;
990    }
991
992    $dir = trailingslashit( $dir );
993
994    if ( ! wpsc_is_in_cache_directory( $dir ) ) {
995        wp_cache_debug( 'wpsc_delete_files: directory is not in cache directory: ' . $dir );
996        return false;
997    }
998
999    if ( in_array( $dir, $protected ) ) {
1000        wp_cache_debug( 'wpsc_delete_files: directory is protected ' . $dir );
1001        return false;
1002    }
1003
1004    if ( is_dir( $dir ) && $dh = @opendir( $dir ) ) {
1005        while ( ( $file = readdir( $dh ) ) !== false ) {
1006            wp_cache_debug( 'wpsc_delete_files: reading files: ' . $file );
1007            if ( $file != '.' && $file != '..' && $file != '.htaccess' && is_file( $dir . $file ) ) {
1008                if ( $delete ) {
1009                    wp_cache_debug( 'wpsc_delete_files: deleting ' . $dir . $file );
1010                    @unlink( $dir . $file );
1011                } else {
1012                    wp_cache_debug( 'wpsc_delete_files: rebuild or delete ' . $dir . $file );
1013                    @wp_cache_rebuild_or_delete( $dir . $file );
1014                }
1015            }
1016        }
1017        closedir( $dh );
1018
1019        if ( $delete ) {
1020            wp_cache_debug( 'wpsc_delete_files: remove directory ' . $dir );
1021            @rmdir( $dir );
1022        }
1023    } else {
1024        wp_cache_debug( 'wpsc_delete_files: could not open directory ' . $dir );
1025    }
1026    return true;
1027}
1028
1029function get_all_supercache_filenames( $dir = '' ) {
1030    global $wp_cache_mobile_enabled, $cache_path;
1031
1032    $dir = wpsc_get_realpath( $dir );
1033    if ( ! $dir ) {
1034        wp_cache_debug( 'get_all_supercache_filenames: directory does not exist' );
1035        return array();
1036    }
1037
1038    if ( ! wpsc_is_in_cache_directory( $dir ) ) {
1039        return array();
1040    }
1041
1042    $filenames = array( 'index.html', 'index-https.html', 'index.html.php' );
1043
1044    if ( isset( $wp_cache_mobile_enabled ) && $wp_cache_mobile_enabled ) {
1045        // open directory and look for index-*.html files
1046        if ( is_dir( $dir ) && $dh = @opendir( $dir ) ) {
1047            while ( ( $file = readdir( $dh ) ) !== false ) {
1048                if ( substr( $file, 0, 6 ) == 'index-' && strpos( $file, '.html' ) ) {
1049                    $filenames[] = $file;
1050                }
1051            }
1052            closedir( $dh );
1053        }
1054    }
1055
1056    if ( function_exists( 'apply_filters' ) ) {
1057        $filenames = apply_filters( 'all_supercache_filenames', $filenames );
1058    } else {
1059        $filenames = do_cacheaction( 'all_supercache_filenames', $filenames );
1060    }
1061
1062    foreach ( $filenames as $file ) {
1063        $out[] = $file;
1064        $out[] = $file . '.gz';
1065    }
1066
1067    return $out;
1068}
1069
1070function wpsc_is_https() {
1071    // Also supports https requests coming from an nginx reverse proxy
1072    return ( ( isset( $_SERVER['HTTPS'] ) && 'on' == strtolower( $_SERVER['HTTPS'] ) ) || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == strtolower( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) );
1073}
1074
1075function supercache_filename() {
1076    global $cached_direct_pages;
1077
1078    // Add support for https and http caching
1079    $is_https  = wpsc_is_https();
1080    $extra_str = $is_https ? '-https' : '';
1081
1082    if ( function_exists( 'apply_filters' ) ) {
1083        $extra_str = apply_filters( 'supercache_filename_str', $extra_str );
1084    } else {
1085        $extra_str = do_cacheaction( 'supercache_filename_str', $extra_str );
1086    }
1087
1088    if ( is_array( $cached_direct_pages ) && in_array( $_SERVER['REQUEST_URI'], $cached_direct_pages ) ) {
1089        $extra_str = '';
1090    }
1091    $filename = 'index' . $extra_str . '.html';
1092
1093    return $filename;
1094}
1095
1096function get_oc_version() {
1097    _deprecated_function( __FUNCTION__, '1.10.0' );
1098}
1099
1100// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
1101function reset_oc_version( $version = 1 ) {
1102    _deprecated_function( __FUNCTION__, '1.10.0' );
1103}
1104
1105// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
1106function get_oc_key( $url = false ) {
1107    _deprecated_function( __FUNCTION__, '1.10.0' );
1108}
1109
1110function wp_supercache_cache_for_admins() {
1111
1112    // Don't remove cookies for some requests.
1113    if (
1114        wpsc_is_backend() ||
1115        $_SERVER['REQUEST_METHOD'] !== 'GET' ||
1116        isset( $_GET['preview'], $_GET['customize_changeset_uuid'] ) || // WPCS: CSRF ok.
1117        strpos( stripslashes( $_SERVER['REQUEST_URI'] ), '/wp-json/' ) !== false // WPCS: sanitization ok.
1118    ) {
1119        return true;
1120    }
1121
1122    if ( false === do_cacheaction( 'wp_supercache_remove_cookies', true ) ) {
1123        return true;
1124    }
1125
1126    $removed_cookies = array();
1127    foreach ( wpsc_get_auth_cookies() as $cookie ) {
1128
1129        $cookies = is_array( $cookie ) ? $cookie : array( $cookie );
1130
1131        foreach ( $cookies as $cookie_key ) {
1132            unset( $_COOKIE[ $cookie_key ] );
1133            $removed_cookies[] = $cookie_key;
1134        }
1135    }
1136
1137    if ( ! empty( $removed_cookies ) ) {
1138        wp_cache_debug( 'Removing auth from $_COOKIE to allow caching for logged in user ( ' . implode( ', ', $removed_cookies ) . ' )', 5 );
1139    }
1140}
1141
1142/*
1143 * Check if caching is disabled for the current visitor based on their cookies
1144 */
1145function wpsc_is_caching_user_disabled() {
1146    global $wp_cache_not_logged_in;
1147    if ( $wp_cache_not_logged_in == 2 && wpsc_get_auth_cookies() ) {
1148        wp_cache_debug( 'wpsc_is_caching_user_disabled: true because logged in' );
1149        return true;
1150    } elseif ( $wp_cache_not_logged_in == 1 && ! empty( $_COOKIE ) ) {
1151        wp_cache_debug( 'wpsc_is_caching_user_disabled: true because cookie found' );
1152        return true;
1153    } else {
1154        wp_cache_debug( 'wpsc_is_caching_user_disabled: false' );
1155        return false;
1156    }
1157}
1158
1159/* returns true/false depending on location of $dir. */
1160function wp_cache_confirm_delete( $dir ) {
1161    global $cache_path, $blog_cache_dir;
1162    // don't allow cache_path, blog cache dir, blog meta dir, supercache.
1163    $dir = wpsc_get_realpath( $dir );
1164
1165    if ( ! $dir ) {
1166        wp_cache_debug( 'wp_cache_confirm_delete: directory does not exist' );
1167        return false;
1168    }
1169
1170    if ( ! wpsc_is_in_cache_directory( $dir ) ) {
1171        return false;
1172    }
1173
1174    $rp_cache_path = wpsc_get_realpath( $cache_path );
1175
1176    if ( ! $rp_cache_path ) {
1177        wp_cache_debug( "wp_cache_confirm_delete: cache_path does not exist: $cache_path" );
1178        return false;
1179    }
1180
1181    if (
1182        $dir == $rp_cache_path ||
1183        $dir == wpsc_get_realpath( $blog_cache_dir ) ||
1184        $dir == wpsc_get_realpath( $blog_cache_dir . 'meta/' ) ||
1185        $dir == wpsc_get_realpath( $cache_path . 'supercache' )
1186    ) {
1187        return false;
1188    } else {
1189        return true;
1190    }
1191}
1192
1193// copy of _deep_replace() to be used before WordPress loads
1194function wpsc_deep_replace( $search, $subject ) {
1195    $subject = (string) $subject;
1196
1197    $count = 1;
1198    while ( $count ) {
1199        $subject = str_replace( $search, '', $subject, $count );
1200    }
1201
1202    return $subject;
1203}
1204
1205function wpsc_get_protected_directories() {
1206    global $cache_path, $blog_cache_dir;
1207    return apply_filters(
1208        'wpsc_protected_directories',
1209        array(
1210            $cache_path . '.htaccess',
1211            $cache_path . 'index.html',
1212            $blog_cache_dir,
1213            $blog_cache_dir . 'index.html',
1214            $blog_cache_dir . 'meta',
1215            $blog_cache_dir . 'meta/index.html',
1216            $cache_path . 'supercache/index.html',
1217            $cache_path . 'supercache',
1218        )
1219    );
1220}
1221
1222function wpsc_debug_username() {
1223    global $wp_cache_debug_username;
1224    if ( ! isset( $wp_cache_debug_username ) || $wp_cache_debug_username == '' ) {
1225        $wp_cache_debug_username = md5( (string) ( time() + wp_rand() ) );
1226        wp_cache_setting( 'wp_cache_debug_username', $wp_cache_debug_username );
1227    }
1228    return $wp_cache_debug_username;
1229}
1230function wpsc_create_debug_log( $filename = '', $username = '' ) {
1231    global $cache_path, $wp_cache_debug_username, $wp_cache_debug_log;
1232    if ( $filename != '' ) {
1233        $wp_cache_debug_log = $filename;
1234    } else {
1235        $wp_cache_debug_log = md5( (string) ( time() + wp_rand() ) ) . '.php';
1236    }
1237    if ( $username != '' ) {
1238        $wp_cache_debug_username = $username;
1239    } else {
1240        $wp_cache_debug_username = wpsc_debug_username();
1241    }
1242
1243    $msg = 'die( "Please use the viewer" );' . PHP_EOL;
1244    $fp  = fopen( $cache_path . $wp_cache_debug_log, 'w' );
1245    if ( $fp ) {
1246        fwrite( $fp, '<' . "?php\n" );
1247        fwrite( $fp, $msg );
1248        fwrite( $fp, '?' . '><pre>' . PHP_EOL );
1249        fwrite( $fp, '<' . '?php // END HEADER ?' . '>' . PHP_EOL );
1250        fclose( $fp );
1251        wp_cache_setting( 'wp_cache_debug_log', $wp_cache_debug_log );
1252        wp_cache_setting( 'wp_cache_debug_username', $wp_cache_debug_username );
1253    }
1254
1255    $msg = '
1256if ( !isset( $_SERVER[ "PHP_AUTH_USER" ] ) || ( $_SERVER[ "PHP_AUTH_USER" ] != "' . $wp_cache_debug_username . '" && $_SERVER[ "PHP_AUTH_PW" ] != "' . $wp_cache_debug_username . '" ) ) {
1257    header( "WWW-Authenticate: Basic realm=\"WP-Super-Cache Debug Log\"" );
1258    header( $_SERVER[ "SERVER_PROTOCOL" ] . " 401 Unauthorized" );
1259    echo "You must login to view the debug log";
1260    exit( 0 );
1261}' . PHP_EOL;
1262
1263    $fp = fopen( $cache_path . 'view_' . $wp_cache_debug_log, 'w' );
1264    if ( $fp ) {
1265        fwrite( $fp, '<' . '?php' . PHP_EOL );
1266        $msg .= '$debug_log = file( "./' . $wp_cache_debug_log . '" );
1267$start_log = 1 + array_search( "<" . "?php // END HEADER ?" . ">" . PHP_EOL, $debug_log );
1268if ( $start_log > 1 ) {
1269    $debug_log = array_slice( $debug_log, $start_log );
1270}
1271?' . '><form action="" method="GET"><' . '?php
1272
1273$checks = array( "wp-admin", "exclude_filter", "wp-content", "wp-json" );
1274foreach( $checks as $check ) {
1275    if ( isset( $_GET[ $check ] ) ) {
1276        $$check = 1;
1277    } else {
1278        $$check = 0;
1279    }
1280}
1281
1282if ( isset( $_GET[ "filter" ] ) ) {
1283    $filter = htmlspecialchars( $_GET[ "filter" ] );
1284} else {
1285    $filter = "";
1286}
1287
1288unset( $checks[1] ); // exclude_filter
1289?' . '>
1290<h2>WP Super Cache Log Viewer</h2>
1291<h3>Warning! Do not copy and paste this log file to a public website!</h3>
1292<p>This log file contains sensitive information about your website such as cookies and directories.</p>
1293<p>If you must share it please remove any cookies and remove any directories such as ' . ABSPATH . '.</p>
1294Exclude requests: <br />
1295<' . '?php foreach ( $checks as $check ) { ?>
1296    <label><input type="checkbox" name="<' . '?php echo $check; ?' . '>" value="1" <' . '?php if ( $$check ) { echo "checked"; } ?' . '> /> <' . '?php echo $check; ?' . '></label><br />
1297<' . '?php } ?' . '>
1298<br />
1299Text to filter by:
1300
1301<input type="text" name="filter" value="<' . '?php echo $filter; ?' . '>" /><br />
1302<input type="checkbox" name="exclude_filter" value="1" <' . '?php if ( $exclude_filter ) { echo "checked"; } ?' . '> /> Exclude by filter instead of include.<br />
1303<input type="submit" value="Submit" />
1304</form>
1305<' . '?php
1306$path_to_site = "' . ABSPATH . '";
1307foreach ( $debug_log as $t => $line ) {
1308    $line = str_replace( $path_to_site, "ABSPATH/", $line );
1309    $debug_log[ $t ] = $line;
1310    foreach( $checks as $check ) {
1311        if ( $$check && str_contains( $line, " /$check/" ) ) {
1312            unset( $debug_log[ $t ] );
1313        }
1314    }
1315    if ( $filter ) {
1316        if ( str_contains( $line, $filter ) && $exclude_filter ) {
1317            unset( $debug_log[ $t ] );
1318        } elseif ( ! str_contains( $line, $filter ) && ! $exclude_filter ) {
1319            unset( $debug_log[ $t ] );
1320        }
1321    }
1322}
1323echo "<pre>";
1324foreach( $debug_log as $line ) {
1325    echo htmlspecialchars( $line );
1326}
1327echo "</pre>";
1328';
1329        fwrite( $fp, $msg );
1330        fclose( $fp );
1331    }
1332
1333    return array(
1334        'wp_cache_debug_log'      => $wp_cache_debug_log,
1335        'wp_cache_debug_username' => $wp_cache_debug_username,
1336    );
1337}
1338
1339function wpsc_delete_url_cache( $url ) {
1340    if ( str_contains( $url, '?' ) ) {
1341        wp_cache_debug( 'wpsc_delete_url_cache: URL contains the character "?". Not deleting URL: ' . $url );
1342        return false;
1343    }
1344    $dir = str_replace( get_option( 'home' ), '', $url );
1345    if ( $dir != '' ) {
1346        $supercachedir = get_supercache_dir();
1347        wpsc_rebuild_files( $supercachedir . $dir );
1348        prune_super_cache( $supercachedir . $dir . '/page', true );
1349        return true;
1350    } else {
1351        return false;
1352    }
1353}
1354
1355// from legolas558 d0t users dot sf dot net at http://www.php.net/is_writable
1356/**
1357 * @param string $path
1358 */
1359function is_writeable_ACLSafe( $path ) {
1360
1361    if (
1362        ( defined( 'PHP_OS_FAMILY' ) && 'Windows' !== constant( 'PHP_OS_FAMILY' ) ) ||
1363        stristr( PHP_OS, 'DAR' ) ||
1364        ! stristr( PHP_OS, 'WIN' )
1365    ) {
1366        return is_writable( $path );
1367    }
1368
1369    // PHP's is_writable does not work with Win32 NTFS
1370
1371    if ( $path[ strlen( $path ) - 1 ] === '/' ) { // recursively return a temporary file path
1372        return is_writeable_ACLSafe( $path . uniqid( (string) wp_rand() ) . '.tmp' );
1373    } elseif ( is_dir( $path ) ) {
1374        return is_writeable_ACLSafe( $path . '/' . uniqid( (string) wp_rand() ) . '.tmp' );
1375    }
1376
1377    // check tmp file for read/write capabilities
1378    $rm = file_exists( $path );
1379    $f  = @fopen( $path, 'a' );
1380    if ( $f === false ) {
1381        return false;
1382    }
1383    fclose( $f );
1384    if ( ! $rm ) {
1385        unlink( $path );
1386    }
1387
1388    return true;
1389}
1390
1391function wp_cache_setting( $field, $value ) {
1392    global $wp_cache_config_file;
1393
1394    $GLOBALS[ $field ] = $value;
1395    if ( is_numeric( $value ) ) {
1396        return wp_cache_replace_line( '^ *\$' . $field, "\$$field = $value;", $wp_cache_config_file );
1397    } elseif ( is_bool( $value ) ) {
1398        $output_value = $value === true ? 'true' : 'false';
1399        return wp_cache_replace_line( '^ *\$' . $field, "\$$field = $output_value;", $wp_cache_config_file );
1400    } elseif ( is_object( $value ) || is_array( $value ) ) {
1401        $text = var_export( $value, true );
1402        $text = preg_replace( '/[\s]+/', ' ', $text );
1403        return wp_cache_replace_line( '^ *\$' . $field, "\$$field = $text;", $wp_cache_config_file );
1404    } else {
1405        return wp_cache_replace_line( '^ *\$' . $field, "\$$field = '$value';", $wp_cache_config_file );
1406    }
1407}
1408
1409function wp_cache_replace_line( $old, $new, $my_file ) {
1410    if ( ! is_string( $my_file ) || @is_file( $my_file ) === false ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1411        if ( function_exists( 'set_transient' ) ) {
1412            set_transient( 'wpsc_config_error', 'config_file_missing', 10 );
1413        }
1414        return false;
1415    }
1416    if ( ! is_writeable_ACLSafe( $my_file ) ) {
1417        if ( function_exists( 'set_transient' ) ) {
1418            set_transient( 'wpsc_config_error', 'config_file_ro', 10 );
1419        }
1420        trigger_error( "Error: file $my_file is not writable." );
1421        return false;
1422    }
1423
1424    $found  = false;
1425    $loaded = false;
1426    $c      = 0;
1427    $lines  = array();
1428    while ( ! $loaded ) {
1429        $lines = file( $my_file );
1430        if ( ! empty( $lines ) && is_array( $lines ) ) {
1431            $loaded = true;
1432        } else {
1433            ++$c;
1434            if ( $c > 100 ) {
1435                if ( function_exists( 'set_transient' ) ) {
1436                    set_transient( 'wpsc_config_error', 'config_file_not_loaded', 10 );
1437                }
1438                trigger_error( "wp_cache_replace_line: Error  - file $my_file could not be loaded." );
1439                return false;
1440            }
1441        }
1442    }
1443    foreach ( (array) $lines as $line ) {
1444        if (
1445            trim( $new ) != '' &&
1446            trim( $new ) == trim( $line )
1447        ) {
1448            wp_cache_debug( "wp_cache_replace_line: setting not changed - $new" );
1449            return true;
1450        } elseif ( preg_match( "/$old/", $line ) ) {
1451            wp_cache_debug( 'wp_cache_replace_line: changing line ' . trim( $line ) . " to *$new*" );
1452            $found = true;
1453        }
1454    }
1455
1456    $tmp_config_filename = tempnam( $GLOBALS['cache_path'], md5( (string) wp_rand( 0, 9999 ) ) );
1457    if ( file_exists( $tmp_config_filename . '.php' ) ) {
1458        unlink( $tmp_config_filename . '.php' );
1459        if ( file_exists( $tmp_config_filename . '.php' ) ) {
1460            die( __( 'WARNING: attempt to intercept updating of config file.', 'wp-super-cache' ) );
1461        }
1462    }
1463    rename( $tmp_config_filename, $tmp_config_filename . '.php' );
1464    $tmp_config_filename .= '.php';
1465    wp_cache_debug( 'wp_cache_replace_line: writing to ' . $tmp_config_filename );
1466    $fd = fopen( $tmp_config_filename, 'w' );
1467    if ( ! $fd ) {
1468        if ( function_exists( 'set_transient' ) ) {
1469            set_transient( 'wpsc_config_error', 'config_file_ro', 10 );
1470        }
1471        trigger_error( "wp_cache_replace_line: Error  - could not write to $my_file" );
1472        return false;
1473    }
1474    if ( $found ) {
1475        foreach ( (array) $lines as $line ) {
1476            if ( ! preg_match( "/$old/", $line ) ) {
1477                fwrite( $fd, $line );
1478            } elseif ( $new != '' ) {
1479                fwrite( $fd, "$new\n" );
1480            }
1481        }
1482    } else {
1483        $done = false;
1484        foreach ( (array) $lines as $line ) {
1485            if ( $done || ! preg_match( '/^(if\ \(\ \!\ )?define|\$|\?>/', $line ) ) {
1486                fwrite( $fd, $line );
1487            } else {
1488                fwrite( $fd, "$new\n" );
1489                fwrite( $fd, $line );
1490                $done = true;
1491            }
1492        }
1493    }
1494    fclose( $fd );
1495
1496    $my_file_permissions = fileperms( $my_file );
1497
1498    rename( $tmp_config_filename, $my_file );
1499
1500    if ( false !== $my_file_permissions ) {
1501        chmod( $my_file, $my_file_permissions );
1502    }
1503
1504    wp_cache_debug( 'wp_cache_replace_line: moved ' . $tmp_config_filename . ' to ' . $my_file );
1505
1506    if ( function_exists( 'opcache_invalidate' ) ) {
1507        @opcache_invalidate( $my_file );
1508    }
1509
1510    return true;
1511}
1512
1513function wpsc_shutdown_message() {
1514    static $did_wp_footer = false;
1515    global $wp_super_cache_comments;
1516
1517    if ( ! defined( 'WPSCSHUTDOWNMESSAGE' ) || ( isset( $wp_super_cache_comments ) && ! $wp_super_cache_comments ) ) {
1518        return;
1519    }
1520
1521    if ( ! $did_wp_footer ) {
1522        $did_wp_footer = true;
1523        register_shutdown_function( 'wpsc_shutdown_message' );
1524    } else {
1525        echo PHP_EOL . '<!-- WP Super Cache: ' . esc_html( constant( 'WPSCSHUTDOWNMESSAGE' ) ) . ' -->' . PHP_EOL;
1526    }
1527}
1528
1529function wp_cache_phase2() {
1530    global $wp_cache_gzip_encoding, $super_cache_enabled, $cache_rebuild_files, $cache_enabled, $wp_cache_gmt_offset, $wp_cache_blog_charset;
1531
1532    if ( $cache_enabled == false ) {
1533        wp_cache_debug( 'wp_cache_phase2: Caching disabled! Exit' );
1534        define( 'WPSCSHUTDOWNMESSAGE', __( 'Caching disabled. Page not cached.', 'wp-super-cache' ) );
1535        add_action( 'wp_footer', 'wpsc_shutdown_message' );
1536        return false;
1537    }
1538
1539    if ( wp_cache_user_agent_is_rejected() ) {
1540        wp_cache_debug( 'wp_cache_phase2: No caching to do as user agent rejected.' );
1541        return false;
1542    }
1543
1544    if ( ob_get_level() > 1 ) {
1545        global $wp_super_cache_late_init;
1546        wp_cache_debug( '***********************************************************************************' );
1547        wp_cache_debug( '* An extra output buffer has been detected. Check your plugins, themes,           *' );
1548        wp_cache_debug( '* mu-plugins, and other custom code as this may interfere with caching.           *' );
1549
1550        if ( isset( $wp_super_cache_late_init ) && $wp_super_cache_late_init ) {
1551            wp_cache_debug( '* Late init is enabled. This allows third-party code to run before WP Super Cache *' );
1552            wp_cache_debug( '* sets up an output buffer. That code may have set up the output buffer.          *' );
1553        }
1554        wp_cache_debug( '***********************************************************************************' );
1555    }
1556
1557    wp_cache_debug( 'In WP Cache Phase 2', 5 );
1558
1559    $wp_cache_gmt_offset   = get_option( 'gmt_offset' ); // caching for later use when wpdb is gone. https://wordpress.org/support/topic/224349
1560    $wp_cache_blog_charset = get_option( 'blog_charset' );
1561
1562    wp_cache_mutex_init();
1563    if ( function_exists( 'add_action' ) && ( ! defined( 'WPLOCKDOWN' ) || constant( 'WPLOCKDOWN' ) == '0' ) ) {
1564        wp_cache_debug( 'Setting up WordPress actions', 5 );
1565
1566        add_action( 'template_redirect', 'wp_super_cache_query_vars' );
1567        add_filter( 'wp_redirect_status', 'wpsc_catch_http_status_code' );
1568        add_filter( 'status_header', 'wpsc_catch_status_header', 10, 2 );
1569        add_filter( 'supercache_filename_str', 'wp_cache_check_mobile' );
1570
1571        wpsc_register_post_hooks();
1572
1573        do_cacheaction( 'add_cacheaction' );
1574    }
1575
1576    if ( wpsc_is_backend() ) {
1577        wp_cache_debug( 'Not caching wp-admin requests.', 5 );
1578        return false;
1579    }
1580
1581    if ( wpsc_is_get_query() ) {
1582        wp_cache_debug( 'Supercache caching disabled. Only using wp-cache. Non empty GET request. ' . wpsc_dump_get_request(), 5 );
1583        $super_cache_enabled = false;
1584    }
1585
1586    if ( defined( 'WPSC_VARY_HEADER' ) ) {
1587        if ( WPSC_VARY_HEADER != '' ) {
1588            header( 'Vary: ' . WPSC_VARY_HEADER );
1589        }
1590    } else {
1591        header( 'Vary: Accept-Encoding, Cookie' );
1592    }
1593
1594    ob_start( 'wp_cache_ob_callback' );
1595    wp_cache_debug( 'Created output buffer', 4 );
1596
1597    // restore old supercache file temporarily
1598    if ( ( $_SERVER['REQUEST_METHOD'] !== 'POST' && empty( $_POST ) ) && $super_cache_enabled && $cache_rebuild_files ) {
1599        $user_info = wp_cache_get_cookies_values();
1600
1601        if ( empty( $user_info )
1602            || true === apply_filters( 'do_createsupercache', $user_info )
1603        ) {
1604            wpcache_do_rebuild( get_current_url_supercache_dir() );
1605        }
1606    }
1607
1608    schedule_wp_gc();
1609}
1610
1611function wpsc_register_post_hooks() {
1612    static $done = false;
1613
1614    if ( $done ) {
1615        return;
1616    }
1617
1618    if ( false === $GLOBALS['cache_enabled']
1619        || ( defined( 'WPLOCKDOWN' ) && constant( 'WPLOCKDOWN' ) != '0' )
1620    ) {
1621        $done = true;
1622        return;
1623    }
1624
1625    // Post ID is received
1626    add_action( 'wp_trash_post', 'wp_cache_post_edit', 0 );
1627    add_action( 'publish_post', 'wp_cache_post_edit', 0 );
1628    add_action( 'edit_post', 'wp_cache_post_change', 0 ); // leaving a comment called edit_post
1629    add_action( 'delete_post', 'wp_cache_post_edit', 0 );
1630    add_action( 'publish_phone', 'wp_cache_post_edit', 0 );
1631
1632    // Coment ID is received
1633    add_action( 'trackback_post', 'wp_cache_get_postid_from_comment', 99 );
1634    add_action( 'pingback_post', 'wp_cache_get_postid_from_comment', 99 );
1635    add_action( 'comment_post', 'wp_cache_get_postid_from_comment', 99 );
1636    add_action( 'edit_comment', 'wp_cache_get_postid_from_comment', 99 );
1637    add_action( 'wp_set_comment_status', 'wp_cache_get_postid_from_comment', 99, 2 );
1638
1639    // No post_id is available
1640    add_action( 'switch_theme', 'wp_cache_no_postid', 99 );
1641    add_action( 'edit_user_profile_update', 'wp_cache_no_postid', 99 );
1642    add_action( 'wp_update_nav_menu', 'wp_cache_clear_cache_on_menu' );
1643    add_action( 'clean_post_cache', 'wp_cache_post_edit' );
1644    add_action( 'transition_post_status', 'wpsc_post_transition', 10, 3 );
1645
1646    // Cron hooks
1647    add_action( 'wp_cache_gc', 'wp_cache_gc_cron' );
1648    add_action( 'wp_cache_gc_watcher', 'wp_cache_gc_watcher' );
1649
1650    $done = true;
1651}
1652
1653function wpcache_do_rebuild( $dir ) {
1654    global $do_rebuild_list, $cache_path, $wpsc_file_mtimes;
1655    wp_cache_debug( "wpcache_do_rebuild: doing rebuild for $dir" );
1656
1657    if ( ! is_dir( $dir ) ) {
1658        wp_cache_debug( "wpcache_do_rebuild: exiting as directory is not a directory: $dir" );
1659        return false;
1660    }
1661
1662    $dir = wpsc_get_realpath( $dir );
1663    if ( ! $dir ) {
1664        wp_cache_debug( 'wpcache_do_rebuild: exiting as directory does not exist.' );
1665        return false;
1666    }
1667
1668    if ( isset( $do_rebuild_list[ $dir ] ) ) {
1669        wp_cache_debug( "wpcache_do_rebuild: directory already rebuilt: $dir" );
1670        return false;
1671    }
1672
1673    $protected = wpsc_get_protected_directories();
1674    foreach ( $protected as $id => $directory ) {
1675        $protected[ $id ] = wpsc_get_realpath( $directory );
1676    }
1677
1678    if ( ! wpsc_is_in_cache_directory( $dir ) ) {
1679        wp_cache_debug( "wpcache_do_rebuild: exiting as directory not in cache_path: $dir" );
1680        return false;
1681    }
1682
1683    if ( in_array( $dir, $protected ) ) {
1684        wp_cache_debug( "wpcache_do_rebuild: exiting as directory is protected: $dir" );
1685        return false;
1686    }
1687
1688    if ( ! is_dir( $dir ) ) {
1689        wp_cache_debug( "wpcache_do_rebuild: exiting as directory is not a directory: $dir" );
1690        return false;
1691    }
1692
1693    $dh = @opendir( $dir );
1694    if ( false == $dh ) {
1695        wp_cache_debug( "wpcache_do_rebuild: exiting as could not open directory for reading: $dir" );
1696        return false;
1697    }
1698
1699    $dir              = trailingslashit( $dir );
1700    $wpsc_file_mtimes = array();
1701    while ( ( $file = readdir( $dh ) ) !== false ) {
1702        if ( $file == '.' || $file == '..' || false == is_file( $dir . $file ) ) {
1703            continue;
1704        }
1705
1706        $cache_file = $dir . $file;
1707        // if the file is index.html.needs-rebuild and index.html doesn't exist and
1708        // if the rebuild file is less than 10 seconds old then remove the ".needs-rebuild"
1709        // extension so index.html can be served to other visitors temporarily
1710        // until index.html is generated again at the end of this page.
1711
1712        if ( substr( $cache_file, -14 ) != '.needs-rebuild' ) {
1713            wp_cache_debug( "wpcache_do_rebuild: base file found: $cache_file" );
1714            continue;
1715        }
1716
1717        wp_cache_debug( "wpcache_do_rebuild: found rebuild file: $cache_file" );
1718
1719        if ( @file_exists( substr( $cache_file, 0, -14 ) ) ) {
1720            wp_cache_debug( "wpcache_do_rebuild: rebuild file deleted because base file found: $cache_file" );
1721            @unlink( $cache_file ); // delete the rebuild file because index.html already exists
1722            continue;
1723        }
1724
1725        $mtime = @filemtime( $cache_file );
1726        if ( $mtime && ( time() - $mtime ) < 10 ) {
1727            wp_cache_debug( "wpcache_do_rebuild: rebuild file is new: $cache_file" );
1728            $base_file = substr( $cache_file, 0, -14 );
1729            if ( false == @rename( $cache_file, $base_file ) ) { // rename the rebuild file
1730                @unlink( $cache_file );
1731                wp_cache_debug( "wpcache_do_rebuild: rebuild file rename failed. Deleted rebuild file: $cache_file" );
1732            } else {
1733                $do_rebuild_list[ $dir ]        = 1;
1734                $wpsc_file_mtimes[ $base_file ] = $mtime;
1735                wp_cache_debug( "wpcache_do_rebuild: rebuild file renamed: $base_file" );
1736            }
1737        } else {
1738            wp_cache_debug( "wpcache_do_rebuild: rebuild file deleted because it's too old: $cache_file" );
1739            @unlink( $cache_file ); // delete the rebuild file because index.html already exists
1740        }
1741    }
1742}
1743
1744function wpcache_logged_in_message() {
1745    echo '<!-- WP Super Cache did not cache this page because you are logged in and "Don\'t cache pages for logged in users" is enabled. -->';
1746}
1747
1748function wp_cache_user_agent_is_rejected() {
1749    global $cache_rejected_user_agent;
1750
1751    if ( empty( $cache_rejected_user_agent ) || ! is_array( $cache_rejected_user_agent ) ) {
1752        return false;
1753    }
1754
1755    $headers = wpsc_apache_request_headers();
1756    if ( empty( $headers['User-Agent'] ) ) {
1757        return false;
1758    }
1759
1760    foreach ( $cache_rejected_user_agent as $user_agent ) {
1761        if ( ! empty( $user_agent ) && stristr( $headers['User-Agent'], $user_agent ) ) {
1762            return true;
1763        }
1764    }
1765
1766    return false;
1767}
1768
1769function wp_cache_get_response_headers() {
1770    static $known_headers = array(
1771        'Access-Control-Allow-Origin',
1772        'Accept-Ranges',
1773        'Age',
1774        'Allow',
1775        'Cache-Control',
1776        'Connection',
1777        'Content-Encoding',
1778        'Content-Language',
1779        'Content-Length',
1780        'Content-Location',
1781        'Content-MD5',
1782        'Content-Disposition',
1783        'Content-Range',
1784        'Content-Type',
1785        'Date',
1786        'ETag',
1787        'Expires',
1788        'Last-Modified',
1789        'Link',
1790        'Location',
1791        'P3P',
1792        'Pragma',
1793        'Proxy-Authenticate',
1794        'Referrer-Policy',
1795        'Refresh',
1796        'Retry-After',
1797        'Server',
1798        'Status',
1799        'Strict-Transport-Security',
1800        'Trailer',
1801        'Transfer-Encoding',
1802        'Upgrade',
1803        'Vary',
1804        'Via',
1805        'Warning',
1806        'WWW-Authenticate',
1807        'X-Frame-Options',
1808        'Public-Key-Pins',
1809        'X-XSS-Protection',
1810        'Content-Security-Policy',
1811        'X-Pingback',
1812        'X-Content-Security-Policy',
1813        'X-WebKit-CSP',
1814        'X-Content-Type-Options',
1815        'X-Powered-By',
1816        'X-UA-Compatible',
1817        'X-Robots-Tag',
1818    );
1819
1820    if ( ! function_exists( 'headers_list' ) ) {
1821        return array();
1822    }
1823
1824    $known_headers = apply_filters( 'wpsc_known_headers', $known_headers );
1825
1826    if ( ! isset( $known_headers['age'] ) ) {
1827        $known_headers = array_map( 'strtolower', $known_headers );
1828    }
1829
1830    $headers = array();
1831    foreach ( headers_list() as $hdr ) {
1832        $ptr = strpos( $hdr, ':' );
1833
1834        if ( empty( $ptr ) ) {
1835            continue;
1836        }
1837
1838        $hdr_key = rtrim( substr( $hdr, 0, $ptr ) );
1839
1840        if ( in_array( strtolower( $hdr_key ), $known_headers, true ) ) {
1841            $hdr_val = ltrim( substr( $hdr, $ptr + 1 ) );
1842
1843            if ( ! empty( $headers[ $hdr_key ] ) ) {
1844                $hdr_val = $headers[ $hdr_key ] . ', ' . $hdr_val;
1845            }
1846
1847            $headers[ $hdr_key ] = $hdr_val;
1848        }
1849    }
1850
1851    return $headers;
1852}
1853
1854function wpsc_is_rejected_cookie() {
1855    global $wpsc_rejected_cookies;
1856    if ( false == is_array( $wpsc_rejected_cookies ) ) {
1857        return false;
1858    }
1859
1860    foreach ( $wpsc_rejected_cookies as $expr ) {
1861        if ( $expr !== '' && $match = preg_grep( "~$expr~", array_keys( $_COOKIE ) ) ) {
1862            wp_cache_debug( 'wpsc_is_rejected_cookie: found cookie: ' . $expr );
1863            return true;
1864        }
1865    }
1866    return false;
1867}
1868
1869function wp_cache_is_rejected( $uri ) {
1870    global $cache_rejected_uri;
1871
1872    if ( empty( $uri ) ) {
1873        return true; // do not cache if we don't know the URI.
1874    }
1875
1876    $auto_rejected = array( '/wp-admin/', 'xmlrpc.php', 'wp-app.php' );
1877    foreach ( $auto_rejected as $u ) {
1878        if ( strstr( $uri, $u ) ) {
1879            return true; // we don't allow caching of wp-admin for security reasons
1880        }
1881    }
1882    if ( false == is_array( $cache_rejected_uri ) ) {
1883        return false;
1884    }
1885    foreach ( $cache_rejected_uri as $expr ) {
1886        if ( $expr != '' && @preg_match( "~$expr~", $uri ) ) {
1887            return true;
1888        }
1889    }
1890    return false;
1891}
1892
1893function wp_cache_mutex_init() {
1894    global $mutex, $wp_cache_mutex_disabled, $use_flock, $blog_cache_dir, $mutex_filename, $sem_id;
1895
1896    if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
1897        return true;
1898    }
1899
1900    if ( ! is_bool( $use_flock ) ) {
1901        if ( function_exists( 'sem_get' ) ) {
1902            $use_flock = false;
1903        } else {
1904            $use_flock = true;
1905        }
1906    }
1907
1908    $mutex = false;
1909    if ( $use_flock ) {
1910        setup_blog_cache_dir();
1911        wp_cache_debug( "Created mutex lock on filename: {$blog_cache_dir}{$mutex_filename}", 5 );
1912        $mutex = @fopen( $blog_cache_dir . $mutex_filename, 'w' );
1913    } else {
1914        wp_cache_debug( "Created mutex lock on semaphore: {$sem_id}", 5 );
1915        // PHP 8.0 expects a bool. Prior expects an int.
1916        $auto_release = ( version_compare( phpversion(), '8.0.0', '<=' ) ) ? 1 : true;
1917        $mutex        = @sem_get( $sem_id, 1, 0666, $auto_release );
1918    }
1919}
1920
1921function wp_cache_writers_entry() {
1922    global $mutex, $wp_cache_mutex_disabled, $use_flock;
1923
1924    if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
1925        return true;
1926    }
1927
1928    if ( ! $mutex ) {
1929        wp_cache_debug( '(writers entry) mutex lock not created. not caching.', 2 );
1930        return false;
1931    }
1932
1933    if ( $use_flock ) {
1934        wp_cache_debug( 'grabbing lock using flock()', 5 );
1935        flock( $mutex, LOCK_EX );
1936    } else {
1937        wp_cache_debug( 'grabbing lock using sem_acquire()', 5 );
1938        @sem_acquire( $mutex );
1939    }
1940
1941    return true;
1942}
1943
1944function wp_cache_writers_exit() {
1945    global $mutex, $wp_cache_mutex_disabled, $use_flock;
1946
1947    if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
1948        return true;
1949    }
1950
1951    if ( ! $mutex ) {
1952        wp_cache_debug( '(writers exit) mutex lock not created. not caching.', 2 );
1953        return false;
1954    }
1955
1956    if ( $use_flock ) {
1957        wp_cache_debug( 'releasing lock using flock()', 5 );
1958        flock( $mutex, LOCK_UN );
1959    } else {
1960        wp_cache_debug( 'releasing lock using sem_release() and sem_remove()', 5 );
1961        @sem_release( $mutex );
1962        if ( defined( 'WPSC_REMOVE_SEMAPHORE' ) ) {
1963            @sem_remove( $mutex );
1964        }
1965    }
1966}
1967
1968function wp_super_cache_query_vars() {
1969    global $wp_super_cache_query;
1970
1971    if ( is_search() ) {
1972        $wp_super_cache_query['is_search'] = 1;
1973    }
1974    if ( is_page() ) {
1975        $wp_super_cache_query['is_page'] = 1;
1976    }
1977    if ( is_archive() ) {
1978        $wp_super_cache_query['is_archive'] = 1;
1979    }
1980    if ( is_tag() ) {
1981        $wp_super_cache_query['is_tag'] = 1;
1982    }
1983    if ( is_single() ) {
1984        $wp_super_cache_query['is_single'] = 1;
1985    }
1986    if ( is_category() ) {
1987        $wp_super_cache_query['is_category'] = 1;
1988    }
1989    if ( is_front_page() ) {
1990        $wp_super_cache_query['is_front_page'] = 1;
1991    }
1992    if ( is_home() ) {
1993        $wp_super_cache_query['is_home'] = 1;
1994    }
1995    if ( is_author() ) {
1996        $wp_super_cache_query['is_author'] = 1;
1997    }
1998
1999    // REST API
2000    if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
2001        ( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) ||
2002        ( defined( 'WC_API_REQUEST' ) && WC_API_REQUEST )
2003    ) {
2004        $wp_super_cache_query['is_rest'] = 1;
2005    }
2006
2007    // Feeds, sitemaps and robots.txt
2008    if ( is_feed() ) {
2009        $wp_super_cache_query['is_feed'] = 1;
2010        if ( get_query_var( 'feed' ) == 'sitemap' ) {
2011            $wp_super_cache_query['is_sitemap'] = 1;
2012        }
2013    } elseif ( get_query_var( 'sitemap' ) || get_query_var( 'xsl' ) || get_query_var( 'xml_sitemap' ) ) {
2014        $wp_super_cache_query['is_feed']    = 1;
2015        $wp_super_cache_query['is_sitemap'] = 1;
2016    } elseif ( is_robots() ) {
2017        $wp_super_cache_query['is_robots'] = 1;
2018    }
2019
2020    // Reset everything if it's 404
2021    if ( is_404() ) {
2022        $wp_super_cache_query = array( 'is_404' => 1 );
2023    }
2024
2025    return $wp_super_cache_query;
2026}
2027
2028function wpsc_catch_status_header( $status_header, $code ) {
2029
2030    if ( $code != 200 ) {
2031        wpsc_catch_http_status_code( $code );
2032    }
2033
2034    return $status_header;
2035}
2036
2037function wpsc_catch_http_status_code( $status ) {
2038    global $wp_super_cache_query;
2039
2040    if ( in_array( intval( $status ), array( 301, 302, 303, 307 ) ) ) {
2041        $wp_super_cache_query['is_redirect'] = 1;
2042    } elseif ( $status == 304 ) {
2043        $wp_super_cache_query['is_304'] = 1;
2044    } elseif ( $status == 404 ) {
2045        $wp_super_cache_query['is_404'] = 1;
2046    }
2047
2048    return $status;
2049}
2050
2051function wpsc_is_fatal_error() {
2052    global $wp_super_cache_query;
2053
2054    if ( null === ( $error = error_get_last() ) ) {
2055        return false;
2056    }
2057
2058    if ( $error['type'] & ( E_ERROR | E_CORE_ERROR | E_PARSE | E_COMPILE_ERROR | E_USER_ERROR ) ) {
2059        $wp_super_cache_query['is_fatal_error'] = 1;
2060        return true;
2061    }
2062
2063    return false;
2064}
2065
2066function wp_cache_ob_callback( $buffer ) {
2067    global $wp_cache_pages, $wp_query, $wp_super_cache_query, $cache_acceptable_files, $wp_cache_no_cache_for_get, $wp_cache_request_uri, $do_rebuild_list, $wpsc_file_mtimes, $wpsc_save_headers, $super_cache_enabled;
2068    $script = basename( $_SERVER['PHP_SELF'] );
2069
2070    // All the things that can stop a page being cached
2071    $cache_this_page = true;
2072
2073    if ( wpsc_is_fatal_error() ) {
2074        wp_cache_debug( 'wp_cache_ob_callback: PHP Fatal error occurred. Not caching incomplete page.' );
2075        $cache_this_page = false;
2076    } elseif ( empty( $wp_super_cache_query ) && ! empty( $buffer ) && is_object( $wp_query ) && method_exists( $wp_query, 'get' ) ) {
2077        $wp_super_cache_query = wp_super_cache_query_vars();
2078    } elseif ( empty( $wp_super_cache_query ) && function_exists( 'http_response_code' ) ) {
2079        wpsc_catch_http_status_code( http_response_code() );
2080    }
2081
2082    $buffer = apply_filters( 'wp_cache_ob_callback_filter', $buffer );
2083
2084    if ( defined( 'DONOTCACHEPAGE' ) ) {
2085        wp_cache_debug( 'DONOTCACHEPAGE defined. Caching disabled.', 2 );
2086        $cache_this_page = false;
2087    } elseif ( $wp_cache_no_cache_for_get && wpsc_is_get_query() ) {
2088        wp_cache_debug( 'Non empty GET request. Caching disabled on settings page. ' . wpsc_dump_get_request(), 1 );
2089        $cache_this_page = false;
2090    } elseif ( $_SERVER['REQUEST_METHOD'] == 'POST' || ! empty( $_POST ) || get_option( 'gzipcompression' ) ) {
2091        wp_cache_debug( 'Not caching POST request.', 5 );
2092        $cache_this_page = false;
2093    } elseif ( $_SERVER['REQUEST_METHOD'] == 'PUT' ) {
2094        wp_cache_debug( 'Not caching PUT request.', 5 );
2095        $cache_this_page = false;
2096    } elseif ( $_SERVER['REQUEST_METHOD'] == 'DELETE' ) {
2097        wp_cache_debug( 'Not caching DELETE request.', 5 );
2098        $cache_this_page = false;
2099    } elseif ( isset( $_GET['preview'] ) ) {
2100        wp_cache_debug( 'Not caching preview post.', 2 );
2101        $cache_this_page = false;
2102    } elseif ( ! in_array( $script, (array) $cache_acceptable_files ) && wp_cache_is_rejected( $wp_cache_request_uri ) ) {
2103        wp_cache_debug( 'URI rejected. Not Caching', 2 );
2104        $cache_this_page = false;
2105    } elseif ( wp_cache_user_agent_is_rejected() ) {
2106        wp_cache_debug( "USER AGENT ({$_SERVER[ 'HTTP_USER_AGENT' ]}) rejected. Not Caching", 4 );
2107        $cache_this_page = false;
2108    } elseif ( isset( $wp_cache_pages['single'] ) && $wp_cache_pages['single'] == 1 && isset( $wp_super_cache_query['is_single'] ) ) {
2109        wp_cache_debug( 'Not caching single post.', 2 );
2110        $cache_this_page = false;
2111    } elseif ( isset( $wp_cache_pages['pages'] ) && $wp_cache_pages['pages'] == 1 && isset( $wp_super_cache_query['is_page'] ) ) {
2112        wp_cache_debug( 'Not caching single page.', 2 );
2113        $cache_this_page = false;
2114    } elseif ( isset( $wp_cache_pages['archives'] ) && $wp_cache_pages['archives'] == 1 && isset( $wp_super_cache_query['is_archive'] ) ) {
2115        wp_cache_debug( 'Not caching archive page.', 2 );
2116        $cache_this_page = false;
2117    } elseif ( isset( $wp_cache_pages['tag'] ) && $wp_cache_pages['tag'] == 1 && isset( $wp_super_cache_query['is_tag'] ) ) {
2118        wp_cache_debug( 'Not caching tag page.', 2 );
2119        $cache_this_page = false;
2120    } elseif ( isset( $wp_cache_pages['category'] ) && $wp_cache_pages['category'] == 1 && isset( $wp_super_cache_query['is_category'] ) ) {
2121        wp_cache_debug( 'Not caching category page.', 2 );
2122        $cache_this_page = false;
2123    } elseif ( isset( $wp_cache_pages['frontpage'] ) && $wp_cache_pages['frontpage'] == 1 && isset( $wp_super_cache_query['is_front_page'] ) ) {
2124        wp_cache_debug( 'Not caching front page.', 2 );
2125        $cache_this_page = false;
2126    } elseif ( isset( $wp_cache_pages['home'] ) && $wp_cache_pages['home'] == 1 && isset( $wp_super_cache_query['is_home'] ) ) {
2127        wp_cache_debug( 'Not caching home page.', 2 );
2128        $cache_this_page = false;
2129    } elseif ( isset( $wp_cache_pages['search'] ) && $wp_cache_pages['search'] == 1 && isset( $wp_super_cache_query['is_search'] ) ) {
2130        wp_cache_debug( 'Not caching search page.', 2 );
2131        $cache_this_page = false;
2132    } elseif ( isset( $wp_cache_pages['author'] ) && $wp_cache_pages['author'] == 1 && isset( $wp_super_cache_query['is_author'] ) ) {
2133        wp_cache_debug( 'Not caching author page.', 2 );
2134        $cache_this_page = false;
2135    } elseif ( isset( $wp_cache_pages['feed'] ) && $wp_cache_pages['feed'] == 1 && isset( $wp_super_cache_query['is_feed'] ) ) {
2136        wp_cache_debug( 'Not caching feed.', 2 );
2137        $cache_this_page = false;
2138    } elseif ( isset( $wp_super_cache_query['is_rest'] ) ) {
2139        wp_cache_debug( 'REST API detected. Caching disabled.' );
2140        $cache_this_page = false;
2141    } elseif ( isset( $wp_super_cache_query['is_robots'] ) ) {
2142        wp_cache_debug( 'robots.txt detected. Caching disabled.' );
2143        $cache_this_page = false;
2144    } elseif ( isset( $wp_super_cache_query['is_redirect'] ) ) {
2145        wp_cache_debug( 'Redirect detected. Caching disabled.' );
2146        $cache_this_page = false;
2147    } elseif ( isset( $wp_super_cache_query['is_304'] ) ) {
2148        wp_cache_debug( 'HTTP 304 (Not Modified) sent. Caching disabled.' );
2149        $cache_this_page = false;
2150    } elseif ( empty( $wp_super_cache_query ) && ! empty( $buffer ) && apply_filters( 'wpsc_only_cache_known_pages', 1 ) ) {
2151        wp_cache_debug( 'wp_cache_ob_callback: wp_super_cache_query is empty. Not caching unknown page type. Return 0 to the wpsc_only_cache_known_pages filter to cache this page.' );
2152        $cache_this_page = false;
2153    } elseif ( wpsc_is_caching_user_disabled() ) {
2154        wp_cache_debug( 'wp_cache_ob_callback: Caching disabled for known user. User logged in or cookie found.' );
2155        $cache_this_page = false;
2156    }
2157
2158    if ( isset( $wpsc_save_headers ) && $wpsc_save_headers ) {
2159        $super_cache_enabled = false; // use standard caching to record headers
2160    }
2161
2162    if ( $cache_this_page ) {
2163
2164        wp_cache_debug( 'Output buffer callback', 4 );
2165
2166        $buffer = wp_cache_get_ob( $buffer );
2167        wp_cache_shutdown_callback();
2168
2169        if ( ! empty( $wpsc_file_mtimes ) && is_array( $wpsc_file_mtimes ) ) {
2170            foreach ( $wpsc_file_mtimes as $cache_file => $old_mtime ) {
2171                if ( $old_mtime == @filemtime( $cache_file ) ) {
2172                    wp_cache_debug( "wp_cache_ob_callback deleting unmodified rebuilt cache file: $cache_file" );
2173                    if ( wp_cache_confirm_delete( $cache_file ) ) {
2174                        @unlink( $cache_file );
2175                    }
2176                }
2177            }
2178        }
2179        return $buffer;
2180    } else {
2181        if ( ! empty( $do_rebuild_list ) && is_array( $do_rebuild_list ) ) {
2182            foreach ( $do_rebuild_list as $dir => $n ) {
2183                if ( wp_cache_confirm_delete( $dir ) ) {
2184                    wp_cache_debug( 'wp_cache_ob_callback clearing rebuilt files in ' . $dir );
2185                    wpsc_delete_files( $dir );
2186                }
2187            }
2188        }
2189        return wp_cache_maybe_dynamic( $buffer );
2190    }
2191}
2192
2193function wp_cache_append_tag( &$buffer ) {
2194    global $wp_cache_gmt_offset, $wp_super_cache_comments;
2195    global $cache_enabled, $super_cache_enabled;
2196
2197    if ( false == isset( $wp_super_cache_comments ) ) {
2198        $wp_super_cache_comments = 1;
2199    }
2200
2201    if ( $wp_super_cache_comments == 0 ) {
2202        return false;
2203    }
2204
2205    $timestamp = gmdate( 'Y-m-d H:i:s', ( time() + ( $wp_cache_gmt_offset * 3600 ) ) );
2206    if ( $cache_enabled || $super_cache_enabled ) {
2207        $msg = "Cached page generated by WP-Super-Cache on $timestamp";
2208    } else {
2209        $msg = "Live page served on $timestamp";
2210    }
2211
2212    if ( strpos( $buffer, '<html' ) === false ) {
2213        wp_cache_debug( site_url( $_SERVER['REQUEST_URI'] ) . ' - ' . $msg );
2214        return false;
2215    }
2216
2217    $buffer .= "\n<!-- $msg -->\n";
2218}
2219
2220function wp_cache_add_to_buffer( &$buffer, $text ) {
2221    global $wp_super_cache_comments;
2222
2223    if ( false == isset( $wp_super_cache_comments ) ) {
2224        $wp_super_cache_comments = 1;
2225    }
2226
2227    if ( $wp_super_cache_comments == 0 ) {
2228        return false;
2229    }
2230
2231    if ( strpos( $buffer, '<html' ) === false ) {
2232        wp_cache_debug( site_url( $_SERVER['REQUEST_URI'] ) . ' - ' . $text );
2233        return false;
2234    }
2235
2236    $buffer .= "\n<!-- $text -->";
2237}
2238
2239/*
2240 * If dynamic caching is enabled then run buffer through wpsc_cachedata filter before returning it.
2241 * or we'll return template tags to visitors.
2242 */
2243function wp_cache_maybe_dynamic( &$buffer ) {
2244    global $wp_cache_mfunc_enabled;
2245    if ( $wp_cache_mfunc_enabled == 1 && do_cacheaction( 'wpsc_cachedata_safety', 0 ) === 1 ) {
2246        wp_cache_debug( 'wp_cache_maybe_dynamic: filtered $buffer through wpsc_cachedata', 4 );
2247        return do_cacheaction( 'wpsc_cachedata', $buffer ); // dynamic content for display
2248    } else {
2249        wp_cache_debug( 'wp_cache_maybe_dynamic: returned $buffer', 4 );
2250        return $buffer;
2251    }
2252}
2253
2254function wp_cache_get_ob( &$buffer ) {
2255    global $cache_enabled, $cache_path, $cache_filename, $wp_start_time, $supercachedir;
2256    global $new_cache, $wp_cache_meta, $cache_compression, $wp_super_cache_query;
2257    global $wp_cache_gzip_encoding, $super_cache_enabled;
2258    global $gzsize, $supercacheonly;
2259    global $blog_cache_dir, $wp_supercache_cache_list;
2260    global $wp_cache_not_logged_in, $cache_max_time;
2261    global $wp_cache_is_home, $wp_cache_front_page_checks, $wp_cache_mfunc_enabled;
2262
2263    if ( ! isset( $wp_cache_mfunc_enabled ) ) {
2264        $wp_cache_mfunc_enabled = 0;
2265    }
2266
2267    $new_cache     = true;
2268    $wp_cache_meta = array();
2269
2270    /*
2271     * Mode paranoic, check for closing tags
2272     * we avoid caching incomplete files */
2273    if ( $buffer == '' ) {
2274        $new_cache = false;
2275        if ( isset( $GLOBALS['wp_super_cache_debug'] ) && $GLOBALS['wp_super_cache_debug'] ) {
2276            wp_cache_debug( "Buffer is blank. Output buffer may have been corrupted by another plugin or this is a redirected URL. Look for text 'ob_start' in the files of your plugins directory.", 2 );
2277            wp_cache_add_to_buffer( $buffer, 'Page not cached by WP Super Cache. Blank Page. Check output buffer usage by plugins.' );
2278        }
2279    }
2280
2281    if ( isset( $wp_super_cache_query['is_404'] ) && false == apply_filters( 'wpsupercache_404', false ) ) {
2282        $new_cache = false;
2283        if ( isset( $GLOBALS['wp_super_cache_debug'] ) && $GLOBALS['wp_super_cache_debug'] ) {
2284            wp_cache_debug( '404 file not found not cached', 2 );
2285            wp_cache_add_to_buffer( $buffer, 'Page not cached by WP Super Cache. 404.' );
2286        }
2287    }
2288
2289    if ( ! preg_match( apply_filters( 'wp_cache_eof_tags', '/(<\/html>|<\/rss>|<\/feed>|<\/urlset|<\?xml)/i' ), $buffer ) ) {
2290        $new_cache = false;
2291        if ( isset( $GLOBALS['wp_super_cache_debug'] ) && $GLOBALS['wp_super_cache_debug'] ) {
2292            wp_cache_debug( 'No closing html tag. Not caching.', 2 );
2293            wp_cache_add_to_buffer( $buffer, 'Page not cached by WP Super Cache. No closing HTML tag. Check your theme.' );
2294        }
2295    }
2296
2297    if ( ! $new_cache ) {
2298        return wp_cache_maybe_dynamic( $buffer );
2299    }
2300
2301    $duration = wp_cache_microtime_diff( $wp_start_time, microtime() );
2302    $duration = sprintf( '%0.3f', $duration );
2303    wp_cache_add_to_buffer( $buffer, "Dynamic page generated in $duration seconds." );
2304
2305    if ( ! wp_cache_writers_entry() ) {
2306        wp_cache_add_to_buffer( $buffer, 'Page not cached by WP Super Cache. Could not get mutex lock.' );
2307        wp_cache_debug( 'Could not get mutex lock. Not caching.', 1 );
2308        return wp_cache_maybe_dynamic( $buffer );
2309    }
2310
2311    if ( $wp_cache_not_logged_in && isset( $wp_super_cache_query['is_feed'] ) ) {
2312        wp_cache_debug( 'Feed detected. Writing wpcache cache files.', 5 );
2313        $wp_cache_not_logged_in = false;
2314    }
2315
2316    $home_url = parse_url( trailingslashit( get_bloginfo( 'url' ) ) );
2317
2318    $dir           = get_current_url_supercache_dir();
2319    $supercachedir = $cache_path . 'supercache/' . preg_replace( '/:.*$/', '', $home_url['host'] );
2320    if ( wpsc_is_get_query() || isset( $wp_super_cache_query['is_feed'] ) || ( $super_cache_enabled == true && is_dir( substr( $supercachedir, 0, -1 ) . '.disabled' ) ) ) {
2321        wp_cache_debug( 'Supercache disabled: GET or feed detected or disabled by config.', 2 );
2322        $super_cache_enabled = false;
2323    }
2324
2325    $tmp_wpcache_filename = $cache_path . uniqid( (string) wp_rand(), true ) . '.tmp';
2326
2327    if ( defined( 'WPSC_SUPERCACHE_ONLY' ) ) {
2328        $supercacheonly = true;
2329        wp_cache_debug( 'wp_cache_get_ob: WPSC_SUPERCACHE_ONLY defined. Only creating supercache files.' );
2330    } else {
2331        $supercacheonly = false;
2332    }
2333
2334    if ( $super_cache_enabled ) {
2335        if ( wp_cache_get_cookies_values() == '' && ! wpsc_is_get_query() ) {
2336            wp_cache_debug( 'Anonymous user detected. Only creating Supercache file.', 3 );
2337            $supercacheonly = true;
2338        }
2339    }
2340
2341    $cache_error = '';
2342    if ( wpsc_is_caching_user_disabled() ) {
2343        $super_cache_enabled = false;
2344        $cache_enabled       = false;
2345        $cache_error         = 'Not caching requests by known users. (See Advanced Settings page)';
2346        wp_cache_debug( 'Not caching for known user.', 5 );
2347    }
2348
2349    if ( ! $cache_enabled ) {
2350        wp_cache_debug( 'Cache is not enabled. Sending buffer to browser.', 5 );
2351        wp_cache_writers_exit();
2352        wp_cache_add_to_buffer( $buffer, "Page not cached by WP Super Cache. Check your settings page. $cache_error" );
2353        if ( $wp_cache_mfunc_enabled == 1 ) {
2354            global $wp_super_cache_late_init;
2355            if ( ! isset( $wp_super_cache_late_init ) || $wp_super_cache_late_init === 0 ) {
2356                wp_cache_add_to_buffer( $buffer, 'Super Cache dynamic page detected but $wp_super_cache_late_init not set. See the readme.txt for further details.' );
2357            }
2358        }
2359
2360        return wp_cache_maybe_dynamic( $buffer );
2361    }
2362
2363    if ( @is_dir( $dir ) == false ) {
2364        @wp_mkdir_p( $dir );
2365    }
2366    $dir = wpsc_get_realpath( $dir );
2367
2368    if ( ! $dir ) {
2369        wp_cache_debug( 'wp_cache_get_ob: not caching as directory does not exist.' );
2370        return $buffer;
2371    }
2372
2373    $dir = trailingslashit( $dir );
2374
2375    if ( ! wpsc_is_in_cache_directory( $dir ) ) {
2376        wp_cache_debug( "wp_cache_get_ob: not caching as directory is not in cache_path: $dir" );
2377        return $buffer;
2378    }
2379
2380    $fr = $fr2 = $gz = false;
2381    // Open wp-cache cache file
2382    if ( ! $supercacheonly ) {
2383        $fr = @fopen( $tmp_wpcache_filename, 'w' );
2384        if ( ! $fr ) {
2385            wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $cache_path ) . $cache_filename, 1 );
2386            wp_cache_add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $cache_path ) . $cache_filename );
2387            wp_cache_writers_exit();
2388            return wp_cache_maybe_dynamic( $buffer );
2389        }
2390    } else {
2391        $user_info = wp_cache_get_cookies_values();
2392        $do_cache  = apply_filters( 'do_createsupercache', $user_info );
2393        if (
2394            $super_cache_enabled &&
2395            (
2396                $user_info == '' ||
2397                $do_cache === true
2398            )
2399        ) {
2400            $cache_fname        = $dir . supercache_filename();
2401            $tmp_cache_filename = $dir . uniqid( (string) wp_rand(), true ) . '.tmp';
2402            $fr2                = @fopen( $tmp_cache_filename, 'w' );
2403            if ( ! $fr2 ) {
2404                wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $tmp_cache_filename ), 1 );
2405                wp_cache_add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $tmp_cache_filename ) );
2406                @fclose( $fr );
2407                @unlink( $tmp_wpcache_filename );
2408                wp_cache_writers_exit();
2409                return wp_cache_maybe_dynamic( $buffer );
2410            } elseif (
2411                $cache_compression &&
2412                $wp_cache_mfunc_enabled === 0
2413            ) { // don't want to store compressed files if using dynamic content
2414                $gz = @fopen( $tmp_cache_filename . '.gz', 'w' );
2415                if ( ! $gz ) {
2416                    wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $tmp_cache_filename ) . '.gz', 1 );
2417                    wp_cache_add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $tmp_cache_filename ) . '.gz' );
2418                    @fclose( $fr );
2419                    @unlink( $tmp_wpcache_filename );
2420                    @fclose( $fr2 );
2421                    @unlink( $tmp_cache_filename );
2422                    wp_cache_writers_exit();
2423                    return wp_cache_maybe_dynamic( $buffer );
2424                }
2425            }
2426        }
2427    }
2428
2429    $added_cache = 0;
2430    $buffer      = apply_filters( 'wpsupercache_buffer', $buffer );
2431    wp_cache_append_tag( $buffer );
2432
2433    /*
2434     * Dynamic content enabled: write the buffer to a file and then process any templates found using
2435     * the wpsc_cachedata filter. Buffer is then returned to the visitor.
2436     */
2437    if ( $wp_cache_mfunc_enabled == 1 ) {
2438        if ( preg_match( '/<!--mclude|<!--mfunc|<!--dynamic-cached-content-->/', $buffer ) ) { // Dynamic content
2439            wp_cache_debug( 'mfunc/mclude/dynamic-cached-content tags have been retired. Please update your theme. See docs for updates.' );
2440            wp_cache_add_to_buffer( $buffer, 'Warning! Obsolete mfunc/mclude/dynamic-cached-content tags found. Please update your theme. See http://ocaoimh.ie/y/5b for more information.' );
2441        }
2442
2443        global $wp_super_cache_late_init;
2444        if ( ! isset( $wp_super_cache_late_init ) || $wp_super_cache_late_init === 0 ) {
2445            wp_cache_add_to_buffer( $buffer, 'Super Cache dynamic page detected but late init not set. See the readme.txt for further details.' );
2446        }
2447
2448        if ( $fr ) { // wpcache caching
2449            wp_cache_debug( 'Writing dynamic buffer to wpcache file.' );
2450            wp_cache_add_to_buffer( $buffer, 'Dynamic WPCache Super Cache' );
2451            fwrite( $fr, '<?php die(); ?>' . $buffer );
2452        } elseif ( $fr2 ) { // supercache active
2453            wp_cache_debug( 'Writing dynamic buffer to supercache file.' );
2454            wp_cache_add_to_buffer( $buffer, 'Dynamic Super Cache' );
2455            fwrite( $fr2, $buffer );
2456        }
2457        $wp_cache_meta['dynamic'] = true;
2458        if ( $wp_cache_mfunc_enabled == 1 && do_cacheaction( 'wpsc_cachedata_safety', 0 ) === 1 ) {
2459            $buffer = do_cacheaction( 'wpsc_cachedata', $buffer ); // dynamic content for display
2460        }
2461
2462        if ( $cache_compression && $wp_cache_gzip_encoding ) {
2463            wp_cache_debug( 'Gzipping dynamic buffer for display.', 5 );
2464            wp_cache_add_to_buffer( $buffer, 'Compression = gzip' );
2465            $gzdata = gzencode( $buffer, 6, FORCE_GZIP );
2466            $gzsize = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $gzdata, '8bit' ) : strlen( $gzdata );
2467        }
2468    } else {
2469        if ( defined( 'WPSC_VARY_HEADER' ) ) {
2470            if ( WPSC_VARY_HEADER != '' ) {
2471                $vary_header = WPSC_VARY_HEADER;
2472            } else {
2473                $vary_header = '';
2474            }
2475        } else {
2476            $vary_header = 'Accept-Encoding, Cookie';
2477        }
2478        if ( $vary_header ) {
2479            $wp_cache_meta['headers']['Vary'] = 'Vary: ' . $vary_header;
2480        }
2481        if ( $gz || $wp_cache_gzip_encoding ) {
2482            wp_cache_debug( 'Gzipping buffer.', 5 );
2483            wp_cache_add_to_buffer( $buffer, 'Compression = gzip' );
2484            $gzdata = gzencode( $buffer, 6, FORCE_GZIP );
2485            $gzsize = ( function_exists( 'mb_strlen' ) && function_exists( 'is_utf8_charset' ) ) ? mb_strlen( $gzdata, '8bit' ) : strlen( $gzdata );
2486
2487            $wp_cache_meta['headers']['Content-Encoding'] = 'Content-Encoding: ' . $wp_cache_gzip_encoding;
2488            // Return uncompressed data & store compressed for later use
2489            if ( $fr ) {
2490                wp_cache_debug( 'Writing gzipped buffer to wp-cache cache file.', 5 );
2491                fwrite( $fr, '<?php die(); ?>' . $gzdata );
2492            }
2493        } elseif ( $fr ) { // no compression
2494            wp_cache_debug( 'Writing non-gzipped buffer to wp-cache cache file.' );
2495            fwrite( $fr, '<?php die(); ?>' . $buffer );
2496        }
2497        if ( $fr2 ) {
2498            wp_cache_debug( 'Writing non-gzipped buffer to supercache file.' );
2499            wp_cache_add_to_buffer( $buffer, 'super cache' );
2500            fwrite( $fr2, $buffer );
2501        }
2502        if ( isset( $gzdata ) && $gz ) {
2503            wp_cache_debug( 'Writing gzipped buffer to supercache file.' );
2504            fwrite( $gz, $gzdata );
2505        }
2506    }
2507
2508    if ( $fr ) {
2509        $supercacheonly = false;
2510        fclose( $fr );
2511        if ( filesize( $tmp_wpcache_filename ) == 0 ) {
2512            wp_cache_debug( "Warning! The file $tmp_wpcache_filename was empty. Did not rename to {$dir}{$cache_filename}", 5 );
2513            @unlink( $tmp_wpcache_filename );
2514        } else {
2515            if ( ! @rename( $tmp_wpcache_filename, $dir . $cache_filename ) ) {
2516                if ( false == is_dir( $dir ) ) {
2517                    @wp_mkdir_p( $dir );
2518                }
2519                @unlink( $dir . $cache_filename );
2520                @rename( $tmp_wpcache_filename, $dir . $cache_filename );
2521            }
2522            if ( file_exists( $dir . $cache_filename ) ) {
2523                wp_cache_debug( "Renamed temp wp-cache file to {$dir}{$cache_filename}", 5 );
2524            } else {
2525                wp_cache_debug( "FAILED to rename temp wp-cache file to {$dir}{$cache_filename}", 5 );
2526            }
2527            $added_cache = 1;
2528        }
2529    }
2530
2531    if ( $fr2 ) {
2532        fclose( $fr2 );
2533        if ( $wp_cache_front_page_checks && $cache_fname == $supercachedir . $home_url['path'] . supercache_filename() && ! ( $wp_cache_is_home ) ) {
2534            wp_cache_writers_exit();
2535            wp_cache_debug( 'Warning! Not writing another page to front page cache.', 1 );
2536            return $buffer;
2537        } elseif ( @filesize( $tmp_cache_filename ) == 0 ) {
2538            wp_cache_debug( "Warning! The file $tmp_cache_filename was empty. Did not rename to {$cache_fname}", 5 );
2539            @unlink( $tmp_cache_filename );
2540        } else {
2541            if ( ! @rename( $tmp_cache_filename, $cache_fname ) ) {
2542                @unlink( $cache_fname );
2543                @rename( $tmp_cache_filename, $cache_fname );
2544            }
2545            wp_cache_debug( "Renamed temp supercache file to $cache_fname", 5 );
2546            $added_cache = 1;
2547        }
2548    }
2549    if ( $gz ) {
2550        fclose( $gz );
2551        if ( @filesize( $tmp_cache_filename . '.gz' ) == 0 ) {
2552            wp_cache_debug( "Warning! The file {$tmp_cache_filename}.gz was empty. Did not rename to {$cache_fname}.gz", 5 );
2553            @unlink( $tmp_cache_filename . '.gz' );
2554        } else {
2555            if ( ! @rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' ) ) {
2556                @unlink( $cache_fname . '.gz' );
2557                @rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' );
2558            }
2559            wp_cache_debug( "Renamed temp supercache gz file to {$cache_fname}.gz", 5 );
2560            $added_cache = 1;
2561        }
2562    }
2563
2564    if ( $added_cache && isset( $wp_supercache_cache_list ) && $wp_supercache_cache_list ) {
2565        update_option( 'wpsupercache_count', (int) get_option( 'wpsupercache_count' ) + 1 );
2566        $last_urls = (array) get_option( 'supercache_last_cached' );
2567        if ( count( $last_urls ) >= 10 ) {
2568            $last_urls = array_slice( $last_urls, 1, 9 );
2569        }
2570        $last_urls[] = array(
2571            'url'  => preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER['REQUEST_URI'] ),
2572            'date' => date( 'Y-m-d H:i:s' ),
2573        );
2574        update_option( 'supercache_last_cached', $last_urls );
2575    }
2576    wp_cache_writers_exit();
2577    if ( ! headers_sent() && $wp_cache_gzip_encoding && $gzdata ) {
2578        wp_cache_debug( 'Writing gzip content headers. Sending buffer to browser', 5 );
2579        header( 'Content-Encoding: ' . $wp_cache_gzip_encoding );
2580        if ( defined( 'WPSC_VARY_HEADER' ) ) {
2581            if ( WPSC_VARY_HEADER != '' ) {
2582                $vary_header = WPSC_VARY_HEADER;
2583            } else {
2584                $vary_header = '';
2585            }
2586        } else {
2587            $vary_header = 'Accept-Encoding, Cookie';
2588        }
2589        if ( $vary_header ) {
2590            header( 'Vary: ' . $vary_header );
2591        }
2592        header( 'Content-Length: ' . $gzsize );
2593        return $gzdata;
2594    } else {
2595        wp_cache_debug( 'Sending buffer to browser', 5 );
2596        return $buffer;
2597    }
2598}
2599
2600function wp_cache_phase2_clean_cache( $file_prefix ) {
2601    global $wpdb, $blog_cache_dir;
2602
2603    if ( ! wp_cache_writers_entry() ) {
2604        return false;
2605    }
2606    wp_cache_debug( "wp_cache_phase2_clean_cache: Cleaning cache in $blog_cache_dir" );
2607    if ( $handle = @opendir( $blog_cache_dir ) ) {
2608        while ( false !== ( $file = @readdir( $handle ) ) ) {
2609            if ( str_contains( $file, $file_prefix ) ) {
2610                if ( strpos( $file, '.html' ) ) {
2611                    // delete old wpcache files immediately
2612                    wp_cache_debug( "wp_cache_phase2_clean_cache: Deleting obsolete wpcache cache+meta files: $file" );
2613                    @unlink( $blog_cache_dir . $file );
2614                    @unlink( $blog_cache_dir . 'meta/' . str_replace( '.html', '.meta', $file ) );
2615                } else {
2616                    $meta = json_decode( wp_cache_get_legacy_cache( $blog_cache_dir . 'meta/' . $file ), true );
2617                    if ( $meta['blog_id'] == $wpdb->blogid ) {
2618                        @unlink( $blog_cache_dir . $file );
2619                        @unlink( $blog_cache_dir . 'meta/' . $file );
2620                    }
2621                }
2622            }
2623        }
2624        closedir( $handle );
2625        do_action( 'wp_cache_cleared' );
2626    }
2627    wp_cache_writers_exit();
2628}
2629
2630function prune_super_cache( $directory, $force = false, $rename = false ) {
2631
2632    // Don't prune a NULL/empty directory.
2633    if ( null === $directory || '' === $directory ) {
2634        wp_cache_debug( 'prune_super_cache: directory is blank' );
2635        return false;
2636    }
2637
2638    global $cache_max_time, $cache_path, $blog_cache_dir;
2639    static $log                   = 0;
2640    static $protected_directories = '';
2641
2642    $dir       = $directory;
2643    $directory = wpsc_get_realpath( $directory );
2644    if ( $directory == '' ) {
2645        wp_cache_debug( "prune_super_cache: exiting as file/directory does not exist : $dir" );
2646        return false;
2647    }
2648    if ( ! wpsc_is_in_cache_directory( $directory ) ) {
2649        wp_cache_debug( "prune_super_cache: exiting as directory is not in cache path: *$directory* (was $dir before realpath)" );
2650        return false;
2651    }
2652
2653    if ( false == @file_exists( $directory ) ) {
2654        wp_cache_debug( "prune_super_cache: exiting as file/dir does not exist: $directory" );
2655        return $log;
2656    }
2657    if ( ! isset( $cache_max_time ) ) {
2658        $cache_max_time = 3600;
2659    }
2660
2661    $now = time();
2662
2663    if ( $protected_directories == '' ) {
2664        $protected_directories = wpsc_get_protected_directories();
2665    }
2666
2667    if ( is_dir( $directory ) ) {
2668        if ( $dh = @opendir( $directory ) ) {
2669            $directory = trailingslashit( $directory );
2670            while ( ( $entry = @readdir( $dh ) ) !== false ) {
2671                if ( $entry == '.' || $entry == '..' ) {
2672                    continue;
2673                }
2674                $entry = $directory . $entry;
2675                prune_super_cache( $entry, $force, $rename );
2676                // If entry is a directory, AND it's not a protected one, AND we're either forcing the delete, OR the file is out of date,
2677                if ( is_dir( $entry ) && ! in_array( $entry, $protected_directories ) && ( $force || @filemtime( $entry ) + $cache_max_time <= $now ) ) {
2678                    $donotdelete = false;
2679                    // if the directory isn't empty can't delete it
2680                    if ( $handle = @opendir( $entry ) ) {
2681                        while ( ! $donotdelete && ( $file = @readdir( $handle ) ) !== false ) {
2682                            if ( $file == '.' || $file == '..' ) {
2683                                continue;
2684                            }
2685                            $donotdelete = true;
2686                            wp_cache_debug( "gc: could not delete $entry as it's not empty: $file", 2 );
2687                        }
2688                        closedir( $handle );
2689                    }
2690                    if ( $donotdelete ) {
2691                        continue;
2692                    }
2693                    if ( ! $rename ) {
2694                        @rmdir( $entry );
2695                        ++$log;
2696                        if ( $force ) {
2697                            wp_cache_debug( "gc: deleted $entry, forced delete", 2 );
2698                        } else {
2699                            wp_cache_debug( "gc: deleted $entry, older than $cache_max_time seconds", 2 );
2700                        }
2701                    }
2702                } elseif ( in_array( $entry, $protected_directories ) ) {
2703                    wp_cache_debug( "gc: could not delete $entry as it's protected.", 2 );
2704                }
2705            }
2706            closedir( $dh );
2707        }
2708    } elseif ( is_file( $directory ) && ( $force || @filemtime( $directory ) + $cache_max_time <= $now ) ) {
2709        $oktodelete = true;
2710        if ( in_array( $directory, $protected_directories ) ) {
2711            wp_cache_debug( "gc: could not delete $directory as it's protected.", 2 );
2712            $oktodelete = false;
2713        }
2714        if ( $oktodelete && ! $rename ) {
2715            wp_cache_debug( "prune_super_cache: deleted $directory", 5 );
2716            @unlink( $directory );
2717            ++$log;
2718        } elseif ( $oktodelete && $rename ) {
2719            wp_cache_debug( "prune_super_cache: wp_cache_rebuild_or_delete( $directory )", 5 );
2720            wp_cache_rebuild_or_delete( $directory );
2721            ++$log;
2722        } else {
2723            wp_cache_debug( "prune_super_cache: did not delete file: $directory" );
2724        }
2725    } else {
2726            wp_cache_debug( "prune_super_cache: did not delete file as it wasn't a directory or file and not forced to delete new file: $directory" );
2727    }
2728    return $log;
2729}
2730
2731function wp_cache_rebuild_or_delete( $file ) {
2732    global $cache_rebuild_files, $cache_path, $file_prefix;
2733
2734    if ( strpos( $file, '?' ) !== false ) {
2735        $file = substr( $file, 0, strpos( $file, '?' ) );
2736    }
2737
2738    $file = wpsc_get_realpath( $file );
2739
2740    if ( ! $file ) {
2741        wp_cache_debug( "wp_cache_rebuild_or_delete: file doesn't exist" );
2742        return false;
2743    }
2744
2745    if ( ! wpsc_is_in_cache_directory( $file ) ) {
2746        wp_cache_debug( "rebuild_or_gc quitting because file is not in cache_path: $file" );
2747        return false;
2748    }
2749
2750    $protected = wpsc_get_protected_directories();
2751    foreach ( $protected as $id => $directory ) {
2752        $protected[ $id ] = wpsc_get_realpath( $directory );
2753    }
2754
2755    if ( in_array( $file, $protected ) ) {
2756        wp_cache_debug( "rebuild_or_gc: file is protected: $file" );
2757        return false;
2758    }
2759
2760    if ( substr( basename( $file ), 0, mb_strlen( $file_prefix ) ) == $file_prefix ) {
2761        @unlink( $file );
2762        wp_cache_debug( "rebuild_or_gc: deleted non-anonymous file: $file" );
2763        return false;
2764    }
2765
2766    if ( substr( basename( $file ), 0, 5 + mb_strlen( $file_prefix ) ) == 'meta-' . $file_prefix ) {
2767        @unlink( $file );
2768        wp_cache_debug( "rebuild_or_gc: deleted meta file: $file" );
2769        return false;
2770    }
2771
2772    if ( false == @file_exists( $file ) ) {
2773        wp_cache_debug( "rebuild_or_gc: file has disappeared: $file" );
2774        return false;
2775    }
2776    if ( $cache_rebuild_files && substr( $file, -14 ) != '.needs-rebuild' ) {
2777        if ( @rename( $file, $file . '.needs-rebuild' ) ) {
2778            @touch( $file . '.needs-rebuild' );
2779            wp_cache_debug( "rebuild_or_gc: rename file to {$file}.needs-rebuild", 2 );
2780        } else {
2781            @unlink( $file );
2782            wp_cache_debug( "rebuild_or_gc: rename failed. deleted $file", 2 );
2783        }
2784    } else {
2785        $mtime = @filemtime( $file );
2786        if ( $mtime && ( time() - $mtime ) > 10 ) {
2787            @unlink( $file );
2788            wp_cache_debug( "rebuild_or_gc: rebuild file found. deleted because it was too old: $file", 2 );
2789        }
2790    }
2791}
2792
2793function wp_cache_phase2_clean_expired( $file_prefix, $force = false ) {
2794    global $cache_path, $cache_max_time, $blog_cache_dir, $wp_cache_preload_on, $wp_cache_debug_log;
2795
2796    if ( $cache_max_time == 0 ) {
2797        wp_cache_debug( 'wp_cache_phase2_clean_expired: disabled because GC disabled.', 2 );
2798        return false;
2799    }
2800
2801    clearstatcache();
2802    if ( ! wp_cache_writers_entry() ) {
2803        return false;
2804    }
2805
2806    // make sure we have a debug log viewer
2807    if ( empty( $wp_cache_debug_log ) ) {
2808        wpsc_create_debug_log();
2809    } else {
2810        touch( $cache_path . 'view_' . $wp_cache_debug_log ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_touch
2811    }
2812
2813    $now = time();
2814    wp_cache_debug( "Cleaning expired cache files in $blog_cache_dir", 2 );
2815    $deleted = 0;
2816    if ( ( $handle = @opendir( $blog_cache_dir ) ) ) {
2817        while ( false !== ( $file = readdir( $handle ) ) ) {
2818            if ( preg_match( "/^$file_prefix/", $file ) &&
2819                ( @filemtime( $blog_cache_dir . $file ) + $cache_max_time ) <= $now ) {
2820                @unlink( $blog_cache_dir . $file );
2821                @unlink( $blog_cache_dir . 'meta/' . str_replace( '.html', '.meta', $file ) );
2822                wp_cache_debug( "wp_cache_phase2_clean_expired: Deleting obsolete wpcache cache+meta files: $file" );
2823                continue;
2824            }
2825            if ( $file != '.' && $file != '..' ) {
2826                if ( is_dir( $blog_cache_dir . $file ) == false && ( @filemtime( $blog_cache_dir . $file ) + $cache_max_time ) <= $now ) {
2827                    if ( substr( $file, -9 ) != '.htaccess' && $file != 'index.html' ) {
2828                        @unlink( $blog_cache_dir . $file );
2829                        wp_cache_debug( "Deleting $blog_cache_dir{$file}, older than $cache_max_time seconds", 5 );
2830                    }
2831                }
2832            }
2833        }
2834        closedir( $handle );
2835        if ( false == $wp_cache_preload_on || true == $force ) {
2836            wp_cache_debug( "Doing GC on supercache dir: {$cache_path}supercache", 2 );
2837            $deleted = prune_super_cache( $cache_path . 'supercache', false, false );
2838        }
2839    }
2840
2841    wp_cache_writers_exit();
2842    return $deleted;
2843}
2844
2845function wp_cache_shutdown_callback() {
2846    global $cache_max_time, $meta_file, $new_cache, $wp_cache_meta, $known_headers, $blog_id, $wp_cache_gzip_encoding, $supercacheonly, $blog_cache_dir;
2847    global $wp_cache_request_uri, $wp_cache_key, $cache_enabled, $wp_cache_blog_charset, $wp_cache_not_logged_in;
2848    global $WPSC_HTTP_HOST, $wp_super_cache_query;
2849
2850    if ( ! function_exists( 'wpsc_init' ) ) {
2851        /*
2852         * If a server has multiple networks the plugin may not have been activated
2853         * on all of them. Give feeds on those blogs a short TTL.
2854         * ref: https://wordpress.org/support/topic/fatal-error-while-updating-post-or-publishing-new-one/
2855         */
2856        $wpsc_feed_ttl = 1;
2857        wp_cache_debug( 'wp_cache_shutdown_callback: Plugin not loaded. Setting feed ttl to 60 seconds.' );
2858    }
2859
2860    if ( false == $new_cache ) {
2861        wp_cache_debug( 'wp_cache_shutdown_callback: No cache file created. Returning.' );
2862        return false;
2863    }
2864
2865    $wp_cache_meta['uri']     = $WPSC_HTTP_HOST . preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $wp_cache_request_uri ); // To avoid XSS attacks
2866    $wp_cache_meta['blog_id'] = $blog_id;
2867    $wp_cache_meta['post']    = wp_cache_post_id();
2868    $wp_cache_meta['key']     = $wp_cache_key;
2869    $wp_cache_meta            = apply_filters( 'wp_cache_meta', $wp_cache_meta );
2870
2871    $response = wp_cache_get_response_headers();
2872    foreach ( $response as $key => $value ) {
2873        $wp_cache_meta['headers'][ $key ] = "$key$value";
2874    }
2875
2876    wp_cache_debug( 'wp_cache_shutdown_callback: collecting meta data.', 2 );
2877
2878    if ( ! isset( $response['Last-Modified'] ) ) {
2879        $value = gmdate( 'D, d M Y H:i:s' ) . ' GMT';
2880        // Don't send this the first time
2881        /* @header('Last-Modified: ' . $value); */
2882        $wp_cache_meta['headers']['Last-Modified'] = "Last-Modified: $value";
2883    }
2884    $is_feed = false;
2885    if ( ! isset( $response['Content-Type'] ) && ! isset( $response['Content-type'] ) ) {
2886        // On some systems, headers set by PHP can't be fetched from
2887        // the output buffer. This is a last ditch effort to set the
2888        // correct Content-Type header for feeds, if we didn't see
2889        // it in the response headers already. -- dougal
2890        if ( isset( $wp_super_cache_query['is_feed'] ) ) {
2891            if ( isset( $wp_super_cache_query['is_sitemap'] ) ) {
2892                $type  = 'sitemap';
2893                $value = 'text/xml';
2894            } else {
2895                $type = get_query_var( 'feed' );
2896                $type = str_replace( '/', '', $type );
2897                switch ( $type ) {
2898                    case 'atom':
2899                        $value = 'application/atom+xml';
2900                        break;
2901                    case 'rdf':
2902                        $value = 'application/rdf+xml';
2903                        break;
2904                    case 'rss':
2905                    case 'rss2':
2906                    default:
2907                        $value = 'application/rss+xml';
2908                }
2909            }
2910
2911            if ( isset( $wpsc_feed_ttl ) && $wpsc_feed_ttl == 1 ) {
2912                $wp_cache_meta['ttl'] = 60;
2913            }
2914            $is_feed = true;
2915
2916            wp_cache_debug( "wp_cache_shutdown_callback: feed is type: $type - $value" );
2917        } elseif ( isset( $wp_super_cache_query['is_rest'] ) ) { // json
2918            $value = 'application/json';
2919        } else { // not a feed
2920            $value = get_option( 'html_type' );
2921            if ( $value == '' ) {
2922                $value = 'text/html';
2923            }
2924        }
2925        $value .= '; charset="' . $wp_cache_blog_charset . '"';
2926
2927        wp_cache_debug( "Sending 'Content-Type: $value' header.", 2 );
2928        @header( "Content-Type: $value" );
2929        $wp_cache_meta['headers']['Content-Type'] = "Content-Type: $value";
2930    }
2931
2932    if ( $cache_enabled && ! $supercacheonly ) {
2933        if ( ! isset( $wp_cache_meta['dynamic'] ) && $wp_cache_gzip_encoding && ! in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $wp_cache_meta['headers'] ) ) {
2934            wp_cache_debug( 'Sending gzip headers.', 2 );
2935            $wp_cache_meta['headers']['Content-Encoding'] = 'Content-Encoding: ' . $wp_cache_gzip_encoding;
2936            if ( defined( 'WPSC_VARY_HEADER' ) ) {
2937                if ( WPSC_VARY_HEADER != '' ) {
2938                    $vary_header = WPSC_VARY_HEADER;
2939                } else {
2940                    $vary_header = '';
2941                }
2942            } else {
2943                $vary_header = 'Accept-Encoding, Cookie';
2944            }
2945            if ( $vary_header ) {
2946                $wp_cache_meta['headers']['Vary'] = 'Vary: ' . $vary_header;
2947            }
2948        }
2949
2950        $serial = '<?php die(); ?>' . wp_json_encode( $wp_cache_meta, JSON_UNESCAPED_SLASHES );
2951        $dir    = get_current_url_supercache_dir();
2952        if ( @is_dir( $dir ) == false ) {
2953            @wp_mkdir_p( $dir );
2954        }
2955
2956        if ( wp_cache_writers_entry() ) {
2957            wp_cache_debug( "Writing meta file: {$dir}meta-{$meta_file}", 2 );
2958
2959            $tmp_meta_filename   = $dir . uniqid( (string) wp_rand(), true ) . '.tmp';
2960            $final_meta_filename = $dir . 'meta-' . $meta_file;
2961            $fr                  = @fopen( $tmp_meta_filename, 'w' );
2962            if ( $fr ) {
2963                fwrite( $fr, $serial );
2964                fclose( $fr );
2965                @chmod( $tmp_meta_filename, 0666 & ~umask() );
2966                if ( ! @rename( $tmp_meta_filename, $final_meta_filename ) ) {
2967                    @unlink( $dir . $final_meta_filename );
2968                    @rename( $tmp_meta_filename, $final_meta_filename );
2969                }
2970            } else {
2971                wp_cache_debug( "Problem writing meta file: {$final_meta_filename}" );
2972            }
2973            wp_cache_writers_exit();
2974
2975            // record locations of archive feeds to be updated when the site is updated.
2976            // Only record a maximum of 50 feeds to avoid bloating database.
2977            if ( ( isset( $wp_super_cache_query['is_feed'] ) || $is_feed ) && ! isset( $wp_super_cache_query['is_single'] ) ) {
2978                $wpsc_feed_list = (array) get_option( 'wpsc_feed_list' );
2979                if ( count( $wpsc_feed_list ) <= 50 ) {
2980                    $wpsc_feed_list[] = $dir . $meta_file;
2981                    update_option( 'wpsc_feed_list', $wpsc_feed_list );
2982                }
2983            }
2984        }
2985    } else {
2986        wp_cache_debug( "Did not write meta file: meta-{$meta_file}\nsupercacheonly: $supercacheonly\nwp_cache_not_logged_in: $wp_cache_not_logged_in\nnew_cache:$new_cache" );
2987    }
2988    global $time_to_gc_cache;
2989    if ( isset( $time_to_gc_cache ) && $time_to_gc_cache == 1 ) {
2990        wp_cache_debug( 'Executing wp_cache_gc action.', 3 );
2991        do_action( 'wp_cache_gc' );
2992    }
2993}
2994
2995function wp_cache_no_postid( $id ) {
2996    return wp_cache_post_change( wp_cache_post_id() );
2997}
2998
2999function wp_cache_get_postid_from_comment( $comment_id, $status = 'NA' ) {
3000    global $super_cache_enabled, $wp_cache_request_uri;
3001
3002    if ( defined( 'DONOTDELETECACHE' ) ) {
3003        return;
3004    }
3005
3006    // Check is it "Empty Spam" or "Empty Trash"
3007    if ( isset( $GLOBALS['pagenow'] ) && $GLOBALS['pagenow'] === 'edit-comments.php' &&
3008        ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) )
3009    ) {
3010        wp_cache_debug( "Delete all SPAM or Trash comments. Don't delete any cache files.", 4 );
3011        define( 'DONOTDELETECACHE', 1 );
3012        return;
3013    }
3014
3015    $comment = get_comment( $comment_id, ARRAY_A );
3016    if ( $status != 'NA' ) {
3017        $comment['old_comment_approved'] = $comment['comment_approved'];
3018        $comment['comment_approved']     = $status;
3019    }
3020
3021    if ( ( $status == 'trash' || $status == 'spam' ) && $comment['old_comment_approved'] != 1 ) {
3022        // don't modify cache if moderated comments are trashed or spammed
3023        wp_cache_debug( "Moderated comment deleted or spammed. Don't delete any cache files.", 4 );
3024        define( 'DONOTDELETECACHE', 1 );
3025        return wp_cache_post_id();
3026    }
3027    $postid = isset( $comment['comment_post_ID'] ) ? (int) $comment['comment_post_ID'] : 0;
3028    // Do nothing if comment is not moderated
3029    // http://ocaoimh.ie/2006/12/05/caching-wordpress-with-wp-cache-in-a-spam-filled-world
3030    if ( ! preg_match( '/wp-admin\//', $wp_cache_request_uri ) ) {
3031        if ( $comment['comment_approved'] == 'delete' && ( isset( $comment['old_comment_approved'] ) && $comment['old_comment_approved'] == 0 ) ) { // do nothing if moderated comments are deleted
3032            wp_cache_debug( "Moderated comment deleted. Don't delete any cache files.", 4 );
3033            define( 'DONOTDELETECACHE', 1 );
3034            return $postid;
3035        } elseif ( $comment['comment_approved'] == 'spam' ) {
3036            wp_cache_debug( "Spam comment. Don't delete any cache files.", 4 );
3037            define( 'DONOTDELETECACHE', 1 );
3038            return $postid;
3039        } elseif ( $comment['comment_approved'] == '0' ) {
3040            if ( $comment['comment_type'] == '' ) {
3041                wp_cache_debug( "Moderated comment. Don't delete supercache file until comment approved.", 4 );
3042                $super_cache_enabled = 0; // don't remove the super cache static file until comment is approved
3043                define( 'DONOTDELETECACHE', 1 );
3044            } else {
3045                wp_cache_debug( 'Moderated ping or trackback. Not deleting cache files..', 4 );
3046                define( 'DONOTDELETECACHE', 1 );
3047                return $postid;
3048            }
3049        }
3050    }
3051    // We must check it up again due to WP bugs calling two different actions
3052    // for delete, for example both wp_set_comment_status and delete_comment
3053    // are called when deleting a comment
3054    if ( $postid > 0 ) {
3055        wp_cache_debug( "Post $postid changed. Update cache.", 4 );
3056        return wp_cache_post_change( $postid );
3057    } else {
3058        wp_cache_debug( 'Unknown post changed. Update cache.', 4 );
3059        return wp_cache_post_change( wp_cache_post_id() );
3060    }
3061}
3062
3063/* Used by wp_update_nav_menu action to clear current blog's cache files when navigation menu is modified */
3064function wp_cache_clear_cache_on_menu() {
3065    global $wpdb;
3066    wp_cache_clear_cache( $wpdb->blogid );
3067}
3068
3069/* Clear out the cache directory. */
3070function wp_cache_clear_cache( $blog_id = 0 ) {
3071    global $cache_path;
3072
3073    if ( $blog_id == 0 ) {
3074        wp_cache_debug( 'Clearing all cached files in wp_cache_clear_cache()', 4 );
3075        prune_super_cache( $cache_path . 'supercache/', true );
3076        prune_super_cache( $cache_path, true );
3077    } else {
3078        wp_cache_debug( "Clearing all cached files for blog $blog_id in wp_cache_clear_cache()", 4 );
3079        prune_super_cache( get_supercache_dir( $blog_id ), true );
3080        prune_super_cache( $cache_path . 'blogs/', true );
3081    }
3082
3083    do_action( 'wp_cache_cleared' );
3084}
3085
3086function wpsc_delete_post_archives( $post ) {
3087    $post = @get_post( $post );
3088    if ( ! is_object( $post ) ) {
3089        return;
3090    }
3091
3092    // Taxonomies - categories, tags, custom taxonomies
3093    foreach ( get_object_taxonomies( $post, 'objects' ) as $taxonomy ) {
3094
3095        if ( ! $taxonomy->public || ! $taxonomy->rewrite ) {
3096            continue;
3097        }
3098
3099        $terms = get_the_terms( $post->ID, $taxonomy->name );
3100        if ( empty( $terms ) ) {
3101            continue;
3102        }
3103
3104        foreach ( $terms as $term ) {
3105
3106            $term_url = get_term_link( $term, $taxonomy->name );
3107            if ( is_wp_error( $term_url ) ) {
3108                continue;
3109            }
3110
3111            wpsc_delete_url_cache( $term_url );
3112            wp_cache_debug( 'wpsc_delete_post_archives: deleting cache of taxonomies: ' . $term_url );
3113        }
3114    }
3115
3116    // Post type archive page
3117    if ( $post->post_type === 'page' ) {
3118        $archive_url = false;
3119    } elseif ( $post->post_type === 'post' && get_option( 'show_on_front' ) !== 'posts' && ! get_option( 'page_for_posts' ) ) {
3120        $archive_url = false;
3121    } else {
3122        $archive_url = get_post_type_archive_link( $post->post_type );
3123    }
3124
3125    if ( $archive_url ) {
3126        wpsc_delete_url_cache( $archive_url );
3127        wp_cache_debug( 'wpsc_delete_post_archives: deleting cache of post type archive: ' . $archive_url );
3128    }
3129
3130    // Author archive page
3131    $author_url = get_author_posts_url( $post->post_author );
3132    if ( $author_url ) {
3133        wpsc_delete_url_cache( $author_url );
3134        wp_cache_debug( 'wpsc_delete_post_archives: deleting cache of author archive: ' . $author_url );
3135    }
3136}
3137
3138function wpsc_delete_cats_tags( $post ) {
3139    if ( function_exists( '_deprecated_function' ) ) {
3140        _deprecated_function( __FUNCTION__, 'WP Super Cache 1.6.3', 'wpsc_delete_post_archives' );
3141    }
3142
3143    $post       = get_post( $post );
3144    $categories = get_the_category( $post->ID );
3145    if ( $categories ) {
3146        $category_base = get_option( 'category_base' );
3147        if ( $category_base == '' ) {
3148            $category_base = '/category/';
3149        }
3150        $category_base = trailingslashit( $category_base ); // paranoid much?
3151        foreach ( $categories as $cat ) {
3152            prune_super_cache( get_supercache_dir() . $category_base . $cat->slug . '/', true );
3153            wp_cache_debug( 'wpsc_post_transition: deleting category: ' . get_supercache_dir() . $category_base . $cat->slug . '/' );
3154        }
3155    }
3156    $posttags = get_the_tags( $post->ID );
3157    if ( $posttags ) {
3158        $tag_base = get_option( 'tag_base' );
3159        if ( $tag_base == '' ) {
3160            $tag_base = '/tag/';
3161        }
3162        $tag_base = trailingslashit( str_replace( '..', '', $tag_base ) ); // maybe!
3163        foreach ( $posttags as $tag ) {
3164            prune_super_cache( get_supercache_dir() . $tag_base . $tag->slug . '/', true );
3165            wp_cache_debug( 'wpsc_post_transition: deleting tag: ' . get_supercache_dir() . $tag_base . $tag->slug . '/' );
3166        }
3167    }
3168}
3169
3170function wpsc_post_transition( $new_status, $old_status, $post ) {
3171
3172    $ptype = is_object( $post ) ? get_post_type_object( $post->post_type ) : null;
3173    if ( empty( $ptype ) || ! $ptype->public ) {
3174        return;
3175    }
3176
3177    // Allow plugins to reject cache clears for specific posts.
3178    if ( ! apply_filters( 'wp_super_cache_clear_post_cache', true, $post ) ) {
3179        return;
3180    }
3181
3182    if ( ( $old_status === 'private' || $old_status === 'publish' ) && $new_status !== 'publish' ) { // post unpublished
3183        if ( ! function_exists( 'get_sample_permalink' ) ) {
3184            require_once ABSPATH . 'wp-admin/includes/post.php';
3185        }
3186        list( $permalink, $post_name ) = get_sample_permalink( $post );
3187        $post_url                      = str_replace( array( '%postname%', '%pagename%' ), $post->post_name, $permalink );
3188        wp_cache_post_edit( $post->ID );
3189    } elseif ( $old_status !== 'publish' && $new_status === 'publish' ) { // post published
3190        wp_cache_post_edit( $post->ID );
3191        return;
3192    }
3193
3194    if ( ! empty( $post_url ) ) {
3195        wp_cache_debug( 'wpsc_post_transition: deleting cache of post: ' . $post_url );
3196        wpsc_delete_url_cache( $post_url );
3197        wpsc_delete_post_archives( $post );
3198    }
3199}
3200
3201/* check if we want to clear out all cached files on post updates, otherwise call standard wp_cache_post_change() */
3202function wp_cache_post_edit( $post_id ) {
3203    global $wp_cache_clear_on_post_edit, $cache_path, $blog_cache_dir;
3204    static $last_post_edited = -1;
3205
3206    if ( $post_id == $last_post_edited ) {
3207        $action = current_filter();
3208        wp_cache_debug( "wp_cache_post_edit({$action}): Already processed post $post_id.", 4 );
3209        return $post_id;
3210    }
3211
3212    $post = get_post( $post_id );
3213    if ( ! is_object( $post ) || 'auto-draft' === $post->post_status ) {
3214        return $post_id;
3215    }
3216
3217    // Allow plugins to reject cache clears for specific posts.
3218    if ( ! apply_filters( 'wp_super_cache_clear_post_cache', true, $post ) ) {
3219        return $post_id;
3220    }
3221
3222    // Some users are inexplicibly seeing this error on scheduled posts.
3223    // define this constant to disable the post status check.
3224    if ( ! defined( 'WPSCFORCEUPDATE' ) && ! in_array( get_post_status( $post ), array( 'publish', 'private' ), true ) ) {
3225        wp_cache_debug( 'wp_cache_post_edit: draft post, not deleting any cache files. status: ' . $post->post_status, 4 );
3226        return $post_id;
3227    }
3228
3229    // we want to process the post again just in case it becomes published before the second time this function is called.
3230    $last_post_edited = $post_id;
3231    if ( $wp_cache_clear_on_post_edit ) {
3232        wp_cache_debug( "wp_cache_post_edit: Clearing cache $blog_cache_dir and {$cache_path}supercache/ on post edit per config.", 2 );
3233        prune_super_cache( $blog_cache_dir, true );
3234        prune_super_cache( get_supercache_dir(), true );
3235
3236        do_action( 'wp_cache_cleared' );
3237    } else {
3238        $action = current_filter();
3239        wp_cache_debug( "wp_cache_post_edit: Clearing cache for post $post_id on {$action}", 2 );
3240        wp_cache_post_change( $post_id );
3241        wpsc_delete_post_archives( $post_id ); // delete related archive pages.
3242    }
3243}
3244
3245function wp_cache_post_id_gc( $post_id, $all = 'all' ) {
3246
3247    $post_id = intval( $post_id );
3248    if ( $post_id == 0 ) {
3249        return true;
3250    }
3251
3252    $permalink = trailingslashit( str_replace( get_option( 'home' ), '', get_permalink( $post_id ) ) );
3253    if ( str_contains( $permalink, '?' ) ) {
3254        wp_cache_debug( 'wp_cache_post_id_gc: NOT CLEARING CACHE. Permalink has a "?". ' . $permalink );
3255        return false;
3256    }
3257    $dir = get_current_url_supercache_dir( $post_id );
3258    wp_cache_debug( "wp_cache_post_id_gc post_id: $post_id " . get_permalink( $post_id ) . " clearing cache in $dir.", 4 );
3259    if ( $all ) {
3260        prune_super_cache( $dir, true, true );
3261        do_action( 'gc_cache', 'prune', $permalink );
3262        @rmdir( $dir );
3263        $supercache_home = get_supercache_dir();
3264        wp_cache_debug( "wp_cache_post_id_gc clearing cache in {$supercache_home}page/." );
3265        prune_super_cache( $supercache_home . 'page/', true );
3266        do_action( 'gc_cache', 'prune', 'page/' );
3267    } else {
3268        wp_cache_debug( "wp_cache_post_id_gc clearing cached index files in $dir.", 4 );
3269        prune_super_cache( $dir, true, true );
3270        do_action( 'gc_cache', 'prune', $permalink );
3271    }
3272    return true;
3273}
3274
3275function wp_cache_post_change( $post_id ) {
3276    global $file_prefix, $cache_path, $blog_id, $super_cache_enabled, $blog_cache_dir, $wp_cache_refresh_single_only;
3277    static $last_processed = -1;
3278
3279    if ( $post_id == $last_processed ) {
3280        $action = current_filter();
3281        wp_cache_debug( "wp_cache_post_change({$action}): Already processed post $post_id.", 4 );
3282        return $post_id;
3283    }
3284
3285    $post  = get_post( $post_id );
3286    $ptype = is_object( $post ) ? get_post_type_object( $post->post_type ) : null;
3287    if ( empty( $ptype ) || ! $ptype->public ) {
3288        return $post_id;
3289    }
3290
3291    // Allow plugins to reject cache clears for specific posts.
3292    if ( ! apply_filters( 'wp_super_cache_clear_post_cache', true, $post ) ) {
3293        return $post_id;
3294    }
3295
3296    // Some users are inexplicibly seeing this error on scheduled posts.
3297    // define this constant to disable the post status check.
3298    if ( ! defined( 'WPSCFORCEUPDATE' ) && ! in_array( get_post_status( $post ), array( 'publish', 'private' ), true ) ) {
3299        wp_cache_debug( 'wp_cache_post_change: draft post, not deleting any cache files.', 4 );
3300        return $post_id;
3301    }
3302    $last_processed = $post_id;
3303
3304    if ( ! wp_cache_writers_entry() ) {
3305        return $post_id;
3306    }
3307
3308    if (
3309        isset( $wp_cache_refresh_single_only ) &&
3310        $wp_cache_refresh_single_only &&
3311        (
3312            isset( $_SERVER['HTTP_REFERER'] ) &&
3313            strpos( $_SERVER['HTTP_REFERER'], 'edit-comments.php' ) ||
3314            strpos( $_SERVER['REQUEST_URI'], 'wp-comments-post.php' )
3315        )
3316    ) {
3317        if ( defined( 'DONOTDELETECACHE' ) ) {
3318            wp_cache_debug( "wp_cache_post_change: comment detected and it's moderated or spam. Not deleting cached files.", 4 );
3319            return $post_id;
3320        } else {
3321            wp_cache_debug( 'wp_cache_post_change: comment detected. only deleting post page.', 4 );
3322            $all = false;
3323        }
3324    } else {
3325        $all = true;
3326    }
3327
3328    $all_backup = $all;
3329    $all        = apply_filters( 'wpsc_delete_related_pages_on_edit', $all ); // return 0 to disable deleting homepage and other pages.
3330    if ( $all != $all_backup ) {
3331        wp_cache_debug( 'wp_cache_post_change: $all changed by wpsc_delete_related_pages_on_edit filter: ' . intval( $all ) );
3332    }
3333
3334    // Delete supercache files whenever a post change event occurs, even if supercache is currently disabled.
3335    $dir = get_supercache_dir();
3336    // make sure the front page has a rebuild file
3337    if ( false == wp_cache_post_id_gc( $post_id, $all ) ) {
3338        wp_cache_debug( 'wp_cache_post_change: not deleting any cache files as GC of post returned false' );
3339        wp_cache_writers_exit();
3340        return false;
3341    }
3342    if ( $all == true ) {
3343        wp_cache_debug( 'Post change: supercache enabled: deleting cache files in ' . $dir );
3344        wpsc_rebuild_files( $dir );
3345        do_action( 'gc_cache', 'prune', 'homepage' );
3346        if ( get_option( 'show_on_front' ) == 'page' ) {
3347            wp_cache_debug( 'Post change: deleting page_on_front and page_for_posts pages.', 4 );
3348            wp_cache_debug( 'Post change: page_on_front ' . get_option( 'page_on_front' ), 4 );
3349            /**
3350             * It's possible that page_for_posts is zero.
3351             * Quick fix to reduce issues in debugging.
3352             */
3353            wp_cache_debug( 'Post change: page_for_posts ' . get_option( 'page_for_posts' ), 4 );
3354            if ( get_option( 'page_for_posts' ) ) {
3355                $permalink = trailingslashit( str_replace( get_option( 'home' ), '', get_permalink( get_option( 'page_for_posts' ) ) ) );
3356                wp_cache_debug( 'Post change: Deleting files in: ' . str_replace( '//', '/', $dir . $permalink ) );
3357                wpsc_rebuild_files( $dir . $permalink );
3358                do_action( 'gc_cache', 'prune', $permalink );
3359            }
3360        }
3361    } else {
3362        wp_cache_debug( 'wp_cache_post_change: not deleting all pages.', 4 );
3363    }
3364
3365    wp_cache_debug( "wp_cache_post_change: checking {$blog_cache_dir}meta/", 4 );
3366    $supercache_files_deleted = false;
3367    if ( $handle = @opendir( $blog_cache_dir ) ) {
3368        while ( false !== ( $file = readdir( $handle ) ) ) {
3369            if ( str_contains( $file, $file_prefix ) ) {
3370                if ( strpos( $file, '.html' ) ) {
3371                    // delete old wpcache files immediately
3372                    wp_cache_debug( "wp_cache_post_change: Deleting obsolete wpcache cache+meta files: $file" );
3373                    @unlink( $blog_cache_dir . $file );
3374                    @unlink( $blog_cache_dir . 'meta/' . str_replace( '.html', '.meta', $file ) );
3375                    continue;
3376                } else {
3377                    $meta = json_decode( wp_cache_get_legacy_cache( $blog_cache_dir . 'meta/' . $file ), true );
3378                    if ( false == is_array( $meta ) ) {
3379                        wp_cache_debug( "Post change cleaning up stray file: $file", 4 );
3380                        @unlink( $blog_cache_dir . 'meta/' . $file );
3381                        @unlink( $blog_cache_dir . $file );
3382                        continue;
3383                    }
3384                    if ( $post_id > 0 && $meta ) {
3385                        $permalink = trailingslashit( str_replace( get_option( 'home' ), '', get_permalink( $post_id ) ) );
3386                        if ( $meta['blog_id'] == $blog_id && ( ( $all == true && ! $meta['post'] ) || $meta['post'] == $post_id ) ) {
3387                            wp_cache_debug( "Post change: deleting post wp-cache files for {$meta[ 'uri' ]}$file", 4 );
3388                            @unlink( $blog_cache_dir . 'meta/' . $file );
3389                            @unlink( $blog_cache_dir . $file );
3390                            if ( false == $supercache_files_deleted && $super_cache_enabled == true ) {
3391                                wp_cache_debug( "Post change: deleting supercache files for {$permalink}" );
3392                                wpsc_rebuild_files( $dir . $permalink );
3393                                $supercache_files_deleted = true;
3394                                do_action( 'gc_cache', 'rebuild', $permalink );
3395                            }
3396                        }
3397                    } elseif ( $meta['blog_id'] == $blog_id ) {
3398                        wp_cache_debug( "Post change: deleting wp-cache files for {$meta[ 'uri' ]}$file", 4 );
3399                        @unlink( $blog_cache_dir . 'meta/' . $file );
3400                        @unlink( $blog_cache_dir . $file );
3401                        if ( $super_cache_enabled == true ) {
3402                            wp_cache_debug( "Post change: deleting supercache files for {$meta[ 'uri' ]}" );
3403                            wpsc_rebuild_files( $dir . $meta['uri'] );
3404                            do_action( 'gc_cache', 'rebuild', trailingslashit( $meta['uri'] ) );
3405                        }
3406                    }
3407                }
3408            }
3409        }
3410        closedir( $handle );
3411    }
3412    wp_cache_writers_exit();
3413    return $post_id;
3414}
3415
3416function wp_cache_microtime_diff( $a, $b ) {
3417    list($a_dec, $a_sec) = explode( ' ', $a );
3418    list($b_dec, $b_sec) = explode( ' ', $b );
3419    return (float) $b_sec - (float) $a_sec + (float) $b_dec - (float) $a_dec;
3420}
3421
3422function wp_cache_post_id() {
3423    global $posts, $comment_post_ID, $post_ID;
3424    // We try hard all options. More frequent first.
3425    if ( $post_ID > 0 ) {
3426        return $post_ID;
3427    }
3428    if ( $comment_post_ID > 0 ) {
3429        return $comment_post_ID;
3430    }
3431    if ( is_singular() && ! empty( $posts ) && is_array( $posts ) ) {
3432        return $posts[0]->ID;
3433    }
3434    if ( isset( $_GET['p'] ) && $_GET['p'] > 0 ) {
3435        return $_GET['p'];
3436    }
3437    if ( isset( $_POST['p'] ) && $_POST['p'] > 0 ) {
3438        return $_POST['p'];
3439    }
3440    return 0;
3441}
3442
3443function maybe_stop_gc( $flag ) {
3444
3445    if ( @file_exists( $flag ) ) {
3446        if ( time() - filemtime( $flag ) > 3600 ) {
3447            @unlink( $flag );
3448            wp_cache_debug( "maybe_stop_gc: GC flag found but deleted because it's older than 3600 seconds.", 5 );
3449            return false;
3450        } else {
3451            wp_cache_debug( 'maybe_stop_gc: GC flag found. GC cancelled.', 5 );
3452            return true;
3453        }
3454    } else {
3455        wp_cache_debug( 'maybe_stop_gc: GC flag not found. GC will go ahead..', 5 );
3456        return false;
3457    }
3458}
3459function get_gc_flag() {
3460    global $cache_path;
3461    return $cache_path . strtolower( preg_replace( '!/:.*$!', '', str_replace( 'http://', '', str_replace( 'https://', '', get_option( 'home' ) ) ) ) ) . '_wp_cache_gc.txt';
3462}
3463
3464function wp_cache_gc_cron() {
3465    global $file_prefix, $cache_max_time, $cache_gc_email_me, $cache_time_interval;
3466
3467    $msg = '';
3468    if ( $cache_max_time == 0 ) {
3469        wp_cache_debug( 'Cache garbage collection disabled because cache expiry time is zero.', 5 );
3470        return false;
3471    }
3472
3473    $gc_flag = get_gc_flag();
3474    if ( maybe_stop_gc( $gc_flag ) ) {
3475        wp_cache_debug( 'GC flag found. GC cancelled.', 5 );
3476        return false;
3477    }
3478
3479    update_option( 'wpsupercache_gc_time', time() );
3480    wp_cache_debug( "wp_cache_gc_cron: Set GC Flag. ($gc_flag)", 5 );
3481    $fp = @fopen( $gc_flag, 'w' );
3482    if ( $fp ) {
3483        @fclose( $fp );
3484    }
3485
3486    wp_cache_debug( 'Cache garbage collection.', 5 );
3487
3488    $start = time();
3489    $num   = 0;
3490    if ( false === ( $num = wp_cache_phase2_clean_expired( $file_prefix ) ) ) {
3491        wp_cache_debug( 'Cache Expiry cron job failed. Probably mutex locked.', 1 );
3492        update_option( 'wpsupercache_gc_time', time() - ( $cache_time_interval - 10 ) ); // if GC failed then run it again in one minute
3493        $msg .= __( 'Cache expiry cron job failed. Job will run again in 10 seconds.', 'wp-super-cache' ) . "\n";
3494    }
3495    if ( time() - $start > 30 ) {
3496        wp_cache_debug( "Cache Expiry cron job took more than 30 seconds to execute.\nYou should reduce the Expiry Time in the WP Super Cache admin page\nas you probably have more cache files than your server can handle efficiently.", 1 );
3497        $msg .= __( 'Cache expiry cron job took more than 30 seconds. You should probably run the garbage collector more often.', 'wp-super-cache' ) . "\n";
3498    }
3499
3500    if ( $cache_gc_email_me ) {
3501        if ( $msg != '' ) {
3502            $msg = "The following warnings were generated by the WP Super Cache Garbage Collector:\n" . $msg;
3503        }
3504
3505        $msg = "Hi,\n\nThe WP Super Cache Garbage Collector has now run, deleting " . (int) $num . " files and directories.\nIf you want to switch off these emails please see the WP Super Cache Advanced Settings\npage on your blog.\n\n{$msg}\nRegards,\nThe Garbage Collector.";
3506
3507        wp_mail( get_option( 'admin_email' ), sprintf( __( '[%1$s] WP Super Cache GC Report', 'wp-super-cache' ), home_url() ), $msg );
3508    }
3509    @unlink( $gc_flag );
3510    wp_cache_debug( 'GC completed. GC flag deleted.', 5 );
3511    schedule_wp_gc( 1 );
3512}
3513
3514function schedule_wp_gc( $forced = 0 ) {
3515    global $cache_schedule_type, $cache_max_time, $cache_time_interval, $cache_scheduled_time, $cache_schedule_interval;
3516
3517    if ( false == isset( $cache_time_interval ) ) {
3518        $cache_time_interval = 3600;
3519    }
3520
3521    if ( false == isset( $cache_schedule_type ) ) {
3522        $cache_schedule_type     = 'interval';
3523        $cache_schedule_interval = $cache_max_time;
3524    }
3525    if ( $cache_schedule_type == 'interval' ) {
3526        if ( ! isset( $cache_max_time ) ) {
3527            $cache_max_time = 600;
3528        }
3529        if ( $cache_max_time == 0 ) {
3530            return false;
3531        }
3532        $last_gc = get_option( 'wpsupercache_gc_time' );
3533
3534        if ( ! $last_gc ) {
3535            update_option( 'wpsupercache_gc_time', time() );
3536            $last_gc = get_option( 'wpsupercache_gc_time' );
3537        }
3538        if ( $forced || ( $last_gc < ( time() - 60 ) ) ) { // Allow up to 60 seconds for the previous job to run
3539            global $wp_cache_shutdown_gc;
3540            if ( ! isset( $wp_cache_shutdown_gc ) || $wp_cache_shutdown_gc == 0 ) {
3541                if ( ! ( $t = wp_next_scheduled( 'wp_cache_gc' ) ) ) {
3542                    wp_clear_scheduled_hook( 'wp_cache_gc' );
3543                    wp_schedule_single_event( time() + $cache_time_interval, 'wp_cache_gc' );
3544                    wp_cache_debug( 'scheduled wp_cache_gc for 10 seconds time.', 5 );
3545                }
3546            } else {
3547                global $time_to_gc_cache;
3548                $time_to_gc_cache = 1; // tell the "shutdown gc" to run!
3549            }
3550        }
3551    } elseif ( $cache_schedule_type == 'time' && ! wp_next_scheduled( 'wp_cache_gc' ) ) {
3552        wp_schedule_event( strtotime( $cache_scheduled_time ), $cache_schedule_interval, 'wp_cache_gc' );
3553    }
3554    return true;
3555}
3556
3557function wp_cache_gc_watcher() {
3558    if ( false == wp_next_scheduled( 'wp_cache_gc' ) ) {
3559        wp_cache_debug( 'GC Watcher: scheduled new gc cron.', 5 );
3560        schedule_wp_gc();
3561    }
3562}
3563
3564function wpsc_is_get_query() {
3565    static $is_get_query = null;
3566
3567    if ( null === $is_get_query ) {
3568        $request_uri  = wpsc_parse_partial_url( $_SERVER['REQUEST_URI'] );
3569        $is_get_query = $request_uri && ! empty( $request_uri['query'] );
3570    }
3571
3572    return $is_get_query;
3573}
3574
3575/**
3576 * A fallback for get request headers.
3577 * Based on comments from http://php.net/manual/en/function.apache-request-headers.php
3578 *
3579 * @return array List of request headers
3580 */
3581function wpsc_apache_request_headers() {
3582
3583    if ( ! function_exists( 'apache_request_headers' ) || ! is_callable( 'apache_request_headers' ) ) {
3584        $headers = array();
3585        foreach ( array_keys( $_SERVER ) as $skey ) {
3586            if ( str_starts_with( $skey, 'HTTP_' ) ) {
3587                $header             = implode( '-', array_map( 'ucfirst', array_slice( explode( '_', strtolower( $skey ) ), 1 ) ) );
3588                $headers[ $header ] = $_SERVER[ $skey ];
3589            }
3590        }
3591    } else {
3592        $headers = apache_request_headers();
3593    }
3594
3595    return $headers;
3596}