PluginProbe
ActivityPub / 8.1.1
ActivityPub v8.1.1
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / integration / class-litespeed-cache.php

class-litespeed-cache.php in ActivityPub 8.1.1, at integration/class-litespeed-cache.php

231 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * LiteSpeed Cache integration file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Integration;
9
10 use function Activitypub\is_plugin_active;
11
12 /**
13 * LiteSpeed Cache integration.
14 *
15 * @see https://wordpress.org/support/topic/avoiding-caching-activitypub-content/
16 */
17 class Litespeed_Cache {
18
19 /**
20 * The rules to add to the htaccess file.
21 *
22 * @var string
23 */
24 public static $rules = '<IfModule LiteSpeed>
25 RewriteEngine On
26 RewriteCond %{HTTP:Accept} application
27 RewriteRule ^ - [E=Cache-Control:vary=%{ENV:LSCACHE_VARY_VALUE}+isjson]
28 </IfModule>';
29
30 /**
31 * The option name to store the htaccess rules.
32 *
33 * @var string
34 */
35 public static $option_name = 'activitypub_litespeed_cache_setup';
36
37 /**
38 * The marker to identify the rules in the htaccess file.
39 *
40 * @var string
41 */
42 public static $marker = 'ActivityPub LiteSpeed Cache';
43
44 /**
45 * The LiteSpeed Cache plugin slug.
46 *
47 * @var string
48 */
49 public static $plugin_slug = 'litespeed-cache/litespeed-cache.php';
50
51 /**
52 * Initialize the integration.
53 */
54 public static function init() {
55 // Add rules if LiteSpeed Cache is active and rules aren't set.
56 if ( is_plugin_active( self::$plugin_slug ) ) {
57 if ( ! \get_option( self::$option_name ) ) {
58 self::add_htaccess_rules();
59 }
60
61 \add_filter( 'site_status_tests', array( self::class, 'add_site_health_test' ) );
62
63 // Remove rules if LiteSpeed Cache is not active but rules were previously set.
64 } elseif ( \get_option( self::$option_name ) ) {
65 self::remove_htaccess_rules();
66 }
67
68 // Clean up when LiteSpeed Cache plugin is deleted.
69 \add_action( 'deleted_plugin', array( self::class, 'on_plugin_deleted' ) );
70 }
71
72 /**
73 * Clean up htaccess rules when LiteSpeed Cache plugin is deleted.
74 *
75 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
76 */
77 public static function on_plugin_deleted( $plugin_file ) {
78 if ( self::$plugin_slug === $plugin_file && \get_option( self::$option_name ) ) {
79 self::remove_htaccess_rules();
80 }
81 }
82
83 /**
84 * Add the LiteSpeed Cache htaccess rules.
85 */
86 public static function add_htaccess_rules() {
87 $added_rules = self::append_with_markers( self::$marker, self::$rules );
88
89 if ( $added_rules ) {
90 \update_option( self::$option_name, '1' );
91 } else {
92 \update_option( self::$option_name, '0' );
93 }
94 }
95
96 /**
97 * Remove the LiteSpeed Cache htaccess rules.
98 */
99 public static function remove_htaccess_rules() {
100 self::append_with_markers( self::$marker, '' );
101
102 \delete_option( self::$option_name );
103 }
104
105 /**
106 * Add the LiteSpeed Cache config test to site health.
107 *
108 * @param array $tests The site health tests.
109 *
110 * @return array The site health tests with the LiteSpeed Cache config test.
111 */
112 public static function add_site_health_test( $tests ) {
113 $tests['direct']['activitypub_test_litespeed_cache_integration'] = array(
114 'label' => \__( 'LiteSpeed Cache Test', 'activitypub' ),
115 'test' => array( self::class, 'test_litespeed_cache_integration' ),
116 );
117
118 return $tests;
119 }
120
121 /**
122 * Test the LiteSpeed Cache integration.
123 *
124 * @return array The test results.
125 */
126 public static function test_litespeed_cache_integration() {
127 $result = array(
128 'label' => \__( 'Compatibility with LiteSpeed Cache', 'activitypub' ),
129 'status' => 'good',
130 'badge' => array(
131 'label' => \__( 'ActivityPub', 'activitypub' ),
132 'color' => 'green',
133 ),
134 'description' => \sprintf(
135 '<p>%s</p>',
136 \__( 'LiteSpeed Cache is well configured to work with ActivityPub.', 'activitypub' )
137 ),
138 'actions' => '',
139 'test' => 'test_litespeed_cache_integration',
140 );
141
142 if ( ! \get_option( self::$option_name ) ) {
143 $result['status'] = 'critical';
144 $result['label'] = \__( 'LiteSpeed Cache might not be properly configured.', 'activitypub' );
145 $result['badge']['color'] = 'red';
146 $result['description'] = \sprintf(
147 '<p>%s</p>',
148 \__( 'LiteSpeed Cache isn&#8217;t currently set up to work with ActivityPub. While this isn&#8217;t a major problem, it&#8217;s a good idea to enable support. Without it, some technical files (like JSON) might accidentally show up in your website&#8217;s cache and be visible to visitors.', 'activitypub' )
149 );
150 $result['actions'] = \sprintf(
151 '<p>%s</p><pre>%s</pre>',
152 \__( 'To enable the ActivityPub integration with LiteSpeed Cache, add the following rules to your <code>.htaccess</code> file:', 'activitypub' ),
153 \esc_html( self::$rules )
154 );
155 }
156
157 return $result;
158 }
159
160 /**
161 * Prepend rules to the top of a file with markers.
162 *
163 * @param string $marker The marker to identify the rules in the file.
164 * @param string $rules The rules to prepend.
165 *
166 * @return bool True on success, false on failure.
167 */
168 private static function append_with_markers( $marker, $rules ) {
169 $htaccess_file = self::get_htaccess_file_path();
170
171 if ( ! \wp_is_writable( $htaccess_file ) ) {
172 return false;
173 }
174
175 // Ensure WP_Filesystem() is declared.
176 require_once ABSPATH . 'wp-admin/includes/file.php';
177
178 global $wp_filesystem;
179 \WP_Filesystem();
180
181 $htaccess = $wp_filesystem->get_contents( $htaccess_file );
182
183 // If marker exists, remove the old block first.
184 if ( strpos( $htaccess, $marker ) !== false ) {
185 // Remove existing marker block.
186 $pattern = '/# BEGIN ' . preg_quote( $marker, '/' ) . '.*?# END ' . preg_quote( $marker, '/' ) . '\r?\n?/s';
187 $htaccess = preg_replace( $pattern, '', $htaccess );
188 $htaccess = trim( $htaccess );
189 }
190
191 // If rules are empty, just return (for removal case).
192 if ( empty( $rules ) ) {
193 return $wp_filesystem->put_contents( $htaccess_file, $htaccess, FS_CHMOD_FILE );
194 }
195
196 // Prepend new rules to the top of the file.
197 $start_marker = "# BEGIN {$marker}";
198 $end_marker = "# END {$marker}";
199
200 $rules = $start_marker . PHP_EOL . $rules . PHP_EOL . $end_marker;
201 $htaccess = $rules . PHP_EOL . PHP_EOL . $htaccess;
202
203 return $wp_filesystem->put_contents( $htaccess_file, $htaccess, FS_CHMOD_FILE );
204 }
205
206 /**
207 * Get the htaccess file.
208 *
209 * @return string|false The htaccess file or false.
210 */
211 private static function get_htaccess_file_path() {
212 $htaccess_file = false;
213
214 // Ensure get_home_path() is declared.
215 require_once ABSPATH . 'wp-admin/includes/file.php';
216
217 // phpcs:ignore WordPress.PHP.NoSilencedErrors
218 if ( @file_exists( \get_home_path() . '.htaccess' ) ) {
219 /** The htaccess file resides in ABSPATH */
220 $htaccess_file = \get_home_path() . '.htaccess';
221 }
222
223 /**
224 * Filter the htaccess file path.
225 *
226 * @param string|false $htaccess_file The htaccess file path.
227 */
228 return \apply_filters( 'activitypub_litespeed_cache_htaccess_file', $htaccess_file );
229 }
230 }
231