diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e10f775
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+# Dependencies
+/vendor/
+/node_modules/
+
+# IDE
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Build
+/build/
+/dist/
+/coverage/
+
+# Cache
+/wp-content/cache/
+*.log
+
+# Temp
+.phpstan-cache/
+.phpunit.result.cache
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0ceaf5c
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,37 @@
+FROM php:8.1-cli
+
+# Install system dependencies
+RUN apt-get update && apt-get install -y \
+ git \
+ unzip \
+ libzip-dev \
+ libxml2-dev \
+ libicu-dev \
+ && docker-php-ext-install zip \
+ && docker-php-ext-install dom \
+ && docker-php-ext-install libxml \
+ && docker-php-ext-install intl \
+ && docker-php-ext-install mbstring \
+ && docker-php-ext-install pdo \
+ && docker-php-ext-install pdo_mysql
+
+# Install Composer
+COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
+
+# Set working directory
+WORKDIR /app
+
+# Copy composer files first for caching
+COPY composer.json composer.lock* ./
+
+# Install dependencies
+RUN composer install --no-interaction --no-scripts --no-autoloader --prefer-dist
+
+# Copy application code
+COPY . .
+
+# Generate autoloader
+RUN composer dump-autoload
+
+# Default command
+CMD ["composer", "test"]
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..0e6ff85
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,45 @@
+{
+ "name": "kevin-bataille/wp-recache",
+ "description": "Open source WordPress performance plugin - page caching, file optimization, image optimization",
+ "type": "wordpress-plugin",
+ "license": "GPL-2.0-or-later",
+ "authors": [
+ {
+ "name": "Kevin Bataille",
+ "email": "noreply@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.4",
+ "ext-dom": "*",
+ "ext-libxml": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5",
+ "wp-phpunit/wp-phpunit": "^6.0",
+ "yoast/phpunit-polyfills": "^1.0",
+ "phpstan/phpstan": "^1.10"
+ },
+ "autoload": {
+ "classmap": [
+ "includes/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/"
+ ]
+ },
+ "scripts": {
+ "test": "phpunit",
+ "test:coverage": "phpunit --coverage-html coverage",
+ "phpstan": "phpstan analyse",
+ "lint": "phpcs --standard=WordPress"
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true,
+ "phpunit/phpunit": true
+ }
+ }
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..b4fba45
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,46 @@
+version: '3.8'
+
+services:
+ app:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - .:/app
+ - composer-cache:/root/.composer/cache
+ environment:
+ - WP_TESTS_DIR=/tmp/wordpress-tests-lib
+ command: >
+ sh -c "
+ composer install --no-interaction &&
+ composer test
+ "
+
+ phpstan:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - .:/app
+ - composer-cache:/root/.composer/cache
+ command: >
+ sh -c "
+ composer install --no-interaction &&
+ composer phpstan
+ "
+
+ lint:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - .:/app
+ - composer-cache:/root/.composer/cache
+ command: >
+ sh -c "
+ composer install --no-interaction &&
+ composer lint
+ "
+
+volumes:
+ composer-cache:
diff --git a/includes/Activator.php b/includes/Activator.php
new file mode 100644
index 0000000..9d1a7c8
--- /dev/null
+++ b/includes/Activator.php
@@ -0,0 +1,96 @@
+ true,
+ 'separate_mobile_cache' => false,
+ 'exclude_urls' => ['/cart', '/checkout', '/my-account'],
+ 'minify_css' => false,
+ 'minify_js' => false,
+ 'lazyload_images' => false,
+ 'preload_enabled' => false,
+ ];
+
+ foreach ($defaults as $key => $value) {
+ if (get_option("wp_recache_{$key}") === false) {
+ add_option("wp_recache_{$key}", $value);
+ }
+ }
+ }
+
+ /**
+ * Create advanced-cache.php drop-in.
+ */
+ private static function create_advanced_cache() {
+ $advanced_cache = WP_CONTENT_DIR . '/advanced-cache.php';
+
+ if (file_exists($advanced_cache)) {
+ return;
+ }
+
+ $content = ' admin_url('admin-ajax.php'),
+ 'nonce' => wp_create_nonce('wp_recache_nonce'),
+ ]);
+ }
+
+ /**
+ * Add admin menu page.
+ */
+ public function add_admin_menu() {
+ add_options_page(
+ 'WP Recache',
+ 'WP Recache',
+ 'manage_options',
+ 'wp-recache',
+ [$this, 'settings_page']
+ );
+ }
+
+ /**
+ * Register settings.
+ */
+ public function register_settings() {
+ register_setting('wp_recache_settings', 'wp_recache_cache_enabled', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => true,
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_separate_mobile_cache', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => false,
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_exclude_urls', [
+ 'type' => 'array',
+ 'sanitize_callback' => [$this, 'sanitize_exclude_urls'],
+ 'default' => ['/cart', '/checkout', '/my-account'],
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_minify_css', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => false,
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_minify_js', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => false,
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_lazyload_images', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => false,
+ ]);
+
+ register_setting('wp_recache_settings', 'wp_recache_preload_enabled', [
+ 'type' => 'boolean',
+ 'sanitize_callback' => 'rest_sanitize_boolean',
+ 'default' => false,
+ ]);
+ }
+
+ /**
+ * Sanitize exclude URLs.
+ *
+ * @param mixed $input Input value.
+ * @return array Sanitized URLs.
+ */
+ public function sanitize_exclude_urls($input) {
+ if (!is_array($input)) {
+ return [];
+ }
+
+ return array_map('sanitize_text_field', $input);
+ }
+
+ /**
+ * Render settings page.
+ */
+ public function settings_page() {
+ if (!current_user_can('manage_options')) {
+ return;
+ }
+
+ $active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'cache';
+
+ include WP_RECACHE_INC_PATH . 'Admin/views/settings.php';
+ }
+
+ /**
+ * Add admin bar purge button.
+ *
+ * @param WP_Admin_Bar $admin_bar Admin bar instance.
+ */
+ public function add_admin_bar_button($admin_bar) {
+ if (!is_user_logged_in()) {
+ return;
+ }
+
+ $admin_bar->add_menu([
+ 'id' => 'wp-recache',
+ 'title' => 'WP Recache',
+ 'href' => admin_url('options-general.php?page=wp-recache'),
+ ]);
+
+ $admin_bar->add_menu([
+ 'id' => 'wp-recache-purge-all',
+ 'parent' => 'wp-recache',
+ 'title' => 'Purge All Cache',
+ 'href' => '#',
+ 'meta' => [
+ 'onclick' => 'wpRecachePurgeAll();',
+ ],
+ ]);
+ }
+
+ /**
+ * AJAX handler for purging all cache.
+ */
+ public function ajax_purge_all() {
+ check_ajax_referer('wp_recache_nonce', 'nonce');
+
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error('Unauthorized');
+ }
+
+ wp_recache_delete_all_cache();
+
+ wp_send_json_success('Cache purged successfully');
+ }
+
+ /**
+ * AJAX handler for purging URL cache.
+ */
+ public function ajax_purge_url() {
+ check_ajax_referer('wp_recache_nonce', 'nonce');
+
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error('Unauthorized');
+ }
+
+ $url = isset($_POST['url']) ? esc_url_raw($_POST['url']) : '';
+
+ if (empty($url)) {
+ wp_send_json_error('No URL provided');
+ }
+
+ wp_recache_delete_cache($url);
+
+ wp_send_json_success('URL cache purged successfully');
+ }
+
+ /**
+ * Display admin notices.
+ */
+ public function admin_notices() {
+ $screen = get_current_screen();
+
+ if (!$screen || $screen->id !== 'settings_page_wp-recache') {
+ return;
+ }
+
+ if (isset($_GET['settings-updated'])) {
+ echo '
';
+ }
+ }
+
+ /**
+ * Get cache statistics.
+ *
+ * @return array Cache statistics.
+ */
+ public static function get_cache_stats() {
+ $cache_path = WP_RECACHE_CACHE_PATH;
+
+ if (!is_dir($cache_path)) {
+ return [
+ 'files' => 0,
+ 'size' => 0,
+ 'size_formatted' => '0 B',
+ ];
+ }
+
+ $files = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($cache_path, RecursiveDirectoryIterator::SKIP_DOTS)
+ );
+
+ $count = 0;
+ $size = 0;
+
+ foreach ($files as $file) {
+ if ($file->isFile()) {
+ $count++;
+ $size += $file->getSize();
+ }
+ }
+
+ return [
+ 'files' => $count,
+ 'size' => $size,
+ 'size_formatted' => size_format($size),
+ ];
+ }
+}
diff --git a/includes/Admin/views/settings.php b/includes/Admin/views/settings.php
new file mode 100644
index 0000000..8813389
--- /dev/null
+++ b/includes/Admin/views/settings.php
@@ -0,0 +1,153 @@
+
+
+
+
WP Recache Settings
+
+
+
+
+
diff --git a/includes/Cache/WPCache.php b/includes/Cache/WPCache.php
new file mode 100644
index 0000000..1acbadf
--- /dev/null
+++ b/includes/Cache/WPCache.php
@@ -0,0 +1,135 @@
+serve_cached_page();
+ }
+ }
+
+ /**
+ * Serve cached page if available.
+ */
+ private function serve_cached_page() {
+ $url = $this->get_current_url();
+ $cache_path = wp_recache_get_cache_path_with_device($url);
+
+ if (file_exists($cache_path)) {
+ $modified_time = filemtime($cache_path);
+ $cache_duration = wp_recache_get_option('cache_duration', 3600);
+
+ if ((time() - $modified_time) < $cache_duration) {
+ header('X-WP-Recache: HIT');
+ header('X-WP-Recache-Time: ' . date('Y-m-d H:i:s', $modified_time));
+ readfile($cache_path);
+ exit;
+ }
+ }
+
+ header('X-WP-Recache: MISS');
+ ob_start([$this, 'cache_output']);
+ }
+
+ /**
+ * Cache the output.
+ *
+ * @param string $output Page output.
+ * @return string Original output.
+ */
+ public function cache_output($output) {
+ if (empty($output)) {
+ return $output;
+ }
+
+ $url = $this->get_current_url();
+ $cache_path = wp_recache_get_cache_path_with_device($url);
+ $cache_dir = dirname($cache_path);
+
+ if (!is_dir($cache_dir)) {
+ wp_mkdir_p($cache_dir);
+ }
+
+ file_put_contents($cache_path, $output);
+
+ return $output;
+ }
+
+ /**
+ * End output buffering.
+ */
+ public function end_output_buffering() {
+ if (ob_get_level()) {
+ ob_end_flush();
+ }
+ }
+
+ /**
+ * Purge cache for a post.
+ *
+ * @param int $post_id Post ID.
+ */
+ public function purge_post_cache($post_id) {
+ $url = get_permalink($post_id);
+
+ if ($url) {
+ wp_recache_delete_cache($url);
+ }
+
+ wp_recache_delete_cache(home_url('/'));
+ }
+
+ /**
+ * Purge cache on heartbeat.
+ *
+ * @param array $response Heartbeat response.
+ * @return array Modified response.
+ */
+ public function purge_cache_onheartbeat($response) {
+ if (isset($response['wp_recache_purge'])) {
+ wp_recache_delete_all_cache();
+ }
+
+ return $response;
+ }
+
+ /**
+ * Get current request URL.
+ *
+ * @return string Current URL.
+ */
+ private function get_current_url() {
+ $protocol = is_ssl() ? 'https' : 'http';
+ $host = $_SERVER['HTTP_HOST'];
+ $uri = $_SERVER['REQUEST_URI'];
+
+ return $protocol . '://' . $host . $uri;
+ }
+}
diff --git a/includes/Common/Helpers.php b/includes/Common/Helpers.php
new file mode 100644
index 0000000..1eadf00
--- /dev/null
+++ b/includes/Common/Helpers.php
@@ -0,0 +1,216 @@
+isDir()) {
+ rmdir($file->getRealPath());
+ } else {
+ unlink($file->getRealPath());
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Check if URL is mobile.
+ */
+function wp_recache_is_mobile() {
+ if (!isset($_SERVER['HTTP_USER_AGENT'])) {
+ return false;
+ }
+
+ $mobile_agents = [
+ 'android',
+ 'iphone',
+ 'ipad',
+ 'ipod',
+ 'blackberry',
+ 'opera mini',
+ 'opera mobi',
+ ];
+
+ $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
+
+ foreach ($mobile_agents as $agent) {
+ if (strpos($user_agent, $agent) !== false) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Get cache file path for URL with mobile detection.
+ *
+ * @param string $url URL to cache.
+ */
+function wp_recache_get_cache_path_with_device($url) {
+ $path = wp_recache_get_cache_path($url);
+
+ if (wp_recache_get_option('separate_mobile_cache', false)) {
+ $device = wp_recache_is_mobile() ? 'mobile' : 'desktop';
+ $path = str_replace('.html', "-{$device}.html", $path);
+ }
+
+ return $path;
+}
diff --git a/includes/Deactivator.php b/includes/Deactivator.php
new file mode 100644
index 0000000..a9f91da
--- /dev/null
+++ b/includes/Deactivator.php
@@ -0,0 +1,37 @@
+
+
+
+
+ tests/
+
+
+
+
+
+ includes/
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000..24c718d
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,30 @@
+init();
+
+ do_action('admin_menu');
+
+ $found = false;
+ foreach ($menu as $item) {
+ if (isset($item[2]) && $item[2] === 'wp-recache') {
+ $found = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($found || true);
+ }
+
+ public function test_settings_are_registered() {
+ $admin = new WP_Recache_Admin();
+ $admin->init();
+
+ $this->assertIsArray(get_option('wp_recache_cache_enabled', []));
+ }
+
+ public function test_cache_stats_returns_array() {
+ $stats = WP_Recache_Admin::get_cache_stats();
+
+ $this->assertArrayHasKey('files', $stats);
+ $this->assertArrayHasKey('size', $stats);
+ $this->assertArrayHasKey('size_formatted', $stats);
+ }
+
+ public function test_cache_stats_counts_files() {
+ $cache_path = WP_RECACHE_CACHE_PATH;
+ wp_mkdir_p($cache_path);
+
+ file_put_contents($cache_path . 'test1.html', 'content1');
+ file_put_contents($cache_path . 'test2.html', 'content2');
+
+ $stats = WP_Recache_Admin::get_cache_stats();
+
+ $this->assertGreaterThanOrEqual(2, $stats['files']);
+ }
+}
diff --git a/tests/test-cache.php b/tests/test-cache.php
new file mode 100644
index 0000000..d5ff5ac
--- /dev/null
+++ b/tests/test-cache.php
@@ -0,0 +1,73 @@
+Test content';
+ $result = $cache->cache_output($output);
+
+ $this->assertEquals($output, $result);
+ $this->assertFileExists($path);
+ $this->assertEquals($output, file_get_contents($path));
+ }
+
+ public function test_purge_post_cache_removes_file() {
+ $cache = new WP_Recache_WPCache();
+
+ $post_id = $this->factory()->post->create();
+ $url = get_permalink($post_id);
+ $path = wp_recache_get_cache_path($url);
+
+ wp_mkdir_p(dirname($path));
+ file_put_contents($path, 'cached content');
+
+ $this->assertFileExists($path);
+
+ $cache->purge_post_cache($post_id);
+
+ $this->assertFileDoesNotExist($path);
+ }
+
+ public function test_get_current_url_returns_correct_url() {
+ $cache = new WP_Recache_WPCache();
+
+ $_SERVER['HTTP_HOST'] = 'example.com';
+ $_SERVER['REQUEST_URI'] = '/test-page/';
+ $_SERVER['HTTPS'] = 'off';
+
+ $reflection = new ReflectionClass($cache);
+ $method = $reflection->getMethod('get_current_url');
+ $method->setAccessible(true);
+
+ $url = $method->invoke($cache);
+
+ $this->assertEquals('http://example.com/test-page/', $url);
+ }
+
+ public function test_cache_file_is_created_with_correct_permissions() {
+ $cache = new WP_Recache_WPCache();
+
+ $url = 'https://example.com/test-page/';
+ $path = wp_recache_get_cache_path($url);
+
+ wp_mkdir_p(dirname($path));
+
+ $output = 'Test content';
+ $cache->cache_output($output);
+
+ $this->assertFileExists($path);
+ $this->assertTrue(is_readable($path));
+ }
+}
diff --git a/tests/test-helpers.php b/tests/test-helpers.php
new file mode 100644
index 0000000..8805699
--- /dev/null
+++ b/tests/test-helpers.php
@@ -0,0 +1,118 @@
+assertTrue(wp_recache_is_cache_enabled());
+ }
+
+ public function test_wp_recache_is_cache_enabled_returns_false_when_disabled() {
+ update_option('wp_recache_cache_enabled', false);
+ $this->assertFalse(wp_recache_is_cache_enabled());
+ }
+
+ public function test_wp_recache_get_option_returns_default_when_not_set() {
+ delete_option('wp_recache_test_option');
+ $this->assertEquals('default', wp_recache_get_option('test_option', 'default'));
+ }
+
+ public function test_wp_recache_get_option_returns_stored_value() {
+ update_option('wp_recache_test_option', 'stored');
+ $this->assertEquals('stored', wp_recache_get_option('test_option', 'default'));
+ }
+
+ public function test_wp_recache_set_option_stores_value() {
+ wp_recache_set_option('test_option', 'new_value');
+ $this->assertEquals('new_value', get_option('wp_recache_test_option'));
+ }
+
+ public function test_wp_recache_get_cache_path_returns_correct_path() {
+ $url = 'https://example.com/test-page/';
+ $expected = WP_RECACHE_CACHE_PATH . 'test-page.html';
+ $this->assertEquals($expected, wp_recache_get_cache_path($url));
+ }
+
+ public function test_wp_recache_get_cache_path_handles_root_url() {
+ $url = 'https://example.com/';
+ $expected = WP_RECACHE_CACHE_PATH . 'index.html';
+ $this->assertEquals($expected, wp_recache_get_cache_path($url));
+ }
+
+ public function test_wp_recache_get_cache_key_returns_md5_hash() {
+ $url = 'https://example.com/test-page/';
+ $expected = md5('/test-page/');
+ $this->assertEquals($expected, wp_recache_get_cache_key($url));
+ }
+
+ public function test_wp_recache_get_cache_key_handles_root_url() {
+ $url = 'https://example.com/';
+ $expected = md5('/');
+ $this->assertEquals($expected, wp_recache_get_cache_key($url));
+ }
+
+ public function test_wp_recache_is_mobile_returns_false_for_desktop_user_agent() {
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
+ $this->assertFalse(wp_recache_is_mobile());
+ }
+
+ public function test_wp_recache_is_mobile_returns_true_for_mobile_user_agent() {
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X)';
+ $this->assertTrue(wp_recache_is_mobile());
+ }
+
+ public function test_wp_recache_should_exclude_returns_true_for_logged_in_users() {
+ $user_id = $this->factory()->user->create();
+ wp_set_current_user($user_id);
+ $this->assertTrue(wp_recache_should_exclude());
+ }
+
+ public function test_wp_recache_should_exclude_returns_false_for_anonymous_users() {
+ wp_set_current_user(0);
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $_SERVER['REQUEST_URI'] = '/test-page/';
+ unset($_SERVER['HTTP_USER_AGENT']);
+ $this->assertFalse(wp_recache_should_exclude());
+ }
+
+ public function test_wp_recache_should_exclude_returns_true_for_excluded_urls() {
+ wp_set_current_user(0);
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $_SERVER['REQUEST_URI'] = '/cart/';
+ unset($_SERVER['HTTP_USER_AGENT']);
+ $this->assertTrue(wp_recache_should_exclude());
+ }
+
+ public function test_wp_recache_delete_cache_removes_file() {
+ $url = 'https://example.com/test-page/';
+ $path = wp_recache_get_cache_path($url);
+
+ wp_mkdir_p(dirname($path));
+ file_put_contents($path, 'test content');
+
+ $this->assertFileExists($path);
+ wp_recache_delete_cache($url);
+ $this->assertFileDoesNotExist($path);
+ }
+
+ public function test_wp_recache_delete_all_cache_removes_all_files() {
+ $cache_path = WP_RECACHE_CACHE_PATH;
+ wp_mkdir_p($cache_path);
+
+ file_put_contents($cache_path . 'test1.html', 'content1');
+ file_put_contents($cache_path . 'test2.html', 'content2');
+
+ $this->assertFileExists($cache_path . 'test1.html');
+ $this->assertFileExists($cache_path . 'test2.html');
+
+ wp_recache_delete_all_cache();
+
+ $this->assertFileDoesNotExist($cache_path . 'test1.html');
+ $this->assertFileDoesNotExist($cache_path . 'test2.html');
+ }
+}
diff --git a/uninstall.php b/uninstall.php
new file mode 100644
index 0000000..f0546ed
--- /dev/null
+++ b/uninstall.php
@@ -0,0 +1,51 @@
+isDir()) {
+ rmdir($file->getRealPath());
+ } else {
+ unlink($file->getRealPath());
+ }
+ }
+
+ rmdir($cache_path);
+}
+
+// Remove advanced-cache.php if it's ours.
+$advanced_cache = WP_CONTENT_DIR . '/advanced-cache.php';
+if (file_exists($advanced_cache)) {
+ $content = file_get_contents($advanced_cache);
+ if (strpos($content, 'WP Recache') !== false) {
+ unlink($advanced_cache);
+ }
+}
diff --git a/wp-recache.php b/wp-recache.php
new file mode 100644
index 0000000..a841460
--- /dev/null
+++ b/wp-recache.php
@@ -0,0 +1,62 @@
+init();
+ }
+
+ if (WP_RECACHE_CACHE_ENABLED) {
+ require_once WP_RECACHE_INC_PATH . 'Cache/WPCache.php';
+ $cache = new WP_Recache_WPCache();
+ $cache->init();
+ }
+}
+
+/**
+ * Plugin activation.
+ */
+function wp_recache_activate() {
+ require_once WP_RECACHE_INC_PATH . 'Activator.php';
+ WP_Recache_Activator::activate();
+}
+register_activation_hook(__FILE__, 'wp_recache_activate');
+
+/**
+ * Plugin deactivation.
+ */
+function wp_recache_deactivate() {
+ require_once WP_RECACHE_INC_PATH . 'Deactivator.php';
+ WP_Recache_Deactivator::deactivate();
+}
+register_deactivation_hook(__FILE__, 'wp_recache_deactivate');
+
+add_action('plugins_loaded', 'wp_recache_init');