PluginProbe
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score / 2.1.2
Powered Cache – Caching and Optimization for WordPress – Easily Improve PageSpeed & Web Vitals Score v2.1.2
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 2.1.2, at includes/admin/dashboard.php

787 lines 30.7 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\DatabaseOptimizer;
12 use PoweredCache\Config;
13 use const PoweredCache\Constants\ICON_BASE64;
14 use const PoweredCache\Constants\MENU_SLUG;
15 use const PoweredCache\Constants\PURGE_CACHE_CRON_NAME;
16 use const PoweredCache\Constants\SETTING_OPTION;
17 use function PoweredCache\Utils\can_configure_htaccess;
18 use function PoweredCache\Utils\can_configure_object_cache;
19 use function PoweredCache\Utils\can_control_all_settings;
20 use function PoweredCache\Utils\cdn_zones;
21 use function PoweredCache\Utils\clean_site_cache_dir;
22 use function PoweredCache\Utils\get_available_object_caches;
23 use function PoweredCache\Utils\get_cache_dir;
24 use function PoweredCache\Utils\get_timeout_with_interval;
25 use function PoweredCache\Utils\is_premium;
26 use function PoweredCache\Utils\js_execution_methods;
27 use function PoweredCache\Utils\powered_cache_flush;
28 use function PoweredCache\Utils\remove_dir;
29 use function PoweredCache\Utils\sanitize_css;
30
31 // phpcs:disable WordPress.WhiteSpace.PrecisionAlignment.Found
32 // phpcs:disable Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed
33 // phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
34
35 /**
36 * Default setup routine
37 *
38 * @return void
39 */
40 function setup() {
41 if ( POWERED_CACHE_IS_NETWORK ) {
42 add_action( 'network_admin_menu', __NAMESPACE__ . '\\admin_menu' );
43 add_action( 'network_admin_notices', __NAMESPACE__ . '\\maybe_display_message' );
44 } else {
45 add_action( 'admin_menu', __NAMESPACE__ . '\\admin_menu' );
46 }
47
48 add_action( 'admin_notices', __NAMESPACE__ . '\\maybe_display_message' );
49
50 add_action( 'admin_init', __NAMESPACE__ . '\\process_form_submit' );
51 add_filter( 'admin_body_class', __NAMESPACE__ . '\\add_sui_admin_body_class' );
52 add_action( 'admin_bar_menu', __NAMESPACE__ . '\\admin_bar_menu', 999 );
53 add_action( 'admin_bar_menu', __NAMESPACE__ . '\\purge_all_admin_bar_menu' );
54 add_action( 'admin_post_powered_cache_purge_all_cache', __NAMESPACE__ . '\\purge_all_cache' );
55 add_action( 'admin_post_powered_cache_download_rewrite_settings', __NAMESPACE__ . '\\download_rewrite_config' );
56 add_action( 'wp_ajax_powered_cache_run_diagnostic', __NAMESPACE__ . '\\run_diagnostic' );
57 add_action( 'admin_post_deactivate_plugin', __NAMESPACE__ . '\\deactivate_plugin' );
58 add_filter( 'plugin_action_links_' . plugin_basename( POWERED_CACHE_PLUGIN_FILE ), __NAMESPACE__ . '\\action_links' );
59 add_filter( 'network_admin_plugin_action_links_' . plugin_basename( POWERED_CACHE_PLUGIN_FILE ), __NAMESPACE__ . '\\action_links' );
60 }
61
62 /**
63 * Add required class for shared UI
64 *
65 * @param string $classes css classes for admin area
66 *
67 * @return string
68 * @see https://wpmudev.github.io/shared-ui/installation/
69 */
70 function add_sui_admin_body_class( $classes ) {
71 $classes .= ' sui-2-12-4 ';
72
73 return $classes;
74 }
75
76 /**
77 * Adds admin menu item
78 *
79 * @since 1.0
80 */
81 function admin_menu() {
82 global $powered_cache_settings_page;
83
84 $capability = 'manage_options';
85
86 if ( POWERED_CACHE_IS_NETWORK ) {
87 $capability = 'manage_network';
88 }
89
90 $powered_cache_settings_page = add_menu_page(
91 esc_html__( 'Powered Cache Settings', 'powered-cache' ),
92 esc_html__( 'Powered Cache', 'powered-cache' ),
93 $capability,
94 MENU_SLUG,
95 __NAMESPACE__ . '\settings_page',
96 ICON_BASE64
97 );
98
99 /**
100 * Different name submenu item, url point same address with parent.
101 */
102 add_submenu_page(
103 MENU_SLUG,
104 esc_html__( 'Powered Cache Settings', 'powered-cache' ),
105 esc_html__( 'Settings', 'powered-cache' ),
106 $capability,
107 MENU_SLUG
108 );
109 }
110
111 /**
112 * Main settings page of the plugin
113 */
114 function settings_page() {
115 include __DIR__ . '/partials/settings-page.php';
116 }
117
118 /**
119 * Process settings form action
120 *
121 * @since 2.0
122 */
123 function process_form_submit() {
124
125 if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) {
126 return;
127 }
128
129 if ( ! current_user_can( 'manage_options' ) ) {
130 return;
131 }
132
133 $nonce = filter_input( INPUT_POST, 'powered_cache_settings_nonce', FILTER_SANITIZE_STRING );
134 if ( wp_verify_nonce( $nonce, 'powered_cache_update_settings' ) ) {
135 $action = $_POST['powered_cache_form_action'] ? $_POST['powered_cache_form_action'] : 'save_settings';
136 $old_options = \PoweredCache\Utils\get_settings();
137 $options = sanitize_options( $_POST );
138
139 switch ( $action ) {
140 case 'reset_settings':
141 if ( POWERED_CACHE_IS_NETWORK ) {
142 delete_site_option( SETTING_OPTION );
143 } else {
144 delete_option( SETTING_OPTION );
145 }
146
147 if ( 'off' !== $old_options['object_cache'] ) {
148 wp_cache_flush();
149 }
150
151 $options = \PoweredCache\Utils\get_settings();
152
153 break;
154 case 'export_settings':
155 $filename = sprintf( 'powered-cache-settings-%s-%s.json', gmdate( 'Y-m-d' ), uniqid() );
156 if ( POWERED_CACHE_IS_NETWORK ) {
157 $options = wp_json_encode( get_site_option( SETTING_OPTION ), JSON_PRETTY_PRINT );
158 } else {
159 $options = wp_json_encode( get_option( SETTING_OPTION ), JSON_PRETTY_PRINT );
160 }
161
162 nocache_headers();
163 // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
164 @header( 'Content-Type: application/json' );
165 @header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
166 @header( 'Content-Transfer-Encoding: binary' );
167 @header( 'Content-Length: ' . strlen( $options ) );
168 @header( 'Connection: close' );
169 // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged
170 echo $options; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
171 exit;
172 case 'import_settings':
173 if ( $_FILES['import_file'] && ! empty( $_FILES['import_file']['tmp_name'] ) ) {
174 $import_data = file_get_contents( $_FILES['import_file']['tmp_name'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
175 $import_settings = json_decode( $import_data, true );
176 $options = sanitize_options( $import_settings );
177 }
178 break;
179 case 'save_settings_and_optimize':
180 db_optimize( $options );
181 break;
182 case 'save_settings':
183 default:
184 break;
185 }
186
187 if ( POWERED_CACHE_IS_NETWORK ) {
188 update_site_option( SETTING_OPTION, $options );
189 } else {
190 update_option( SETTING_OPTION, $options );
191 }
192
193 Config::factory()->save_configuration( $options, POWERED_CACHE_IS_NETWORK );
194
195 // drop object cache on backend changes
196 if ( isset( $options['object_cache'] ) && $old_options['object_cache'] !== $options['object_cache'] ) {
197 wp_cache_flush();
198 }
199
200 // maybe cancel preloading process when it turned off
201 if ( $old_options['enable_cache_preload'] && ! $options['enable_cache_preload'] ) {
202 cancel_preloading();
203 }
204
205 // cleanup existing cache on toggling cache option
206 if ( $old_options['enable_page_cache'] && ! $options['enable_page_cache'] ) {
207 clean_site_cache_dir();
208 }
209
210 if ( $old_options['cache_timeout'] !== $options['cache_timeout'] ) {
211 $timestamp = wp_next_scheduled( PURGE_CACHE_CRON_NAME );
212
213 wp_unschedule_event( $timestamp, PURGE_CACHE_CRON_NAME );
214 }
215
216 /**
217 * Fires after saving configurations.
218 *
219 * @hook powered_cache_settings_saved
220 *
221 * @param {array} $old_options Old settings.
222 * @param {array} $options New settings.
223 *
224 * @since 1.0
225 */
226 do_action( 'powered_cache_settings_saved', $old_options, $options );
227
228 $redirect_url = wp_get_referer();
229
230 if ( empty( $redirect_url ) ) {
231 $redirect_url = $_SERVER['REQUEST_URI'];
232 }
233
234 $redirect_url = add_query_arg(
235 [
236 'pc_action' => $action,
237 ],
238 $redirect_url
239 );
240
241 wp_safe_redirect( esc_url_raw( $redirect_url ) );
242 exit;
243 }
244 }
245
246 /**
247 * Sanitize options
248 *
249 * @param array $options Raw input, most likely $_POST request
250 *
251 * @return array|mixed Sanitized options
252 */
253 function sanitize_options( $options ) {
254 $sanitized_options = [];
255
256 if ( isset( $options['object_cache'] ) && in_array( $options['object_cache'], get_available_object_caches(), true ) ) {
257 $sanitized_options['object_cache'] = sanitize_text_field( $options['object_cache'] );
258 } else {
259 $sanitized_options['object_cache'] = 'off';
260 }
261
262 $sanitized_options['enable_page_cache'] = ! empty( $options['enable_page_cache'] );
263 $sanitized_options['cache_mobile'] = ! empty( $options['cache_mobile'] );
264 $sanitized_options['cache_mobile_separate_file'] = ! empty( $options['cache_mobile_separate_file'] );
265 $sanitized_options['loggedin_user_cache'] = ! empty( $options['loggedin_user_cache'] );
266 $sanitized_options['gzip_compression'] = ! empty( $options['gzip_compression'] );
267 $sanitized_options['cache_timeout'] = absint( $options['cache_timeout'] );
268 $sanitized_options['auto_configure_htaccess'] = ! empty( $options['auto_configure_htaccess'] );
269 $sanitized_options['rejected_user_agents'] = sanitize_textarea_field( $options['rejected_user_agents'] );
270 $sanitized_options['rejected_cookies'] = sanitize_textarea_field( $options['rejected_cookies'] );
271 $sanitized_options['vary_cookies'] = sanitize_textarea_field( $options['vary_cookies'] );
272 $sanitized_options['rejected_uri'] = sanitize_textarea_field( $options['rejected_uri'] );
273 $sanitized_options['accepted_query_strings'] = sanitize_textarea_field( $options['accepted_query_strings'] );
274 $sanitized_options['purge_additional_pages'] = sanitize_textarea_field( $options['purge_additional_pages'] );
275 $sanitized_options['purge_additional_pages'] = sanitize_textarea_field( $options['purge_additional_pages'] );
276 $sanitized_options['minify_html'] = ! empty( $options['minify_html'] );
277 $sanitized_options['combine_google_fonts'] = ! empty( $options['combine_google_fonts'] );
278 $sanitized_options['minify_css'] = ! empty( $options['minify_css'] );
279 $sanitized_options['combine_css'] = ! empty( $options['combine_css'] );
280 $sanitized_options['critical_css'] = ! empty( $options['critical_css'] );
281 $sanitized_options['critical_css_additional_files'] = sanitize_textarea_field( $options['critical_css_additional_files'] );
282 $sanitized_options['critical_css_excluded_files'] = sanitize_textarea_field( $options['critical_css_excluded_files'] );
283 $sanitized_options['excluded_css_files'] = sanitize_textarea_field( $options['excluded_css_files'] );
284 $sanitized_options['minify_js'] = ! empty( $options['minify_js'] );
285 $sanitized_options['combine_js'] = ! empty( $options['combine_js'] );
286 $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] );
287 $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] );
288 $sanitized_options['js_execution_method'] = sanitize_text_field( $options['js_execution_method'] );
289 $sanitized_options['js_execution_optimized_only'] = ! empty( $options['js_execution_optimized_only'] );
290 $sanitized_options['enable_lazy_load'] = ! empty( $options['enable_lazy_load'] );
291 $sanitized_options['lazy_load_post_content'] = ! empty( $options['lazy_load_post_content'] );
292 $sanitized_options['lazy_load_images'] = ! empty( $options['lazy_load_images'] );
293 $sanitized_options['lazy_load_iframes'] = ! empty( $options['lazy_load_iframes'] );
294 $sanitized_options['lazy_load_widgets'] = ! empty( $options['lazy_load_widgets'] );
295 $sanitized_options['lazy_load_post_thumbnail'] = ! empty( $options['lazy_load_post_thumbnail'] );
296 $sanitized_options['lazy_load_avatars'] = ! empty( $options['lazy_load_avatars'] );
297 $sanitized_options['disable_wp_lazy_load'] = ! empty( $options['disable_wp_lazy_load'] );
298 $sanitized_options['disable_wp_embeds'] = ! empty( $options['disable_wp_embeds'] );
299 $sanitized_options['disable_emoji_scripts'] = ! empty( $options['disable_emoji_scripts'] );
300 $sanitized_options['enable_cdn'] = ! empty( $options['enable_cdn'] );
301
302 // convert TTL in minute
303 if ( $options['cache_timeout'] > 0 && isset( $options['cache_timeout_interval'] ) ) {
304 switch ( $options['cache_timeout_interval'] ) {
305 case 'DAY':
306 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1440;
307 break;
308 case 'HOUR':
309 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 60;
310 break;
311 case 'MINUTE':
312 default:
313 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1;
314 }
315 }
316
317 $cdn_hostname = [];
318 if ( isset( $options['cdn_hostname'] ) ) {
319 foreach ( (array) $options['cdn_hostname'] as $hostname ) {
320 $cdn_hostname[] = esc_url_raw( $hostname );
321 }
322 }
323
324 $cdn_zone = [];
325
326 if ( isset( $options['cdn_zone'] ) ) {
327 foreach ( (array) $options['cdn_zone'] as $zone ) {
328 $cdn_zone[] = sanitize_text_field( $zone );
329 }
330 }
331
332 if ( empty( $cdn_hostname ) ) {
333 $cdn_hostname = [ '' ];
334 }
335
336 if ( empty( $cdn_zone ) ) {
337 $cdn_zone = [ '' ];
338 }
339
340 $sanitized_options['cdn_hostname'] = $cdn_hostname;
341 $sanitized_options['cdn_zone'] = $cdn_zone;
342 $sanitized_options['cdn_rejected_files'] = sanitize_textarea_field( $options['cdn_rejected_files'] );
343 $sanitized_options['enable_cache_preload'] = ! empty( $options['enable_cache_preload'] );
344 $sanitized_options['preload_homepage'] = ! empty( $options['preload_homepage'] );
345 $sanitized_options['preload_public_posts'] = ! empty( $options['preload_public_posts'] );
346 $sanitized_options['preload_public_tax'] = ! empty( $options['preload_public_tax'] );
347 $sanitized_options['enable_sitemap_preload'] = ! empty( $options['enable_sitemap_preload'] );
348 $sanitized_options['preload_sitemap'] = sanitize_textarea_field( $options['preload_sitemap'] );
349 $sanitized_options['prefetch_dns'] = sanitize_textarea_field( $options['prefetch_dns'] );
350 $sanitized_options['db_cleanup_post_revisions'] = ! empty( $options['db_cleanup_post_revisions'] );
351 $sanitized_options['db_cleanup_auto_drafts'] = ! empty( $options['db_cleanup_auto_drafts'] );
352 $sanitized_options['db_cleanup_trashed_posts'] = ! empty( $options['db_cleanup_trashed_posts'] );
353 $sanitized_options['db_cleanup_spam_comments'] = ! empty( $options['db_cleanup_spam_comments'] );
354 $sanitized_options['db_cleanup_trashed_comments'] = ! empty( $options['db_cleanup_trashed_comments'] );
355 $sanitized_options['db_cleanup_expired_transients'] = ! empty( $options['db_cleanup_expired_transients'] );
356 $sanitized_options['db_cleanup_all_transients'] = ! empty( $options['db_cleanup_all_transients'] );
357 $sanitized_options['db_cleanup_optimize_tables'] = ! empty( $options['db_cleanup_optimize_tables'] );
358 $sanitized_options['enable_scheduled_db_cleanup'] = ! empty( $options['enable_scheduled_db_cleanup'] );
359 $sanitized_options['scheduled_db_cleanup_frequency'] = sanitize_text_field( $options['scheduled_db_cleanup_frequency'] );
360 $sanitized_options['enable_cloudflare'] = ! empty( $options['enable_cloudflare'] );
361 $sanitized_options['cloudflare_email'] = sanitize_email( $options['cloudflare_email'] );
362 $sanitized_options['cloudflare_api_key'] = sanitize_text_field( $options['cloudflare_api_key'] );
363 $sanitized_options['cloudflare_zone'] = sanitize_text_field( $options['cloudflare_zone'] );
364 $sanitized_options['enable_heartbeat'] = ! empty( $options['enable_heartbeat'] );
365 $sanitized_options['heartbeat_dashboard_status'] = sanitize_text_field( $options['heartbeat_dashboard_status'] );
366 $sanitized_options['heartbeat_editor_status'] = sanitize_text_field( $options['heartbeat_editor_status'] );
367 $sanitized_options['heartbeat_frontend_status'] = sanitize_text_field( $options['heartbeat_frontend_status'] );
368 $sanitized_options['heartbeat_dashboard_interval'] = absint( $options['heartbeat_dashboard_interval'] );
369 $sanitized_options['heartbeat_editor_interval'] = absint( $options['heartbeat_editor_interval'] );
370 $sanitized_options['heartbeat_frontend_interval'] = absint( $options['heartbeat_frontend_interval'] );
371 $sanitized_options['enable_varnish'] = ! empty( $options['enable_varnish'] );
372 $sanitized_options['varnish_ip'] = sanitize_text_field( $options['varnish_ip'] );
373 $sanitized_options['cache_footprint'] = ! empty( $options['cache_footprint'] );
374 $sanitized_options['enable_google_tracking'] = ! empty( $options['enable_google_tracking'] );
375 $sanitized_options['enable_fb_tracking'] = ! empty( $options['enable_fb_tracking'] );
376
377 if ( isset( $options['critical_css_appended_content'] ) ) {
378 $sanitized_options['critical_css_appended_content'] = sanitize_css( $options['critical_css_appended_content'] );
379 }
380
381 if ( isset( $options['critical_css_fallback'] ) ) {
382 $sanitized_options['critical_css_fallback'] = sanitize_css( $options['critical_css_fallback'] );
383 }
384
385 /**
386 * Filters sanitized options.
387 *
388 * @hook powered_cache_sanitized_options
389 *
390 * @param {array} $sanitized_options Sanitized options.
391 * @param {array} $options raw input.
392 *
393 * @return {array} New value.
394 *
395 * @since 2.0
396 */
397 return apply_filters( 'powered_cache_sanitized_options', $sanitized_options, $options );
398 }
399
400 /**
401 * Add base admin bar menu
402 *
403 * @param object $wp_admin_bar Admin bar object
404 *
405 * @since 2.0
406 */
407 function admin_bar_menu( $wp_admin_bar ) {
408 $href = admin_url( 'admin.php?page=powered-cache' );
409
410 if ( POWERED_CACHE_IS_NETWORK && current_user_can( 'manage_network' ) ) {
411 $href = network_admin_url( 'admin.php?page=powered-cache' );
412 }
413
414 if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) {
415 $href = '#';
416 }
417
418 if ( current_user_can( 'manage_options' ) ) {
419 $wp_admin_bar->add_menu(
420 array(
421 'id' => MENU_SLUG,
422 'title' => __( 'Powered Cache', 'powered-cache' ),
423 'href' => $href,
424 )
425 );
426 }
427 }
428
429 /**
430 * Maybe display feedback messages when certain action is taken
431 *
432 * @since 2.0
433 */
434 function maybe_display_message() {
435 // phpcs:disable WordPress.Security.NonceVerification.Recommended
436 if ( ! isset( $_GET['pc_action'] ) ) {
437 return;
438 }
439
440 /**
441 * Dont display multiple message when saving the options while having the query_params
442 */
443 if ( ! empty( $_POST ) ) {
444 return;
445 }
446
447 $screen = get_current_screen();
448
449 $success_messages = [
450 'flush_page_cache_network' => esc_html__( 'Page cache deleted for all websites!', 'powered-cache' ),
451 'flush_page_cache' => esc_html__( 'Page cache deleted successfully!', 'powered-cache' ),
452 'flush_object_cache' => esc_html__( 'Object cache deleted successfully!', 'powered-cache' ),
453 'flush_all_cache' => esc_html__( 'All cached items flushed successfully!', 'powered-cache' ),
454 'start_preload' => esc_html__( 'The cache preloading has been initialized!', 'powered-cache' ),
455 'generate_critical' => esc_html__( 'The Critical CSS generation process has been initialized!', 'powered-cache' ),
456 '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' ),
457 'flush_cf_cache' => esc_html__( 'Cloudflare cache flushed, it can take up to 30 seconds to delete all cache from Cloudflare!', 'powered-cache' ),
458 'reset_settings' => esc_html__( 'Settings have been reset!', 'powered-cache' ),
459 'import_settings' => esc_html__( 'Settings have been imported!', 'powered-cache' ),
460 'save_settings_and_optimize' => esc_html__( 'Settings saved and database being optimized...', 'powered-cache' ),
461 'save_settings' => esc_html__( 'Settings saved.', 'powered-cache' ),
462 ];
463
464 $err_messages = [
465 'generic_permission_err' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
466 'flush_page_cache_network_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
467 'flush_page_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
468 'flush_object_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
469 'flush_all_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
470 'start_preload_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
471 'start_critical_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
472 'start_critical_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for the Critical CSS!', 'powered-cache' ),
473 'flush_cf_cache_failed' => esc_html__( 'Could not flush Cloudflare cache. Please make sure you entered the correct credentials and zone id!', 'powered-cache' ),
474 ];
475
476 if ( isset( $success_messages[ $_GET['pc_action'] ] ) ) {
477 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
478 add_settings_error( $screen->parent_file, MENU_SLUG, $success_messages[ $_GET['pc_action'] ], 'success' );
479
480 return;
481 }
482
483 printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', $success_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
484 }
485
486 if ( isset( $err_messages[ $_GET['pc_action'] ] ) ) {
487 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
488 add_settings_error( $screen->parent_file, MENU_SLUG, $err_messages[ $_GET['pc_action'] ], 'error' );
489
490 return;
491 }
492
493 printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', $err_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
494 }
495 // phpcs:enable WordPress.Security.NonceVerification.Recommended
496 }
497
498
499 /**
500 * Adds `Purge All Cache` menu bar item
501 *
502 * @param object $wp_admin_bar Admin bar object
503 *
504 * @since 1.1
505 */
506 function purge_all_admin_bar_menu( $wp_admin_bar ) {
507 // Only available for the network admins on multisite.
508 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
509 return;
510 }
511
512 $wp_admin_bar->add_menu(
513 array(
514 'id' => 'all-cache-purge',
515 'title' => __( 'Purge All Cache', 'powered-cache' ),
516 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_all_cache' ), 'powered_cache_purge_all_cache' ),
517 'parent' => 'powered-cache',
518 )
519 );
520 }
521
522 /**
523 * Purges all cache related things
524 *
525 * @since 1.1
526 */
527 function purge_all_cache() {
528
529 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_purge_all_cache' ) ) {
530 wp_nonce_ays( '' );
531 }
532
533 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
534 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
535 wp_safe_redirect( esc_url_raw( $redirect_url ) );
536 exit;
537 }
538
539 if ( ! current_user_can( 'manage_options' ) ) {
540 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
541 wp_safe_redirect( esc_url_raw( $redirect_url ) );
542 exit;
543 }
544
545 powered_cache_flush();// cleans object cache + page cache dir
546
547 /**
548 * Fires after purging all cache
549 *
550 * @hook powered_cache_purge_all_cache
551 *
552 * @since 1.1
553 */
554 do_action( 'powered_cache_purge_all_cache' );
555
556 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache', wp_get_referer() );
557
558 wp_safe_redirect( esc_url_raw( $redirect_url ) );
559 exit;
560 }
561
562
563 /**
564 * Downloads proper configuration file
565 *
566 * @since 1.1
567 */
568 function download_rewrite_config() {
569 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_download_rewrite' ) ) {
570 wp_nonce_ays( '' );
571 }
572
573 if ( ! can_control_all_settings() ) {
574 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
575 wp_safe_redirect( esc_url_raw( $redirect_url ) );
576 exit;
577 }
578
579 $server = $_GET['server'];
580 Config::factory()->download_rewrite_rules( $server );
581
582 wp_safe_redirect( wp_get_referer() );
583 die();
584 }
585
586 /**
587 * Run DB optimization
588 *
589 * @param array $options plugin settings
590 */
591 function db_optimize( $options ) {
592 $powered_cache_db_optimizer = DatabaseOptimizer::factory();
593
594 $supported_options = $powered_cache_db_optimizer->get_supported_options();
595
596 if ( POWERED_CACHE_IS_NETWORK ) {
597 $sites = get_sites();
598 foreach ( $sites as $site ) {
599 switch_to_blog( $site->blog_id );
600 foreach ( $supported_options as $optimization_item ) {
601 if ( $options[ $optimization_item ] ) {
602 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
603 }
604 }
605
606 $powered_cache_db_optimizer->save()->dispatch();
607 restore_current_blog();
608 }
609 } else {
610 foreach ( $supported_options as $optimization_item ) {
611 if ( $options[ $optimization_item ] ) {
612 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
613 }
614 }
615
616 $powered_cache_db_optimizer->save()->dispatch();
617 }
618
619 }
620
621 /**
622 * Cancel preloading process on toggling preload option
623 */
624 function cancel_preloading() {
625 \PoweredCache\Utils\log( 'Cancel preload process' );
626 $cache_preloader = CachePreloader::factory();
627 $cache_preloader->cancel_process();
628 }
629
630
631 /**
632 * Perform diagnostic checks
633 */
634 function run_diagnostic() {
635 global $is_apache;
636
637 $nonce = $_POST['nonce'];
638
639 if ( wp_verify_nonce( $nonce, 'powered_cache_run_diagnostic' ) ) {
640 $settings = \PoweredCache\Utils\get_settings();
641 $checks = array();
642
643 // check config file
644 $config_file = Config::factory()->find_wp_config_file();
645 $config_file_status = is_writeable( $config_file );
646
647 if ( $config_file_status ) {
648 $config_file_desc = esc_html__( 'wp-config.php is writable.', 'powered-cache' );
649 } else {
650 $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>' );
651 }
652
653 $checks[] = array(
654 'check' => 'config',
655 'status' => $config_file_status,
656 'description' => $config_file_desc,
657 );
658
659 // check cache directory
660 $cache_dir = get_cache_dir();
661 $cache_dir_status = false;
662 if ( ! file_exists( $cache_dir ) ) {
663 $cache_dir_desc = sprintf( __( 'Cache directory %s is not exist!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
664 } elseif ( ! is_writeable( $cache_dir ) ) {
665 $cache_dir_desc = sprintf( __( 'Cache directory %s is not writeable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
666 } else {
667 $cache_dir_status = true;
668 $cache_dir_desc = sprintf( __( 'Cache directory %s exist and writable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
669 }
670
671 $checks[] = array(
672 'check' => 'cache-dir',
673 'status' => $cache_dir_status,
674 'description' => $cache_dir_desc,
675 );
676
677 // check .htaccess file
678 if ( $is_apache && $settings['auto_configure_htaccess'] ) {
679 $htaccess_file = get_home_path() . '.htaccess';
680 $htaccess_file_status = false;
681 if ( ! file_exists( $htaccess_file ) ) {
682 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not exist!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
683 } elseif ( ! is_writeable( $htaccess_file ) ) {
684 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not writeable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
685 } else {
686 $htaccess_file_status = true;
687 $htaccess_file_desc = sprintf( __( '.htaccess file %s exist and writable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
688 }
689
690 $checks[] = array(
691 'check' => 'htaccess',
692 'status' => $htaccess_file_status,
693 'description' => $htaccess_file_desc,
694 );
695 }
696
697 // check page cache
698 if ( $settings['enable_page_cache'] ) {
699 $advanced_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php';
700 $advanced_cache_file_status = false;
701 if ( ! file_exists( $advanced_cache_file ) ) {
702 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not exist!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
703 } elseif ( ! is_writeable( $advanced_cache_file ) ) {
704 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not writeable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
705 } else {
706 $advanced_cache_file_status = true;
707 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s exist and writable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
708 }
709
710 $checks[] = array(
711 'check' => 'advanced-cache',
712 'status' => $advanced_cache_file_status,
713 'description' => $advanced_cache_file_desc,
714 );
715 }
716
717 // check object cache
718 if ( 'off' !== $settings['object_cache'] ) {
719 $object_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
720 $object_cache_file_status = false;
721 if ( ! file_exists( $object_cache_file ) ) {
722 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not exist!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
723 } elseif ( ! is_writeable( $object_cache_file ) ) {
724 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not writeable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
725 } else {
726 $object_cache_file_status = true;
727 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s exist and writable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
728 }
729
730 $checks[] = array(
731 'check' => 'object-cache',
732 'status' => $object_cache_file_status,
733 'description' => $object_cache_file_desc,
734 );
735 }
736
737 wp_send_json_success( $checks );
738 }
739
740 wp_send_json_error( [ esc_html__( 'Invalid request', 'powered-cache' ) ] );
741 }
742
743
744 /**
745 * Deactivate incompatible plugins
746 *
747 * @since 1.0
748 */
749 function deactivate_plugin() {
750 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'deactivate_plugin' ) ) {
751 wp_nonce_ays( '' );
752 }
753
754 if ( ! current_user_can( 'activate_plugins' ) ) {
755 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
756 wp_safe_redirect( esc_url_raw( $redirect_url ) );
757 exit;
758 }
759
760 deactivate_plugins( $_GET['plugin'] );
761
762 wp_safe_redirect( wp_get_referer() );
763 die();
764 }
765
766 /**
767 * Adds settings link to plugin actions
768 *
769 * @param array $actions Plugin actions.
770 *
771 * @return array
772 * @since 1.0
773 */
774 function action_links( $actions ) {
775
776 $settings_url = POWERED_CACHE_IS_NETWORK ? network_admin_url( 'admin.php?page=powered-cache' ) : admin_url( 'admin.php?page=powered-cache' );
777 $powered_cache_url = 'https://poweredcache.com/?utm_source=wp_admin&utm_medium=plugin&utm_campaign=plugin_action_links';
778
779 $actions['powered_settings'] = sprintf( '<a href="%s">%s</a>', esc_url( $settings_url ), esc_html__( 'Settings', 'powered-cache' ) );
780
781 if ( ! is_premium() ) {
782 $actions['get_premium'] = sprintf( '<a href="%s" style="color: red;">%s</a>', esc_url( $powered_cache_url ), esc_html__( 'Get Premium', 'powered-cache' ) );
783 }
784
785 return array_reverse( $actions );
786 }
787