PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 3.6.3
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v3.6.3
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 / dashboard.php

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

1,025 lines 41.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Dashboard Page
4 *
5 * @package PoweredCache
6 */
7
8 namespace PoweredCache\Admin\Dashboard;
9
10 use PoweredCache\Async\CachePreloader;
11 use PoweredCache\Async\CachePurger;
12 use PoweredCache\Async\DatabaseOptimizer;
13 use PoweredCache\Config;
14 use PoweredCache\Encryption;
15 use PoweredCache\Preloader;
16 use function PoweredCache\Utils\is_dev_mode_active;
17 use function PoweredCache\Utils\mask_string;
18 use const PoweredCache\Constants\ALLOPTIONS_CRITICAL_THRESHOLD;
19 use const PoweredCache\Constants\ALLOPTIONS_WARNING_THRESHOLD;
20 use const PoweredCache\Constants\ICON_BASE64;
21 use const PoweredCache\Constants\MENU_SLUG;
22 use const PoweredCache\Constants\PURGE_CACHE_CRON_NAME;
23 use const PoweredCache\Constants\PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT;
24 use const PoweredCache\Constants\SETTING_OPTION;
25 use function PoweredCache\Utils\can_configure_htaccess;
26 use function PoweredCache\Utils\can_configure_object_cache;
27 use function PoweredCache\Utils\can_control_all_settings;
28 use function PoweredCache\Utils\cdn_zones;
29 use function PoweredCache\Utils\clean_site_cache_dir;
30 use function PoweredCache\Utils\get_available_object_caches;
31 use function PoweredCache\Utils\get_cache_dir;
32 use function PoweredCache\Utils\get_timeout_with_interval;
33 use function PoweredCache\Utils\is_premium;
34 use function PoweredCache\Utils\powered_cache_flush;
35 use function PoweredCache\Utils\remove_dir;
36 use function PoweredCache\Utils\sanitize_css;
37 use const PoweredCache\Constants\UNMASK_CHARACTER_LENGTH;
38
39 // phpcs:disable WordPress.WhiteSpace.PrecisionAlignment.Found
40 // phpcs:disable Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed
41 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
42
43 /**
44 * Default setup routine
45 *
46 * @return void
47 */
48 function setup() {
49 if ( POWERED_CACHE_IS_NETWORK ) {
50 add_action( 'network_admin_menu', __NAMESPACE__ . '\\admin_menu' );
51 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_message' );
52 } else {
53 add_action( 'admin_menu', __NAMESPACE__ . '\\admin_menu' );
54 }
55
56 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_message' );
57
58 add_action( 'admin_init', __NAMESPACE__ . '\\process_form_submit' );
59 add_filter( 'admin_body_class', __NAMESPACE__ . '\\add_sui_admin_body_class' );
60 add_action( 'admin_bar_menu', __NAMESPACE__ . '\\admin_bar_menu', 999 );
61 add_action( 'admin_bar_menu', __NAMESPACE__ . '\\purge_all_admin_bar_menu' );
62 add_action( 'admin_post_powered_cache_purge_all_cache', __NAMESPACE__ . '\\purge_all_cache_action' );
63 add_action( 'admin_post_powered_cache_download_rewrite_settings', __NAMESPACE__ . '\\download_rewrite_config' );
64 add_action( 'wp_ajax_powered_cache_run_diagnostic', __NAMESPACE__ . '\\run_diagnostic' );
65 add_action( 'wp_ajax_powered_cache_check_alloptions', __NAMESPACE__ . '\\check_alloptions' );
66 add_action( 'admin_post_deactivate_plugin', __NAMESPACE__ . '\\deactivate_plugin' );
67 add_filter( 'plugin_action_links_' . plugin_basename( POWERED_CACHE_PLUGIN_FILE ), __NAMESPACE__ . '\\action_links' );
68 add_filter( 'network_admin_plugin_action_links_' . plugin_basename( POWERED_CACHE_PLUGIN_FILE ), __NAMESPACE__ . '\\action_links' );
69 }
70
71 /**
72 * Add required class for shared UI
73 *
74 * @param string $classes css classes for admin area
75 *
76 * @return string
77 * @see https://wpmudev.github.io/shared-ui/installation/
78 */
79 function add_sui_admin_body_class( $classes ) {
80 $classes .= ' sui-2-12-24 ';
81
82 return $classes;
83 }
84
85 /**
86 * Adds admin menu item
87 *
88 * @since 1.0
89 */
90 function admin_menu() {
91 global $powered_cache_settings_page;
92
93 $capability = 'manage_options';
94
95 if ( POWERED_CACHE_IS_NETWORK ) {
96 $capability = 'manage_network';
97 }
98
99 $powered_cache_settings_page = add_menu_page(
100 esc_html__( 'Powered Cache Settings', 'powered-cache' ),
101 esc_html__( 'Powered Cache', 'powered-cache' ),
102 $capability,
103 MENU_SLUG,
104 __NAMESPACE__ . '\settings_page',
105 ICON_BASE64
106 );
107
108 /**
109 * Different name submenu item, url point same address with parent.
110 */
111 add_submenu_page(
112 MENU_SLUG,
113 esc_html__( 'Powered Cache Settings', 'powered-cache' ),
114 esc_html__( 'Settings', 'powered-cache' ),
115 $capability,
116 MENU_SLUG
117 );
118 }
119
120 /**
121 * Main settings page of the plugin
122 */
123 function settings_page() {
124 include __DIR__ . '/partials/settings-page.php';
125 }
126
127 /**
128 * Process settings form action
129 *
130 * @since 2.0
131 */
132 function process_form_submit() {
133
134 if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) {
135 return;
136 }
137
138 if ( ! current_user_can( 'manage_options' ) ) {
139 return;
140 }
141
142 $nonce = filter_input( INPUT_POST, 'powered_cache_settings_nonce', FILTER_SANITIZE_SPECIAL_CHARS );
143 if ( wp_verify_nonce( $nonce, 'powered_cache_update_settings' ) ) {
144 $action = isset( $_POST['powered_cache_form_action'] ) ? sanitize_text_field( wp_unslash( $_POST['powered_cache_form_action'] ) ) : 'save_settings';
145 $old_options = \PoweredCache\Utils\get_settings();
146 $options = sanitize_options( $_POST );
147 $options = maybe_process_cloudflare_settings( $options );
148
149 switch ( $action ) {
150 case 'reset_settings':
151 if ( POWERED_CACHE_IS_NETWORK ) {
152 delete_site_option( SETTING_OPTION );
153 } else {
154 delete_option( SETTING_OPTION );
155 }
156
157 if ( 'off' !== $old_options['object_cache'] ) {
158 wp_cache_flush();
159 }
160
161 $options = \PoweredCache\Utils\get_settings();
162
163 break;
164 case 'export_settings':
165 $filename = sprintf( 'powered-cache-settings-%s-%s.json', gmdate( 'Y-m-d' ), uniqid() );
166 if ( POWERED_CACHE_IS_NETWORK ) {
167 $options = get_site_option( SETTING_OPTION );
168 } else {
169 $options = get_option( SETTING_OPTION );
170 }
171
172 $sensitive_options = [
173 'cloudflare_email', // PII data
174 'cloudflare_api_key',
175 'cloudflare_api_token',
176 ];
177
178 foreach ( $sensitive_options as $option_key ) {
179 if ( isset( $options[ $option_key ] ) ) {
180 $options[ $option_key ] = '';
181 }
182 }
183
184 $options = wp_json_encode( $options, JSON_PRETTY_PRINT );
185
186 nocache_headers();
187 // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
188 @header( 'Content-Type: application/json' );
189 @header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
190 @header( 'Content-Transfer-Encoding: binary' );
191 @header( 'Content-Length: ' . strlen( $options ) );
192 @header( 'Connection: close' );
193 // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged
194 echo $options; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
195 exit;
196 case 'import_settings':
197 if ( $_FILES['import_file'] && ! empty( $_FILES['import_file']['tmp_name'] ) ) { // phpcs:ignore
198 $import_data = file_get_contents( $_FILES['import_file']['tmp_name'] ); // phpcs:ignore
199 $import_settings = json_decode( $import_data, true );
200 $options = sanitize_options( $import_settings );
201 }
202 break;
203 case 'enable_dev_mode':
204 $options['dev_mode'] = true;
205 break;
206 case 'disable_dev_mode':
207 $options['dev_mode'] = false;
208 break;
209 case 'save_settings_and_optimize':
210 db_optimize( $options );
211 break;
212 case 'save_settings_and_clear_cache':
213 purge_all_cache( $options );
214 break;
215 case 'save_settings':
216 default:
217 break;
218 }
219
220 if ( POWERED_CACHE_IS_NETWORK ) {
221 update_site_option( SETTING_OPTION, $options );
222 } else {
223 update_option( SETTING_OPTION, $options );
224 }
225
226 Config::factory()->save_configuration( $options, POWERED_CACHE_IS_NETWORK );
227
228 // drop object cache on backend changes
229 if ( isset( $options['object_cache'] ) && $old_options['object_cache'] !== $options['object_cache'] ) {
230 wp_cache_flush();
231 }
232
233 // Flush cache when Dev Mode is turned OFF
234 if ( ! empty( $old_options['dev_mode'] ) && empty( $options['dev_mode'] ) ) {
235 wp_cache_flush();
236 }
237
238 // maybe cancel preloading process when it turned off
239 if ( $old_options['enable_cache_preload'] && ! $options['enable_cache_preload'] ) {
240 cancel_preloading();
241 }
242
243 // start the preloading process when it is turned on
244 if ( ! $old_options['enable_cache_preload'] && $options['enable_cache_preload'] ) {
245 start_preloading();
246 }
247
248 if ( $old_options['async_cache_cleaning'] && ! $options['async_cache_cleaning'] ) {
249 cancel_async_cache_cleaning();
250 }
251
252 // cleanup existing cache on toggling cache option
253 if ( $old_options['enable_page_cache'] && ! $options['enable_page_cache'] ) {
254 clean_site_cache_dir();
255 }
256
257 // cleanup existing cache due to optimized URL changes
258 if ( $old_options['rewrite_file_optimizer'] && ! $options['rewrite_file_optimizer'] ) {
259 clean_site_cache_dir();
260 }
261
262 if ( $old_options['cache_timeout'] !== $options['cache_timeout'] ) {
263 $timestamp = wp_next_scheduled( PURGE_CACHE_CRON_NAME );
264
265 wp_unschedule_event( $timestamp, PURGE_CACHE_CRON_NAME );
266 }
267
268 /**
269 * Fires after saving configurations.
270 *
271 * @hook powered_cache_settings_saved
272 *
273 * @param {array} $old_options Old settings.
274 * @param {array} $options New settings.
275 *
276 * @since 1.0
277 */
278 do_action( 'powered_cache_settings_saved', $old_options, $options );
279
280 $redirect_url = wp_get_referer();
281
282 if ( empty( $redirect_url ) && isset( $_SERVER['REQUEST_URI'] ) ) {
283 $redirect_url = wp_unslash( $_SERVER['REQUEST_URI'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
284 }
285
286 $redirect_url = add_query_arg(
287 [
288 'pc_action' => $action,
289 ],
290 $redirect_url
291 );
292
293 wp_safe_redirect( esc_url_raw( $redirect_url ) );
294 exit;
295 }
296 }
297
298 /**
299 * Sanitize options
300 *
301 * @param array $options Raw input, most likely $_POST request
302 *
303 * @return array|mixed Sanitized options
304 */
305 function sanitize_options( $options ) {
306 $sanitized_options = [];
307
308 if ( isset( $options['object_cache'] ) && in_array( $options['object_cache'], get_available_object_caches(), true ) ) {
309 $sanitized_options['object_cache'] = sanitize_text_field( $options['object_cache'] );
310 } else {
311 $sanitized_options['object_cache'] = 'off';
312 }
313
314 $sanitized_options['enable_page_cache'] = ! empty( $options['enable_page_cache'] );
315 $sanitized_options['cache_mobile'] = ! empty( $options['cache_mobile'] );
316 $sanitized_options['cache_mobile_separate_file'] = ! empty( $options['cache_mobile_separate_file'] );
317 $sanitized_options['loggedin_user_cache'] = ! empty( $options['loggedin_user_cache'] );
318 $sanitized_options['gzip_compression'] = ! empty( $options['gzip_compression'] );
319 $sanitized_options['cache_timeout'] = absint( $options['cache_timeout'] );
320 $sanitized_options['auto_configure_htaccess'] = ! empty( $options['auto_configure_htaccess'] );
321 $sanitized_options['rewrite_file_optimizer'] = ! empty( $options['rewrite_file_optimizer'] );
322 $sanitized_options['rejected_user_agents'] = sanitize_textarea_field( $options['rejected_user_agents'] );
323 $sanitized_options['rejected_cookies'] = sanitize_textarea_field( $options['rejected_cookies'] );
324 $sanitized_options['rejected_referrers'] = sanitize_textarea_field( $options['rejected_referrers'] );
325 $sanitized_options['vary_cookies'] = sanitize_textarea_field( $options['vary_cookies'] );
326 $sanitized_options['rejected_uri'] = sanitize_textarea_field( $options['rejected_uri'] );
327 $sanitized_options['cache_query_strings'] = sanitize_textarea_field( $options['cache_query_strings'] );
328 $sanitized_options['ignored_query_strings'] = sanitize_textarea_field( $options['ignored_query_strings'] );
329 $sanitized_options['purge_additional_pages'] = sanitize_textarea_field( $options['purge_additional_pages'] );
330 $sanitized_options['minify_html'] = ! empty( $options['minify_html'] );
331 $sanitized_options['minify_html_dom_optimization'] = ! empty( $options['minify_html_dom_optimization'] );
332 $sanitized_options['combine_google_fonts'] = ! empty( $options['combine_google_fonts'] );
333 $sanitized_options['swap_google_fonts_display'] = ! empty( $options['swap_google_fonts_display'] );
334 $sanitized_options['use_bunny_fonts'] = ! empty( $options['use_bunny_fonts'] );
335 $sanitized_options['minify_css'] = ! empty( $options['minify_css'] );
336 $sanitized_options['combine_css'] = ! empty( $options['combine_css'] );
337 $sanitized_options['critical_css'] = ! empty( $options['critical_css'] );
338 $sanitized_options['critical_css_additional_files'] = sanitize_textarea_field( $options['critical_css_additional_files'] );
339 $sanitized_options['critical_css_excluded_files'] = sanitize_textarea_field( $options['critical_css_excluded_files'] );
340 $sanitized_options['excluded_css_files'] = sanitize_textarea_field( $options['excluded_css_files'] );
341 $sanitized_options['remove_unused_css'] = ! empty( $options['remove_unused_css'] );
342 $sanitized_options['ucss_safelist'] = sanitize_textarea_field( $options['ucss_safelist'] );
343 $sanitized_options['ucss_excluded_files'] = sanitize_textarea_field( $options['ucss_excluded_files'] );
344 $sanitized_options['minify_js'] = ! empty( $options['minify_js'] );
345 $sanitized_options['combine_js'] = ! empty( $options['combine_js'] );
346 $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] );
347 $sanitized_options['js_defer'] = ! empty( $options['js_defer'] );
348 $sanitized_options['js_defer_exclusions'] = sanitize_textarea_field( $options['js_defer_exclusions'] );
349 $sanitized_options['js_delay'] = ! empty( $options['js_delay'] );
350 $sanitized_options['js_delay_exclusions'] = sanitize_textarea_field( $options['js_delay_exclusions'] );
351 $sanitized_options['js_delay_timeout'] = absint( $options['js_delay_timeout'] );
352 $sanitized_options['enable_image_optimization'] = ! empty( $options['enable_image_optimization'] );
353 $sanitized_options['image_optimizer_preferred_format'] = isset( $options['image_optimizer_preferred_format'] ) ? sanitize_text_field( wp_unslash( $options['image_optimizer_preferred_format'] ) ) : '';
354 $sanitized_options['enable_lazy_load'] = ! empty( $options['enable_lazy_load'] );
355 $sanitized_options['lazy_load_post_content'] = ! empty( $options['lazy_load_post_content'] );
356 $sanitized_options['lazy_load_images'] = ! empty( $options['lazy_load_images'] );
357 $sanitized_options['lazy_load_iframes'] = ! empty( $options['lazy_load_iframes'] );
358 $sanitized_options['lazy_load_widgets'] = ! empty( $options['lazy_load_widgets'] );
359 $sanitized_options['lazy_load_post_thumbnail'] = ! empty( $options['lazy_load_post_thumbnail'] );
360 $sanitized_options['lazy_load_avatars'] = ! empty( $options['lazy_load_avatars'] );
361 $sanitized_options['lazy_load_youtube'] = ! empty( $options['lazy_load_youtube'] );
362 $sanitized_options['lazy_load_exclusions'] = sanitize_textarea_field( $options['lazy_load_exclusions'] );
363 $sanitized_options['lazy_load_skip_first_nth_img'] = absint( $options['lazy_load_skip_first_nth_img'] );
364 $sanitized_options['disable_wp_lazy_load'] = ! empty( $options['disable_wp_lazy_load'] );
365 $sanitized_options['add_missing_image_dimensions'] = ! empty( $options['add_missing_image_dimensions'] );
366 $sanitized_options['disable_wp_embeds'] = ! empty( $options['disable_wp_embeds'] );
367 $sanitized_options['disable_emoji_scripts'] = ! empty( $options['disable_emoji_scripts'] );
368 $sanitized_options['enable_cdn'] = ! empty( $options['enable_cdn'] );
369
370 // convert TTL in minute
371 if ( $options['cache_timeout'] > 0 && isset( $options['cache_timeout_interval'] ) ) {
372 switch ( $options['cache_timeout_interval'] ) {
373 case 'DAY':
374 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1440;
375 break;
376 case 'HOUR':
377 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 60;
378 break;
379 case 'MINUTE':
380 default:
381 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1;
382 }
383 }
384
385 $cdn_hostname = [];
386 if ( isset( $options['cdn_hostname'] ) ) {
387 foreach ( (array) $options['cdn_hostname'] as $hostname ) {
388 $hostname = trim( $hostname );
389 if ( filter_var( $hostname, FILTER_VALIDATE_URL ) ) {
390 $cdn_hostname[] = wp_parse_url( $hostname, PHP_URL_HOST );
391 } else {
392 $cdn_hostname[] = $hostname;
393 }
394 }
395 }
396
397 $cdn_zone = [];
398
399 if ( isset( $options['cdn_zone'] ) ) {
400 foreach ( (array) $options['cdn_zone'] as $zone ) {
401 $cdn_zone[] = sanitize_text_field( $zone );
402 }
403 }
404
405 if ( empty( $cdn_hostname ) ) {
406 $cdn_hostname = [ '' ];
407 }
408
409 if ( empty( $cdn_zone ) ) {
410 $cdn_zone = [ '' ];
411 }
412
413 $sanitized_options['cdn_hostname'] = $cdn_hostname;
414 $sanitized_options['cdn_zone'] = $cdn_zone;
415 $sanitized_options['cdn_rejected_files'] = sanitize_textarea_field( $options['cdn_rejected_files'] );
416 $sanitized_options['enable_cache_preload'] = ! empty( $options['enable_cache_preload'] );
417 $sanitized_options['preload_homepage'] = ! empty( $options['preload_homepage'] );
418 $sanitized_options['preload_public_posts'] = ! empty( $options['preload_public_posts'] );
419 $sanitized_options['preload_public_tax'] = ! empty( $options['preload_public_tax'] );
420 $sanitized_options['enable_sitemap_preload'] = ! empty( $options['enable_sitemap_preload'] );
421 $sanitized_options['preload_request_interval'] = absint( $options['preload_request_interval'] );
422 $sanitized_options['preload_sitemap'] = sanitize_textarea_field( $options['preload_sitemap'] );
423 $sanitized_options['prefetch_dns'] = sanitize_textarea_field( $options['prefetch_dns'] );
424 $sanitized_options['preconnect_resource'] = sanitize_textarea_field( $options['preconnect_resource'] );
425 $sanitized_options['prefetch_links'] = ! empty( $options['prefetch_links'] );
426 $sanitized_options['db_cleanup_post_revisions'] = ! empty( $options['db_cleanup_post_revisions'] );
427 $sanitized_options['db_cleanup_auto_drafts'] = ! empty( $options['db_cleanup_auto_drafts'] );
428 $sanitized_options['db_cleanup_trashed_posts'] = ! empty( $options['db_cleanup_trashed_posts'] );
429 $sanitized_options['db_cleanup_spam_comments'] = ! empty( $options['db_cleanup_spam_comments'] );
430 $sanitized_options['db_cleanup_trashed_comments'] = ! empty( $options['db_cleanup_trashed_comments'] );
431 $sanitized_options['db_cleanup_expired_transients'] = ! empty( $options['db_cleanup_expired_transients'] );
432 $sanitized_options['db_cleanup_all_transients'] = ! empty( $options['db_cleanup_all_transients'] );
433 $sanitized_options['db_cleanup_optimize_tables'] = ! empty( $options['db_cleanup_optimize_tables'] );
434 $sanitized_options['enable_scheduled_db_cleanup'] = ! empty( $options['enable_scheduled_db_cleanup'] );
435 $sanitized_options['scheduled_db_cleanup_frequency'] = sanitize_text_field( $options['scheduled_db_cleanup_frequency'] );
436 $sanitized_options['enable_cloudflare'] = ! empty( $options['enable_cloudflare'] );
437 $sanitized_options['cloudflare_email'] = sanitize_email( $options['cloudflare_email'] );
438 $sanitized_options['cloudflare_api_key'] = sanitize_text_field( $options['cloudflare_api_key'] );
439 $sanitized_options['cloudflare_api_token'] = sanitize_text_field( $options['cloudflare_api_token'] );
440 $sanitized_options['cloudflare_zone'] = sanitize_text_field( $options['cloudflare_zone'] );
441 $sanitized_options['enable_heartbeat'] = ! empty( $options['enable_heartbeat'] );
442 $sanitized_options['heartbeat_dashboard_status'] = sanitize_text_field( $options['heartbeat_dashboard_status'] );
443 $sanitized_options['heartbeat_editor_status'] = sanitize_text_field( $options['heartbeat_editor_status'] );
444 $sanitized_options['heartbeat_frontend_status'] = sanitize_text_field( $options['heartbeat_frontend_status'] );
445 $sanitized_options['heartbeat_dashboard_interval'] = absint( $options['heartbeat_dashboard_interval'] );
446 $sanitized_options['heartbeat_editor_interval'] = absint( $options['heartbeat_editor_interval'] );
447 $sanitized_options['heartbeat_frontend_interval'] = absint( $options['heartbeat_frontend_interval'] );
448 $sanitized_options['enable_varnish'] = ! empty( $options['enable_varnish'] );
449 $sanitized_options['varnish_ip'] = sanitize_text_field( $options['varnish_ip'] );
450 $sanitized_options['cache_footprint'] = ! empty( $options['cache_footprint'] );
451 $sanitized_options['async_cache_cleaning'] = ! empty( $options['async_cache_cleaning'] );
452 $sanitized_options['dev_mode'] = ! empty( $options['dev_mode'] );
453 $sanitized_options['enable_google_tracking'] = ! empty( $options['enable_google_tracking'] );
454 $sanitized_options['enable_fb_tracking'] = ! empty( $options['enable_fb_tracking'] );
455
456 if ( isset( $options['critical_css_appended_content'] ) ) {
457 $sanitized_options['critical_css_appended_content'] = sanitize_css( $options['critical_css_appended_content'] );
458 }
459
460 if ( isset( $options['critical_css_fallback'] ) ) {
461 $sanitized_options['critical_css_fallback'] = sanitize_css( $options['critical_css_fallback'] );
462 }
463
464 /**
465 * Filters sanitized options.
466 *
467 * @hook powered_cache_sanitized_options
468 *
469 * @param {array} $sanitized_options Sanitized options.
470 * @param {array} $options raw input.
471 *
472 * @return {array} New value.
473 *
474 * @since 2.0
475 */
476 return apply_filters( 'powered_cache_sanitized_options', $sanitized_options, $options );
477 }
478
479 /**
480 * Add base admin bar menu
481 *
482 * @param object $wp_admin_bar Admin bar object
483 *
484 * @since 2.0
485 */
486 function admin_bar_menu( $wp_admin_bar ) {
487 $href = admin_url( 'admin.php?page=powered-cache' );
488
489 if ( POWERED_CACHE_IS_NETWORK && current_user_can( 'manage_network' ) ) {
490 $href = network_admin_url( 'admin.php?page=powered-cache' );
491 }
492
493 if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) {
494 $href = '#';
495 }
496
497 if ( current_user_can( 'manage_options' ) ) {
498 $wp_admin_bar->add_menu(
499 array(
500 'id' => MENU_SLUG,
501 'title' => __( 'Powered Cache', 'powered-cache' ),
502 'href' => $href,
503 )
504 );
505 }
506 }
507
508 /**
509 * Maybe display feedback messages when certain action is taken
510 *
511 * @since 2.0
512 */
513 function maybe_display_message() {
514 // phpcs:disable WordPress.Security.NonceVerification.Recommended
515 if ( ! isset( $_GET['pc_action'] ) ) {
516 return;
517 }
518
519 /**
520 * Dont display multiple message when saving the options while having the query_params
521 */
522 if ( ! empty( $_POST ) ) {
523 return;
524 }
525
526 $screen = get_current_screen();
527
528 $success_messages = [
529 'purge_image_optimizer_cache' => esc_html__( 'Image optimizer cache purged successfully!', 'powered-cache' ),
530 'flush_page_cache_network' => esc_html__( 'Page cache deleted for all websites!', 'powered-cache' ),
531 'flush_page_cache' => esc_html__( 'Page cache deleted successfully!', 'powered-cache' ),
532 'flush_object_cache' => esc_html__( 'Object cache deleted successfully!', 'powered-cache' ),
533 'flush_all_cache' => esc_html__( 'All cached items flushed successfully!', 'powered-cache' ),
534 'start_preload' => esc_html__( 'The cache preloading has been initialized!', 'powered-cache' ),
535 'generate_critical' => esc_html__( 'The Critical CSS generation process has been initialized!', 'powered-cache' ),
536 'generate_critical_network' => esc_html__( 'The Critical CSS generation process has been initialized for all sites! This might take a while, depending on the network size.', 'powered-cache' ),
537 'generate_ucss' => esc_html__( 'The UCSS generation process has been initialized!', 'powered-cache' ),
538 'generate_ucss_network' => esc_html__( 'The UCSS generation process has been initialized for all sites! This might take a while, depending on the network size.', 'powered-cache' ),
539 'flush_cf_cache' => esc_html__( 'Cloudflare cache flushed, it can take up to 30 seconds to delete all cache from Cloudflare!', 'powered-cache' ),
540 'reset_settings' => esc_html__( 'Settings have been reset!', 'powered-cache' ),
541 'import_settings' => esc_html__( 'Settings have been imported!', 'powered-cache' ),
542 'save_settings_and_optimize' => esc_html__( 'Settings saved and database being optimized...', 'powered-cache' ),
543 'save_settings_and_clear_cache' => esc_html__( 'Settings have been successfully saved, and all cache has been cleared.', 'powered-cache' ),
544 'save_settings' => esc_html__( 'Settings saved.', 'powered-cache' ),
545 ];
546
547 if ( isset( $_GET['language'] ) ) {
548 $success_messages['flush_lang_cache'] = sprintf( esc_html__( 'Page cache for %s language has been deleted!', 'powered-cache' ), esc_attr( urldecode_deep( $_GET['language'] ) ) ); // phpcs:ignore
549 }
550
551 $err_messages = [
552 'purge_image_optimizer_cache_failed' => esc_html__( 'Could not purge image optimizer cache. Please try again later and ensure your license key is activated!', 'powered-cache' ),
553 'generic_permission_err' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
554 'flush_page_cache_network_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
555 'flush_page_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
556 'flush_object_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
557 'flush_all_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
558 'start_preload_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
559 'start_critical_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
560 'start_ucss_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
561 'start_critical_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for the Critical CSS!', 'powered-cache' ),
562 'start_ucss_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for removing unused CSS!', 'powered-cache' ),
563 'flush_cf_cache_failed' => esc_html__( 'Could not flush Cloudflare cache. Please make sure you entered the correct credentials and zone id!', 'powered-cache' ),
564 ];
565
566 if ( isset( $success_messages[ $_GET['pc_action'] ] ) ) {
567 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
568 add_settings_error( $screen->parent_file, MENU_SLUG, $success_messages[ $_GET['pc_action'] ], 'success' ); // phpcs:ignore
569
570 return;
571 }
572
573 printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', $success_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
574 }
575
576 if ( isset( $err_messages[ $_GET['pc_action'] ] ) ) {
577 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
578 add_settings_error( $screen->parent_file, MENU_SLUG, $err_messages[ $_GET['pc_action'] ], 'error' ); // phpcs:ignore
579
580 return;
581 }
582
583 printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', $err_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
584 }
585 // phpcs:enable WordPress.Security.NonceVerification.Recommended
586 }
587
588
589 /**
590 * Adds `Purge All Cache` menu bar item
591 *
592 * @param object $wp_admin_bar Admin bar object
593 *
594 * @since 1.1
595 */
596 function purge_all_admin_bar_menu( $wp_admin_bar ) {
597 // Only available for the network admins on multisite.
598 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
599 return;
600 }
601
602 $wp_admin_bar->add_menu(
603 array(
604 'id' => 'all-cache-purge',
605 'title' => __( 'Purge All Cache', 'powered-cache' ),
606 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_all_cache' ), 'powered_cache_purge_all_cache' ),
607 'parent' => 'powered-cache',
608 )
609 );
610 }
611
612 /**
613 * Purges all cache related things
614 *
615 * @since 1.1
616 */
617 function purge_all_cache_action() {
618
619 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_purge_all_cache' ) ) { // phpcs:ignore
620 wp_nonce_ays( '' );
621 }
622
623 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
624 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
625 wp_safe_redirect( esc_url_raw( $redirect_url ) );
626 exit;
627 }
628
629 if ( ! current_user_can( 'manage_options' ) ) {
630 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
631 wp_safe_redirect( esc_url_raw( $redirect_url ) );
632 exit;
633 }
634
635 purge_all_cache();
636
637 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache', wp_get_referer() );
638
639 wp_safe_redirect( esc_url_raw( $redirect_url ) );
640 exit;
641 }
642
643
644 /**
645 * Purge all cache
646 *
647 * @param array $settings plugin settings
648 *
649 * @return void
650 */
651 function purge_all_cache( $settings = array() ) {
652 $cache_purger = CachePurger::factory();
653 if ( empty( $settings ) ) {
654 $settings = \PoweredCache\Utils\get_settings();
655 }
656
657 if ( $settings['async_cache_cleaning'] ) {
658 if ( function_exists( 'wp_cache_flush' ) ) {
659 wp_cache_flush();
660 }
661 $cache_purger->push_to_queue( [ 'call' => 'powered_cache_flush' ] );
662 $cache_purger->save()->dispatch();
663 } else {
664 powered_cache_flush();// cleans object cache + page cache dir
665 }
666
667 /**
668 * Fires after purging all cache
669 *
670 * @hook powered_cache_purge_all_cache
671 * @since 1.1
672 */
673 do_action( 'powered_cache_purge_all_cache' );
674
675 if ( POWERED_CACHE_IS_NETWORK ) {
676 delete_site_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT );
677 } else {
678 delete_transient( PURGE_CACHE_PLUGIN_NOTICE_TRANSIENT );
679 }
680 }
681
682
683 /**
684 * Downloads proper configuration file
685 *
686 * @since 1.1
687 */
688 function download_rewrite_config() {
689 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_download_rewrite' ) ) { // phpcs:ignore
690 wp_nonce_ays( '' );
691 }
692
693 if ( ! can_control_all_settings() ) {
694 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
695 wp_safe_redirect( esc_url_raw( $redirect_url ) );
696 exit;
697 }
698
699 if ( ! empty( $_GET['server'] ) ) {
700 $server = sanitize_text_field( wp_unslash( $_GET['server'] ) );
701 Config::factory()->download_rewrite_rules( $server );
702 }
703
704 wp_safe_redirect( wp_get_referer() );
705 die();
706 }
707
708 /**
709 * Run DB optimization
710 *
711 * @param array $options plugin settings
712 */
713 function db_optimize( $options ) {
714 $powered_cache_db_optimizer = DatabaseOptimizer::factory();
715
716 $supported_options = $powered_cache_db_optimizer->get_supported_options();
717
718 if ( POWERED_CACHE_IS_NETWORK ) {
719 $sites = get_sites();
720 foreach ( $sites as $site ) {
721 switch_to_blog( $site->blog_id );
722 foreach ( $supported_options as $optimization_item ) {
723 if ( $options[ $optimization_item ] ) {
724 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
725 }
726 }
727
728 $powered_cache_db_optimizer->save()->dispatch();
729 restore_current_blog();
730 }
731 } else {
732 foreach ( $supported_options as $optimization_item ) {
733 if ( $options[ $optimization_item ] ) {
734 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
735 }
736 }
737
738 $powered_cache_db_optimizer->save()->dispatch();
739 }
740
741 }
742
743 /**
744 * Cancel preloading process on toggling preload option
745 */
746 function cancel_preloading() {
747 \PoweredCache\Utils\log( 'Cancel preload process - Settings toggle' );
748 $cache_preloader = CachePreloader::factory();
749 $cache_preloader->cancel_process();
750 $cache_preloader->delete_all();
751 }
752
753 /**
754 * Kick-start preloading process
755 *
756 * @return void
757 */
758 function start_preloading() {
759 \PoweredCache\Utils\log( 'Enable Preloader - Settings toggle' );
760 Preloader::factory()->setup_preload_queue();
761 // kickstart the preloading process
762 Preloader::factory()->dispatch_preload_queue();
763 }
764
765 /**
766 * Cancel async cache purging processes
767 *
768 * @since 2.3
769 */
770 function cancel_async_cache_cleaning() {
771 \PoweredCache\Utils\log( 'Cancel CachePurger process' );
772 $cache_preloader = CachePurger::factory();
773 $cache_preloader->cancel_process();
774 }
775
776
777 /**
778 * Perform diagnostic checks
779 */
780 function run_diagnostic() {
781 global $is_apache;
782
783 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
784
785 if ( wp_verify_nonce( $nonce, 'powered_cache_run_diagnostic' ) ) {
786 $settings = \PoweredCache\Utils\get_settings();
787 $checks = array();
788
789 // check config file
790 $config_file = Config::factory()->find_wp_config_file();
791 $config_file_status = is_writeable( $config_file );
792
793 if ( $config_file_status ) {
794 $config_file_desc = esc_html__( 'wp-config.php is writable.', 'powered-cache' );
795 } else {
796 $config_file_desc = sprintf( __( 'wp-config.php is not writable. Please make sure the file writable or you can manually define %s constant.', 'powered-cache' ), '<code>WP_CACHE</code>' );
797 }
798
799 $checks[] = array(
800 'check' => 'config',
801 'status' => $config_file_status,
802 'description' => $config_file_desc,
803 );
804
805 // check cache directory
806 $cache_dir = get_cache_dir();
807 $cache_dir_status = false;
808 if ( ! file_exists( $cache_dir ) ) {
809 $cache_dir_desc = sprintf( __( 'Cache directory %s is not exist!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
810 } elseif ( ! is_writeable( $cache_dir ) ) {
811 $cache_dir_desc = sprintf( __( 'Cache directory %s is not writeable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
812 } else {
813 $cache_dir_status = true;
814 $cache_dir_desc = sprintf( __( 'Cache directory %s exist and writable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
815 }
816
817 $checks[] = array(
818 'check' => 'cache-dir',
819 'status' => $cache_dir_status,
820 'description' => $cache_dir_desc,
821 );
822
823 // check .htaccess file
824 if ( $is_apache && $settings['auto_configure_htaccess'] ) {
825 $htaccess_file = get_home_path() . '.htaccess';
826 $htaccess_file_status = false;
827 if ( ! file_exists( $htaccess_file ) ) {
828 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not exist!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
829 } elseif ( ! is_writeable( $htaccess_file ) ) {
830 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not writeable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
831 } else {
832 $htaccess_file_status = true;
833 $htaccess_file_desc = sprintf( __( '.htaccess file %s exist and writable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
834 }
835
836 $checks[] = array(
837 'check' => 'htaccess',
838 'status' => $htaccess_file_status,
839 'description' => $htaccess_file_desc,
840 );
841 }
842
843 // check page cache
844 if ( $settings['enable_page_cache'] ) {
845 $advanced_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php';
846 $advanced_cache_file_status = false;
847 if ( ! file_exists( $advanced_cache_file ) ) {
848 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not exist!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
849 } elseif ( ! is_writeable( $advanced_cache_file ) ) {
850 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not writeable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
851 } else {
852 $advanced_cache_file_status = true;
853 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s exist and writable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
854 }
855
856 $checks[] = array(
857 'check' => 'advanced-cache',
858 'status' => $advanced_cache_file_status,
859 'description' => $advanced_cache_file_desc,
860 );
861 }
862
863 // check object cache
864 if ( 'off' !== $settings['object_cache'] ) {
865 $object_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
866 $object_cache_file_status = false;
867 if ( ! file_exists( $object_cache_file ) ) {
868 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not exist!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
869 } elseif ( ! is_writeable( $object_cache_file ) ) {
870 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not writeable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
871 } else {
872 $object_cache_file_status = true;
873 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s exist and writable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
874 }
875
876 $checks[] = array(
877 'check' => 'object-cache',
878 'status' => $object_cache_file_status,
879 'description' => $object_cache_file_desc,
880 );
881 }
882
883 wp_send_json_success( $checks );
884 }
885
886 wp_send_json_error( [ esc_html__( 'Invalid request', 'powered-cache' ) ] );
887 }
888
889 /**
890 * Check alloptions size like performance lab does.
891 * It's critical to know this before enabling memcached based persistent object cache backends.
892 * When alloptions size is too big (1mb in this case), it will cause performance degradation instead of improvement.
893 *
894 * @return void
895 * @since 3.4
896 */
897 function check_alloptions() {
898 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
899 if ( ! wp_verify_nonce( $nonce, 'powered_cache_update_settings' ) || ! can_configure_object_cache() ) {
900 wp_send_json_error( [ 'message' => esc_html__( 'Invalid request', 'powered-cache' ) ] );
901
902 return;
903 }
904
905 $autoload_option_size = \PoweredCache\Utils\autoloaded_options_size();
906 $autoload_option_count = count( wp_load_alloptions() );
907
908 if ( $autoload_option_size > ALLOPTIONS_CRITICAL_THRESHOLD ) {
909 $status = 'critical';
910 } elseif ( $autoload_option_size > ALLOPTIONS_WARNING_THRESHOLD && $autoload_option_size <= ALLOPTIONS_CRITICAL_THRESHOLD ) {
911 $status = 'warning';
912 } else {
913 $status = 'good';
914 }
915
916 $message = '<p><b>' . esc_html__( 'Autoloaded options could affect performance:', 'powered-cache' ) . '</b> ' .
917 sprintf(
918 esc_html__(
919 /* translators: 1: Number of autoloaded options. 2: Size of autoloaded options. */
920 'Your site has %1$s autoloaded options (size: %2$s) in the options table, which could cause your site to be slow. You can reduce the number of autoloaded options by cleaning up your site\'s options table.',
921 'powered-cache'
922 ),
923 esc_html( number_format_i18n( $autoload_option_count ) ),
924 esc_html( size_format( $autoload_option_size ) )
925 ) . '</p>';
926
927 wp_send_json_success(
928 [
929 'status' => $status,
930 'message' => $message,
931 ]
932 );
933 }
934
935
936 /**
937 * Deactivate incompatible plugins
938 *
939 * @since 1.0
940 */
941 function deactivate_plugin() {
942 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'deactivate_plugin' ) ) { // phpcs:ignore
943 wp_nonce_ays( '' );
944 }
945
946 if ( ! current_user_can( 'activate_plugins' ) ) {
947 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
948 wp_safe_redirect( esc_url_raw( $redirect_url ) );
949 exit;
950 }
951
952 if ( isset( $_GET['plugin'] ) ) {
953 $plugin = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
954 deactivate_plugins( $plugin );
955 }
956
957 wp_safe_redirect( wp_get_referer() );
958 die();
959 }
960
961 /**
962 * Adds settings link to plugin actions
963 *
964 * @param array $actions Plugin actions.
965 *
966 * @return array
967 * @since 1.0
968 */
969 function action_links( $actions ) {
970
971 $settings_url = POWERED_CACHE_IS_NETWORK ? network_admin_url( 'admin.php?page=powered-cache' ) : admin_url( 'admin.php?page=powered-cache' );
972 $powered_cache_url = 'https://poweredcache.com/?utm_source=wp_admin&utm_medium=plugin&utm_campaign=plugin_action_links';
973
974 $actions['powered_settings'] = sprintf( '<a href="%s">%s</a>', esc_url( $settings_url ), esc_html__( 'Settings', 'powered-cache' ) );
975
976 if ( ! is_premium() ) {
977 $actions['get_premium'] = sprintf( '<a href="%s" style="color: red;">%s</a>', esc_url( $powered_cache_url ), esc_html__( 'Get Premium', 'powered-cache' ) );
978 }
979
980 return array_reverse( $actions );
981 }
982
983 /**
984 * Conditionally process Cloudflare API key and token settings based on the form input.
985 *
986 * @param array $options The form options submitted by the user.
987 *
988 * @return array Updated options with processed Cloudflare settings.
989 */
990 function maybe_process_cloudflare_settings( $options ) {
991 // Retrieve the previous Cloudflare API key and token values.
992 $prev_cf_api_key = \PoweredCache\Extensions\Cloudflare\Cloudflare::get_cf_api_key();
993 $prev_cf_api_token = \PoweredCache\Extensions\Cloudflare\Cloudflare::get_cf_api_token();
994
995 // Check if the submitted Cloudflare API key matches the masked version of the previous key.
996 if ( isset( $options['cloudflare_api_key'] ) && mask_string( $prev_cf_api_key, UNMASK_CHARACTER_LENGTH ) === $options['cloudflare_api_key'] ) {
997 $options['cloudflare_api_key'] = $prev_cf_api_key; // Use the unmasked value.
998 }
999
1000 if ( isset( $options['cloudflare_api_token'] ) && mask_string( $prev_cf_api_token, UNMASK_CHARACTER_LENGTH ) === $options['cloudflare_api_token'] ) {
1001 $options['cloudflare_api_token'] = $prev_cf_api_token; // Use the unmasked value.
1002 }
1003
1004 $encryption = new Encryption();
1005 // Encrypt sensitive data if it's not empty.
1006 if ( ! empty( $options['cloudflare_api_key'] ) ) {
1007 $options['cloudflare_api_key'] = $encryption->encrypt( $options['cloudflare_api_key'] );
1008 }
1009
1010 if ( ! empty( $options['cloudflare_api_token'] ) ) {
1011 $options['cloudflare_api_token'] = $encryption->encrypt( $options['cloudflare_api_token'] );
1012 }
1013
1014 // Override with empty values if constants are defined.
1015 if ( defined( 'POWERED_CACHE_CF_API_KEY' ) && POWERED_CACHE_CF_API_KEY ) {
1016 $options['cloudflare_api_key'] = '';
1017 }
1018
1019 if ( defined( 'POWERED_CACHE_CF_API_TOKEN' ) && POWERED_CACHE_CF_API_TOKEN ) {
1020 $options['cloudflare_api_token'] = '';
1021 }
1022
1023 return $options;
1024 }
1025