diff --git a/admin/class-wp-super-cache-admin.php b/admin/class-wp-super-cache-admin.php
new file mode 100755
index 00000000..f493a9b4
--- /dev/null
+++ b/admin/class-wp-super-cache-admin.php
@@ -0,0 +1,321 @@
+
+ */
+class Wp_Super_Cache_Admin {
+
+ /**
+ * The ID of this plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ * @var string $plugin_name The ID of this plugin.
+ */
+ private $plugin_name;
+
+ /**
+ * The version of this plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ * @var string $version The current version of this plugin.
+ */
+ private $version;
+
+ /**
+ * Configuration object
+ *
+ * @since 2.0.0
+ * @var object $config
+ */
+ private $config;
+
+ /**
+ * Setup object
+ *
+ * @since 2.0.0
+ * @access private
+ * @var object $config.
+ */
+ private $setup;
+
+ /**
+ * Initialize the class and set its properties.
+ *
+ * @since 2.0.0
+ * @param string $plugin_name The name of this plugin.
+ * @param string $version The version of this plugin.
+ */
+ public function __construct( $plugin_name, $version ) {
+
+ $this->plugin_name = $plugin_name;
+ $this->version = $version;
+ $this->config = Wp_Super_Cache_Config::instance();
+ $this->setup = Wp_Super_cache_Setup::instance();
+
+ // Create page environment for cache info like blog_cache_dir.
+ $page = Wp_Super_Cache_Page::instance();
+ }
+
+ /**
+ * Register the stylesheets for the admin area.
+ *
+ * @since 2.0.0
+ */
+ public function enqueue_styles() {
+
+ /**
+ * This function is provided for demonstration purposes only.
+ *
+ * An instance of this class should be passed to the run() function
+ * defined in Wp_Super_Cache_Loader as all of the hooks are defined
+ * in that particular class.
+ *
+ * The Wp_Super_Cache_Loader will then create the relationship
+ * between the defined hooks and the functions defined in this
+ * class.
+ */
+
+ wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wp-super-cache-admin.css', array(), $this->version, 'all' );
+
+ }
+
+ /**
+ * Register the JavaScript for the admin area.
+ *
+ * @since 2.0.0
+ */
+ public function enqueue_scripts() {
+
+ /**
+ * This function is provided for demonstration purposes only.
+ *
+ * An instance of this class should be passed to the run() function
+ * defined in Wp_Super_Cache_Loader as all of the hooks are defined
+ * in that particular class.
+ *
+ * The Wp_Super_Cache_Loader will then create the relationship
+ * between the defined hooks and the functions defined in this
+ * class.
+ */
+
+ wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-super-cache-admin.js', array( 'jquery' ), $this->version, false );
+
+ }
+
+ /**
+ * Output network setting menu option
+ *
+ * @since 1.7
+ */
+ public function network_admin_menu() {
+ add_submenu_page( 'settings.php', esc_html__( 'WP Super Cache', 'wp-super-cache' ), esc_html__( 'WP Super Cache', 'wp-super-cache' ), 'manage_options', 'wp-super-cache', array( $this, 'screen_options' ) );
+ }
+
+ /**
+ * Add options page
+ *
+ * @since 1.0
+ */
+ public function action_admin_menu() {
+ add_submenu_page( 'options-general.php', esc_html__( 'WP Super Cache', 'wp-super-cache' ), esc_html__( 'WP Super Cache', 'wp-super-cache' ), 'manage_options', 'wp-super-cache', array( $this, 'screen_options' ) );
+ }
+
+ /**
+ * Add purge cache button to admin bar
+ *
+ * @since 1,3
+ */
+ public function admin_bar_menu() {
+ global $wp_admin_bar;
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ return;
+ }
+ if ( ( is_singular() || is_archive() || is_front_page() || is_search() ) && current_user_can( 'delete_others_posts' ) ) {
+ $site_regex = preg_quote( rtrim( (string) wp_parse_url( get_option( 'home' ), PHP_URL_PATH ), '/' ), '`' );
+ $req_uri = preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER[ 'REQUEST_URI' ] ); // phpcs:ignore
+ $path = preg_replace( '`^' . $site_regex . '`', '', $req_uri );
+
+ $wp_admin_bar->add_menu(
+ array(
+ 'parent' => '',
+ 'id' => 'delete-cache',
+ 'title' => __( 'Delete Cache', 'wp-super-cache' ),
+ 'meta' => array( 'title' => __( 'Delete cache of the current page', 'wp-super-cache' ) ),
+ 'href' => wp_nonce_url( admin_url( 'index.php?action=delcachepage&path=' . rawurlencode( $path ) ), 'delete-cache' ),
+ )
+ );
+ }
+ }
+
+ /**
+ * Output settings
+ *
+ * @since 1.0
+ */
+ public function screen_options() {
+ // TODO - setup screen to create cache dir.
+ $setup_done = true;
+ if ( ! $this->setup->is_wp_cache_constant_defined() ) {
+ $setup_done = $this->setup->add_wp_cache_constant();
+ }
+
+ if ( ! $this->setup->is_wpcachehome_constant_defined() ) {
+ $setup_done = $this->setup->add_wpcachehome_constant();
+ }
+
+ if ( $setup_done && ! $this->setup->advanced_cache_exists() ) {
+ $setup_done = $this->setup->create_advanced_cache();
+ }
+
+ if ( $setup_done && ! $this->setup->plugin_config_exists() ) {
+ $setup_done = $this->setup->create_config_file();
+ }
+
+ if ( $setup_done && ! $this->config->config['wp_cache_home_path'] ) {
+ $setup_done = $this->setup->set_home_path();
+ }
+
+ if ( $setup_done ) {
+ $setup_done = $this->setup->create_cache_storage();
+ }
+
+ if ( ! $setup_done ) {
+ include_once 'partials/wp-super-cache-admin-setup.php';
+ } else {
+ include_once 'partials/wp-super-cache-admin-screen.php';
+ }
+ }
+
+ /**
+ * Update settings
+ *
+ * @since 2.0
+ */
+ public function update() {
+ if ( ! isset( $_GET['page'] ) || 'wp-super-cache' !== $_GET['page'] ) {
+ return false;
+ }
+
+ if ( ! isset( $_POST['wp-super-cache_settings_nonce'] ) ) {
+ return false;
+ }
+
+ if (
+ ! wp_verify_nonce(
+ sanitize_key( $_POST['wp-super-cache_settings_nonce'] ),
+ 'wp-super-cache_update_settings'
+ )
+ ) {
+ return false;
+ }
+
+ // TODO - switch to update settings for various pages.
+
+ $this->config->update_setting(
+ 'cache_enabled',
+ isset( $_POST['cache_enabled'] ) ? 1 : 0
+ );
+
+ $this->config->update_setting(
+ 'wp_super_cache_debug',
+ isset( $_POST['wp_super_cache_debug'] ) ? 1 : 0
+ );
+
+ if ( $this->config->config['wp_super_cache_debug'] ) {
+ $debug = Wp_Super_Cache_Debug::instance();
+ if (
+ isset( $this->config->config['wp_super_cache_debug_log'] ) && $this->config->config['wp_super_cache_debug_log'] &&
+ isset( $this->config->config['wp_super_cache_debug_username'] ) && $this->config->config['wp_super_cache_debug_username']
+ ) {
+ $debug->create_debug_log( $this->config->config['wp_super_cache_debug_log'], $this->config->config['wp_super_cache_debug_username'] );
+ } else {
+ $debug->create_debug_log();
+ }
+ }
+
+ if ( false === isset( $this->config->config['cache_page_secret'] ) ) {
+ $cache_page_secret = md5( gmdate( 'H:i:s' ) . wp_rand() );
+ $this->config->update_setting( 'cache_page_secret', $cache_page_secret );
+ }
+
+ if ( isset( $_POST['action'] ) && 'easysetup' === $_POST['action'] ) {
+ $_POST['action'] = 'scupdates';
+ if ( isset( $_POST['wp_cache_easy_on'] ) && 1 === $_POST['wp_cache_easy_on'] ) {
+ $_POST['wp_cache_enabled'] = 1;
+ $_POST['super_cache_enabled'] = 1;
+ $_POST['cache_rebuild_files'] = 1;
+ unset( $_POST['cache_compression'] );
+ if ( WP_CONTENT_DIR . '/cache/' !== $cache_path ) {
+ $_POST['wp_cache_location'] = $cache_path;
+ }
+
+ // set up garbage collection with some default settings.
+ if ( ( ! isset( $wp_cache_shutdown_gc ) || 0 === $wp_cache_shutdown_gc ) && false === wp_next_scheduled( 'wp_cache_gc' ) ) {
+ if ( false === isset( $cache_schedule_type ) ) {
+ $cache_schedule_type = 'interval';
+ $cache_time_interval = 600;
+ $cache_max_time = 1800;
+ $this->config->update_setting( 'cache_schedule_type', $cache_schedule_type );
+ $this->config->update_setting( 'cache_time_interval', $cache_time_interval );
+ $this->config->update_setting( 'cache_max_time', $cache_max_time );
+ }
+ wp_schedule_single_event( time() + 600, 'wp_cache_gc' );
+ }
+ } else {
+ unset( $_POST['wp_cache_enabled'] );
+ wp_clear_scheduled_hook( 'wp_cache_check_site_hook' );
+ wp_clear_scheduled_hook( 'wp_cache_gc' );
+ wp_clear_scheduled_hook( 'wp_cache_gc_watcher' );
+ }
+ $advanced_settings = array( 'wp_super_cache_late_init', 'wp_cache_disable_utf8', 'wp_cache_no_cache_for_get', 'wp_supercache_304', 'wp_cache_mfunc_enabled', 'wp_cache_front_page_checks', 'wp_supercache_cache_list', 'wp_cache_clear_on_post_edit', 'wp_cache_make_known_anon', 'wp_cache_refresh_single_only', 'cache_compression' );
+ foreach ( $advanced_settings as $setting ) {
+ if ( isset( $GLOBALS[ $setting ] ) && 1 === $GLOBALS[ $setting ] ) {
+ $_POST[ $setting ] = 1;
+ }
+ }
+ $_POST['wp_cache_not_logged_in'] = 2;
+ }
+
+ }
+
+ /**
+ * Check if user can use admin page.
+ *
+ * @since 1.0
+ */
+ private function is_super_admin() {
+ global $wp_version;
+
+ if ( version_compare( $wp_version, '4.8', '>=' ) ) {
+ return current_user_can( 'setup_network' );
+ }
+
+ return is_super_admin();
+ }
+
+}
diff --git a/admin/css/wp-super-cache-admin.css b/admin/css/wp-super-cache-admin.css
new file mode 100755
index 00000000..00c8c7f7
--- /dev/null
+++ b/admin/css/wp-super-cache-admin.css
@@ -0,0 +1,4 @@
+/**
+ * All of the CSS for your admin-specific functionality should be
+ * included in this file.
+ */
\ No newline at end of file
diff --git a/admin/index.php b/admin/index.php
new file mode 100755
index 00000000..7751eb07
--- /dev/null
+++ b/admin/index.php
@@ -0,0 +1,2 @@
+
+
+
+
diff --git a/admin/partials/wp-super-cache-admin-setup.php b/admin/partials/wp-super-cache-admin-setup.php
new file mode 100755
index 00000000..8472ae71
--- /dev/null
+++ b/admin/partials/wp-super-cache-admin-setup.php
@@ -0,0 +1,26 @@
+
+
+
+
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 66636662..2cf18bbf 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -33,7 +33,7 @@ services:
volumes:
- "./wordpress:/var/www/html"
- "./plugins:/var/www/html/wp-content/plugins"
- - ..:/var/www/html/wp-content/plugins/wp-super-cache"
+ - ..:/var/www/html/wp-content/plugins/wp-super-cache
- dockerdirectory:/var/www/html/wp-content/plugins/wp-super-cache/docker
- ./mu-plugins:/var/www/html/wp-content/mu-plugins
- ./logs/apache2/:/var/log/apache2
diff --git a/includes/class-wp-super-cache-activator.php b/includes/class-wp-super-cache-activator.php
new file mode 100755
index 00000000..ebfbe1d5
--- /dev/null
+++ b/includes/class-wp-super-cache-activator.php
@@ -0,0 +1,35 @@
+
+ */
+class Wp_Super_Cache_Activator {
+
+ /**
+ * Short Description. (use period)
+ *
+ * Long Description.
+ *
+ * @since 2.0.0
+ */
+ public static function activate() {
+
+ }
+
+}
diff --git a/includes/class-wp-super-cache-config.php b/includes/class-wp-super-cache-config.php
new file mode 100644
index 00000000..c98fc8e5
--- /dev/null
+++ b/includes/class-wp-super-cache-config.php
@@ -0,0 +1,254 @@
+get();
+ }
+
+ /**
+ * Get configuration.
+ *
+ * @since 1.0
+ */
+ public function get() {
+
+ if ( ! empty( $this->config ) ) {
+ return $this->config;
+ }
+
+ if ( ! file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) || ! include WP_CONTENT_DIR . '/wp-cache-config.php' ) {
+ return false;
+ }
+ $this->config = get_defined_vars();
+
+ return $this->config;
+ }
+
+ /**
+ * Update a setting.
+ *
+ * @param string $field the name of the setting.
+ * @param string $value the value of the setting.
+ * @since 2.0
+ */
+ public function update_setting( $field, $value ) {
+ $this->config[ $field ] = $value;
+ if ( is_numeric( $value ) ) {
+ return $this->replace_line_in_file( '^ *\$' . $field, "\$$field = $value;", $this->config_filename );
+ } elseif ( is_bool( $value ) ) {
+ $output_value = true === $value ? 'true' : 'false';
+ return $this->replace_line_in_file( '^ *\$' . $field, "\$$field = $output_value;", $this->config_filename );
+ } elseif ( is_object( $value ) || is_array( $value ) ) {
+ $text = var_export( $value, true ); // phpcs:ignore
+ $text = preg_replace( '/[\s]+/', ' ', $text );
+ return $this->replace_line_in_file( '^ *\$' . $field, "\$$field = $text;", $this->config_filename );
+ } else {
+ return $this->replace_line_in_file( '^ *\$' . $field, "\$$field = '$value';", $this->config_filename );
+ }
+ }
+
+ /**
+ * Replace a line in the config file.
+ *
+ * @param string $old the old line in the file.
+ * @param string $new the new line to replace it.
+ * @param string $filename the filename of the file to write to.
+ * @since 2.0
+ */
+ public function replace_line_in_file( $old, $new, $filename ) {
+ if ( is_file( $filename ) === false ) {
+ if ( function_exists( 'set_transient' ) ) {
+ set_transient( 'wpsc_config_error', 'config_file_missing', 10 );
+ }
+ return false;
+ }
+ if ( ! $this->is_writeable( $filename ) ) {
+ if ( function_exists( 'set_transient' ) ) {
+ set_transient( 'wpsc_config_error', 'config_file_ro', 10 );
+ }
+ return false;
+ }
+
+ $found = false;
+ $loaded = false;
+ $c = 0;
+ $lines = array();
+ while ( ! $loaded ) {
+ $lines = file( $filename );
+ if ( ! empty( $lines ) && is_array( $lines ) ) {
+ $loaded = true;
+ } else {
+ $c++;
+ if ( $c > 100 ) {
+ if ( function_exists( 'set_transient' ) ) {
+ set_transient( 'wpsc_config_error', 'config_file_not_loaded', 10 );
+ }
+ return false;
+ }
+ }
+ }
+ foreach ( (array) $lines as $line ) {
+ if (
+ trim( $new ) !== '' &&
+ trim( $new ) === trim( $line )
+ ) {
+ wp_cache_debug( "replace_line_in_file: setting not changed - $new" );
+ return true;
+ } elseif ( preg_match( "/$old/", $line ) ) {
+ wp_cache_debug( 'replace_line_in_file: changing line ' . trim( $line ) . " to *$new*" );
+ $found = true;
+ }
+ }
+
+ /**
+ * TODO: The tmp config filename must be put in the cache_path as not all servers have /tmp
+ * $tmp_config_filename = tempnam( $GLOBALS['cache_path'], 'wpsc' );
+ */
+ $tmp_config_filename = tempnam( '/tmp/', 'wpsc' );
+ rename( $tmp_config_filename, $tmp_config_filename . '.php' );
+ $tmp_config_filename .= '.php';
+ wp_cache_debug( 'replace_line_in_file: writing to ' . $tmp_config_filename );
+ $fd = fopen( $tmp_config_filename, 'w' ); // phpcs:ignore
+ if ( ! $fd ) {
+ if ( function_exists( 'set_transient' ) ) {
+ set_transient( 'wpsc_config_error', 'config_file_ro', 10 );
+ }
+ return false;
+ }
+ if ( $found ) {
+ foreach ( (array) $lines as $line ) {
+ if ( ! preg_match( "/$old/", $line ) ) {
+ fputs( $fd, $line );
+ } elseif ( '' !== $new ) {
+ fputs( $fd, "$new\n" );
+ }
+ }
+ } else {
+ $done = false;
+ foreach ( (array) $lines as $line ) {
+ if ( $done || ! preg_match( '/^(if\ \(\ \!\ )?define|\$|\?>/', $line ) ) {
+ fputs( $fd, $line );
+ } else {
+ fputs( $fd, "$new\n" );
+ fputs( $fd, $line );
+ $done = true;
+ }
+ }
+ }
+ fclose( $fd ); // phpcs:ignore
+ rename( $tmp_config_filename, $filename );
+ wp_cache_debug( 'replace_line_in_file: moved ' . $tmp_config_filename . ' to ' . $filename );
+
+ if ( function_exists( 'opcache_invalidate' ) ) {
+ @opcache_invalidate( $filename ); // phpcs:ignore
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if $path is writeable.
+ * From legolas558 d0t users dot sf dot net at http://www.php.net/is_writable
+ *
+ * @param string $path the path to be checked.
+ * @since 2.0
+ */
+ private function is_writeable( $path ) {
+
+ // PHP's is_writable does not work with Win32 NTFS.
+
+ if ( '/' === $path[ strlen( $path ) - 1 ] ) { // recursively return a temporary file path.
+ return $this->is_writeable( $path . uniqid( wp_rand() ) . '.tmp' );
+ } elseif ( is_dir( $path ) ) {
+ return $this->is_writeable( $path . '/' . uniqid( wp_rand() ) . '.tmp' );
+ }
+
+ // check tmp file for read/write capabilities.
+ $rm = file_exists( $path );
+ $f = @fopen( $path, 'a' ); // phpcs:ignore
+ if ( false === $f ) {
+ return false;
+ }
+ fclose( $f ); // phpcs:ignore
+ if ( ! $rm ) {
+ unlink( $path );
+ }
+
+ return true;
+ }
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_Config
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+}
+
+/**
+ * Return the config for the plugin.
+ *
+ * @since 2.0
+ * @return array of configuration data.
+ **/
+function wp_super_cache_get_config() {
+ global $wpsc_config;
+
+ if ( false === isset( $wpsc_config ) ) {
+ $wpsc_config = Wp_Super_cache_Config::instance();
+ }
+
+ return $wpsc_config;
+}
diff --git a/includes/class-wp-super-cache-deactivator.php b/includes/class-wp-super-cache-deactivator.php
new file mode 100755
index 00000000..180c48cf
--- /dev/null
+++ b/includes/class-wp-super-cache-deactivator.php
@@ -0,0 +1,36 @@
+
+ */
+class Wp_Super_Cache_Deactivator {
+
+ /**
+ * Short Description. (use period)
+ *
+ * Long Description.
+ *
+ * @since 2.0.0
+ */
+ public static function deactivate() {
+
+ }
+
+}
diff --git a/includes/class-wp-super-cache-debug.php b/includes/class-wp-super-cache-debug.php
new file mode 100644
index 00000000..f6510dff
--- /dev/null
+++ b/includes/class-wp-super-cache-debug.php
@@ -0,0 +1,237 @@
+config = Wp_Super_Cache_Config::instance();
+ }
+
+ /**
+ * Add a log message to the file, if debugging is turned on
+ *
+ * @param string $message The message that should be added to the log.
+ */
+ public function log( $message ) {
+ static $last_message = '';
+
+ if ( $last_message === $message ) {
+ return false;
+ }
+ $last_message = $message;
+
+ // If either of the debug or log globals aren't set, then we can stop.
+ if ( ! isset( $this->config->config['wp_super_cache_debug'] ) || ! isset( $this->config->config['wp_cache_debug_log'] ) ) {
+ return false;
+ }
+
+ // If either the debug or log globals are false or empty, we can stop.
+ if ( false === $this->config->config['wp_super_cache_debug'] || '' === $this->config->config['wp_cache_debug_log'] ) {
+ return false;
+ }
+
+ // If the debug_ip has been set, but it doesn't match the ip of the requester
+ // then we can stop.
+ if (
+ isset( $this->config->config['wp_cache_debug_ip'] )
+ && '' !== $this->config->config['wp_cache_debug_ip']
+ && $this->config->config['wp_cache_debug_ip'] !== $_SERVER['REMOTE_ADDR'] // phpcs:ignore
+ ) {
+ return false;
+ }
+
+ // Log message: Date URI Message.
+ $log_message = gmdate( 'H:i:s' ) . ' ' . getmypid() . ' ' . wp_unslash( $_SERVER['REQUEST_URI'] ) . ' ' . $message . PHP_EOL; // phpcs:ignore
+ // path to the log file in the cache folder.
+ $log_file = $this->config->config['cache_path'] . str_replace( '/', '', str_replace( '..', '', $this->config->config['wp_cache_debug_log'] ) );
+
+ if ( ! file_exists( $log_file ) ) {
+ if ( ! isset( $this->config->config['wp_cache_debug_username'] ) ) {
+ $this->config->config['wp_cache_debug_username'] = '';
+ }
+
+ $this->create_debug_log( $this->config->config['wp_cache_debug_log'], $this->config->config['wp_cache_debug_username'] );
+ }
+
+ error_log( $log_message, 3, $log_file ); // phpcs:ignore
+ }
+
+ /**
+ * Get a username to use for the debug log.
+ */
+ private function get_debug_username() {
+
+ if ( ! isset( $this->config->config['wp_cache_debug_username'] ) || '' === $this->config->config['wp_cache_debug_username'] ) {
+ $this->config->update_setting( 'wp_cache_debug_username', md5( time() + wp_rand() ) );
+ }
+ return $wp_cache_debug_username;
+ }
+
+ /**
+ * Create a new debug log
+ *
+ * @param string $filename The name of the log file.
+ * @param string $username username and password used to protect the log file.
+ */
+ public function create_debug_log( $filename = '', $username = '' ) {
+ $debug_setting = $this->config->config['wp_super_cache_debug'];
+ $this->config->config['wp_super_cache_debug'] = false;
+
+ if ( '' !== $filename ) {
+ $this->config->update_setting( 'wp_cache_debug_log', $filename );
+ } else {
+ $this->config->update_setting( 'wp_cache_debug_log', md5( time() + wp_rand() ) . '.php' );
+ }
+ if ( '' !== $username ) {
+ $this->config->update_setting( 'wp_cache_debug_username', $username );
+ } else {
+ $this->get_debug_username();
+ }
+ // phpcs:disable
+ $msg = 'die( "Please use the viewer" );' . PHP_EOL;
+ $fp = fopen( $this->config->config['cache_path'] . $this->config->config['wp_cache_debug_log'], 'w' );
+ if ( $fp ) {
+ fwrite( $fp, '<' . "?php\n" );
+ fwrite( $fp, $msg );
+ fwrite( $fp, '?' . '>' . PHP_EOL );
+ fwrite( $fp, '<' . '?php // END HEADER ?' . '>' . PHP_EOL );
+ fclose( $fp );
+ $this->config->update_setting( 'wp_cache_debug_log', $this->config->config['wp_cache_debug_log'] );
+ $this->config->update_setting( 'wp_cache_debug_username', $this->config->config['wp_cache_debug_username'] );
+ }
+
+ $msg = '
+if ( !isset( $_SERVER[ "PHP_AUTH_USER" ] ) || ( $_SERVER[ "PHP_AUTH_USER" ] != "' . $this->config->config['wp_cache_debug_username'] . '" && $_SERVER[ "PHP_AUTH_PW" ] != "' . $this->config->config['wp_cache_debug_username'] . '" ) ) {
+ header( "WWW-Authenticate: Basic realm=\"WP-Super-Cache Debug Log\"" );
+ header( $_SERVER[ "SERVER_PROTOCOL" ] . " 401 Unauthorized" );
+ echo "You must login to view the debug log";
+ exit;
+}' . PHP_EOL;
+
+ $fp = fopen( $this->config->config['cache_path'] . 'view_' . $this->config->config['wp_cache_debug_log'], 'w' );
+ if ( $fp ) {
+ fwrite( $fp, '<' . '?php' . PHP_EOL );
+ $msg .= '$debug_log = file( "./' . $this->config->config['wp_cache_debug_log'] . '" );
+$start_log = 1 + array_search( "<" . "?php // END HEADER ?" . ">" . PHP_EOL, $debug_log );
+if ( $start_log > 1 ) {
+ $debug_log = array_slice( $debug_log, $start_log );
+}
+?' . '>
+<' . '?php
+$path_to_site = "' . ABSPATH . '";
+foreach ( $debug_log as $t => $line ) {
+ $line = str_replace( $path_to_site, "ABSPATH/", $line );
+ $debug_log[ $t ] = $line;
+ foreach( $checks as $check ) {
+ if ( $$check && false !== strpos( $line, " /$check/" ) ) {
+ unset( $debug_log[ $t ] );
+ }
+ }
+ if ( $filter ) {
+ if ( false !== strpos( $line, $filter ) && $exclude_filter ) {
+ unset( $debug_log[ $t ] );
+ } elseif ( false === strpos( $line, $filter ) && ! $exclude_filter ) {
+ unset( $debug_log[ $t ] );
+ }
+ }
+}
+foreach( $debug_log as $line ) {
+ echo htmlspecialchars( $line ) . "
";
+}';
+ fwrite( $fp, $msg );
+ fclose( $fp );
+ }
+ // phpcs:enable
+ $this->config->config['wp_super_cache_debug'] = $debug_setting;
+
+ return array(
+ 'wp_cache_debug_log' => $this->config->config['wp_cache_debug_log'],
+ 'wp_cache_debug_username' => $this->config->config['wp_cache_debug_username'],
+ );
+ }
+
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_Config
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+}
+
+/**
+ * Add a log message to the file, if debugging is turned on
+ *
+ * @param string $message The message that should be added to the log.
+ * @param int $level deprecated.
+ */
+function wp_cache_debug( $message, $level = false ) {
+ return Wp_Super_Cache_Debug::instance()->log( $message );
+}
diff --git a/includes/class-wp-super-cache-file-cache.php b/includes/class-wp-super-cache-file-cache.php
new file mode 100644
index 00000000..e89eb6d1
--- /dev/null
+++ b/includes/class-wp-super-cache-file-cache.php
@@ -0,0 +1,1271 @@
+config = Wp_Super_Cache_Config::instance();
+ add_filter( 'wpsc_create_cache_storage', array( $this, 'create_cache_storage' ) );
+ }
+
+ /**
+ * Create cache storage
+ *
+ * @since 2.0
+ */
+ public function create_cache_storage( $setup_done ) {
+ $directory_functions = array( 'create_cache_directory', 'create_supercache_directory', 'create_blogcache_directory' );
+ foreach ( $directory_functions as $dir_function ) {
+ $setup_done = $this->$dir_function();
+ if ( ! $setup_done ) {
+ return false;
+ }
+ }
+ return $setup_done;
+ }
+
+ /**
+ * Create WP_CONTENT/cache
+ *
+ * @since 2.0.0
+ * @return bool if succeeded or not.
+ */
+ public function create_cache_directory() {
+ if ( ! empty( $this->config->config['cache_path'] ) && ! is_dir( $this->config->config['cache_path'] ) ) {
+ @mkdir( $this->config->config['cache_path'] ); // phpcs:ignore
+ }
+ return is_dir( $this->config->config['cache_path'] ) ? true : false;
+ }
+
+ /**
+ * Create WP_CONTENT/cache/supercache
+ *
+ * @since 2.0.0
+ * @return bool if succeeded or not.
+ */
+ public function create_supercache_directory() {
+ if ( ! empty( $this->config->config['cache_path'] ) && ! is_dir( $this->config->config['cache_path'] . '/supercache/' ) ) {
+ @mkdir( $this->config->config['cache_path'] . '/supercache/' ); // phpcs:ignore
+ }
+ return is_dir( $this->config->config['cache_path'] . '/supercache/' ) ? true : false;
+ }
+
+ /**
+ * Create WP_CONTENT/cache/blogs
+ *
+ * @since 2.0.0
+ * @return bool if succeeded or not.
+ */
+ public function create_blogcache_directory() {
+ if ( ! empty( $this->config->config['blog_cache_dir'] ) && ! is_dir( $this->config->config['blog_cache_dir'] ) ) {
+ @mkdir( $this->config->config['blog_cache_dir'] ); // phpcs:ignore
+ }
+ return is_dir( $this->config->config['blog_cache_dir'] ) ? true : false;
+ }
+
+ /**
+ * Get cache directory
+ *
+ * @since 2.0
+ * @return string
+ */
+ public function get_cache_dir() {
+ if ( isset( $this->config->config['cache_path'] ) ) {
+ return $this->config->config['cache_path'];
+ } else {
+ return ( defined( 'WPSC_CACHE_DIR' ) ) ? rtrim( WPSC_CACHE_DIR, '/' ) : rtrim( WP_CONTENT_DIR, '/' ) . '/cache';
+ }
+ }
+
+ /**
+ * Cache the query vars that may get destroyed by PHP garbage collection
+ *
+ * @since 2.0
+ * @return string
+ */
+ public function get_query_vars() {
+ global $wp_query;
+
+ if ( ! empty( $this->config->query_vars ) ) {
+ return $this->config->query_vars;
+ }
+
+ if ( ! is_object( $wp_query ) || ! method_exists( $wp_query, 'get' ) ) {
+ return false;
+ }
+
+ if ( is_search() ) {
+ $this->config->query_vars['is_search'] = 1;
+ }
+ if ( is_page() ) {
+ $this->config->query_vars['is_page'] = 1;
+ }
+ if ( is_archive() ) {
+ $this->config->query_vars['is_archive'] = 1;
+ }
+ if ( is_tag() ) {
+ $this->config->query_vars['is_tag'] = 1;
+ }
+ if ( is_single() ) {
+ $this->config->query_vars['is_single'] = 1;
+ }
+ if ( is_category() ) {
+ $this->config->query_vars['is_category'] = 1;
+ }
+ if ( is_front_page() ) {
+ $this->config->query_vars['is_front_page'] = 1;
+ }
+ if ( is_home() ) {
+ $this->config->query_vars['is_home'] = 1;
+ }
+ if ( is_author() ) {
+ $this->config->query_vars['is_author'] = 1;
+ }
+
+ // REST API.
+ if (
+ ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
+ ( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) ||
+ ( defined( 'WC_API_REQUEST' ) && WC_API_REQUEST )
+ ) {
+ $this->config->query_vars['is_rest'] = 1;
+ }
+
+ // Feeds, sitemaps and robots.txt.
+ if ( is_feed() ) {
+ $this->config->query_vars['is_feed'] = 1;
+ if ( 'sitemap' === get_query_var( 'feed' ) ) {
+ $this->config->query_vars['is_sitemap'] = 1;
+ }
+ } elseif ( get_query_var( 'sitemap' ) || get_query_var( 'xsl' ) || get_query_var( 'xml_sitemap' ) ) {
+ $this->config->query_vars['is_feed'] = 1;
+ $this->config->query_vars['is_sitemap'] = 1;
+ } elseif ( is_robots() ) {
+ $this->config->query_vars['is_robots'] = 1;
+ }
+
+ // Reset everything if it's 404.
+ if ( is_404() ) {
+ $this->config->query_vars = array( 'is_404' => 1 );
+ }
+
+ return $this->config->query_vars;
+ }
+
+ /**
+ * Was there a fatal error in the page?
+ *
+ * @since 2.0
+ */
+ private function is_fatal_error() {
+ $error = error_get_last();
+ if ( null === $error ) {
+ return false;
+ }
+
+ if ( $error['type'] & ( E_ERROR | E_CORE_ERROR | E_PARSE | E_COMPILE_ERROR | E_USER_ERROR ) ) {
+ $this->config->query_vars['is_fatal_error'] = 1;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Create cache file from buffer
+ *
+ * @param int $status status code of the current HTTTP request.
+ * @since 2.0
+ */
+ private function catch_http_status_code( $status ) {
+ if ( in_array( intval( $status ), array( 301, 302, 303, 307 ), true ) ) {
+ $this->config->query_vars['is_redirect'] = 1;
+ } elseif ( 304 === $status ) {
+ $this->config->query_vars['is_304'] = 1;
+ } elseif ( 303 === $status ) {
+ $this->config->query_vars['is_404'] = 1;
+ }
+
+ return $status;
+ }
+
+ /**
+ * Will we be allowed serve gzip content?
+ *
+ * @since 2.0
+ */
+ public function gzip_encoding() {
+ static $gzip_accepted = 1;
+
+ if ( 1 !== $gzip_accepted ) {
+ return $gzip_accepted;
+ }
+
+ if ( ! $this->config->config['cache_compression'] ) {
+ $gzip_accepted = false;
+ return $gzip_accepted;
+ }
+
+ if ( 1 === ini_get( 'zlib.output_compression' ) || 'on' === strtolower( ini_get( 'zlib.output_compression' ) ) ) { // Don't compress WP-Cache data files when PHP is already doing it.
+ $gzip_accepted = false;
+ return $gzip_accepted;
+ }
+
+ if ( ! isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) || ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) && false === strpos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) ) ) {
+ $gzip_accepted = false;
+ return $gzip_accepted;
+ }
+
+ $gzip_accepted = 'gzip';
+ return $gzip_accepted;
+ }
+
+ public function get_response_headers() {
+ static $known_headers = array(
+ 'Access-Control-Allow-Origin',
+ 'Accept-Ranges',
+ 'Age',
+ 'Allow',
+ 'Cache-Control',
+ 'Connection',
+ 'Content-Encoding',
+ 'Content-Language',
+ 'Content-Length',
+ 'Content-Location',
+ 'Content-MD5',
+ 'Content-Disposition',
+ 'Content-Range',
+ 'Content-Type',
+ 'Date',
+ 'ETag',
+ 'Expires',
+ 'Last-Modified',
+ 'Link',
+ 'Location',
+ 'P3P',
+ 'Pragma',
+ 'Proxy-Authenticate',
+ 'Referrer-Policy',
+ 'Refresh',
+ 'Retry-After',
+ 'Server',
+ 'Status',
+ 'Strict-Transport-Security',
+ 'Trailer',
+ 'Transfer-Encoding',
+ 'Upgrade',
+ 'Vary',
+ 'Via',
+ 'Warning',
+ 'WWW-Authenticate',
+ 'X-Frame-Options',
+ 'Public-Key-Pins',
+ 'X-XSS-Protection',
+ 'Content-Security-Policy',
+ 'X-Pingback',
+ 'X-Content-Security-Policy',
+ 'X-WebKit-CSP',
+ 'X-Content-Type-Options',
+ 'X-Powered-By',
+ 'X-UA-Compatible',
+ 'X-Robots-Tag',
+ );
+
+ if ( ! function_exists( 'headers_list' ) ) {
+ return array();
+ }
+
+ $known_headers = apply_filters( 'wpsc_known_headers', $known_headers );
+
+ if ( ! isset( $known_headers['age'] ) ) {
+ $known_headers = array_map( 'strtolower', $known_headers );
+ }
+
+ $headers = array();
+ foreach ( headers_list() as $hdr ) {
+ $ptr = strpos( $hdr, ':' );
+
+ if ( empty( $ptr ) ) {
+ continue;
+ }
+
+ $hdr_key = rtrim( substr( $hdr, 0, $ptr ) );
+
+ if ( in_array( strtolower( $hdr_key ), $known_headers, true ) ) {
+ $hdr_val = ltrim( substr( $hdr, $ptr + 1 ) );
+
+ if ( ! empty( $headers[ $hdr_key ] ) ) {
+ $hdr_val = $headers[ $hdr_key ] . ', ' . $hdr_val;
+ }
+
+ $headers[ $hdr_key ] = $hdr_val;
+ }
+ }
+
+ return $headers;
+ }
+
+
+ /**
+ * Get meta information about new cache file.
+ *
+ * @since 2.0
+ * @return array
+ */
+ private function get_cache_meta_information() {
+ if ( ! function_exists( 'wpsc_init' ) ) {
+ /*
+ * If a server has multiple networks the plugin may not have been activated
+ * on all of them. Give feeds on those blogs a short TTL.
+ * * ref: https://wordpress.org/support/topic/fatal-error-while-updating-post-or-publishing-new-one/
+ */
+ $wpsc_feed_ttl = 1;
+ wp_cache_debug( 'wp_cache_shutdown_callback: Plugin not loaded. Setting feed ttl to 60 seconds.' );
+ }
+
+ $wp_cache_meta['uri'] = WPSC_HTTP_HOST . preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', WPSC_URI ); // To avoid XSS attacks
+ $wp_cache_meta['blog_id'] = $blog_id;
+ $wp_cache_meta['post'] = $this->config->config['post_id'];
+ $wp_cache_meta['key'] = $wp_cache_key;
+
+ $wp_cache_meta = apply_filters( 'wp_cache_meta', $wp_cache_meta );
+
+ $response = $this->get_response_headers();
+ foreach( $response as $key => $value ) {
+ $wp_cache_meta['headers'][ $key ] = "$key: $value";
+ }
+
+ wp_cache_debug( 'wp_cache_shutdown_callback: collecting meta data.', 2 );
+
+ if (!isset( $response['Last-Modified'] )) {
+ $value = gmdate('D, d M Y H:i:s') . ' GMT';
+ /* Dont send this the first time */
+ /* @header('Last-Modified: ' . $value); */
+ $wp_cache_meta['headers']['Last-Modified'] = "Last-Modified: $value";
+ }
+ $is_feed = false;
+ if ( !isset( $response['Content-Type'] ) && !isset( $response['Content-type'] ) ) {
+ // On some systems, headers set by PHP can't be fetched from
+ // the output buffer. This is a last ditch effort to set the
+ // correct Content-Type header for feeds, if we didn't see
+ // it in the response headers already. -- dougal
+ if ( isset( $this->config->query_vars['is_feed'] ) ) {
+ if ( isset( $this->config->query_vars['is_sitemap'] ) ) {
+ $type = 'sitemap';
+ $value = 'text/xml';
+ } else {
+ $type = get_query_var( 'feed' );
+ $type = str_replace('/','',$type);
+ switch ($type) {
+ case 'atom':
+ $value = 'application/atom+xml';
+ break;
+ case 'rdf':
+ $value = 'application/rdf+xml';
+ break;
+ case 'rss':
+ case 'rss2':
+ default:
+ $value = 'application/rss+xml';
+ }
+ }
+ $is_feed = true;
+
+ if ( isset( $wpsc_feed_ttl ) && $wpsc_feed_ttl == 1 ) {
+ $wp_cache_meta['ttl'] = 60;
+ }
+ $is_feed = true;
+
+ wp_cache_debug( "wp_cache_shutdown_callback: feed is type: $type - $value" );
+ } elseif ( isset( $this->config->query_vars['is_rest'] ) ) { // json
+ $value = 'application/json';
+ } else { // not a feed
+ $value = get_option( 'html_type' );
+ if( $value == '' )
+ $value = 'text/html';
+ }
+ if ( defined( 'WPSC_BLOG_CHARSET' ) ) {
+ $value .= "; charset=\"" . constant( 'WPSC_BLOG_CHARSET' ) . "\"";
+ }
+
+ $wp_cache_meta['headers']['Content-Type'] = "Content-Type: $value";
+ }
+
+ if ( $cache_enabled && !$supercacheonly && $new_cache ) {
+ if( !isset( $wp_cache_meta['dynamic'] ) && $wp_cache_gzip_encoding && !in_array( 'Content-Encoding: ' . $wp_cache_gzip_encoding, $wp_cache_meta['headers'] ) ) {
+ wp_cache_debug( 'Sending gzip headers.', 2 );
+ $wp_cache_meta['headers']['Content-Encoding'] = 'Content-Encoding: ' . $wp_cache_gzip_encoding;
+ if ( defined( 'WPSC_VARY_HEADER' ) ) {
+ if ( WPSC_VARY_HEADER != '' ) {
+ $vary_header = WPSC_VARY_HEADER;
+ } else {
+ $vary_header = '';
+ }
+ } else {
+ $vary_header = 'Accept-Encoding, Cookie';
+ }
+ if ( $vary_header ) {
+ $wp_cache_meta['headers']['Vary'] = 'Vary: ' . $vary_header;
+ }
+ }
+
+ $serial = '' . json_encode( $wp_cache_meta );
+ $dir = get_current_url_supercache_dir();
+ if( @is_dir( $dir ) == false )
+ @wp_mkdir_p( $dir );
+
+ if( wp_cache_writers_entry() ) {
+ wp_cache_debug( "Writing meta file: {$dir}meta-{$meta_file}", 2 );
+
+ $tmp_meta_filename = $dir . uniqid( mt_rand(), true ) . '.tmp';
+ $final_meta_filename = $dir . "meta-" . $meta_file;
+ $fr = @fopen( $tmp_meta_filename, 'w');
+ if ( $fr ) {
+ fputs($fr, $serial);
+ fclose($fr);
+ @chmod( $tmp_meta_filename, 0666 & ~umask());
+ if( !@rename( $tmp_meta_filename, $final_meta_filename ) ) {
+ @unlink( $dir . $final_meta_filename );
+ @rename( $tmp_meta_filename, $final_meta_filename );
+ }
+ } else {
+ wp_cache_debug( "Problem writing meta file: {$final_meta_filename}" );
+ }
+ wp_cache_writers_exit();
+
+ // record locations of archive feeds to be updated when the site is updated.
+ // Only record a maximum of 50 feeds to avoid bloating database.
+ if ( ( isset( $this->config->query_vars['is_feed'] ) || $is_feed ) && ! isset( $this->config->query_vars['is_single'] ) ) {
+ $wpsc_feed_list = (array) get_option( 'wpsc_feed_list' );
+ if ( count( $wpsc_feed_list ) <= 50 ) {
+ $wpsc_feed_list[] = $dir . $meta_file;
+ update_option( 'wpsc_feed_list', $wpsc_feed_list );
+ }
+ }
+ }
+ } else {
+ 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" );
+ }
+ global $time_to_gc_cache;
+ if ( isset( $time_to_gc_cache ) && $time_to_gc_cache == 1 ) {
+ wp_cache_debug( 'Executing wp_cache_gc action.', 3 );
+ do_action( 'wp_cache_gc' );
+ }
+
+ return $wp_cache_meta;
+ }
+
+ /**
+ * Get headers for newly created cache file.
+ *
+ * @since 2.0
+ * @return array
+ */
+ private function send_cache_headers( $wp_cache_meta ) {
+ if ( isset( $wp_cache_meta['headers']['Content-Type'] ) ) {
+ wp_cache_debug( "Sending header: $value" );
+ @header( $value );
+ }
+
+ return true;
+ }
+
+ /**
+ * Create cache file from buffer
+ *
+ * @param string $buffer the output buffer containing the current page.
+ * @since 2.0
+ */
+ public function ob_handler( $buffer ) {
+
+ $cache_this_page = true;
+
+ if ( mb_strlen( $buffer ) < 255 ) {
+ wp_cache_debug( 'ob_handler: not caching a small page.' );
+ $cache_this_page = false;
+ }
+
+ if ( $this->is_fatal_error() ) {
+ wp_cache_debug( 'ob_handler: PHP Fatal error occurred. Not caching incomplete page.' );
+ $cache_this_page = false;
+ } elseif ( empty( $this->config->query_vars ) && ! empty( $buffer ) ) {
+ $this->get_query_vars();
+ } elseif ( empty( $this->config->query_vars ) && function_exists( 'http_response_code' ) ) {
+ $this->catch_http_status_code( http_response_code() );
+ }
+ $buffer = apply_filters( 'ob_handler_filter', $buffer );
+
+ if ( $cache_this_page ) {
+ $cache_this_page = WP_Super_cache_Page::instance()->post_cache_checks();
+ }
+
+ if ( isset( $this->config->config['wpsc_save_headers'] ) && $this->config->config['wpsc_save_headers'] ) {
+ $this->config->config['super_cache_enabled'] = false; // use standard caching to record headers.
+ }
+
+ if ( $cache_this_page ) {
+
+ wp_cache_debug( 'Output buffer callback' );
+
+ $buffer = $this->write_buffer_to_file( $buffer );
+ // TODO.
+ //wp_cache_shutdown_callback();
+ $meta_info = $this->get_cache_meta_information();
+
+ $this->send_cache_headers( $meta_info );
+
+ /*
+ * TODO - rebuild system
+ */
+ if ( ! empty( $wpsc_file_mtimes ) && is_array( $wpsc_file_mtimes ) ) {
+ foreach ( $wpsc_file_mtimes as $cache_file => $old_mtime ) {
+ if ( $old_mtime === @filemtime( $cache_file ) ) { // phpcs:ignore
+ wp_cache_debug( "wp_cache_ob_callback deleting unmodified rebuilt cache file: $cache_file" );
+ if ( wp_cache_confirm_delete( $cache_file ) ) {
+ @unlink( $cache_file ); // phpcs:ignore
+ }
+ }
+ }
+ }
+ return $buffer;
+ } else {
+ if ( ! empty( $do_rebuild_list ) && is_array( $do_rebuild_list ) ) {
+ foreach ( $do_rebuild_list as $dir => $n ) {
+ if ( wp_cache_confirm_delete( $dir ) ) {
+ wp_cache_debug( 'wp_cache_ob_callback clearing rebuilt files in ' . $dir );
+ wpsc_delete_files( $dir );
+ }
+ }
+ }
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Add text to the buffer
+ *
+ * @param string $buffer the output buffer containing the current page.
+ * @param string $text text to add to the buffer.
+ * @since 2.0
+ * @return bool
+ */
+ private function add_to_buffer( &$buffer, $text ) {
+ if ( ! isset( $this->config->config['wp_super_cache_debug'] ) || $this->config->config['wp_super_cache_debug'] ) {
+ return false;
+ }
+
+ if ( false === isset( $this->config->config['wp_super_cache_comments'] ) ) {
+ $this->config->config['wp_super_cache_comments'] = 1;
+ }
+
+ if ( 0 === $this->config->config['wp_super_cache_comments'] ) {
+ return false;
+ }
+
+ if ( false === strpos( $buffer, 'config->config['cached_direct_pages'] ) && in_array( $_SERVER['REQUEST_URI'], $this->config->config['cached_direct_pages'] ) ) { // phpcs:ignore
+ $extra_str = '';
+ }
+ $filename = 'index' . $extra_str . '.html';
+
+ return $filename;
+ }
+
+ /**
+ * If dynamic caching is enabled then run buffer through wpsc_cachedata filter before returning it.
+ * or we'll return template tags to visitors.
+ *
+ * @param string $buffer the output buffer containing the current page.
+ * @since 2.0
+ * @return string
+ */
+ private function wp_cache_maybe_dynamic( &$buffer ) {
+ if ( 1 === $this->config->config['wp_cache_mfunc_enabled'] && 1 === do_cacheaction( 'wpsc_cachedata_safety', 0 ) ) {
+ wp_cache_debug( 'wp_cache_maybe_dynamic: filtered $buffer through wpsc_cachedata' );
+ return do_cacheaction( 'wpsc_cachedata', $buffer ); // dynamic content for display.
+ } else {
+ wp_cache_debug( 'wp_cache_maybe_dynamic: returned $buffer' );
+ return $buffer;
+ }
+ }
+
+ /**
+ * Get the supercache directory for the current url or post ID.
+ *
+ * @param int $post_id The post_id of the post being queried, or 0 to get URL.
+ * @since 2.0
+ * @return string
+ */
+ public function get_current_url_supercache_dir( $post_id = 0 ) {
+ global $wpsc_http_host;
+ static $saved_supercache_dir = array();
+
+ if ( isset( $saved_supercache_dir[ $post_id ] ) ) {
+ return $saved_supercache_dir[ $post_id ];
+ }
+
+ $do_not_remember = 0;
+ if ( 0 !== $post_id ) {
+ $site_url = site_url();
+ $permalink = get_permalink( $post_id );
+ if ( false === strpos( $permalink, $site_url ) ) {
+ /*
+ * Sometimes site_url doesn't return the siteurl. See https://wordpress.org/support/topic/wp-super-cache-not-refreshing-post-after-comments-made
+ */
+ $do_not_remember = 1;
+ wp_cache_debug( "get_current_url_supercache_dir: WARNING! site_url ($site_url) not found in permalink ($permalink).", 1 );
+ if ( preg_match( '`^(https?:)?//([^/]+)(/.*)?$`i', $permalink, $matches ) ) {
+ if ( $wpsc_http_host !== $matches[2] ) {
+ wp_cache_debug( "get_current_url_supercache_dir: WARNING! SERVER_NAME ({$wpsc_http_host}) not found in permalink ($permalink).", 1 );
+ }
+ wp_cache_debug( "get_current_url_supercache_dir: Removing SERVER_NAME ({$matches[2]}) from permalink ($permalink). Is the url right?", 1 );
+ $uri = isset( $matches[3] ) ? $matches[3] : '';
+ } elseif ( preg_match( '`^/([^/]+)(/.*)?$`i', $permalink, $matches ) ) {
+ wp_cache_debug( "get_current_url_supercache_dir: WARNING! Permalink ($permalink) looks as absolute path. Is the url right?", 1 );
+ $uri = $permalink;
+ } else {
+ wp_cache_debug( "get_current_url_supercache_dir: WARNING! Permalink ($permalink) could not be understood by parsing url. Using front page.", 1 );
+ $uri = '';
+ }
+ } else {
+ $uri = str_replace( $site_url, '', $permalink );
+ if ( strpos( $uri, $wp_cache_home_path ) !== 0 ) {
+ $uri = rtrim( $wp_cache_home_path, '/' ) . $uri;
+ }
+ }
+ } else {
+ $uri = strtolower( WPSC_URI );
+ }
+ $uri = wpsc_deep_replace(
+ array( '..', '\\', 'index.php' ),
+ preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', preg_replace( '/(\?.*)?(#.*)?$/', '', $uri ) )
+ );
+ $hostname = $wpsc_http_host;
+ // Get hostname from wp options for wp-cron, wp-cli and similar requests.
+ if ( empty( $hostname ) && function_exists( 'get_option' ) ) {
+ $hostname = (string) wp_parse_url( get_option( 'home' ), PHP_URL_HOST );
+ }
+ $dir = preg_replace( '/:.*$/', '', $hostname ) . $uri; // To avoid XSS attacks.
+ if ( function_exists( 'apply_filters' ) ) {
+ $dir = apply_filters( 'supercache_dir', $dir );
+ } else {
+ $dir = do_cacheaction( 'supercache_dir', $dir );
+ }
+ $dir = $this->config->config['cache_path'] . 'supercache/' . $dir . '/';
+ if ( is_array( $this->config->config['cached_direct_pages'] ) && in_array( $_SERVER['REQUEST_URI'], $this->config->config['cached_direct_pages'] ) ) { // phpcs:ignore
+ $dir = ABSPATH . $uri . '/';
+ }
+ $dir = str_replace( '..', '', str_replace( '//', '/', $dir ) );
+ wp_cache_debug( "supercache dir: $dir" );
+ if ( 0 === $do_not_remember ) {
+ $saved_supercache_dir[ $post_id ] = $dir;
+ }
+ return $dir;
+ }
+
+ /**
+ * Create mutex flag for file locking
+ *
+ * @since 2.0
+ * @return string
+ */
+ public function wp_cache_mutex_init() {
+ global $mutex, $wp_cache_mutex_disabled, $use_flock, $blog_cache_dir, $mutex_filename, $sem_id;
+
+ if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
+ return true;
+ }
+
+ if ( ! is_bool( $use_flock ) ) {
+ if ( function_exists( 'sem_get' ) ) {
+ $use_flock = false;
+ } else {
+ $use_flock = true;
+ }
+ }
+
+ $mutex = false;
+ if ( $use_flock ) {
+ setup_blog_cache_dir();
+ wp_cache_debug( "Created mutex lock on filename: {$blog_cache_dir}{$mutex_filename}" );
+ $mutex = @fopen( $blog_cache_dir . $mutex_filename, 'w' ); // phpcs:ignore
+ } else {
+ wp_cache_debug( "Created mutex lock on semaphore: {$sem_id}" );
+ $mutex = @sem_get( $sem_id, 1, 0666, 1 ); // phpcs:ignore
+ }
+ }
+
+ /**
+ * Entry to writer's lock
+ *
+ * @since 2.0
+ * @return string
+ */
+ private function wp_cache_writers_entry() {
+ global $mutex, $wp_cache_mutex_disabled, $use_flock;
+
+ if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
+ return true;
+ }
+
+ if ( ! $mutex ) {
+ wp_cache_debug( '(writers entry) mutex lock not created. not caching.' );
+ return false;
+ }
+
+ if ( $use_flock ) {
+ wp_cache_debug( 'grabbing lock using flock()' );
+ flock( $mutex, LOCK_EX );
+ } else {
+ wp_cache_debug( 'grabbing lock using sem_acquire()' );
+ @sem_acquire( $mutex ); // phpcs:ignore
+ }
+
+ return true;
+ }
+
+ /**
+ * Exit to writer's lock
+ *
+ * @since 2.0
+ * @return string
+ */
+ private function wp_cache_writers_exit() {
+ global $mutex, $wp_cache_mutex_disabled, $use_flock;
+
+ if ( defined( 'WPSC_DISABLE_LOCKING' ) || ( isset( $wp_cache_mutex_disabled ) && $wp_cache_mutex_disabled ) ) {
+ return true;
+ }
+
+ if ( ! $mutex ) {
+ wp_cache_debug( '(writers exit) mutex lock not created. not caching.' );
+ return false;
+ }
+
+ if ( $use_flock ) {
+ wp_cache_debug( 'releasing lock using flock()', 5 );
+ flock( $mutex, LOCK_UN );
+ } else {
+ wp_cache_debug( 'releasing lock using sem_release() and sem_remove()' );
+ @sem_release( $mutex ); // phpcs:ignore
+ if ( defined( 'WPSC_REMOVE_SEMAPHORE' ) ) {
+ @sem_remove( $mutex ); // phpcs:ignore
+ }
+ }
+ }
+
+
+ /**
+ * Count the micro seconds between $a and $b
+ *
+ * @param string $a the start time.
+ * @param string $b the end time.
+ * @since 2.0
+ * @return string
+ */
+ private function wp_cache_microtime_diff( $a, $b ) {
+ list( $a_dec, $a_sec ) = explode( ' ', $a );
+ list( $b_dec, $b_sec ) = explode( ' ', $b );
+ return (float) $b_sec - (float) $a_sec + (float) $b_dec - (float) $a_dec;
+ }
+
+ /**
+ * Write buffer to the cache file.
+ *
+ * @param string $buffer the output buffer containing the current page.
+ * @since 2.0
+ * @return string
+ */
+ private function write_buffer_to_file( &$buffer ) {
+ global $wp_super_cache_start_time;
+
+ if ( false === isset( $this->config->config['wp_cache_mfunc_enabled'] ) ) {
+ $this->config->config['wp_cache_mfunc_enabled'] = 0;
+ }
+
+ $new_cache = true;
+ $wp_cache_meta = array();
+
+ if ( '' === $buffer ) {
+ $new_cache = false;
+ 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." );
+ $this->add_to_buffer( $buffer, 'Page not cached by WP Super Cache. Blank Page. Check output buffer usage by plugins.' );
+ }
+
+ if ( isset( $this->config->query_vars['is_404'] ) && false === apply_filters( 'wpsupercache_404', false ) ) {
+ $new_cache = false;
+ wp_cache_debug( '404 file not found not cached' );
+ $this->add_to_buffer( $buffer, 'Page not cached by WP Super Cache. 404.' );
+ }
+
+ if ( ! preg_match( apply_filters( 'wp_cache_eof_tags', '/(<\/html>|<\/rss>|<\/feed>|<\/urlset|<\?xml)/i' ), $buffer ) ) {
+ $new_cache = false;
+ wp_cache_debug( 'No closing html tag. Not caching.', 2 );
+ $this->add_to_buffer( $buffer, 'Page not cached by WP Super Cache. No closing HTML tag. Check your theme.' );
+ }
+
+ if ( ! $new_cache ) {
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+
+ $duration = $this->wp_cache_microtime_diff( $wp_super_cache_start_time, microtime() );
+ $duration = sprintf( '%0.3f', $duration );
+ $this->add_to_buffer( $buffer, "Dynamic page generated in $duration seconds." );
+
+ if ( ! $this->wp_cache_writers_entry() ) {
+ $this->add_to_buffer( $buffer, 'Page not cached by WP Super Cache. Could not get mutex lock.' );
+ wp_cache_debug( 'Could not get mutex lock. Not caching.' );
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+
+ if ( $this->config->config['wp_cache_not_logged_in'] && isset( $this->config->query_vars['is_feed'] ) ) {
+ wp_cache_debug( 'Feed detected. Writing wpcache cache files.' );
+ $wp_cache_not_logged_in = false;
+ }
+
+ $home_url = wp_parse_url( trailingslashit( get_bloginfo( 'url' ) ) );
+ $dir = get_current_url_supercache_dir();
+ $supercachedir = $this->config->config['cache_path'] . 'supercache/' . preg_replace( '/:.*$/', '', $home_url['host'] );
+
+ if (
+ ! empty( $_GET ) || // phpcs:ignore
+ isset( $this->config->query_vars['is_feed'] ) ||
+ (
+ $this->config->config['super_cache_enabled'] &&
+ is_dir( substr( $supercachedir, 0, -1 ) . '.disabled' )
+ )
+ ) {
+ wp_cache_debug( 'Supercache disabled: GET or feed detected or disabled by config.' );
+ $this->config->config['super_cache_enabled'] = false;
+ }
+
+ $tmp_wpcache_filename = $this->config->config['cache_path'] . uniqid( wp_rand(), true ) . '.tmp';
+
+ if ( defined( 'WPSC_SUPERCACHE_ONLY' ) ) {
+ $supercacheonly = true;
+ wp_cache_debug( 'wp_cache_get_ob: WPSC_SUPERCACHE_ONLY defined. Only creating supercache files.' );
+ } else {
+ $supercacheonly = false;
+ }
+
+ if ( $this->config->config['super_cache_enabled'] ) {
+ if ( '' === $this->wp_cache_get_cookies_values() && empty( $_GET ) ) { // phpcs:ignore
+ wp_cache_debug( 'Anonymous user detected. Only creating Supercache file.' );
+ $supercacheonly = true;
+ }
+ }
+ $cache_error = '';
+ if ( wpsc_is_caching_user_disabled() ) {
+ $super_cache_enabled = false;
+ $cache_enabled = false;
+ $cache_error = 'Not caching requests by known users. (See Advanced Settings page)';
+ wp_cache_debug( 'Not caching for known user.' );
+ }
+
+ if ( ! $cache_enabled ) {
+ wp_cache_debug( 'Cache is not enabled. Sending buffer to browser.' );
+ $this->wp_cache_writers_exit();
+ $this->add_to_buffer( $buffer, "Page not cached by WP Super Cache. Check your settings page. $cache_error" );
+ if ( 1 === $this->config->config['wp_cache_mfunc_enabled'] ) {
+ if (
+ false === isset( $this->config->config['wp_super_cache_late_init'] ) ||
+ ( isset( $this->config->config['wp_super_cache_late_init'] ) && 0 === $this->config->config['wp_super_cache_late_init'] )
+ ) {
+ $this->add_to_buffer( $buffer, 'Super Cache dynamic page detected but $wp_super_cache_late_init not set. See the readme.txt for further details.' );
+ }
+ }
+
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+
+ if ( false === @is_dir( $dir ) ) { // phpcs:ignore
+ @wp_mkdir_p( $dir ); // phpcs:ignore
+ }
+ // TODO.
+ $dir = wpsc_get_realpath( $dir );
+
+ if ( ! $dir ) {
+ wp_cache_debug( 'wp_cache_get_ob: not caching as directory does not exist.' );
+ return $buffer;
+ }
+
+ $dir = trailingslashit( $dir );
+
+ // TODO.
+ if ( ! wpsc_is_in_cache_directory( $dir ) ) {
+ wp_cache_debug( "wp_cache_get_ob: not caching as directory is not in cache_path: $dir" );
+ return $buffer;
+ }
+
+ $fr = false;
+ $fr2 = false;
+ $gz = false;
+
+ // Open wp-cache cache file.
+ if ( ! $supercacheonly ) {
+ $fr = @fopen( $tmp_wpcache_filename, 'w' ); //phpcs:ignore
+ if ( ! $fr ) {
+ wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $this->config->config['cache_path'] ) . $cache_filename );
+ $this->add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $this->config->config['cache_path'] ) . $cache_filename );
+ $this->wp_cache_writers_exit();
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+ } else {
+ $user_info = $this->wp_cache_get_cookies_values();
+ $do_cache = apply_filters( 'do_createsupercache', $user_info );
+ if (
+ $super_cache_enabled &&
+ (
+ '' === $user_info ||
+ true === $do_cache
+ )
+ ) {
+ $cache_fname = $dir . $this->supercache_filename();
+ $tmp_cache_filename = $dir . uniqid( wp_rand(), true ) . '.tmp';
+
+ $fr2 = @fopen( $tmp_cache_filename, 'w' ); // phpcs:ignore
+ if ( ! $fr2 ) {
+ wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $tmp_cache_filename ) );
+ $this->add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $tmp_cache_filename ) );
+ @fclose( $fr ); // phpcs:ignore
+ @unlink( $tmp_wpcache_filename ); // phpcs:ignore
+ $this->wp_cache_writers_exit();
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ } elseif (
+ $this->gzip_encoding() &&
+ 0 === $wp_cache_mfunc_enabled
+ ) { // don't want to store compressed files if using dynamic content.
+ $gz = @fopen( $tmp_cache_filename . '.gz', 'w' ); // phpcs:ignore
+ if ( ! $gz ) {
+ wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $tmp_cache_filename ) . '.gz' );
+ $this->add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $tmp_cache_filename ) . '.gz' );
+ @fclose( $fr ); // phpcs:ignore
+ @unlink( $tmp_wpcache_filename ); //phpcs:ignore
+ @fclose( $fr2 ); // phpcs:ignore
+ @unlink( $tmp_cache_filename ); //phpcs:ignore
+ $this->wp_cache_writers_exit();
+ return $this->wp_cache_maybe_dynamic( $buffer );
+ }
+ }
+ }
+ }
+
+ // TODO.
+ $added_cache = 0;
+ $oc_key = get_oc_key();
+ $buffer = apply_filters( 'wpsupercache_buffer', $buffer );
+ wp_cache_append_tag( $buffer );
+
+ /*
+ * Dynamic content enabled: write the buffer to a file and then process any templates found using
+ * the wpsc_cachedata filter. Buffer is then returned to the visitor.
+ */
+ if ( 1 === $this->config->config['wp_cache_mfunc_enabled'] ) {
+ if ( preg_match( '//', $buffer ) ) { // Dynamic content.
+ wp_cache_debug( 'mfunc/mclude/dynamic-cached-content tags have been retired. Please update your theme. See docs for updates.' );
+ $this->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.' );
+ }
+
+ if ( false === isset( $this->config->config['wp_super_cache_late_init'] ) || ( isset( $this->config->config['wp_super_cache_late_init'] ) && 0 === $this->config->config['wp_super_cache_late_init'] ) ) {
+ $this->add_to_buffer( $buffer, 'Super Cache dynamic page detected but late init not set. See the readme.txt for further details.' );
+ }
+
+ if ( $fr ) { // wpcache caching.
+ wp_cache_debug( 'Writing dynamic buffer to wpcache file.' );
+ $this->add_to_buffer( $buffer, 'Dynamic WPCache Super Cache' );
+ fputs( $fr, '' . $buffer );
+ } elseif ( isset( $fr2 ) ) { // supercache active.
+ wp_cache_debug( 'Writing dynamic buffer to supercache file.' );
+ $this->add_to_buffer( $buffer, 'Dynamic Super Cache' );
+ fputs( $fr2, $buffer );
+ }
+ $wp_cache_meta['dynamic'] = true;
+ if ( 1 === $wp_cache_mfunc_enabled && 1 === do_cacheaction( 'wpsc_cachedata_safety', 0 ) ) {
+ $buffer = do_cacheaction( 'wpsc_cachedata', $buffer ); // dynamic content for display.
+ }
+
+ if ( $this->gzip_encoding() ) {
+ wp_cache_debug( 'Gzipping dynamic buffer for display.', 5 );
+ $this->add_to_buffer( $buffer, 'Compression = gzip' );
+ $gzdata = gzencode( $buffer, 6, FORCE_GZIP );
+ $gzsize = function_exists( 'mb_strlen' ) ? mb_strlen( $gzdata, '8bit' ) : strlen( $gzdata );
+ }
+ } else {
+ if ( defined( 'WPSC_VARY_HEADER' ) ) {
+ if ( '' !== WPSC_VARY_HEADER ) {
+ $vary_header = WPSC_VARY_HEADER;
+ } else {
+ $vary_header = '';
+ }
+ } else {
+ $vary_header = 'Accept-Encoding, Cookie';
+ }
+ if ( $vary_header ) {
+ $wp_cache_meta['headers']['Vary'] = 'Vary: ' . $vary_header;
+ }
+ if ( $gz || $this->gzip_encoding() ) {
+ wp_cache_debug( 'Gzipping buffer.' );
+ $this->add_to_buffer( $buffer, 'Compression = gzip' );
+ $gzdata = gzencode( $buffer, 6, FORCE_GZIP );
+ $gzsize = function_exists( 'mb_strlen' ) ? mb_strlen( $gzdata, '8bit' ) : strlen( $gzdata );
+
+ $wp_cache_meta['headers']['Content-Encoding'] = 'Content-Encoding: ' . $this->gzip_encoding();
+ // Return uncompressed data & store compressed for later use.
+ if ( $fr ) {
+ wp_cache_debug( 'Writing gzipped buffer to wp-cache cache file.', 5 );
+ fputs( $fr, '' . $gzdata );
+ }
+ } else { // no compression.
+ if ( $fr ) {
+ wp_cache_debug( 'Writing non-gzipped buffer to wp-cache cache file.' );
+ fputs( $fr, '' . $buffer );
+ }
+ }
+ if ( $fr2 ) {
+ wp_cache_debug( 'Writing non-gzipped buffer to supercache file.' );
+ $this->add_to_buffer( $buffer, 'super cache' );
+ fputs( $fr2, $buffer );
+ }
+ if ( isset( $gzdata ) && $gz ) {
+ wp_cache_debug( 'Writing gzipped buffer to supercache file.' );
+ fwrite( $gz, $gzdata ); // phpcs:ignore
+ }
+ }
+
+ $new_cache = true;
+ if ( $fr ) {
+ $supercacheonly = false;
+ fclose( $fr ); // phpcs:ignore
+ if ( 0 === filesize( $tmp_wpcache_filename ) ) {
+ wp_cache_debug( "Warning! The file $tmp_wpcache_filename was empty. Did not rename to {$dir}{$cache_filename}", 5 );
+ @unlink( $tmp_wpcache_filename ); //phpcs:ignore
+ } else {
+ if ( ! @rename( $tmp_wpcache_filename, $dir . $cache_filename ) ) { // phpcs:ignore
+ if ( false === is_dir( $dir ) ) {
+ @wp_mkdir_p( $dir ); //phpcs:ignore
+ }
+ @unlink( $dir . $cache_filename ); // phpcs:ignore
+ @rename( $tmp_wpcache_filename, $dir . $cache_filename ); // phpcs:ignore
+ }
+ if ( file_exists( $dir . $cache_filename ) ) {
+ wp_cache_debug( "Renamed temp wp-cache file to {$dir}{$cache_filename}", 5 );
+ } else {
+ wp_cache_debug( "FAILED to rename temp wp-cache file to {$dir}{$cache_filename}", 5 );
+ }
+ $added_cache = 1;
+ }
+ }
+
+ if ( $fr2 ) {
+ fclose( $fr2 ); //phpcs:ignore
+ if ( $wp_cache_front_page_checks && $cache_fname === $supercachedir . $home_url['path'] . $this->supercache_filename() && ! $wp_cache_is_home ) {
+ $this->wp_cache_writers_exit();
+ wp_cache_debug( 'Warning! Not writing another page to front page cache.', 1 );
+ return $buffer;
+ } elseif ( 0 === filesize( $tmp_cache_filename ) ) {
+ wp_cache_debug( "Warning! The file $tmp_cache_filename was empty. Did not rename to {$cache_fname}", 5 );
+ @unlink( $tmp_cache_filename ); // phpcs:ignore
+ } else {
+ if ( ! @rename( $tmp_cache_filename, $cache_fname ) ) { // phpcs:ignore
+ @unlink( $cache_fname ); // phpcs:ignore
+ @rename( $tmp_cache_filename, $cache_fname ); // phpcs:ignore
+ }
+ wp_cache_debug( "Renamed temp supercache file to $cache_fname", 5 );
+ $added_cache = 1;
+ }
+ }
+ if ( $gz ) {
+ fclose( $gz ); // phpcs:ignore
+ if ( 0 === filesize( $tmp_cache_filename . '.gz' ) ) {
+ wp_cache_debug( "Warning! The file {$tmp_cache_filename}.gz was empty. Did not rename to {$cache_fname}.gz" );
+ @unlink( $tmp_cache_filename . '.gz' ); // phpcs:ignore
+ } else {
+ if ( ! @rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' ) ) { // phpcs:ignore
+ @unlink( $cache_fname . '.gz' ); // phpcs:ignore
+ @rename( $tmp_cache_filename . '.gz', $cache_fname . '.gz' ); // phpcs:ignore
+ }
+ wp_cache_debug( "Renamed temp supercache gz file to {$cache_fname}.gz" );
+ $added_cache = 1;
+ }
+ }
+
+ if ( $added_cache && isset( $wp_supercache_cache_list ) && $wp_supercache_cache_list ) {
+ update_option( 'wpsupercache_count', ( get_option( 'wpsupercache_count' ) + 1 ) );
+ $last_urls = (array) get_option( 'supercache_last_cached' );
+ if ( count( $last_urls ) >= 10 ) {
+ $last_urls = array_slice( $last_urls, 1, 9 );
+ }
+ $last_urls[] = array(
+ 'url' => preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER['REQUEST_URI'] ), // phpcs:ignore
+ 'date' => gmdate( 'Y-m-d H:i:s' ),
+ );
+ update_option( 'supercache_last_cached', $last_urls );
+ }
+ $this->wp_cache_writers_exit();
+ if ( ! headers_sent() && $this->gzip_encoding() && $gzdata ) {
+ wp_cache_debug( 'Writing gzip content headers. Sending buffer to browser', 5 );
+ header( 'Content-Encoding: ' . $this->gzip_encoding() );
+ if ( defined( 'WPSC_VARY_HEADER' ) ) {
+ if ( '' !== WPSC_VARY_HEADER ) {
+ $vary_header = WPSC_VARY_HEADER;
+ } else {
+ $vary_header = '';
+ }
+ } else {
+ $vary_header = 'Accept-Encoding, Cookie';
+ }
+ if ( $vary_header ) {
+ header( 'Vary: ' . $vary_header );
+ }
+ header( 'Content-Length: ' . $gzsize );
+ return $gzdata;
+ } else {
+ wp_cache_debug( 'Sending buffer to browser', 5 );
+ return $buffer;
+ }
+ }
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_File_Cache
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+
+}
+
+/**
+ * Create cache file from buffer.
+ *
+ * @param string $buffer the output buffer containing the current page.
+ * @since 2.0
+ */
+function wp_super_cache_ob_handler( $buffer ) {
+ $caching = Wp_Super_cache_File_Cache::instance();
+ $buffer = $caching->ob_handler();
+
+}
diff --git a/includes/class-wp-super-cache-i18n.php b/includes/class-wp-super-cache-i18n.php
new file mode 100755
index 00000000..0730ca15
--- /dev/null
+++ b/includes/class-wp-super-cache-i18n.php
@@ -0,0 +1,46 @@
+
+ */
+class Wp_Super_Cache_I18n {
+
+ /**
+ * Load the plugin text domain for translation.
+ *
+ * @since 2.0.0
+ */
+ public function load_plugin_textdomain() {
+
+ load_plugin_textdomain(
+ 'wp-super-cache',
+ false,
+ dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
+ );
+
+ }
+
+
+
+}
diff --git a/includes/class-wp-super-cache-loader.php b/includes/class-wp-super-cache-loader.php
new file mode 100755
index 00000000..8687b024
--- /dev/null
+++ b/includes/class-wp-super-cache-loader.php
@@ -0,0 +1,128 @@
+
+ */
+class Wp_Super_Cache_Loader {
+
+ /**
+ * The array of actions registered with WordPress.
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var array $actions The actions registered with WordPress to fire when the plugin loads.
+ */
+ protected $actions;
+
+ /**
+ * The array of filters registered with WordPress.
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var array $filters The filters registered with WordPress to fire when the plugin loads.
+ */
+ protected $filters;
+
+ /**
+ * Initialize the collections used to maintain the actions and filters.
+ *
+ * @since 2.0.0
+ */
+ public function __construct() {
+
+ $this->actions = array();
+ $this->filters = array();
+
+ }
+
+ /**
+ * Add a new action to the collection to be registered with WordPress.
+ *
+ * @since 2.0.0
+ * @param string $hook The name of the WordPress action that is being registered.
+ * @param object $component A reference to the instance of the object on which the action is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
+ */
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
+ }
+
+ /**
+ * Add a new filter to the collection to be registered with WordPress.
+ *
+ * @since 2.0.0
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object on which the filter is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
+ */
+ public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
+ }
+
+ /**
+ * A utility function that is used to register the actions and hooks into a single
+ * collection.
+ *
+ * @since 2.0.0
+ * @access private
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object on which the filter is defined.
+ * @param string $callback The name of the function definition on the $component.
+ * @param int $priority The priority at which the function should be fired.
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
+ * @return array The collection of actions and filters registered with WordPress.
+ */
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
+
+ $hooks[] = array(
+ 'hook' => $hook,
+ 'component' => $component,
+ 'callback' => $callback,
+ 'priority' => $priority,
+ 'accepted_args' => $accepted_args,
+ );
+
+ return $hooks;
+
+ }
+
+ /**
+ * Register the filters and actions with WordPress.
+ *
+ * @since 2.0.0
+ */
+ public function run() {
+
+ foreach ( $this->filters as $hook ) {
+ add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
+ }
+
+ foreach ( $this->actions as $hook ) {
+ add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
+ }
+
+ }
+
+}
diff --git a/includes/class-wp-super-cache-page.php b/includes/class-wp-super-cache-page.php
new file mode 100644
index 00000000..d152f3dc
--- /dev/null
+++ b/includes/class-wp-super-cache-page.php
@@ -0,0 +1,499 @@
+config = Wp_Super_Cache_Config::instance();
+
+ if ( defined( 'DISABLE_SUPERCACHE' ) ) {
+ wp_cache_debug( 'DISABLE_SUPERCACHE set, super_cache disabled.' );
+ $this->config->config['super_cache_enabled'] = 0;
+ }
+
+ if ( ! defined( 'WPCACHEHOME' ) ) {
+ define( 'WPCACHEHOME', dirname( dirname( __FILE__ ) ) . '/' );
+ }
+
+ // In the future we might have different caching engines.
+ $this->cache = WP_Super_Cache_File_Cache::instance();
+
+ // remove authentication cookies so page can be super cached for admin users.
+ if ( $this->config->config['wp_cache_make_known_anon'] ) {
+ $this->make_anonymous();
+ }
+
+ $this->set_env();
+
+ do_cacheaction( 'cache_init' );
+ }
+
+ /**
+ * Set up cached environment for caching during shutdown.
+ * Caching for later use when wpdb is gone. https://wordpress.org/support/topic/224349
+ * Details of the current blog being cached.
+ *
+ * @since 2.0
+ */
+ public function set_env() {
+ // Cache this in case any plugin modifies it.
+ // Used to be: wp_cache_request_uri.
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
+ define( 'WPSC_URI', $_SERVER['REQUEST_URI'] ); // phpcs:ignore
+ } else {
+ define( 'WPSC_URI', '' );
+ }
+
+ if ( isset( $_SERVER['HTTP_HOST'] ) && ! empty( $_SERVER['HTTP_HOST'] ) ) {
+ $http_host = function_exists( 'mb_strtolower' ) ? mb_strtolower( $_SERVER['HTTP_HOST'] ) : strtolower( $_SERVER['HTTP_HOST'] );
+ define( 'WPSC_HTTP_HOST', htmlentities( $http_host ) );
+ } elseif ( PHP_SAPI === 'cli' && function_exists( 'get_option' ) ) {
+ define( 'WPSC_HTTP_HOST', (string) parse_url( get_option( 'home' ), PHP_URL_HOST ) );
+ } else {
+ $this->config->config['cache_enabled'] = false;
+ define( 'WPSC_HTTP_HOST', '' );
+ }
+
+ // We want to be able to identify each blog in a WordPress MU install.
+ $this->config->config['blogcacheid'] = '';
+ $this->config->config['blog_cache_dir'] = $this->config->config['cache_path'];
+
+ if ( is_multisite() ) {
+ global $current_blog;
+
+ if ( is_object( $current_blog ) && function_exists( 'is_subdomain_install' ) ) {
+ $this->config->config['blogcacheid'] = is_subdomain_install() ? $current_blog->domain : trim( $current_blog->path, '/' );
+ } elseif ( ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) || ( defined( 'VHOST' ) && VHOST === 'yes' ) ) {
+ $this->config->config['blogcacheid'] = constant( 'WPSC_HTTP_HOST' );
+ } else {
+ $request_uri = str_replace( '..', '', preg_replace( '/[ <>\'\"\r\n\t\(\)]/', '', $_SERVER['REQUEST_URI'] ) );
+ $request_uri = str_replace( '//', '/', $request_uri );
+
+ $wpsc_path_segs = array_filter( explode( '/', trim( $request_uri, '/' ) ) );
+ $wpsc_base_count = defined( 'PATH_CURRENT_SITE' ) ? count( array_filter( explode( '/', trim( PATH_CURRENT_SITE, '/' ) ) ) ) : 0;
+ if ( '/' !== substr( $request_uri, -1 ) ) {
+ $wpsc_path_segs = array_slice( $wpsc_path_segs, 0, -1 );
+ }
+
+ if ( count( $wpsc_path_segs ) > $wpsc_base_count &&
+ ( ! defined( 'PATH_CURRENT_SITE' ) || 0 === strpos( $request_uri, PATH_CURRENT_SITE ) )
+ ) {
+ $this->config->config['blogcacheid'] = $wpsc_path_segs[ $wpsc_base_count ];
+ }
+ }
+
+ // If blogcacheid is empty then set it to main blog.
+ if ( empty( $this->config->config['blogcacheid'] ) ) {
+ $this->config->config['blogcacheid'] = 'blog';
+ }
+ $this->config->config['blog_cache_dir'] = str_replace( '//', '/', $this->config->config['cache_path'] . 'blogs/' . $this->config->config['blogcacheid'] . '/' );
+ }
+ add_action( 'template_redirect', array( $this, 'wp_set_env' ) );
+ }
+
+ /**
+ * Setup environment with blog options. Must be run on "init" when WP has loaded.
+ *
+ * @since 2.0
+ */
+ public function wp_set_env() {
+ // $wp_cache_gmt_offset.
+ define( 'WPSC_GMT_OFFSET', get_option( 'gmt_offset' ) );
+ // $wp_cache_blog_charset.
+ define( 'WPSC_BLOG_CHARSET', get_option( 'blog_charset' ) );
+ $this->config->config['post_id'] = $this->get_post_id();
+
+ }
+
+ /**
+ * Return the post ID from the current page.
+ * // used to be wp_cache_post_id
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function get_post_id() {
+ global $posts, $comment_post_ID, $post_ID;
+
+ if ( $post_ID > 0 ) {
+ return $post_ID;
+ }
+
+ if ( $comment_post_ID > 0 ) {
+ return $comment_post_ID;
+ }
+
+ if ( is_singular() && ! empty( $posts ) ) {
+ return $posts[0]->ID;
+ }
+
+ if ( isset( $_GET['p'] ) && $_GET['p'] > 0 ) {
+ return $_GET['p'];
+ }
+
+ if ( isset( $_POST['p'] ) && $_POST['p'] > 0 ) {
+ return $_POST['p'];
+ }
+
+ return 0;
+ }
+
+ /**
+ * Can page be cached?
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function is_cacheable() {
+ if ( ! $this->config->config['cache_enabled'] ) {
+ wp_cache_debug( 'is_cacheable: Caching disabled.' );
+ return false;
+ }
+
+ if ( isset( $_GET['customize_changeset_uuid'] ) ) { //phpcs:ignore
+ return false;
+ }
+
+ if ( $this->is_backend() ) {
+ wp_cache_debug( 'is_cacheable: Not caching backend request.' );
+ return false;
+ }
+
+ if ( ! $this->pre_cache_checks() ) {
+ return false;
+ }
+
+ if ( $this->is_user_agent_rejected() ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Is page cached?
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function is_cached() {
+ return false;
+ }
+
+ /**
+ * Serve the current page from a cache file.
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function serve_page() {
+ return true;
+ }
+
+ /**
+ * Store the current page in a cache file.
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function cache_page() {
+ ob_start( array( Wp_Super_Cache_File_Cache::instance(), 'ob_handler' ) );
+
+ return true;
+ }
+
+ /**
+ * Make the current request anonymouse for every type of visitor.
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function make_anonymous() {
+
+ // Don't remove cookies for some requests.
+ if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'GET' !== $_SERVER['REQUEST_METHOD'] ) {
+ return true;
+ }
+
+ if ( $this->is_backend() ) {
+ return true;
+ }
+
+ if ( isset( $_GET['preview'], $_GET['customize_changeset_uuid'] ) ) { // phpcs:ignore
+ return true;
+ }
+
+ if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( stripslashes( $_SERVER['REQUEST_URI'] ), '/wp-json/' ) !== false ) { // WPCS: sanitization ok.
+ return true;
+ }
+
+ if ( false === do_cacheaction( 'wp_supercache_remove_cookies', true ) ) {
+ return true;
+ }
+
+ $this->removed_cookies = array();
+ foreach ( WP_Super_Cache_User::instance()->get_auth_cookies() as $cookie ) {
+
+ $cookies = is_array( $cookie ) ? $cookie : array( $cookie );
+
+ foreach ( $cookies as $cookie_key ) {
+ unset( $_COOKIE[ $cookie_key ] );
+ $this->removed_cookies[] = $cookie_key;
+ }
+ }
+
+ if ( ! empty( $this->removed_cookies ) ) {
+ wp_cache_debug( 'Removing auth from $_COOKIE to allow caching for logged in user ( ' . implode( ', ', $this->removed_cookies ) . ' )' );
+ }
+ }
+
+
+ /**
+ * Return true if in wp-admin or other admin non cacheable page.
+ *
+ * @since 2.0
+ * @return bool
+ */
+ public function is_backend() {
+ static $is_backend;
+
+ if ( isset( $is_backend ) ) {
+ return $is_backend;
+ }
+
+ $is_backend = is_admin();
+ if ( $is_backend ) {
+ return $is_backend;
+ }
+
+ $script = isset( $_SERVER['PHP_SELF'] ) ? basename( $_SERVER['PHP_SELF'] ) : ''; // phpcs:ignore
+ if ( 'index.php' !== $script ) {
+ if ( in_array( $script, array( 'wp-login.php', 'xmlrpc.php', 'wp-cron.php' ), true ) ) {
+ $is_backend = true;
+ } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
+ $is_backend = true;
+ } elseif ( 'cli' === PHP_SAPI || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
+ $is_backend = true;
+ }
+ }
+
+ return $is_backend;
+ }
+
+ /**
+ * Check if url is on the rejected list.
+ *
+ * @param string $url the url to be checked.
+ * @since 2.0
+ */
+ public function url_is_rejected( $url ) {
+ $auto_rejected = array( '/wp-admin/', 'xmlrpc.php', 'wp-app.php' );
+ foreach ( $auto_rejected as $u ) {
+ if ( strstr( $url, $u ) ) {
+ return true; // we don't allow caching of wp-admin for security reasons.
+ }
+ }
+
+ if ( false === is_array( $this->config->config['cache_rejected_uri'] ) ) {
+ return false;
+ }
+ foreach ( $this->config->config['cache_rejected_uri'] as $expr ) {
+ if ( '' !== $expr && @preg_match( "~$expr~", $uri ) ) { // phpcs:ignore
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if user agent is on the rejected list.
+ *
+ * @since 2.0
+ */
+ public function is_user_agent_rejected() {
+ if ( empty( $this->config->config['cache_rejected_user_agent'] ) || ! is_array( $this->config->config['cache_rejected_user_agent'] ) ) {
+ return false;
+ }
+
+ $headers = apache_request_headers();
+ if ( empty( $headers['User-Agent'] ) ) {
+ return false;
+ }
+
+ foreach ( $this->config->config['cache_rejected_user_agent'] as $user_agent ) {
+ if ( ! empty( $user_agent ) && stristr( $headers['User-Agent'], $user_agent ) ) {
+ wp_cache_debug( 'is_user_agent_rejected: found user-agent in list: ' . $headers['User-Agent'] );
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if we can cache this page. Runs before caching.
+ *
+ * @since 2.0
+ */
+ private function pre_cache_checks() {
+ $cache_this_page = true;
+
+ if ( ! isset( $_SERVER['REQUEST_METHOD'] ) ) {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ }
+
+ if ( ! isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
+ $_SERVER['HTTP_USER_AGENT'] = '';
+ }
+
+ if ( defined( 'DONOTCACHEPAGE' ) ) {
+ wp_cache_debug( 'DONOTCACHEPAGE defined. Caching disabled.' );
+ $cache_this_page = false;
+ } elseif ( $this->config->config['wp_cache_no_cache_for_get'] && ! empty( $_GET ) ) { // phpcs:ignore
+ wp_cache_debug( 'Non empty GET request. Caching disabled on settings page. ' . wpsc_dump_get_request() );
+ $cache_this_page = false;
+ } elseif ( 'POST' === $_SERVER['REQUEST_METHOD'] || ! empty( $_POST ) ) { // phpcs:ignore
+ wp_cache_debug( 'Not caching POST request.' );
+ $cache_this_page = false;
+ } elseif ( 'PUT' === $_SERVER['REQUEST_METHOD'] ) {
+ wp_cache_debug( 'Not caching PUT request.' );
+ $cache_this_page = false;
+ } elseif ( 'DELETE' === $_SERVER['REQUEST_METHOD'] ) {
+ wp_cache_debug( 'Not caching DELETE request.' );
+ $cache_this_page = false;
+ } elseif ( isset( $_GET['preview'] ) ) { // phpcs:ignore
+ wp_cache_debug( 'Not caching preview post.' );
+ $cache_this_page = false;
+ } elseif ( ! in_array( $script, (array) $this->config->config['cache_acceptable_files'], true ) && $this->url_is_rejected( constant( 'WPSC_URI' ) ) ) {
+ wp_cache_debug( 'URI rejected. Not Caching' );
+ $cache_this_page = false;
+ } elseif ( $this->is_user_agent_rejected() ) {
+ wp_cache_debug( 'USER AGENT (' . esc_html( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) . ') rejected. Not Caching' );
+ $cache_this_page = false;
+ }
+
+ return $cache_this_page;
+ }
+
+ /**
+ * Check if we can cache this page. Uses functions only available after WordPress is loaded.
+ *
+ * @since 2.0
+ */
+ public function post_cache_checks() {
+
+ $cache_this_page = true;
+ $query_vars = WP_Super_cache_File_Cache::instance()->get_query_vars();
+
+ if ( isset( $this->config->config['wp_cache_pages']['single'] ) && 1 === $this->config->config['wp_cache_pages']['single'] && isset( $query_vars['is_single'] ) ) {
+ wp_cache_debug( 'Not caching single post.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['pages'] ) && 1 === $this->config->config['wp_cache_pages']['pages'] && isset( $query_vars['is_page'] ) ) {
+ wp_cache_debug( 'Not caching single page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['archives'] ) && 1 === $this->config->config['wp_cache_pages']['archives'] && isset( $query_vars['is_archive'] ) ) {
+ wp_cache_debug( 'Not caching archive page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['tag'] ) && 1 === $this->config->config['wp_cache_pages']['tag'] && isset( $query_vars['is_tag'] ) ) {
+ wp_cache_debug( 'Not caching tag page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['category'] ) && 1 === $this->config->config['wp_cache_pages']['category'] && isset( $query_vars['is_category'] ) ) {
+ wp_cache_debug( 'Not caching category page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['frontpage'] ) && 1 === $this->config->config['wp_cache_pages']['frontpage'] && isset( $query_vars['is_front_page'] ) ) {
+ wp_cache_debug( 'Not caching front page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['home'] ) && 1 === $this->config->config['wp_cache_pages']['home'] && isset( $query_vars['is_home'] ) ) {
+ wp_cache_debug( 'Not caching home page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['search'] ) && 1 === $this->config->config['wp_cache_pages']['search'] && isset( $query_vars['is_search'] ) ) {
+ wp_cache_debug( 'Not caching search page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['author'] ) && 1 === $this->config->config['wp_cache_pages']['author'] && isset( $query_vars['is_author'] ) ) {
+ wp_cache_debug( 'Not caching author page.' );
+ $cache_this_page = false;
+ } elseif ( isset( $this->config->config['wp_cache_pages']['feed'] ) && 1 === $this->config->config['wp_cache_pages']['feed'] && isset( $query_vars['is_feed'] ) ) {
+ wp_cache_debug( 'Not caching feed.' );
+ $cache_this_page = false;
+ } elseif ( isset( $query_vars['is_rest'] ) ) {
+ wp_cache_debug( 'REST API detected. Caching disabled.' );
+ $cache_this_page = false;
+ } elseif ( isset( $query_vars['is_robots'] ) ) {
+ wp_cache_debug( 'robots.txt detected. Caching disabled.' );
+ $cache_this_page = false;
+ } elseif ( isset( $query_vars['is_redirect'] ) ) {
+ wp_cache_debug( 'Redirect detected. Caching disabled.' );
+ $cache_this_page = false;
+ } elseif ( isset( $query_vars['is_304'] ) ) {
+ wp_cache_debug( 'HTTP 304 (Not Modified) sent. Caching disabled.' );
+ $cache_this_page = false;
+ } elseif ( empty( $query_vars ) && apply_filters( 'wpsc_only_cache_known_pages', 1 ) ) {
+ wp_cache_debug( 'ob_handler: query_vars is empty. Not caching unknown page type. Return 0 to the wpsc_only_cache_known_pages filter to cache this page.' );
+ $cache_this_page = false;
+ } elseif ( Wp_Super_Cache_User::instance()->is_caching_disabled() ) {
+ wp_cache_debug( 'ob_handler: Caching disabled for known user. User logged in or cookie found.' );
+ $cache_this_page = false;
+ }
+
+ return $cache_this_page;
+ }
+
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_Page
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+
+}
diff --git a/includes/class-wp-super-cache-setup.php b/includes/class-wp-super-cache-setup.php
new file mode 100644
index 00000000..fba792e1
--- /dev/null
+++ b/includes/class-wp-super-cache-setup.php
@@ -0,0 +1,379 @@
+advanced_cache_filename = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php';
+ $this->plugin_config_filename = untrailingslashit( WP_CONTENT_DIR ) . '/wp-cache-config.php';
+ $this->config = Wp_Super_Cache_Config::instance();
+
+ if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
+ $this->config_filename = ABSPATH . 'wp-config.php';
+ } else {
+ $this->config_filename = dirname( ABSPATH ) . '/wp-config.php';
+ }
+
+ }
+
+ /**
+ * Create cache storage.
+ *
+ * @since 2.0.0
+ */
+ public function create_cache_storage() {
+ return apply_filters( 'wpsc_create_cache_storage', true );
+ }
+
+ /**
+ * Create WP_CONTENT/advanced_cache.php
+ *
+ * @since 2.0.0
+ */
+ public function create_advanced_cache() {
+ // Old plugin loads wp-cache-phase1.php, we load includes/pre-wp-functions.php includes/pre-wp-cache.php.
+
+ // phpcs:disable
+ $code = <<';
+ }
+}
+
+defined( 'ABSPATH' ) || exit;
+if ( is_admin() ) {
+ return;
+}
+
+if ( ! defined( "WPCACHEHOME" ) ) {
+ define( "WPCACHEHOME", ABSPATH . "wp-content/plugins/wp-super-cache/" );
+}
+
+if ( false === defined( 'WPCACHEHOME' ) ) {
+ define( 'ADVANCEDCACHEPROBLEM', 1 );
+} elseif ( ! file_exists( WPCACHEHOME . 'includes/pre-wp-functions.php' ) ) {
+ define( 'ADVANCEDCACHEPROBLEM', 1 );
+}
+if ( defined( 'ADVANCEDCACHEPROBLEM' ) ) {
+ register_shutdown_function( 'wpcache_broken_message' );
+ exit;
+}
+include_once WPCACHEHOME . '/includes/pre-wp-functions.php';
+include_once WPCACHEHOME . '/includes/pre-wp-cache.php';
+ADVANCEDCACHE;
+ // phpcs:enable
+
+ if ( ! file_put_contents( $this->advanced_cache_filename, $code ) ) { // phpcs:ignore
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
+ /**
+ * Create WP_CONTENT/wp-cache-config.php
+ *
+ * @since 2.0.0
+ */
+ public function create_config_file() {
+ $code = << 'bot', 1 => 'ia_archive', 2 => 'slurp', 3 => 'crawl', 4 => 'spider', 5 => 'Yandex' );
+
+\$cache_rebuild_files = 1;
+
+// Disable the file locking system.
+// If you are experiencing problems with clearing or creating cache files
+// uncommenting this may help.
+\$wp_cache_mutex_disabled = 1;
+
+// Just modify it if you have conflicts with semaphores
+\$sem_id = 5419;
+
+if ( '/' != substr( \$cache_path, -1)) { \$cache_path .= '/'; }
+
+\$wp_cache_mobile = 0;
+\$wp_cache_mobile_whitelist = 'Stand Alone/QNws';
+\$wp_cache_mobile_browsers = 'Android, 2.0 MMP, 240x320, AvantGo, BlackBerry, Blazer, Cellphone, Danger, DoCoMo, Elaine/3.0, EudoraWeb, hiptop, IEMobile, iPhone, iPod, KYOCERA/WX310K, LG/U990, MIDP-2.0, MMEF20, MOT-V, NetFront, Newt, Nintendo Wii, Nitro, Nokia, Opera Mini, Palm, Playstation Portable, portalmmm, Proxinet, ProxiNet, SHARP-TQ-GX10, Small, SonyEricsson, Symbian OS, SymbianOS, TS21i-10, UP.Browser, UP.Link, Windows CE, WinWAP';
+
+// change to relocate the supercache plugins directory
+\$wp_cache_plugins_dir = WPCACHEHOME . 'plugins';
+// set to 1 to do garbage collection during normal process shutdown instead of wp-cron
+\$wp_cache_shutdown_gc = 0;
+\$wp_super_cache_late_init = 0;
+
+// uncomment the next line to enable advanced debugging features
+\$wp_super_cache_advanced_debug = 0;
+\$wp_super_cache_front_page_text = '';
+\$wp_super_cache_front_page_clear = 0;
+\$wp_super_cache_front_page_check = 0;
+\$wp_super_cache_front_page_notification = '0';
+
+\$wp_cache_anon_only = 0;
+\$wp_supercache_cache_list = 0;
+\$wp_cache_debug_to_file = 0;
+\$wp_super_cache_debug = 0;
+\$wp_cache_debug_level = 5;
+\$wp_cache_debug_ip = '';
+\$wp_cache_debug_log = '';
+\$wp_cache_debug_email = '';
+\$wp_cache_pages['search'] = 0;
+\$wp_cache_pages['feed'] = 0;
+\$wp_cache_pages['category'] = 0;
+\$wp_cache_pages['home'] = 0;
+\$wp_cache_pages['frontpage'] = 0;
+\$wp_cache_pages['tag'] = 0;
+\$wp_cache_pages['archives'] = 0;
+\$wp_cache_pages['pages'] = 0;
+\$wp_cache_pages['single'] = 0;
+\$wp_cache_pages['author'] = 0;
+\$wp_cache_hide_donation = 0;
+\$wp_cache_not_logged_in = 0;
+\$wp_cache_clear_on_post_edit = 0;
+\$wp_cache_hello_world = 0;
+\$wp_cache_mobile_enabled = 0;
+\$wp_cache_cron_check = 0;
+\$wp_cache_mfunc_enabled = 0;
+\$wp_cache_make_known_anon = 0;
+\$wp_cache_refresh_single_only = 0;
+\$wp_cache_mod_rewrite = 0;
+\$wp_supercache_304 = 0;
+\$wp_cache_front_page_checks = 0;
+\$wp_cache_disable_utf8 = 0;
+\$wp_cache_no_cache_for_get = 0;
+\$cache_scheduled_time = "00:00";
+\$wp_cache_preload_interval = 600;
+\$cache_schedule_type = 'interval';
+\$wp_cache_preload_posts = 0;
+\$wp_cache_preload_on = 0;
+\$wp_cache_preload_taxonomies = 0;
+\$wp_cache_preload_email_me = 0;
+\$wp_cache_preload_email_volume = 'none';
+\$wp_cache_mobile_prefixes = '';
+\$cached_direct_pages = array();
+\$wpsc_served_header = false;
+\$cache_gc_email_me = 0;
+\$wpsc_save_headers = 0;
+\$cache_schedule_interval = 'daily';
+\$wp_super_cache_comments = 1;
+\$wpsc_version = 169;
+
+CONFIGFILE;
+ if ( ! file_put_contents( $this->plugin_config_filename, $code ) ) { // phpcs:ignore
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Set the homepath setting
+ *
+ * @since 2.0.0
+ */
+ public function set_home_path() {
+ $home_path = wp_parse_url( site_url() );
+ $home_path = trailingslashit( array_key_exists( 'path', $home_path ) ? $home_path['path'] : '' );
+
+ if ( ! isset( $this->config->config['wp_cache_home_path'] ) ) {
+ $this->config->update_setting( 'wp_cache_home_path', '/' );
+ }
+
+ if ( "$home_path" !== "$wp_cache_home_path" ) {
+ $this->config->update_setting( 'wp_cache_home_path', $home_path );
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Add WP_CACHE to wp-config.php
+ *
+ * @since 2.0.0
+ */
+ public function add_wp_cache_constant() {
+ $line = "define( 'WP_CACHE', true );";
+ if ( ! defined( 'WP_CACHE' ) ) {
+ define( 'WP_CACHE', true );
+ }
+ return $this->config->replace_line_in_file( 'define *\( *\'WP_CACHE\'', $line, $this->config_filename );
+ }
+
+ /**
+ * Add WPCACHEHOME to wp-config.php
+ *
+ * @since 2.0.0
+ */
+ public function add_wpcachehome_constant() {
+ if ( ! defined( 'WPCACHEHOME' ) ) {
+ define( 'WPCACHEHOME', trailingslashit( dirname( __FILE__ ) ) );
+ }
+ $line = "define( 'WPCACHEHOME', '" . trailingslashit( dirname( dirname( __FILE__ ) ) ) . "' );";
+ return $this->config->replace_line_in_file( 'define *\( *\'WPCACHEHOME\'', $line, $this->config_filename );
+ }
+
+ /**
+ * Check if WP_CACHE defined in wp-config.php
+ *
+ * @since 2.0.0
+ */
+ public function is_wp_cache_constant_defined() {
+ if ( ! defined( 'WP_CACHE' ) ) {
+ return false;
+ }
+ if ( ! strpos( file_get_contents( $this->config_filename ), 'WP_CACHE' ) ) { // phpcs:ignore
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if WPCACHEHOME defined in wp-config.php
+ *
+ * @since 2.0.0
+ */
+ public function is_wpcachehome_constant_defined() {
+ if ( ! defined( 'WPCACHEHOME' ) ) {
+ return false;
+ }
+ if ( ! strpos( file_get_contents( $this->config_filename ), 'WPCACHEHOME' ) ) { // phpcs:ignore
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if advanced-cache.php created.
+ *
+ * @since 2.0.0
+ */
+ public function advanced_cache_exists() {
+ if ( file_exists( $this->advanced_cache_filename ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check if wp-cache-config.php created.
+ *
+ * @since 2.0.0
+ */
+ public function plugin_config_exists() {
+ if ( file_exists( $this->plugin_config_filename ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_Setup
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+}
diff --git a/includes/class-wp-super-cache-user.php b/includes/class-wp-super-cache-user.php
new file mode 100644
index 00000000..f7c707f0
--- /dev/null
+++ b/includes/class-wp-super-cache-user.php
@@ -0,0 +1,159 @@
+config = Wp_Super_Cache_Config::instance();
+ }
+
+ /**
+ * Get authentication cookies for visitor.
+ *
+ * @since 2.0
+ */
+ public function get_auth_cookies() {
+ static $cached_cookies;
+
+ if ( isset( $cached_cookies ) && is_array( $cached_cookies ) ) {
+ return $cached_cookies;
+ }
+
+ $cookies = array_keys( $_COOKIE );
+ if ( empty( $cookies ) ) {
+ return array();
+ }
+
+ $auth_cookies = array();
+ $duplicate_cookies = array();
+
+ $wp_cookies = array(
+ 'AUTH_COOKIE' => 'wordpress_',
+ 'SECURE_AUTH_COOKIE' => 'wordpress_sec_',
+ 'LOGGED_IN_COOKIE' => 'wordpress_logged_in_',
+ );
+
+ foreach ( $wp_cookies as $cookie_const => $cookie_prefix ) {
+ $cookie_key = strtolower( $cookie_const );
+
+ if ( defined( $cookie_const ) ) {
+ if ( in_array( constant( $cookie_const ), $cookies, true ) ) {
+ $auth_cookies[ $cookie_key ] = constant( $cookie_const );
+ }
+
+ continue;
+ }
+
+ $found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
+
+ if ( count( $found_cookies ) === 1 ) {
+ $auth_cookies[ $cookie_key ] = reset( $found_cookies );
+ } elseif ( count( $found_cookies ) > 1 ) {
+ $duplicate_cookies = array_merge( $duplicate_cookies, $found_cookies );
+ $auth_cookies[ $cookie_key ] = $found_cookies;
+ }
+ }
+
+ $cookie_hash = defined( 'COOKIEHASH' ) ? COOKIEHASH : '';
+ $other_cookies = array(
+ 'comment_cookie' => 'comment_author_',
+ 'postpass_cookie' => 'wp-postpass_',
+ );
+
+ foreach ( $other_cookies as $cookie_key => $cookie_prefix ) {
+
+ if ( $cookie_hash ) {
+ if ( in_array( $cookie_prefix . $cookie_hash, $cookies, true ) ) {
+ $auth_cookies[ $cookie_key ] = $cookie_prefix . $cookie_hash;
+ }
+
+ continue;
+ }
+
+ $found_cookies = preg_grep( '`^' . preg_quote( $cookie_prefix, '`' ) . '([0-9a-f]+)$`', $cookies );
+
+ if ( count( $found_cookies ) === 1 ) {
+ $auth_cookies[ $cookie_key ] = reset( $found_cookies );
+ } elseif ( count( $found_cookies ) > 1 ) {
+ $duplicate_cookies = array_merge( $duplicate_cookies, $found_cookies );
+ $auth_cookies[ $cookie_key ] = $found_cookies;
+ }
+ }
+
+ if ( ! $duplicate_cookies ) {
+ $cached_cookies = $auth_cookies;
+ }
+
+ if ( empty( $auth_cookies ) ) {
+ wp_cache_debug( 'get_auth_cookies: no auth cookies detected', 5 );
+ } else {
+ if ( $duplicate_cookies ) {
+ wp_cache_debug( 'get_auth_cookies: duplicate cookies detected( ' . implode( ', ', $duplicate_cookies ) . ' )', 5 );
+ } else {
+ wp_cache_debug( 'get_auth_cookies: cookies detected: ' . implode( ', ', $auth_cookies ), 5 );
+ }
+ }
+
+ return $auth_cookies;
+ }
+
+ /**
+ * Check if caching is disabled for the current visitor based on their cookies
+ *
+ * @since 2.0
+ */
+ public function is_caching_disabled() {
+ if ( 2 === $this->config->config['wp_cache_not_logged_in'] && $this->get_auth_cookies() ) {
+ wp_cache_debug( 'User - is_caching_disabled: true because logged in' );
+ return true;
+ } elseif ( 1 === $this->config->config['wp_cache_not_logged_in'] && ! empty( $_COOKIE ) ) {
+ wp_cache_debug( 'User - is_caching_disabled: true because cookie found' );
+ return true;
+ } else {
+ wp_cache_debug( 'User - is_caching_disabled: false' );
+ return false;
+ }
+ }
+
+ /**
+ * Return an instance of the current class, create one if it doesn't exist
+ *
+ * @since 2.0
+ * @return Wp_Super_Cache_User
+ */
+ public static function instance() {
+
+ static $instance;
+
+ if ( ! $instance ) {
+ $instance = new self();
+ }
+
+ return $instance;
+ }
+}
diff --git a/includes/class-wp-super-cache.php b/includes/class-wp-super-cache.php
new file mode 100755
index 00000000..0fea57c6
--- /dev/null
+++ b/includes/class-wp-super-cache.php
@@ -0,0 +1,244 @@
+
+ */
+class Wp_Super_Cache {
+
+ /**
+ * The loader that's responsible for maintaining and registering all hooks that power
+ * the plugin.
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var Wp_Super_Cache_Loader $loader Maintains and registers all hooks for the plugin.
+ */
+ protected $loader;
+
+ /**
+ * The unique identifier of this plugin.
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var string $plugin_name The string used to uniquely identify this plugin.
+ */
+ protected $plugin_name;
+
+ /**
+ * The current version of the plugin.
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var string $version The current version of the plugin.
+ */
+ protected $version;
+
+ /**
+ * Configuration
+ *
+ * @since 2.0.0
+ * @access protected
+ * @var string $config The current configuration of the plugin.
+ */
+ protected $config;
+
+ /**
+ * Define the core functionality of the plugin.
+ *
+ * Set the plugin name and the plugin version that can be used throughout the plugin.
+ * Load the dependencies, define the locale, and set the hooks for the admin area and
+ * the public-facing side of the site.
+ *
+ * @since 2.0.0
+ */
+ public function __construct() {
+ if ( defined( 'WP_SUPER_CACHE_VERSION' ) ) {
+ $this->version = WP_SUPER_CACHE_VERSION;
+ } else {
+ $this->version = '2.0.0';
+ }
+ $this->plugin_name = 'wp-super-cache';
+
+ $this->load_dependencies();
+ $this->set_locale();
+ $this->define_admin_hooks();
+ $this->define_public_hooks();
+
+ }
+
+ /**
+ * Load the required dependencies for this plugin.
+ *
+ * Include the following files that make up the plugin:
+ *
+ * - Wp_Super_Cache_Loader. Orchestrates the hooks of the plugin.
+ * - Wp_Super_Cache_i18n. Defines internationalization functionality.
+ * - Wp_Super_Cache_Admin. Defines all hooks for the admin area.
+ * - Wp_Super_Cache_Public. Defines all hooks for the public side of the site.
+ *
+ * Create an instance of the loader which will be used to register the hooks
+ * with WordPress.
+ *
+ * @since 2.0.0
+ * @access private
+ */
+ private function load_dependencies() {
+
+ /**
+ * Basic functions that are used everywhere, before and after
+ * WordPress is loaded.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/pre-wp-functions.php';
+
+ /**
+ * The class responsible for orchestrating the actions and filters of the
+ * core plugin.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-super-cache-loader.php';
+
+ /**
+ * The class responsible for defining internationalization functionality
+ * of the plugin.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-super-cache-i18n.php';
+
+ /**
+ * The class responsible for defining all actions that occur in the admin area.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wp-super-cache-admin.php';
+
+ /**
+ * The class responsible for defining all actions that occur in the public-facing
+ * side of the site.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wp-super-cache-public.php';
+
+ /**
+ * The class responsible for defining configuration functions used by the plugin.
+ */
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-super-cache-config.php';
+
+ $this->config = Wp_Super_cache_Config::instance();
+ $this->loader = new Wp_Super_Cache_Loader();
+
+ }
+
+ /**
+ * Define the locale for this plugin for internationalization.
+ *
+ * Uses the Wp_Super_Cache_i18n class in order to set the domain and to register the hook
+ * with WordPress.
+ *
+ * @since 2.0.0
+ * @access private
+ */
+ private function set_locale() {
+
+ $plugin_i18n = new Wp_Super_Cache_i18n();
+
+ $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
+
+ }
+
+ /**
+ * Register all of the hooks related to the admin area functionality
+ * of the plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ */
+ private function define_admin_hooks() {
+
+ $plugin_admin = new Wp_Super_Cache_Admin( $this->get_plugin_name(), $this->get_version() );
+
+ $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
+ $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
+ if ( WPSC_IS_NETWORK ) {
+ $this->loader->add_action( 'network_admin_menu', $plugin_admin, 'network_admin_menu' );
+ } else {
+ $this->loader->add_action( 'admin_menu', $plugin_admin, 'action_admin_menu' );
+ $this->loader->add_action( 'admin_bar_menu', $plugin_admin, 'admin_bar_menu' );
+ }
+ add_action( 'load-settings_page_wp-super-cache', array( $plugin_admin, 'update' ) );
+ }
+
+ /**
+ * Register all of the hooks related to the public-facing functionality
+ * of the plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ */
+ private function define_public_hooks() {
+
+ $plugin_public = new Wp_Super_Cache_Public( $this->get_plugin_name(), $this->get_version() );
+
+ $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
+ $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
+
+ }
+
+ /**
+ * Run the loader to execute all of the hooks with WordPress.
+ *
+ * @since 2.0.0
+ */
+ public function run() {
+ $this->loader->run();
+ }
+
+ /**
+ * The name of the plugin used to uniquely identify it within the context of
+ * WordPress and to define internationalization functionality.
+ *
+ * @since 2.0.0
+ * @return string The name of the plugin.
+ */
+ public function get_plugin_name() {
+ return $this->plugin_name;
+ }
+
+ /**
+ * The reference to the class that orchestrates the hooks with the plugin.
+ *
+ * @since 2.0.0
+ * @return Wp_Super_Cache_Loader Orchestrates the hooks of the plugin.
+ */
+ public function get_loader() {
+ return $this->loader;
+ }
+
+ /**
+ * Retrieve the version number of the plugin.
+ *
+ * @since 2.0.0
+ * @return string The version number of the plugin.
+ */
+ public function get_version() {
+ return $this->version;
+ }
+
+}
diff --git a/includes/index.php b/includes/index.php
new file mode 100755
index 00000000..0268c0c4
--- /dev/null
+++ b/includes/index.php
@@ -0,0 +1,2 @@
+config['cache_page_secret'] ) && $_GET['donotcachepage'] === $wp_super_cache_config->config['cache_page_secret']
+) {
+ $wp_super_cache_config->config['cache_enabled'] = false;
+ define( 'DONOTCACHEPAGE', 1 );
+}
+
+$wp_super_cache_plugins = glob( $wp_super_cache_config->config['wp_cache_plugins_dir'] . '/*.php' );
+if ( is_array( $wp_super_cache_plugins ) ) {
+ foreach ( $wp_super_cache_plugins as $wp_super_cache_plugin ) {
+ if ( is_file( $wp_super_cache_plugin ) ) {
+ require_once $wp_super_cache_plugin;
+ }
+ }
+}
+
+if ( isset( $wpsc_plugins ) && is_array( $wpsc_plugins ) ) {
+ foreach ( $wpsc_plugins as $wp_super_cache_plugin_file ) {
+ if ( file_exists( ABSPATH . $wp_super_cache_plugin_file ) ) {
+ include_once ABSPATH . $wp_super_cache_plugin_file;
+ }
+ }
+}
+
+if (
+ file_exists( WPCACHEHOME . '../wp-super-cache-plugins/' ) &&
+ is_dir( WPCACHEHOME . '../wp-super-cache-plugins/' )
+) {
+ $wp_super_cache_plugins = glob( WPCACHEHOME . '../wp-super-cache-plugins/*.php' );
+ if ( is_array( $wp_super_cache_plugins ) ) {
+ foreach ( $wp_super_cache_plugins as $wp_super_cache_plugin ) {
+ if ( is_file( $wp_super_cache_plugin ) ) {
+ require_once $wp_super_cache_plugin;
+ }
+ }
+ }
+}
+
+$wp_super_cache_start_time = microtime();
+
+if ( $wp_super_cache_page->is_cached() ) {
+ $wp_super_cache_page->serve_page();
+} elseif ( $wp_super_cache_page->is_cacheable() ) {
+ $wp_super_cache_page->cache_page();
+}
diff --git a/includes/pre-wp-functions.php b/includes/pre-wp-functions.php
new file mode 100644
index 00000000..47d7e383
--- /dev/null
+++ b/includes/pre-wp-functions.php
@@ -0,0 +1,55 @@
+
+ */
+class Wp_Super_Cache_Public {
+
+ /**
+ * The ID of this plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ * @var string $plugin_name The ID of this plugin.
+ */
+ private $plugin_name;
+
+ /**
+ * The version of this plugin.
+ *
+ * @since 2.0.0
+ * @access private
+ * @var string $version The current version of this plugin.
+ */
+ private $version;
+
+ /**
+ * Initialize the class and set its properties.
+ *
+ * @since 2.0.0
+ * @param string $plugin_name The name of the plugin.
+ * @param string $version The version of this plugin.
+ */
+ public function __construct( $plugin_name, $version ) {
+
+ $this->plugin_name = $plugin_name;
+ $this->version = $version;
+
+ }
+
+ /**
+ * Register the stylesheets for the public-facing side of the site.
+ *
+ * @since 2.0.0
+ */
+ public function enqueue_styles() {
+
+ /**
+ * This function is provided for demonstration purposes only.
+ *
+ * An instance of this class should be passed to the run() function
+ * defined in Wp_Super_Cache_Loader as all of the hooks are defined
+ * in that particular class.
+ *
+ * The Wp_Super_Cache_Loader will then create the relationship
+ * between the defined hooks and the functions defined in this
+ * class.
+ */
+
+ wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wp-super-cache-public.css', array(), $this->version, 'all' );
+
+ }
+
+ /**
+ * Register the JavaScript for the public-facing side of the site.
+ *
+ * @since 2.0.0
+ */
+ public function enqueue_scripts() {
+
+ /**
+ * This function is provided for demonstration purposes only.
+ *
+ * An instance of this class should be passed to the run() function
+ * defined in Wp_Super_Cache_Loader as all of the hooks are defined
+ * in that particular class.
+ *
+ * The Wp_Super_Cache_Loader will then create the relationship
+ * between the defined hooks and the functions defined in this
+ * class.
+ */
+
+ wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wp-super-cache-public.js', array( 'jquery' ), $this->version, false );
+
+ }
+
+}
diff --git a/public/css/wp-super-cache-public.css b/public/css/wp-super-cache-public.css
new file mode 100755
index 00000000..65bbf963
--- /dev/null
+++ b/public/css/wp-super-cache-public.css
@@ -0,0 +1,4 @@
+/**
+ * All of the CSS for your public-facing functionality should be
+ * included in this file.
+ */
\ No newline at end of file
diff --git a/public/index.php b/public/index.php
new file mode 100755
index 00000000..7751eb07
--- /dev/null
+++ b/public/index.php
@@ -0,0 +1,2 @@
+
+
+
diff --git a/uninstall.php b/uninstall.php
new file mode 100755
index 00000000..f29f3d3b
--- /dev/null
+++ b/uninstall.php
@@ -0,0 +1,31 @@
+run();
+
+}
+run_wp_super_cache();