Skip to content

Commit 3d01a9b

Browse files
authored
Merge pull request #73 from circuscode/feature-caching-wprestapi
Caching WP REST API
2 parents fa5ecbd + dc9e523 commit 3d01a9b

File tree

3 files changed

+174
-0
lines changed

3 files changed

+174
-0
lines changed

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ Standard features of the following plugins will be manipulated or extended.
151151
### WP REST CACHE
152152

153153
* Fade out Icon @ Admin Bar
154+
* ActivityPub Endpoints Caching
154155

155156
### wpRocket
156157

@@ -215,6 +216,7 @@ This project is licensed under the GPL3 License.
215216

216217
Release pending.
217218

219+
* Added: Caching of ActivityPub Endpoints in WP REST API
218220
* Added: Fade out WB REST CACHE Icon @ Admin Bar
219221
* Added: Disable UpdraftPlus @ Admin Bar
220222

unmus.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
require_once('unmus_activitypub.php');
4848
require_once('unmus_widgets.php');
4949
require_once('unmus_visibility.php');
50+
require_once('unmus_cache.php');
5051

5152
// Ensure that all required functions are available during setup
5253
require_once( ABSPATH . 'wp-admin/includes/upgrade.php');

unmus_cache.php

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
3+
/**
4+
* Caching
5+
*
6+
* Rocket-related Caching, see unmus_rocket.php
7+
* Following is referring to WP REST API (Plugin WP-REST-CACHE)
8+
*
9+
* @package unmus
10+
* @since 0.9
11+
*
12+
* @link https://epiph.yt/en/blog/2025/activitypub-plugin-and-accidental-ddos/
13+
*/
14+
15+
// Security: Stops code execution if WordPress is not loaded
16+
if (!defined('ABSPATH')) { exit; }
17+
18+
// Import Caching Class from WP_Rest_Cache_Plugin
19+
use WP_Rest_Cache_Plugin\Includes\Caching\Caching;
20+
21+
/**
22+
* Get ActivityPub REST API Namespace
23+
*
24+
* @since 0.9
25+
*
26+
* @return string The ActivityPub REST API namespace
27+
*/
28+
29+
function unmus_cache_get_activitypub_restapi_namespace() {
30+
31+
$activitypub_api_namespace = 'activitypub/1.0';
32+
return $activitypub_api_namespace;
33+
}
34+
35+
/**
36+
* Get ActivityPub endpoints to be cached
37+
*
38+
* @since 0.9
39+
*
40+
* @return array The ActivityPub endpoints to be cached
41+
*/
42+
43+
function unmus_cache_get_activitypub_endpoints() {
44+
45+
$endpoints = [ unmus_cache_get_activitypub_restapi_namespace() => [
46+
'',
47+
'actors',
48+
'application',
49+
'collections',
50+
'comments',
51+
'inbox',
52+
'interactions',
53+
'nodeinfo',
54+
'posts',
55+
'users',
56+
'webfinger'
57+
]];
58+
59+
return $endpoints;
60+
}
61+
62+
/**
63+
* Add ActivityPub Endpoints to Cache
64+
*
65+
* @since 0.9
66+
*
67+
* @param array Endpoints that are allowed to be cached
68+
* @return array Allowed Endpoints extended with ActivityPub
69+
*/
70+
71+
function unmus_cache_add_activitypub_endpoints( $allowed_endpoints ) {
72+
73+
$activitypub_api_namespace = unmus_cache_get_activitypub_restapi_namespace();
74+
$endpoints = unmus_cache_get_activitypub_endpoints();
75+
76+
if(!isset($allowed_endpoints[$activitypub_api_namespace])) {
77+
$allowed_endpoints[$activitypub_api_namespace] = $endpoints[$activitypub_api_namespace];
78+
}
79+
80+
return $allowed_endpoints;
81+
82+
}
83+
add_filter( 'wp_rest_cache/allowed_endpoints', 'unmus_cache_add_activitypub_endpoints', 10, 1);
84+
85+
/**
86+
* Is ActivityPub Endpoint
87+
*
88+
* @param string $uri URI to test
89+
* @return bool Whether the current endpoint is an ActivityPub endpoint
90+
*/
91+
92+
function unmus_is_activitypub_endpoint( string $uri ) :bool {
93+
94+
$search = '/' . unmus_cache_get_activitypub_restapi_namespace() . '/';
95+
96+
return \str_contains( $uri, $search ) || \str_contains( $uri, 'rest_route=' . \rawurlencode( $search ) );
97+
}
98+
99+
/**
100+
* Determine Object Type
101+
*
102+
* @since 0.9
103+
*
104+
* @param string $object_type Object type
105+
* @param string $cache_key Object key
106+
* @param mixed $data Data to cache
107+
* @param string $uri Request URI
108+
* @return string Updated object type
109+
*/
110+
111+
function unmus_cache_determine_object_type( $object_type, $cache_key, $data, $uri ) {
112+
113+
if (unmus_is_activitypub_endpoint( $uri ) ) {
114+
$object_type = 'ActivityPub';
115+
return $object_type;
116+
}
117+
}
118+
add_filter( 'wp_rest_cache/determine_object_type', 'unmus_cache_determine_object_type', 10, 4 );
119+
120+
/**
121+
* Reset Cache by Transition Post Status
122+
*
123+
* @since 0.9
124+
*
125+
* @param string $new_status New post status
126+
* @param string $old_status Old post status
127+
* @param \WP_Post $post Post object
128+
*/
129+
130+
function unmus_cache_reset_by_transition_post_status( string $new_status, string $old_status, \WP_Post $post ): void {
131+
132+
if ( $new_status !== 'publish' && $old_status !== 'publish' ) {
133+
return;
134+
}
135+
136+
$supported_post_types = (array) \get_option( 'activitypub_support_post_types', [] );
137+
138+
if ( ! \in_array( $post->post_type, $supported_post_types, true ) ) {
139+
return;
140+
}
141+
142+
if ( ! \class_exists( 'WP_Rest_Cache_Plugin\Includes\Caching\Caching' ) ) {
143+
return;
144+
}
145+
146+
Caching::get_instance()->delete_object_type_caches( 'ActivityPub' );
147+
}
148+
add_action( 'transition_post_status', 'unmus_cache_reset_by_transition_post_status', 10, 3 );
149+
150+
/**
151+
* Set whether the cache represents a single item.
152+
*
153+
* Always return false for ActivityPub endpoints,
154+
* since cache entries cannot be flushed otherwise.
155+
*
156+
* @param bool $is_single Whether the current cache represents a single item
157+
* @param mixed $data Data to cache
158+
* @param string $uri Request URI
159+
* @return bool Whether the cache represents a single item
160+
*/
161+
162+
function set_is_single_item( bool $is_single, mixed $data, string $uri ): bool {
163+
if ( unmus_is_activitypub_endpoint( $uri ) ) {
164+
return false;
165+
}
166+
167+
return $is_single;
168+
}
169+
add_filter( 'wp_rest_cache/is_single_item', 'set_is_single_item' , 10, 3 );
170+
171+
?>

0 commit comments

Comments
 (0)