PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 3.7
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v3.7
trunk 1.0 1.0.1 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1 2.1.1 2.1.2 2.2 2.2.1 All 69 releases
powered-cache / includes / admin / notices.php

notices.php in Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score 3.7, at includes/admin/notices.php

523 lines 17.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin Notices
4 *
5 * @package PoweredCache
6 */
7
8 namespace PoweredCache\Admin\Notices;
9
10 use function PoweredCache\Utils\can_configure_htaccess;
11 use function PoweredCache\Utils\can_configure_object_cache;
12 use function PoweredCache\Utils\can_control_all_settings;
13 use function PoweredCache\Utils\get_object_cache_dropins;
14 use function PoweredCache\Utils\is_premium;
15 use const PoweredCache\Constants\PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT;
16
17 /**
18 * Default setup routine
19 *
20 * @return void
21 */
22 function setup() {
23 if ( POWERED_CACHE_IS_NETWORK ) {
24 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_plugin_compatibility_notices' );
25 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_advanced_cache_notices' );
26 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_object_cache_notices' );
27 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_htaccess_notice' );
28 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_purge_cache_plugin_notice' );
29 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_dev_mode_notice' );
30 } else {
31 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_plugin_compatibility_notices' );
32 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_advanced_cache_notices' );
33 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_object_cache_notices' );
34 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_htaccess_notice' );
35 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_purge_cache_plugin_notice' );
36 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_dev_mode_notice' );
37 }
38
39 add_action( 'activated_plugin', __NAMESPACE__ . '\\observe_plugin_changes', 10, 2 );
40 add_action( 'deactivated_plugin', __NAMESPACE__ . '\\observe_plugin_changes', 10, 2 );
41 add_action( 'admin_post_powered_cache_dismiss_notice', __NAMESPACE__ . '\\dismiss_notice' );
42 add_action( 'wp_ajax_powered_cache_dismiss_notice_ajax', __NAMESPACE__ . '\\dismiss_notice_ajax' );
43 }
44
45 /**
46 * Display incompatible plugins
47 *
48 * @since 1.0
49 */
50 function maybe_display_plugin_compatibility_notices() {
51 $settings = \PoweredCache\Utils\get_settings();
52
53 $plugins = array(
54 'hummingbird-performance' => 'hummingbird-performance/wp-hummingbird.php',
55 'wp-rocket' => 'wp-rocket/wp-rocket.php',
56 'w3-total-cache' => 'w3-total-cache/w3-total-cache.php',
57 'wp-super-cache' => 'wp-super-cache/wp-cache.php',
58 'hyper-cache' => 'hyper-cache/plugin.php',
59 'hyper-cache-extended' => 'hyper-cache-extended/plugin.php',
60 'wp-fast-cache' => 'wp-fast-cache/wp-fast-cache.php',
61 'flexicache' => 'flexicache/wp-plugin.php',
62 'wp-fastest-cache' => 'wp-fastest-cache/wpFastestCache.php',
63 'wp-http-compression' => 'wp-http-compression/wp-http-compression.php',
64 'wordpress-gzip-compression' => 'wordpress-gzip-compression/ezgz.php',
65 'gzip-ninja-speed-compression' => 'gzip-ninja-speed-compression/gzip-ninja-speed.php',
66 'speed-booster-pack' => 'speed-booster-pack/speed-booster-pack.php',
67 'wp-performance-score-booster' => 'wp-performance-score-booster/wp-performance-score-booster.php',
68 'check-and-enable-gzip-compression' => 'check-and-enable-gzip-compression/richards-toolbox.php',
69 'swift-performance-lite' => 'swift-performance-lite/performance.php',
70 'swift-performance' => 'swift-performance/performance.php',
71 'litespeed-cache' => 'litespeed-cache/litespeed-cache.php',
72 'wp-optimize' => 'wp-optimize/wp-optimize.php',
73 );
74
75 if ( $settings['prefetch_links'] && is_premium() ) {
76 $plugins['quicklink'] = 'quicklink/quicklink.php';
77 $plugins['flying-pages'] = 'flying-pages/flying-pages.php';
78 $plugins['instant-page'] = 'instant-page/instantpage.php';
79 }
80
81 $callback = POWERED_CACHE_IS_NETWORK ? 'is_plugin_active_for_network' : 'is_plugin_active';
82
83 $plugins = array_filter( $plugins, $callback );
84
85 if ( 0 >= count( $plugins ) ) {
86 return;
87 }
88 ?>
89
90 <?php if ( current_user_can( 'activate_plugins' ) ) : ?>
91 <div class="error">
92 <p><?php esc_html_e( 'The following plugins are not compatible with Powered Cache and may cause unintended results:', 'powered-cache' ); ?></p>
93 <ul class="incompatible-plugin-list">
94 <?php
95 foreach ( $plugins as $plugin ) {
96 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin );
97 echo '<li>' . esc_attr( $plugin_data['Name'] ) . '</span> <a href="' . esc_url_raw( wp_nonce_url( admin_url( 'admin-post.php?action=deactivate_plugin&plugin=' . rawurlencode( $plugin ) ), 'deactivate_plugin' ) ) . '" class="button-secondary">' . esc_html__( 'Deactivate', 'powered-cache' ) . '</a></li>'; // phpcs:ignore WordPressVIPMinimum.Security.ProperEscapingFunction.notAttrEscAttr
98 }
99 ?>
100 </ul>
101 </div>
102 <?php endif; ?>
103
104 <?php
105 }
106
107
108 /**
109 * Show notices about page cache
110 *
111 * @since 1.0
112 */
113 function maybe_display_advanced_cache_notices() {
114 /**
115 * Determine whether show or not show advanced cache related notices
116 * eg: Varnish users don't need to turning on page cache.
117 *
118 * @hook powered_cache_disable_advanced_cache_notices
119 *
120 * @param {boolean} $status false
121 *
122 * @return {boolean} New value
123 * @since 1.2
124 */
125 if ( apply_filters( 'powered_cache_disable_advanced_cache_notices', false ) ) {
126 return;
127 }
128
129 $settings = \PoweredCache\Utils\get_settings();
130
131 if ( ! $settings['enable_page_cache'] ) {
132
133 $settings_page = POWERED_CACHE_IS_NETWORK ? network_admin_url( 'admin.php?page=powered-cache#basic-options' ) : admin_url( 'admin.php?page=powered-cache#basic-options' );
134
135 /* translators: %s: Powered Cache settings page URL */
136 $message = sprintf( __( '<strong>Powered Cache:</strong> Page caching needs to be activated in order to speed up your website. Please activate it on <a href="%s">settings page</a>', 'powered-cache' ), esc_url( $settings_page ) );
137 ?>
138 <div class="notice notice-warning">
139 <p>
140 <?php echo wp_kses_post( $message ); ?>
141 </p>
142 </div>
143 <?php
144 return;
145 }
146
147 if ( file_exists( untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php' ) ) {
148 $modify_time = filemtime( untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php' );
149 if ( time() - absint( $modify_time ) < 10 ) {
150 /**
151 * Modify drop-ins and can take ~5 seconds to place the configuration and it might cause misinformation to the user
152 * So, suppress the error message here when doing something related to settings.
153 *
154 * This wouldn't be an issue if there is no immediate redirection right after saving the settings. However, in that case
155 * the admin bar items won't be properly utilized unless refreshing the page
156 */
157 return;
158 }
159 }
160
161 $err = array();
162
163 if ( ! defined( 'WP_CACHE' ) || true !== WP_CACHE ) {
164 /* translators: %s: WP_CACHE definition*/
165 $err['wp_cache'] = sprintf( __( '<code>%s</code> is not found in wp-config.php.', 'powered-cache' ), 'define("WP_CACHE", true);' );
166 }
167
168 if ( defined( 'WP_CACHE' ) && WP_CACHE && ( ! defined( 'POWERED_CACHE_PAGE_CACHING' ) || true !== POWERED_CACHE_PAGE_CACHING ) ) {
169 /* translators: %s: advanced-cache.php drop-in path */
170 $err['powered_cache_page_cache'] = sprintf( __( '<code>%s</code> file was edited or deleted. You can recreate the correct configuration files by saving Powered Cache settings.', 'powered-cache' ), basename( WP_CONTENT_DIR ) . '/advanced-cache.php' );
171 }
172
173 if ( defined( 'POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM' ) && POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM ) {
174 /* translators: %s: page-cache.php drop-in path */
175 $err['powered_cache_page_cache_has_problem'] = sprintf( __( 'Powered Cache could not access dropin. Please check <code>%s</code> exist and accessible on your server.', 'powered-cache' ), POWERED_CACHE_DROPIN_DIR . 'page-cache.php' );
176 }
177
178 // everything ok
179 if ( empty( $err ) ) {
180 return;
181 }
182
183 // dont show when settings just saved
184 if ( did_action( 'powered_cache_settings_saved' ) ) {
185 return;
186 }
187
188 $capability = POWERED_CACHE_IS_NETWORK ? 'manage_network' : 'manage_options';
189
190 if ( ! current_user_can( $capability ) ) {
191 return;
192 }
193 ?>
194 <div class="error">
195 <p>
196 <strong><?php esc_html_e( 'Page Cache is not working, because:', 'powered-cache' ); ?></strong>
197 </p>
198 <?php foreach ( $err as $error_msg ) : ?>
199 <p><?php echo wp_kses_post( $error_msg ); ?></p>
200 <?php endforeach; ?>
201 </div>
202 <?php
203
204 }
205
206
207 /**
208 * Display object cache broken msg
209 *
210 * @since 1.0
211 */
212 function maybe_display_object_cache_notices() {
213 $settings = \PoweredCache\Utils\get_settings();
214
215 $object_cache_backends = get_object_cache_dropins();
216 $object_cache_driver = $settings['object_cache'];
217 $object_cache_dropin = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
218
219 if ( ! can_configure_object_cache() ) {
220 return;
221 }
222
223 // dont show when settings just saved
224 if ( did_action( 'powered_cache_settings_saved' ) ) {
225 return;
226 }
227
228 if ( file_exists( $object_cache_dropin ) ) {
229 $modify_time = filemtime( $object_cache_dropin );
230 if ( time() - absint( $modify_time ) < 10 ) { // just created
231 return;
232 }
233 }
234
235 // first check object cache file exist
236 if ( isset( $object_cache_backends[ $object_cache_driver ] ) && ! file_exists( $object_cache_dropin ) ) {
237 /* translators: %s: object cache dropin path */
238 $message = sprintf( __( 'The object cache file seems missing. Please check <code>%s</code> exist, writable and accessible on your server.', 'powered-cache' ), $object_cache_dropin );
239 ?>
240 <div class="error">
241 <p><strong><?php esc_html_e( 'Powered Cache:', 'powered-cache' ); ?></strong>
242 <?php echo wp_kses_post( $message ); ?>
243 </p>
244 </div>
245 <?php
246 return;
247 }
248
249 if ( defined( 'POWERED_OBJECT_CACHE_HAS_PROBLEM' ) && POWERED_OBJECT_CACHE_HAS_PROBLEM ) {
250 $broken_file = '';
251
252 if ( isset( $object_cache_backends[ $object_cache_driver ] ) ) {
253 $broken_file = $object_cache_backends[ $object_cache_driver ];
254 }
255 /* translators: %s: object cache dropin path */
256 $message = sprintf( __( 'The object cache file couldn\'t be loaded. Please check <code>%s</code> exist and accessible on your server.', 'powered-cache' ), $broken_file );
257 ?>
258 <div class="error">
259 <p><strong><?php esc_html_e( 'Powered Cache:', 'powered-cache' ); ?></strong>
260 <?php echo wp_kses_post( $message ); ?>
261 </p>
262 </div>
263 <?php
264 }
265
266 }
267
268 /**
269 * Notices for the .htaccess
270 *
271 * @since 1.2
272 */
273 function maybe_display_htaccess_notice() {
274 global $is_apache;
275
276 if ( ! $is_apache ) {
277 return;
278 }
279
280 $settings = \PoweredCache\Utils\get_settings();
281
282 if ( ! $settings['auto_configure_htaccess'] ) {
283 return;
284 }
285
286 if ( ! can_configure_htaccess() ) {
287 return;
288 }
289
290 // dont show when settings just saved
291 if ( did_action( 'powered_cache_settings_saved' ) ) {
292 return;
293 }
294
295 $htaccess_file = get_home_path() . '.htaccess';
296
297 if ( file_exists( $htaccess_file ) ) {
298 $modify_time = filemtime( $htaccess_file );
299 if ( time() - absint( $modify_time ) < 10 ) { // just modified
300 return;
301 }
302 }
303
304 $message = '';
305
306 if ( ! file_exists( $htaccess_file ) ) {
307 $message = __( 'The <code>.htaccess</code> couldn\'t be found on your server. Please create a new <code>.htaccess</code> file. (<a href="https://wordpress.org/support/article/htaccess/" target="_blank" rel="noopener">?</a>)', 'powered-cache' );
308 } elseif ( ! is_writeable( $htaccess_file ) ) {
309 $message = __( 'Oh no! It looks <code>.htaccess</code> file is not writable. Please make sure it is writable by the application server. Your website will be much faster when .htaccess is configured for Powered Cache.', 'powered-cache' );
310 }
311
312 if ( empty( $message ) ) {
313 return;
314 }
315
316 ?>
317
318 <div class="error">
319 <p><strong><?php esc_html_e( 'Powered Cache:', 'powered-cache' ); ?></strong>
320 <?php echo wp_kses_post( $message ); ?>
321 </p>
322 </div>
323
324 <?php
325 }
326
327 /**
328 * Observe new plugin activation/deactivation
329 *
330 * @param string $plugin file
331 * @param boolean $network_wide Whether plugin de/activated network wide or not
332 *
333 * @return void
334 * @since 3.2
335 */
336 function observe_plugin_changes( $plugin, $network_wide ) {
337 if ( false !== stripos( $plugin, 'powered-cache' ) ) {
338 return;
339 }
340
341 if ( $network_wide ) {
342 set_site_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT, '1' );
343
344 return;
345 }
346
347 set_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT, '1' );
348 }
349
350 /**
351 * Display cache purging notice upon a new plugin activated/deactivated
352 *
353 * @return void
354 * @since 3.2
355 */
356 function maybe_display_purge_cache_plugin_notice() {
357 $has_notice = false;
358
359 if ( POWERED_CACHE_IS_NETWORK && current_user_can( 'manage_network' ) ) {
360 $has_notice = get_site_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT );
361 $purge_url = wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_page_cache_network' ), 'powered_cache_purge_page_cache_network' );
362 } elseif ( current_user_can( 'activate_plugins' ) ) {
363 $has_notice = get_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT );
364 $purge_url = wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_all_cache' ), 'powered_cache_purge_all_cache' );
365 }
366
367 if ( $has_notice ) {
368 $message = __( '<strong>Powered Cache:</strong> One or more plugins have been activated or deactivated; consider clearing the cache if these changes impact your site\'s front end.', 'powered-cache' );
369 $dismiss_nonce = wp_create_nonce( 'powered_cache_dismiss_notice_ajax' );
370 ?>
371 <div class="notice notice-warning is-dismissible powered-cache-dismissible-notice" data-notice-id="<?php echo esc_attr( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT ); ?>" data-nonce="<?php echo esc_attr( $dismiss_nonce ); ?>">
372 <p>
373 <?php echo wp_kses_post( $message ); ?>
374 </p>
375 <p>
376 <a href="<?php echo esc_url_raw( $purge_url ); ?>" class="button-primary">
377 <?php esc_html_e( 'Purge Cache', 'powered-cache' ); ?>
378 </a>
379 <a href="<?php echo esc_url_raw( wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_dismiss_notice&notice=' . PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT ), 'powered_cache_dismiss_notice' ) ); ?>" class="button-secondary powered-cache-dismiss-button">
380 <?php esc_html_e( 'Dismiss this notice', 'powered-cache' ); ?>
381 </a>
382 </p>
383 </div>
384 <script type="text/javascript">
385 (function() {
386 document.addEventListener('click', function(e) {
387 var button = e.target.closest('.notice-dismiss, .powered-cache-dismiss-button');
388 if (!button) {
389 return;
390 }
391
392 var notice = button.closest('.powered-cache-dismissible-notice');
393 if (!notice) {
394 return;
395 }
396
397 e.preventDefault();
398
399 var noticeId = notice.getAttribute('data-notice-id');
400 var nonce = notice.getAttribute('data-nonce');
401
402 if (button.classList.contains('powered-cache-dismiss-button')) {
403 e.preventDefault();
404 notice.style.opacity = '1';
405 notice.style.transition = 'opacity 0.3s';
406 notice.style.opacity = '0';
407
408 setTimeout(function() {
409 if (notice && notice.parentNode) {
410 notice.parentNode.removeChild(notice);
411 }
412 }, 300);
413 }
414
415 var xhr = new XMLHttpRequest();
416 xhr.open('POST', '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', true);
417 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
418 xhr.onload = function () {
419 if (xhr.status !== 200) {
420 console.error('Dismiss failed');
421 }
422 };
423
424 xhr.send(
425 'action=powered_cache_dismiss_notice_ajax'
426 + '&notice=' + encodeURIComponent(noticeId)
427 + '&nonce=' + encodeURIComponent(nonce)
428 );
429 });
430 })();
431 </script>
432 <?php
433 }
434 }
435
436 /**
437 * Dismis given notice
438 *
439 * @return void
440 * @since 3.2
441 */
442 function dismiss_notice() {
443 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'powered_cache_dismiss_notice' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
444 wp_nonce_ays( '' );
445 }
446
447 if ( current_user_can( 'manage_options' ) && ! empty( $_GET['notice'] ) ) {
448 $notice = sanitize_text_field( wp_unslash( $_GET['notice'] ) );
449
450 if ( POWERED_CACHE_IS_NETWORK ) {
451 delete_site_transient( $notice );
452 } else {
453 delete_transient( $notice );
454 }
455 }
456
457 wp_safe_redirect( esc_url_raw( wp_get_referer() ) );
458 exit;
459 }
460
461 /**
462 * Dismiss notice via AJAX
463 *
464 * @return void
465 * @since 3.7
466 */
467 function dismiss_notice_ajax() {
468 check_ajax_referer( 'powered_cache_dismiss_notice_ajax', 'nonce' );
469
470 if ( ! current_user_can( 'manage_options' ) ) {
471 wp_send_json_error( array( 'message' => esc_html__( 'Permission denied', 'powered-cache' ) ) );
472 }
473
474 if ( empty( $_POST['notice'] ) ) {
475 wp_send_json_error( array( 'message' => esc_html__( 'Notice ID missing', 'powered-cache' ) ) );
476 }
477
478 $notice = sanitize_text_field( wp_unslash( $_POST['notice'] ) );
479
480 if ( POWERED_CACHE_IS_NETWORK ) {
481 delete_site_transient( $notice );
482 } else {
483 delete_transient( $notice );
484 }
485
486 wp_send_json_success( array( 'message' => esc_html__( 'Notice dismissed', 'powered-cache' ) ) );
487 }
488
489 /**
490 * Display a notice when development mode is active
491 *
492 * @return void
493 * @since 3.6
494 * @related \PoweredCache\DevMode
495 */
496 function maybe_display_dev_mode_notice() {
497 if ( ! \PoweredCache\Utils\is_dev_mode_active() ) {
498 return;
499 }
500
501 if ( ! current_user_can( 'manage_options' ) ) {
502 return;
503 }
504
505 // Only display on Powered Cache settings page
506 $current_screen = get_current_screen();
507
508 if (
509 ! $current_screen
510 || ( ! isset( $current_screen->id ) || false === strpos( $current_screen->id, 'powered-cache' ) )
511 ) {
512 return;
513 }
514
515 ?>
516 <div class="notice notice-warning is-dismissible">
517 <p><strong><?php esc_html_e( 'Development Mode is active.', 'powered-cache' ); ?></strong>
518 <?php esc_html_e( 'Caching and optimizations are currently disabled. Don’t forget to disable it when done.', 'powered-cache' ); ?>
519 </p>
520 </div>
521 <?php
522 }
523