Files
wp-recache/includes/Cache/WPCache.php
T
kevin.bataille 33099591f5 feat: implement Phase 1 - Core Page Cache and Admin Settings UI
Implement the core page caching functionality and admin settings interface
for WP Recache plugin. This includes:

- Plugin bootstrap with activation/deactivation handlers
- Admin settings page with tabbed interface (Cache, Optimization, Advanced)
- Admin bar integration for quick cache purging
- Core page cache using output buffering
- Cache file management with mobile device separation
- Cache purge on post update/comment
- Default URL exclusions (cart, checkout, account)
- Cache statistics display
- PHPUnit test suite setup
- Docker-based development environment
- PHPStan configuration for static analysis

References:
- Closes #1 (Core Page Cache)
- Closes #8 (Admin Settings UI)
2026-09-13 09:56:35 +02:00

136 lines
3.2 KiB
PHP

<?php
/**
* Core page cache functionality.
*
* @package WP_Recache
*/
defined('ABSPATH') || exit;
class WP_Recache_WPCache {
/**
* Initialize cache hooks.
*/
public function init() {
add_action('init', [$this, 'start_output_buffering']);
add_action('shutdown', [$this, 'end_output_buffering']);
add_action('save_post', [$this, 'purge_post_cache']);
add_action('wp_insert_comment', [$this, 'purge_post_cache']);
add_filter('heartbeat_received', [$this, 'purge_cache_onheartbeat']);
}
/**
* Start output buffering.
*/
public function start_output_buffering() {
if (wp_recache_should_exclude()) {
return;
}
if (wp_recache_is_cache_enabled()) {
$this->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;
}
}