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

794 lines 31.1 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-8 ';
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['swap_google_fonts_display'] = ! empty( $options['swap_google_fonts_display'] );
279 $sanitized_options['minify_css'] = ! empty( $options['minify_css'] );
280 $sanitized_options['combine_css'] = ! empty( $options['combine_css'] );
281 $sanitized_options['critical_css'] = ! empty( $options['critical_css'] );
282 $sanitized_options['critical_css_additional_files'] = sanitize_textarea_field( $options['critical_css_additional_files'] );
283 $sanitized_options['critical_css_excluded_files'] = sanitize_textarea_field( $options['critical_css_excluded_files'] );
284 $sanitized_options['excluded_css_files'] = sanitize_textarea_field( $options['excluded_css_files'] );
285 $sanitized_options['minify_js'] = ! empty( $options['minify_js'] );
286 $sanitized_options['combine_js'] = ! empty( $options['combine_js'] );
287 $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] );
288 $sanitized_options['excluded_js_files'] = sanitize_textarea_field( $options['excluded_js_files'] );
289 $sanitized_options['js_execution_method'] = sanitize_text_field( $options['js_execution_method'] );
290 $sanitized_options['js_execution_optimized_only'] = ! empty( $options['js_execution_optimized_only'] );
291 $sanitized_options['enable_image_optimization'] = ! empty( $options['enable_image_optimization'] );
292 $sanitized_options['enable_lazy_load'] = ! empty( $options['enable_lazy_load'] );
293 $sanitized_options['lazy_load_post_content'] = ! empty( $options['lazy_load_post_content'] );
294 $sanitized_options['lazy_load_images'] = ! empty( $options['lazy_load_images'] );
295 $sanitized_options['lazy_load_iframes'] = ! empty( $options['lazy_load_iframes'] );
296 $sanitized_options['lazy_load_widgets'] = ! empty( $options['lazy_load_widgets'] );
297 $sanitized_options['lazy_load_post_thumbnail'] = ! empty( $options['lazy_load_post_thumbnail'] );
298 $sanitized_options['lazy_load_avatars'] = ! empty( $options['lazy_load_avatars'] );
299 $sanitized_options['disable_wp_lazy_load'] = ! empty( $options['disable_wp_lazy_load'] );
300 $sanitized_options['disable_wp_embeds'] = ! empty( $options['disable_wp_embeds'] );
301 $sanitized_options['disable_emoji_scripts'] = ! empty( $options['disable_emoji_scripts'] );
302 $sanitized_options['enable_cdn'] = ! empty( $options['enable_cdn'] );
303
304 // convert TTL in minute
305 if ( $options['cache_timeout'] > 0 && isset( $options['cache_timeout_interval'] ) ) {
306 switch ( $options['cache_timeout_interval'] ) {
307 case 'DAY':
308 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1440;
309 break;
310 case 'HOUR':
311 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 60;
312 break;
313 case 'MINUTE':
314 default:
315 $sanitized_options['cache_timeout'] = $options['cache_timeout'] * 1;
316 }
317 }
318
319 $cdn_hostname = [];
320 if ( isset( $options['cdn_hostname'] ) ) {
321 foreach ( (array) $options['cdn_hostname'] as $hostname ) {
322 if ( filter_var( $hostname, FILTER_VALIDATE_URL ) ) {
323 $cdn_hostname[] = wp_parse_url( $hostname, PHP_URL_HOST );
324 } else {
325 $cdn_hostname[] = $hostname;
326 }
327 }
328 }
329
330 $cdn_zone = [];
331
332 if ( isset( $options['cdn_zone'] ) ) {
333 foreach ( (array) $options['cdn_zone'] as $zone ) {
334 $cdn_zone[] = sanitize_text_field( $zone );
335 }
336 }
337
338 if ( empty( $cdn_hostname ) ) {
339 $cdn_hostname = [ '' ];
340 }
341
342 if ( empty( $cdn_zone ) ) {
343 $cdn_zone = [ '' ];
344 }
345
346 $sanitized_options['cdn_hostname'] = $cdn_hostname;
347 $sanitized_options['cdn_zone'] = $cdn_zone;
348 $sanitized_options['cdn_rejected_files'] = sanitize_textarea_field( $options['cdn_rejected_files'] );
349 $sanitized_options['enable_cache_preload'] = ! empty( $options['enable_cache_preload'] );
350 $sanitized_options['preload_homepage'] = ! empty( $options['preload_homepage'] );
351 $sanitized_options['preload_public_posts'] = ! empty( $options['preload_public_posts'] );
352 $sanitized_options['preload_public_tax'] = ! empty( $options['preload_public_tax'] );
353 $sanitized_options['enable_sitemap_preload'] = ! empty( $options['enable_sitemap_preload'] );
354 $sanitized_options['preload_sitemap'] = sanitize_textarea_field( $options['preload_sitemap'] );
355 $sanitized_options['prefetch_dns'] = sanitize_textarea_field( $options['prefetch_dns'] );
356 $sanitized_options['preconnect_resource'] = sanitize_textarea_field( $options['preconnect_resource'] );
357 $sanitized_options['db_cleanup_post_revisions'] = ! empty( $options['db_cleanup_post_revisions'] );
358 $sanitized_options['db_cleanup_auto_drafts'] = ! empty( $options['db_cleanup_auto_drafts'] );
359 $sanitized_options['db_cleanup_trashed_posts'] = ! empty( $options['db_cleanup_trashed_posts'] );
360 $sanitized_options['db_cleanup_spam_comments'] = ! empty( $options['db_cleanup_spam_comments'] );
361 $sanitized_options['db_cleanup_trashed_comments'] = ! empty( $options['db_cleanup_trashed_comments'] );
362 $sanitized_options['db_cleanup_expired_transients'] = ! empty( $options['db_cleanup_expired_transients'] );
363 $sanitized_options['db_cleanup_all_transients'] = ! empty( $options['db_cleanup_all_transients'] );
364 $sanitized_options['db_cleanup_optimize_tables'] = ! empty( $options['db_cleanup_optimize_tables'] );
365 $sanitized_options['enable_scheduled_db_cleanup'] = ! empty( $options['enable_scheduled_db_cleanup'] );
366 $sanitized_options['scheduled_db_cleanup_frequency'] = sanitize_text_field( $options['scheduled_db_cleanup_frequency'] );
367 $sanitized_options['enable_cloudflare'] = ! empty( $options['enable_cloudflare'] );
368 $sanitized_options['cloudflare_email'] = sanitize_email( $options['cloudflare_email'] );
369 $sanitized_options['cloudflare_api_key'] = sanitize_text_field( $options['cloudflare_api_key'] );
370 $sanitized_options['cloudflare_zone'] = sanitize_text_field( $options['cloudflare_zone'] );
371 $sanitized_options['enable_heartbeat'] = ! empty( $options['enable_heartbeat'] );
372 $sanitized_options['heartbeat_dashboard_status'] = sanitize_text_field( $options['heartbeat_dashboard_status'] );
373 $sanitized_options['heartbeat_editor_status'] = sanitize_text_field( $options['heartbeat_editor_status'] );
374 $sanitized_options['heartbeat_frontend_status'] = sanitize_text_field( $options['heartbeat_frontend_status'] );
375 $sanitized_options['heartbeat_dashboard_interval'] = absint( $options['heartbeat_dashboard_interval'] );
376 $sanitized_options['heartbeat_editor_interval'] = absint( $options['heartbeat_editor_interval'] );
377 $sanitized_options['heartbeat_frontend_interval'] = absint( $options['heartbeat_frontend_interval'] );
378 $sanitized_options['enable_varnish'] = ! empty( $options['enable_varnish'] );
379 $sanitized_options['varnish_ip'] = sanitize_text_field( $options['varnish_ip'] );
380 $sanitized_options['cache_footprint'] = ! empty( $options['cache_footprint'] );
381 $sanitized_options['enable_google_tracking'] = ! empty( $options['enable_google_tracking'] );
382 $sanitized_options['enable_fb_tracking'] = ! empty( $options['enable_fb_tracking'] );
383
384 if ( isset( $options['critical_css_appended_content'] ) ) {
385 $sanitized_options['critical_css_appended_content'] = sanitize_css( $options['critical_css_appended_content'] );
386 }
387
388 if ( isset( $options['critical_css_fallback'] ) ) {
389 $sanitized_options['critical_css_fallback'] = sanitize_css( $options['critical_css_fallback'] );
390 }
391
392 /**
393 * Filters sanitized options.
394 *
395 * @hook powered_cache_sanitized_options
396 *
397 * @param {array} $sanitized_options Sanitized options.
398 * @param {array} $options raw input.
399 *
400 * @return {array} New value.
401 *
402 * @since 2.0
403 */
404 return apply_filters( 'powered_cache_sanitized_options', $sanitized_options, $options );
405 }
406
407 /**
408 * Add base admin bar menu
409 *
410 * @param object $wp_admin_bar Admin bar object
411 *
412 * @since 2.0
413 */
414 function admin_bar_menu( $wp_admin_bar ) {
415 $href = admin_url( 'admin.php?page=powered-cache' );
416
417 if ( POWERED_CACHE_IS_NETWORK && current_user_can( 'manage_network' ) ) {
418 $href = network_admin_url( 'admin.php?page=powered-cache' );
419 }
420
421 if ( POWERED_CACHE_IS_NETWORK && ! current_user_can( 'manage_network' ) ) {
422 $href = '#';
423 }
424
425 if ( current_user_can( 'manage_options' ) ) {
426 $wp_admin_bar->add_menu(
427 array(
428 'id' => MENU_SLUG,
429 'title' => __( 'Powered Cache', 'powered-cache' ),
430 'href' => $href,
431 )
432 );
433 }
434 }
435
436 /**
437 * Maybe display feedback messages when certain action is taken
438 *
439 * @since 2.0
440 */
441 function maybe_display_message() {
442 // phpcs:disable WordPress.Security.NonceVerification.Recommended
443 if ( ! isset( $_GET['pc_action'] ) ) {
444 return;
445 }
446
447 /**
448 * Dont display multiple message when saving the options while having the query_params
449 */
450 if ( ! empty( $_POST ) ) {
451 return;
452 }
453
454 $screen = get_current_screen();
455
456 $success_messages = [
457 'flush_page_cache_network' => esc_html__( 'Page cache deleted for all websites!', 'powered-cache' ),
458 'flush_page_cache' => esc_html__( 'Page cache deleted successfully!', 'powered-cache' ),
459 'flush_object_cache' => esc_html__( 'Object cache deleted successfully!', 'powered-cache' ),
460 'flush_all_cache' => esc_html__( 'All cached items flushed successfully!', 'powered-cache' ),
461 'start_preload' => esc_html__( 'The cache preloading has been initialized!', 'powered-cache' ),
462 'generate_critical' => esc_html__( 'The Critical CSS generation process has been initialized!', 'powered-cache' ),
463 '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' ),
464 'flush_cf_cache' => esc_html__( 'Cloudflare cache flushed, it can take up to 30 seconds to delete all cache from Cloudflare!', 'powered-cache' ),
465 'reset_settings' => esc_html__( 'Settings have been reset!', 'powered-cache' ),
466 'import_settings' => esc_html__( 'Settings have been imported!', 'powered-cache' ),
467 'save_settings_and_optimize' => esc_html__( 'Settings saved and database being optimized...', 'powered-cache' ),
468 'save_settings' => esc_html__( 'Settings saved.', 'powered-cache' ),
469 ];
470
471 $err_messages = [
472 'generic_permission_err' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
473 'flush_page_cache_network_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
474 'flush_page_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
475 'flush_object_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
476 'flush_all_cache_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
477 'start_preload_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
478 'start_critical_err_permission' => esc_html__( 'You don\'t have permission to perform this action!', 'powered-cache' ),
479 'start_critical_err_license' => esc_html__( 'Your license key does not seem valid. A valid license is required for the Critical CSS!', 'powered-cache' ),
480 'flush_cf_cache_failed' => esc_html__( 'Could not flush Cloudflare cache. Please make sure you entered the correct credentials and zone id!', 'powered-cache' ),
481 ];
482
483 if ( isset( $success_messages[ $_GET['pc_action'] ] ) ) {
484 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
485 add_settings_error( $screen->parent_file, MENU_SLUG, $success_messages[ $_GET['pc_action'] ], 'success' );
486
487 return;
488 }
489
490 printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', $success_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
491 }
492
493 if ( isset( $err_messages[ $_GET['pc_action'] ] ) ) {
494 if ( MENU_SLUG === $screen->parent_base ) { // display with shared-ui on plugin page
495 add_settings_error( $screen->parent_file, MENU_SLUG, $err_messages[ $_GET['pc_action'] ], 'error' );
496
497 return;
498 }
499
500 printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', $err_messages[ $_GET['pc_action'] ] ); // phpcs:ignore
501 }
502 // phpcs:enable WordPress.Security.NonceVerification.Recommended
503 }
504
505
506 /**
507 * Adds `Purge All Cache` menu bar item
508 *
509 * @param object $wp_admin_bar Admin bar object
510 *
511 * @since 1.1
512 */
513 function purge_all_admin_bar_menu( $wp_admin_bar ) {
514 // Only available for the network admins on multisite.
515 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
516 return;
517 }
518
519 $wp_admin_bar->add_menu(
520 array(
521 'id' => 'all-cache-purge',
522 'title' => __( 'Purge All Cache', 'powered-cache' ),
523 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=powered_cache_purge_all_cache' ), 'powered_cache_purge_all_cache' ),
524 'parent' => 'powered-cache',
525 )
526 );
527 }
528
529 /**
530 * Purges all cache related things
531 *
532 * @since 1.1
533 */
534 function purge_all_cache() {
535
536 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_purge_all_cache' ) ) {
537 wp_nonce_ays( '' );
538 }
539
540 if ( is_multisite() && ! current_user_can( 'manage_network' ) ) {
541 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
542 wp_safe_redirect( esc_url_raw( $redirect_url ) );
543 exit;
544 }
545
546 if ( ! current_user_can( 'manage_options' ) ) {
547 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache_err_permission', wp_get_referer() );
548 wp_safe_redirect( esc_url_raw( $redirect_url ) );
549 exit;
550 }
551
552 powered_cache_flush();// cleans object cache + page cache dir
553
554 /**
555 * Fires after purging all cache
556 *
557 * @hook powered_cache_purge_all_cache
558 *
559 * @since 1.1
560 */
561 do_action( 'powered_cache_purge_all_cache' );
562
563 $redirect_url = add_query_arg( 'pc_action', 'flush_all_cache', wp_get_referer() );
564
565 wp_safe_redirect( esc_url_raw( $redirect_url ) );
566 exit;
567 }
568
569
570 /**
571 * Downloads proper configuration file
572 *
573 * @since 1.1
574 */
575 function download_rewrite_config() {
576 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'powered_cache_download_rewrite' ) ) {
577 wp_nonce_ays( '' );
578 }
579
580 if ( ! can_control_all_settings() ) {
581 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
582 wp_safe_redirect( esc_url_raw( $redirect_url ) );
583 exit;
584 }
585
586 $server = $_GET['server'];
587 Config::factory()->download_rewrite_rules( $server );
588
589 wp_safe_redirect( wp_get_referer() );
590 die();
591 }
592
593 /**
594 * Run DB optimization
595 *
596 * @param array $options plugin settings
597 */
598 function db_optimize( $options ) {
599 $powered_cache_db_optimizer = DatabaseOptimizer::factory();
600
601 $supported_options = $powered_cache_db_optimizer->get_supported_options();
602
603 if ( POWERED_CACHE_IS_NETWORK ) {
604 $sites = get_sites();
605 foreach ( $sites as $site ) {
606 switch_to_blog( $site->blog_id );
607 foreach ( $supported_options as $optimization_item ) {
608 if ( $options[ $optimization_item ] ) {
609 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
610 }
611 }
612
613 $powered_cache_db_optimizer->save()->dispatch();
614 restore_current_blog();
615 }
616 } else {
617 foreach ( $supported_options as $optimization_item ) {
618 if ( $options[ $optimization_item ] ) {
619 $powered_cache_db_optimizer->push_to_queue( $optimization_item );
620 }
621 }
622
623 $powered_cache_db_optimizer->save()->dispatch();
624 }
625
626 }
627
628 /**
629 * Cancel preloading process on toggling preload option
630 */
631 function cancel_preloading() {
632 \PoweredCache\Utils\log( 'Cancel preload process' );
633 $cache_preloader = CachePreloader::factory();
634 $cache_preloader->cancel_process();
635 }
636
637
638 /**
639 * Perform diagnostic checks
640 */
641 function run_diagnostic() {
642 global $is_apache;
643
644 $nonce = $_POST['nonce'];
645
646 if ( wp_verify_nonce( $nonce, 'powered_cache_run_diagnostic' ) ) {
647 $settings = \PoweredCache\Utils\get_settings();
648 $checks = array();
649
650 // check config file
651 $config_file = Config::factory()->find_wp_config_file();
652 $config_file_status = is_writeable( $config_file );
653
654 if ( $config_file_status ) {
655 $config_file_desc = esc_html__( 'wp-config.php is writable.', 'powered-cache' );
656 } else {
657 $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>' );
658 }
659
660 $checks[] = array(
661 'check' => 'config',
662 'status' => $config_file_status,
663 'description' => $config_file_desc,
664 );
665
666 // check cache directory
667 $cache_dir = get_cache_dir();
668 $cache_dir_status = false;
669 if ( ! file_exists( $cache_dir ) ) {
670 $cache_dir_desc = sprintf( __( 'Cache directory %s is not exist!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
671 } elseif ( ! is_writeable( $cache_dir ) ) {
672 $cache_dir_desc = sprintf( __( 'Cache directory %s is not writeable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
673 } else {
674 $cache_dir_status = true;
675 $cache_dir_desc = sprintf( __( 'Cache directory %s exist and writable!', 'powered-cache' ), '<code>' . $cache_dir . '</code>' );
676 }
677
678 $checks[] = array(
679 'check' => 'cache-dir',
680 'status' => $cache_dir_status,
681 'description' => $cache_dir_desc,
682 );
683
684 // check .htaccess file
685 if ( $is_apache && $settings['auto_configure_htaccess'] ) {
686 $htaccess_file = get_home_path() . '.htaccess';
687 $htaccess_file_status = false;
688 if ( ! file_exists( $htaccess_file ) ) {
689 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not exist!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
690 } elseif ( ! is_writeable( $htaccess_file ) ) {
691 $htaccess_file_desc = sprintf( __( '.htaccess file %s is not writeable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
692 } else {
693 $htaccess_file_status = true;
694 $htaccess_file_desc = sprintf( __( '.htaccess file %s exist and writable!', 'powered-cache' ), '<code>' . $htaccess_file . '</code>' );
695 }
696
697 $checks[] = array(
698 'check' => 'htaccess',
699 'status' => $htaccess_file_status,
700 'description' => $htaccess_file_desc,
701 );
702 }
703
704 // check page cache
705 if ( $settings['enable_page_cache'] ) {
706 $advanced_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/advanced-cache.php';
707 $advanced_cache_file_status = false;
708 if ( ! file_exists( $advanced_cache_file ) ) {
709 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not exist!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
710 } elseif ( ! is_writeable( $advanced_cache_file ) ) {
711 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s is not writeable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
712 } else {
713 $advanced_cache_file_status = true;
714 $advanced_cache_file_desc = sprintf( __( 'Required file for the page caching %s exist and writable!', 'powered-cache' ), '<code>' . $advanced_cache_file . '</code>' );
715 }
716
717 $checks[] = array(
718 'check' => 'advanced-cache',
719 'status' => $advanced_cache_file_status,
720 'description' => $advanced_cache_file_desc,
721 );
722 }
723
724 // check object cache
725 if ( 'off' !== $settings['object_cache'] ) {
726 $object_cache_file = untrailingslashit( WP_CONTENT_DIR ) . '/object-cache.php';
727 $object_cache_file_status = false;
728 if ( ! file_exists( $object_cache_file ) ) {
729 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not exist!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
730 } elseif ( ! is_writeable( $object_cache_file ) ) {
731 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s is not writeable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
732 } else {
733 $object_cache_file_status = true;
734 $object_cache_file_desc = sprintf( __( 'Required file for the object caching %s exist and writable!', 'powered-cache' ), '<code>' . $object_cache_file . '</code>' );
735 }
736
737 $checks[] = array(
738 'check' => 'object-cache',
739 'status' => $object_cache_file_status,
740 'description' => $object_cache_file_desc,
741 );
742 }
743
744 wp_send_json_success( $checks );
745 }
746
747 wp_send_json_error( [ esc_html__( 'Invalid request', 'powered-cache' ) ] );
748 }
749
750
751 /**
752 * Deactivate incompatible plugins
753 *
754 * @since 1.0
755 */
756 function deactivate_plugin() {
757 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'deactivate_plugin' ) ) {
758 wp_nonce_ays( '' );
759 }
760
761 if ( ! current_user_can( 'activate_plugins' ) ) {
762 $redirect_url = add_query_arg( 'pc_action', 'generic_permission_err', wp_get_referer() );
763 wp_safe_redirect( esc_url_raw( $redirect_url ) );
764 exit;
765 }
766
767 deactivate_plugins( $_GET['plugin'] );
768
769 wp_safe_redirect( wp_get_referer() );
770 die();
771 }
772
773 /**
774 * Adds settings link to plugin actions
775 *
776 * @param array $actions Plugin actions.
777 *
778 * @return array
779 * @since 1.0
780 */
781 function action_links( $actions ) {
782
783 $settings_url = POWERED_CACHE_IS_NETWORK ? network_admin_url( 'admin.php?page=powered-cache' ) : admin_url( 'admin.php?page=powered-cache' );
784 $powered_cache_url = 'https://poweredcache.com/?utm_source=wp_admin&utm_medium=plugin&utm_campaign=plugin_action_links';
785
786 $actions['powered_settings'] = sprintf( '<a href="%s">%s</a>', esc_url( $settings_url ), esc_html__( 'Settings', 'powered-cache' ) );
787
788 if ( ! is_premium() ) {
789 $actions['get_premium'] = sprintf( '<a href="%s" style="color: red;">%s</a>', esc_url( $powered_cache_url ), esc_html__( 'Get Premium', 'powered-cache' ) );
790 }
791
792 return array_reverse( $actions );
793 }
794