Skip to content

Commit 33daa57

Browse files
committed
Merge branch 'release-3.1.0'
2 parents 2ee4acc + abfc1ca commit 33daa57

File tree

17 files changed

+367
-130
lines changed

17 files changed

+367
-130
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# BC Cache Changelog
22

3+
## Upcoming version 3.1.0 (2023-01-04)
4+
5+
### Changed
6+
7+
* WordPress 5.9 or newer is now required [#88](https://github.com/chesio/bc-cache/issues/88).
8+
* Improved serialization of data stored in database [#90](https://github.com/chesio/bc-cache/issues/90).
9+
* On WordPress 6.1 and newer, output buffering is started in `send_headers` action already [#87](https://github.com/chesio/bc-cache/issues/87).
10+
11+
### Fixed
12+
13+
* Prevent deprecation notices on PHP 8.1 and newer [#89](https://github.com/chesio/bc-cache/issues/89).
14+
315
## Version 3.0.1 (2022-12-28)
416

517
### Fixed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ Modern and simple full page cache plugin for WordPress inspired by [Cachify](htt
77

88
BC Cache has no settings page - it is intended for webmasters who are familiar with `.htaccess` files and WordPress actions and filters.
99

10-
BC Cache can cache not only HTML pages, but [core XML sitemaps](https://make.wordpress.org/core/2020/07/22/new-xml-sitemaps-functionality-in-wordpress-5-5/) as well. Technically, any content type generated by WordPress for front-end requests routed via root `index.php` file can be handled provided that output generation triggers [`template_redirect`](https://developer.wordpress.org/reference/hooks/template_redirect/) hook.
10+
BC Cache can cache not only HTML pages, but [core XML sitemaps](https://make.wordpress.org/core/2020/07/22/new-xml-sitemaps-functionality-in-wordpress-5-5/) as well. Technically, any content type generated by WordPress for front-end requests routed via root `index.php` file can be handled provided that output generation triggers [`send_headers`](https://developer.wordpress.org/reference/hooks/send_headers/) (on WordPress 6.1 and newer) or [`template_redirect`](https://developer.wordpress.org/reference/hooks/template_redirect/) (on WordPress 6.0 and older) hook.
1111

1212
## Requirements
1313

1414
* Apache webserver with [mod_rewrite](https://httpd.apache.org/docs/current/mod/mod_rewrite.html) enabled
1515
* [PHP](https://www.php.net/) 7.3 or newer
16-
* [WordPress](https://wordpress.org/) 5.5 or newer with [pretty permalinks](https://codex.wordpress.org/Using_Permalinks) on
16+
* [WordPress](https://wordpress.org/) 5.9 or newer with [pretty permalinks](https://codex.wordpress.org/Using_Permalinks) on
1717

1818
## Limitations
1919

@@ -233,7 +233,7 @@ wp cron event schedule 'bc-cache/action:flush-cache' midnight daily
233233
A response to HTTP(S) request is **not** cached by BC Cache if **any** of the conditions below evaluates as true:
234234

235235
1. Request is a POST request.
236-
2. Request is a GET request with one or more query string fields that are not whitelisted. By default, the whitelist consists of [Google click IDs](https://support.google.com/searchads/answer/7342044), [Facebook Click Identifier](https://fbclid.com/) and standard [UTM parameters](https://en.wikipedia.org/wiki/UTM_parameters), but it can be [filtered](#filters).
236+
2. Request is a GET request with one or more query string fields that are not whitelisted. By default, the whitelist consists of [Google click IDs](https://support.google.com/searchads/answer/7342044), [Facebook Click Identifier](https://fbclid.com/), [Microsoft Click ID](https://help.ads.microsoft.com/apex/index/3/en/60000) and standard [UTM parameters](https://en.wikipedia.org/wiki/UTM_parameters), but it can be [filtered](#filters).
237237
3. Request is not for a front-end page (ie. [`wp_using_themes`](https://developer.wordpress.org/reference/functions/wp_using_themes/) returns `false`). Output of AJAX, WP-CLI or WP-Cron calls is never cached.
238238
4. Request comes from a non-anonymous user (ie. user that is logged in, left a comment or accessed password protected page/post). The rule can be tweaked to ignore [front-end users](#front-end-users-and-caching) if your theme supports it.
239239
5. Request/response type is one of the following: search, 404, feed, trackback, robots.txt, preview or password protected post.

autoload.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
*/
66

77
// Register autoload function
8-
spl_autoload_register(function (string $class) {
8+
\spl_autoload_register(function (string $class) {
99
// Only autoload classes shipped with the plugin.
10-
if (strpos($class, 'BlueChip\\Cache') !== 0) {
10+
if (!\str_starts_with($class, 'BlueChip\\Cache')) {
1111
return;
1212
}
1313

1414
// Get absolute name of class file
15-
$file = __DIR__ . '/classes/' . str_replace('\\', '/', $class) . '.php';
15+
$file = __DIR__ . '/classes/' . \str_replace('\\', '/', $class) . '.php';
1616

1717
// If the class file is readable, load it!
18-
if (is_readable($file)) {
18+
if (\is_readable($file)) {
1919
require_once $file;
2020
}
2121
});

bc-cache.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
* Plugin Name: BC Cache
55
* Plugin URI: https://github.com/chesio/bc-cache
66
* Description: Simple full page cache plugin inspired by Cachify.
7-
* Version: 3.0.1
7+
* Version: 3.1.0
88
* Author: Česlav Przywara <ceslav@przywara.cz>
99
* Author URI: https://www.chesio.com
1010
* Requires PHP: 7.3
11-
* Requires WP: 5.5
11+
* Requires WP: 5.9
1212
* Tested up to: 6.1
1313
* Text Domain: bc-cache
1414
* GitHub Plugin URI: https://github.com/chesio/bc-cache

classes/BlueChip/Cache/Core.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -595,13 +595,13 @@ private function getPath(string $url): string
595595
$url_parts['host'],
596596
trailingslashit($url_path),
597597
// URL path ends with slash? Yes: treat as directory path. No: treat as file path.
598-
Utils::endsWithString($url_path, '/') ? self::DIRECTORY_PATH_DIRNAME : self::FILE_PATH_DIRNAME
598+
\str_ends_with($url_path, '/') ? self::DIRECTORY_PATH_DIRNAME : self::FILE_PATH_DIRNAME
599599
]);
600600

601601
$normalized_path = self::normalizePath($path);
602602

603603
// Make sure that normalized path still points to a subdirectory of root cache directory.
604-
if (\strpos($normalized_path, $this->cache_dir . DIRECTORY_SEPARATOR) !== 0) {
604+
if (!\str_starts_with($normalized_path, $this->cache_dir . DIRECTORY_SEPARATOR)) {
605605
throw new Exception("Could not retrieve a valid cache filename from URL {$url}.");
606606
}
607607

@@ -626,7 +626,7 @@ private function getUrl(string $path): string
626626
$normalized_path = self::normalizePath($path);
627627

628628
// The path must point to a subdirectory of root cache directory.
629-
if (\strpos($normalized_path, $this->cache_dir . DIRECTORY_SEPARATOR) !== 0) {
629+
if (!\str_starts_with($normalized_path, $this->cache_dir . DIRECTORY_SEPARATOR)) {
630630
throw new Exception("Path {$path} is not a valid cache path.");
631631
}
632632

@@ -645,12 +645,12 @@ private function getUrl(string $path): string
645645
}
646646

647647
$path = DIRECTORY_SEPARATOR . $subparts[1];
648-
if (Utils::endsWithString($path, DIRECTORY_SEPARATOR . self::FILE_PATH_DIRNAME)) {
648+
if (\str_ends_with($path, DIRECTORY_SEPARATOR . self::FILE_PATH_DIRNAME)) {
649649
// Strip file path dirname including trailing directory separator.
650-
$path = substr($path, 0, -1 * strlen(DIRECTORY_SEPARATOR . self::FILE_PATH_DIRNAME));
651-
} elseif (Utils::endsWithString($path, DIRECTORY_SEPARATOR . self::DIRECTORY_PATH_DIRNAME)) {
650+
$path = \substr($path, 0, -1 * \strlen(DIRECTORY_SEPARATOR . self::FILE_PATH_DIRNAME));
651+
} elseif (\str_ends_with($path, DIRECTORY_SEPARATOR . self::DIRECTORY_PATH_DIRNAME)) {
652652
// Strip directory path dirname, but keep trailing directory separator.
653-
$path = substr($path, 0, -1 * strlen(self::DIRECTORY_PATH_DIRNAME));
653+
$path = \substr($path, 0, -1 * \strlen(self::DIRECTORY_PATH_DIRNAME));
654654
}
655655

656656
return $parts[0] . '://' . $subparts[0] . \str_replace(DIRECTORY_SEPARATOR, '/', $path);
@@ -850,7 +850,7 @@ private static function prepareHtaccessFile(array $headers): string
850850
$headers = \array_filter(
851851
$headers,
852852
function (string $header): bool {
853-
return \strpos($header, ':') !== false;
853+
return \str_contains($header, ':');
854854
}
855855
);
856856

classes/BlueChip/Cache/Info.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Info
2424

2525

2626
/**
27-
* @var mixed[] Cache data (lazy loaded)
27+
* @var array Cache data (lazy loaded)
2828
*/
2929
private $data = [];
3030

classes/BlueChip/Cache/Item.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
/**
66
* A single cache item consists of URL and request variant.
77
*/
8-
class Item
8+
class Item extends Serializable
99
{
10+
/**
11+
* @var int Internal class version (used for serialization/unserialization)
12+
*/
13+
protected const DB_VERSION = 1;
14+
1015
/**
1116
* @var string
1217
*/
@@ -30,6 +35,24 @@ public function __construct(string $url, string $request_variant)
3035
}
3136

3237

38+
/**
39+
* @internal Serialization helper.
40+
*/
41+
protected function deflate(): array
42+
{
43+
return ['request_variant' => $this->request_variant, 'url' => $this->url];
44+
}
45+
46+
47+
/**
48+
* @internal Serialization helper.
49+
*/
50+
public function inflate(array $data): void
51+
{
52+
['request_variant' => $this->request_variant, 'url' => $this->url] = $data;
53+
}
54+
55+
3356
public function getUrl(): string
3457
{
3558
return $this->url;

classes/BlueChip/Cache/ListTable.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ public function __construct(Core $cache, ?Crawler $cache_crawler, ?Feeder $cache
105105
// Get list of request variants.
106106
$this->request_variants = $cache->getRequestVariants();
107107

108-
$order_by = \filter_input(INPUT_GET, 'orderby', FILTER_SANITIZE_STRING);
108+
$order_by = \filter_input(INPUT_GET, 'orderby');
109109
if (\in_array($order_by, $this->get_sortable_columns(), true)) {
110110
$this->order_by = $order_by;
111111
$this->url = add_query_arg('orderby', $order_by, $this->url);
112112
}
113113

114-
$order = \filter_input(INPUT_GET, 'order', FILTER_SANITIZE_STRING);
114+
$order = \filter_input(INPUT_GET, 'order');
115115
if ($order === 'asc' || $order === 'desc') {
116116
$this->order = $order;
117117
$this->url = add_query_arg('order', $order, $this->url);
@@ -339,7 +339,7 @@ public function processActions(): void
339339
return;
340340
}
341341

342-
$request_variant = \filter_input(INPUT_GET, 'request_variant', FILTER_SANITIZE_STRING);
342+
$request_variant = \filter_input(INPUT_GET, 'request_variant');
343343
if (!isset($this->request_variants[$request_variant])) {
344344
return;
345345
}

classes/BlueChip/Cache/Plugin.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ class Plugin
139139
*/
140140
private $cache_feeder;
141141

142+
/**
143+
* @var bool|null Null if cache has not been flushed yet in this request or cache flush status.
144+
*/
145+
private $cache_is_flushed = null;
146+
142147

143148
/**
144149
* Perform activation and installation tasks.
@@ -291,7 +296,9 @@ public function init(): void
291296
}
292297
} else {
293298
// Add action to catch output buffer.
294-
add_action('template_redirect', [$this, 'startOutputBuffering'], 0, 0);
299+
// Use `send_headers` action from WordPress 6.1 on - see:
300+
// https://make.wordpress.org/core/2022/10/10/moving-the-send_headers-action-to-later-in-the-load/
301+
add_action(is_wp_version_compatible('6.1') ? 'send_headers' : 'template_redirect', [$this, 'startOutputBuffering'], 0, 0);
295302
}
296303

297304
if ($this->cache_crawler) {
@@ -488,18 +495,12 @@ public function enqueueDashboardAssets(): void
488495
* Flush cache once per request only.
489496
*
490497
* @see Core::flush()
491-
*
492-
* @return bool Cached result of call to Core::flush().
493498
*/
494-
public function flushCacheOnce(): bool
499+
public function flushCacheOnce(): void
495500
{
496-
static $is_flushed = null;
497-
498-
if ($is_flushed === null) {
499-
$is_flushed = $this->cache->flush();
501+
if ($this->cache_is_flushed === null) {
502+
$this->cache_is_flushed = $this->cache->flush();
500503
}
501-
502-
return $is_flushed;
503504
}
504505

505506

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace BlueChip\Cache;
4+
5+
/**
6+
* Serialization helper
7+
*
8+
* @internal As soon as PHP 7.4 is required, only __serialize() and __unserialize() methods are necessary.
9+
*/
10+
abstract class Serializable implements \Serializable
11+
{
12+
/**
13+
* @var int
14+
*
15+
* @internal Should be overriden in child classes to non-zero value and incremented on every class properties change.
16+
*/
17+
protected const DB_VERSION = 0;
18+
19+
20+
public function serialize(): string
21+
{
22+
return \serialize($this->__serialize());
23+
}
24+
25+
26+
public function unserialize($serialized): void
27+
{
28+
$this->__unserialize(\unserialize($serialized));
29+
}
30+
31+
32+
public function __serialize(): array
33+
{
34+
return ['db_version' => static::DB_VERSION, 'data' => $this->deflate()];
35+
}
36+
37+
38+
public function __unserialize(array $data): void
39+
{
40+
if ($data['db_version'] === static::DB_VERSION) {
41+
$this->inflate($data['data']);
42+
}
43+
}
44+
45+
abstract protected function deflate(): array;
46+
47+
abstract protected function inflate(array $data);
48+
}

0 commit comments

Comments
 (0)