PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / trunk
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score vtrunk
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
← All changes | includes/admin/notices.php +443 -72 1.0trunk View file →
@@ -1,81 +1,110 @@
1 1 <?php
2 -// Exit if accessed directly
3 -if ( ! defined( 'ABSPATH' ) ) {
4 - exit;
5 -}
2 +/**
3 + * Admin Notices
4 + *
5 + * @package PoweredCache
6 + */
6 7
7 -add_action( 'admin_notices', 'powered_cache_flash_messages' );
8 +namespace PoweredCache\Admin\Notices;
8 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 +
9 17 /**
10 - * Display flash messages
18 + * Default setup routine
11 19 *
12 - * @since 1.0
20 + * @return void
13 21 */
14 -function powered_cache_flash_messages() {
15 - Powered_Cache_Admin_Helper::get_flash_message();
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' );
16 43 }
17 44
18 -
19 -add_action( 'admin_notices', 'powered_cache_plugin_compatability_notices' );
20 -
21 45 /**
22 46 * Display incompatible plugins
23 47 *
24 48 * @since 1.0
25 49 */
26 -function powered_cache_plugin_compatability_notices() {
50 +function maybe_display_plugin_compatibility_notices() {
51 + $settings = \PoweredCache\Utils\get_settings();
27 52
28 53 $plugins = array(
29 - 'w3-total-cache' => 'w3-total-cache/w3-total-cache.php',
30 - 'wp-super-cache' => 'wp-super-cache/wp-cache.php',
31 - 'quick-cache' => 'quick-cache/quick-cache.php',
32 - 'hyper-cache' => 'hyper-cache/plugin.php',
33 - 'hyper-cache-extended' => 'hyper-cache-extended/plugin.php',
34 - 'wp-fast-cache' => 'wp-fast-cache/wp-fast-cache.php',
35 - 'flexicache' => 'flexicache/wp-plugin.php',
36 - 'wp-fastest-cache' => 'wp-fastest-cache/wpFastestCache.php',
37 - 'lite-cache' => 'lite-cache/plugin.php',
38 - 'gator-cache' => 'gator-cache/gator-cache.php',
39 - 'wp-http-compression' => 'wp-http-compression/wp-http-compression.php',
40 - 'wordpress-gzip-compression' => 'wordpress-gzip-compression/ezgz.php',
41 - 'gzip-ninja-speed-compression' => 'gzip-ninja-speed-compression/gzip-ninja-speed.php',
42 - 'speed-booster-pack' => 'speed-booster-pack/speed-booster-pack.php',
43 - 'wp-performance-score-booster' => 'wp-performance-score-booster/wp-performance-score-booster.php',
44 - 'remove-query-strings-from-static-resources' => 'remove-query-strings-from-static-resources/remove-query-strings.php',
45 - 'query-strings-remover' => 'query-strings-remover/query-strings-remover.php',
46 - 'wp-ffpc' => 'wp-ffpc/wp-ffpc.php',
47 - 'far-future-expiry-header' => 'far-future-expiry-header/far-future-expiration.php',
48 - 'combine-css' => 'combine-css/combine-css.php',
49 - 'super-static-cache' => 'super-static-cache/super-static-cache.php',
50 - 'wpcompressor' => 'wpcompressor/wpcompressor.php',
51 - 'check-and-enable-gzip-compression' => 'check-and-enable-gzip-compression/richards-toolbox.php',
52 - 'leverage-browser-caching-ninjas' => 'leverage-browser-caching-ninjas/leverage-browser-caching-ninja.php',
53 - 'force-gzip' => 'force-gzip/force-gzip.php'
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',
54 73 );
55 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 + }
56 80
57 - $plugins = array_filter( $plugins, 'is_plugin_active' );
81 + $callback = POWERED_CACHE_IS_NETWORK ? 'is_plugin_active_for_network' : 'is_plugin_active';
58 82
59 - if ( count( $plugins ) > 0 && current_user_can( apply_filters( 'powered_cache_cap', 'manage_options' ) ) ) { ?>
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' ) ) : ?>
60 91 <div class="error">
61 - <h2><?php _e( 'Powered Cache', 'powered-cache' ); ?></h2>
62 -
63 - <p><?php printf( __( 'The following plugins are not compatible with <b>%s</b> and will cause unintended results:', 'powered-cache' ), __( 'Powered Cache', 'powered-cache' ) ); ?></p>
92 + <p><?php esc_html_e( 'The following plugins are not compatible with Powered Cache and may cause unintended results:', 'powered-cache' ); ?></p>
64 93 <ul class="incompatible-plugin-list">
65 94 <?php
66 95 foreach ( $plugins as $plugin ) {
67 96 $plugin_data = get_plugin_data( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin );
68 - echo '<li>' . $plugin_data['Name'] . '</span> <a href="' . wp_nonce_url( admin_url( 'admin-post.php?action=deactivate_plugin&plugin=' . urlencode( $plugin ) ), 'deactivate_plugin' ) . '" class="button-secondary">' . __( 'Deactivate', 'powered-cache' ) . '</a></li>';
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
69 98 }
70 99 ?>
71 100 </ul>
72 101 </div>
73 - <?php
74 - }
102 + <?php endif; ?>
103 +
104 + <?php
75 105 }
76 106
77 -add_action( 'admin_notices', 'powered_cache_advanced_cache_notices' );
78 107
79 108 /**
80 109 * Show notices about page cache
81 110 *
@@ -80,30 +109,70 @@
80 109 * Show notices about page cache
81 110 *
82 111 * @since 1.0
83 112 */
84 -function powered_cache_advanced_cache_notices() {
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 + }
85 128
86 - if ( powered_cache_is_saving_options() ) {
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
87 144 return;
88 145 }
89 146
90 - if ( true !== powered_cache_get_option( 'enable_page_caching' ) ) {
91 - return;
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 + }
92 159 }
93 160
94 161 $err = array();
95 162
96 163 if ( ! defined( 'WP_CACHE' ) || true !== WP_CACHE ) {
97 - $err['wp_cache'] = sprintf( __( '<code>%s</code> is not in wp-config.php.', 'powered-cache' ), 'define("WP_CACHE", true);' );
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);' );
98 166 }
99 167
100 - if ( ! defined( 'POWERED_CACHE_PAGE_CACHING' ) || true !== POWERED_CACHE_PAGE_CACHING ) {
101 - $err['powered_cache_page_cache'] = sprintf( __( '<code>%s</code> file was edited or deleted. You can re-create correct configuration files by saving settings.', 'powered-cache' ), basename( WP_CONTENT_DIR ) . '/advanced-cache.php' );
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' );
102 171 }
103 172
104 -
105 - if ( defined( 'POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM' ) && true === POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM ) {
173 + if ( defined( 'POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM' ) && POWERED_CACHE_PAGE_CACHING_HAS_PROBLEM ) {
174 + /* translators: %s: page-cache.php drop-in path */
106 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' );
107 176 }
108 177
109 178 // everything ok
@@ -110,23 +179,31 @@
110 179 if ( empty( $err ) ) {
111 180 return;
112 181 }
113 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 + }
114 193 ?>
115 194 <div class="error">
116 - <h2><?php _e( 'Powered Cache', 'powered-cache' ); ?></h2>
117 - <strong><?php echo __( 'Page Caching feature could not work because:', 'powered-cache' ); ?></strong>
118 -
119 - <?php foreach ( $err as $error_msg ): ?>
120 - <p><?php echo $error_msg; ?></p>
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>
121 200 <?php endforeach; ?>
122 201 </div>
123 202 <?php
124 203
125 -
126 204 }
127 205
128 -add_action( 'admin_notices', 'powered_cache_object_cache_notices' );
129 206
130 207 /**
131 208 * Display object cache broken msg
132 209 *
@@ -131,22 +208,316 @@
131 208 * Display object cache broken msg
132 209 *
133 210 * @since 1.0
134 211 */
135 -function powered_cache_object_cache_notices() {
136 - if ( defined( 'POWERED_OBJECT_CACHE_HAS_PROBLEM' ) && true === POWERED_OBJECT_CACHE_HAS_PROBLEM ) {
137 - $object_caches = Powered_Cache_Admin_Helper::object_cache_dropins();
138 - $broken_file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
139 - if ( isset( $object_caches[ powered_cache_get_option( 'object_cache' ) ] ) ) {
140 - $broken_file = $object_caches[ powered_cache_get_option( 'object_cache' ) ];
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;
141 232 }
233 + }
142 234
143 - $message = sprintf( __( 'Powered Cache could not access object cache backend. Please check <code>%s</code> exist and accessible on your server.', 'powered-cache' ), $broken_file );
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 );
144 239 ?>
145 240 <div class="error">
146 - <p><strong><?php echo __( 'Powered Cache:', 'powered-cache' ); ?></strong>
147 - <?php echo $message; ?>
241 + <p><strong><?php esc_html_e( 'Powered Cache:', 'powered-cache' ); ?></strong>
242 + <?php echo wp_kses_post( $message ); ?>
148 243 </p>
149 244 </div>
150 245 <?php
246 + return;
151 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 + $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
444 + if ( ! wp_verify_nonce( $nonce, 'powered_cache_dismiss_notice' ) ) {
445 + wp_nonce_ays( '' );
446 + }
447 +
448 + if ( current_user_can( 'manage_options' ) && ! empty( $_GET['notice'] ) ) {
449 + $notice = sanitize_text_field( wp_unslash( $_GET['notice'] ) );
450 +
451 + if ( POWERED_CACHE_IS_NETWORK ) {
452 + delete_site_transient( $notice );
453 + } else {
454 + delete_transient( $notice );
455 + }
456 + }
457 +
458 + wp_safe_redirect( esc_url_raw( wp_get_referer() ) );
459 + exit;
460 +}
461 +
462 +/**
463 + * Dismiss notice via AJAX
464 + *
465 + * @return void
466 + * @since 3.7
467 + */
468 +function dismiss_notice_ajax() {
469 + check_ajax_referer( 'powered_cache_dismiss_notice_ajax', 'nonce' );
470 +
471 + if ( ! current_user_can( 'manage_options' ) ) {
472 + wp_send_json_error( array( 'message' => esc_html__( 'Permission denied', 'powered-cache' ) ) );
473 + }
474 +
475 + if ( empty( $_POST['notice'] ) ) {
476 + wp_send_json_error( array( 'message' => esc_html__( 'Notice ID missing', 'powered-cache' ) ) );
477 + }
478 +
479 + $notice = sanitize_text_field( wp_unslash( $_POST['notice'] ) );
480 +
481 + if ( POWERED_CACHE_IS_NETWORK ) {
482 + delete_site_transient( $notice );
483 + } else {
484 + delete_transient( $notice );
485 + }
486 +
487 + wp_send_json_success( array( 'message' => esc_html__( 'Notice dismissed', 'powered-cache' ) ) );
488 +}
489 +
490 +/**
491 + * Display a notice when development mode is active
492 + *
493 + * @return void
494 + * @since 3.6
495 + * @related \PoweredCache\DevMode
496 + */
497 +function maybe_display_dev_mode_notice() {
498 + if ( ! \PoweredCache\Utils\is_dev_mode_active() ) {
499 + return;
500 + }
501 +
502 + if ( ! current_user_can( 'manage_options' ) ) {
503 + return;
504 + }
505 +
506 + // Only display on Powered Cache settings page
507 + $current_screen = get_current_screen();
508 +
509 + if (
510 + ! $current_screen
511 + || ( ! isset( $current_screen->id ) || false === strpos( $current_screen->id, 'powered-cache' ) )
512 + ) {
513 + return;
514 + }
515 +
516 + ?>
517 + <div class="notice notice-warning is-dismissible">
518 + <p><strong><?php esc_html_e( 'Development Mode is active.', 'powered-cache' ); ?></strong>
519 + <?php esc_html_e( 'Caching and optimizations are currently disabled. Don’t forget to disable it when done.', 'powered-cache' ); ?>
520 + </p>
521 + </div>
522 + <?php
152 523 }