PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | cache/class-wpo-page-cache.php +100 -91 4.5.4 → 4.7.0 View file →
@@ -128,8 +128,9 @@
128 128 * Regenerate config file on cache flush.
129 129 */
130 130 add_action('wpo_cache_flush', array($this, 'update_cache_config'));
131 131 add_action('wpo_cache_flush', array($this, 'delete_cache_size_information'));
132 + add_action('wpo_cache_flush', array($this, 'update_cache_cleared_time'));
132 133 add_action('update_option_permalink_structure', array($this, 'update_option_permalink_structure'), 10, 3);
133 134
134 135 // Add purge cache link to admin bar.
135 136 add_filter('wpo_cache_admin_bar_menu_items', array($this, 'admin_bar_purge_cache'), 20, 1);
@@ -193,44 +194,37 @@
193 194 *
194 195 * This method checks cache rules to identify if caching is possible.
195 196 * If caching is not allowed, it adds appropriate HTTP headers and debug messages.
196 197 *
197 - * @return bool True if the page should be cached, false otherwise.
198 + * @return bool|array True if the page should be cached, false otherwise or not empty array with the reasons why the page isn't cached
198 199 */
199 200 public function should_cache_page() {
200 201
201 202 if (!$this->is_enabled()) return false;
202 203
203 - $no_cache_because = array();
204 + return wpo_can_serve_from_cache();
205 + }
204 206
205 - // Check serve cache rules, to identify if we need to cache the page.
206 - $can_serve_from_cache = wpo_can_serve_from_cache();
207 -
208 - if (false === $can_serve_from_cache) return false;
207 + /**
208 + * Maybe add information about why the page is not cached to the headers and footer output
209 + *
210 + * @param array $no_cache_because
211 + * @return void
212 + */
213 + public function maybe_add_no_cache_because_info($no_cache_because) {
214 + // Add http header
215 + if (!wp_doing_cron() && !empty($no_cache_because)) {
216 + $no_cache_because_message = join(", ", $no_cache_because);
217 + wpo_cache_add_nocache_http_header_with_send_headers_action($no_cache_because_message);
209 218
210 - if (is_array($can_serve_from_cache)) $no_cache_because = $can_serve_from_cache;
211 -
212 - if (!empty($no_cache_because)) {
213 - do_action('wpo_page_not_cached', $no_cache_because);
214 -
215 - // Add http header
216 - if (!wp_doing_cron()) {
217 - $no_cache_because_message = join(", ", $no_cache_because);
218 - wpo_cache_add_nocache_http_header_with_send_headers_action($no_cache_because_message);
219 -
220 - $not_cached_details = "";
221 -
222 - // Output the reason only when the user has turned on debugging
223 - if ((defined('WP_DEBUG') && WP_DEBUG) || !empty(TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('get', 'wpo_cache_debug'))) {
224 - $not_cached_details = "because: ".$no_cache_because_message;
225 - }
226 - wpo_cache_add_footer_output(sprintf("Page not served from cache %s", $not_cached_details));
219 + $not_cached_details = "";
220 +
221 + // Output the reason only when the user has turned on debugging
222 + if ((defined('WP_DEBUG') && WP_DEBUG) || !empty(TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('get', 'wpo_cache_debug'))) {
223 + $not_cached_details = "because: ".$no_cache_because_message;
227 224 }
228 -
229 - return false;
225 + wpo_cache_add_footer_output(sprintf("Page not served from cache %s", $not_cached_details));
230 226 }
231 -
232 - return true;
233 227 }
234 228
235 229 /**
236 230 * Handle cache settings update
@@ -304,15 +298,10 @@
304 298 * @return bool
305 299 */
306 300 public function can_purge_cache() {
307 301 if (!$this->is_enabled()) return false;
308 - $required_capability = is_multisite() ? 'manage_network_options' : 'manage_options';
309 302
310 - if (WP_Optimize::is_premium()) {
311 - return current_user_can($required_capability) || WP_Optimize_Premium()->can_purge_the_cache();
312 - } else {
313 - return current_user_can($required_capability);
314 - }
303 + return WP_Optimize_Utils::current_user_can_purge_cache();
315 304 }
316 305
317 306 /**
318 307 * Add Purge from cache in admin bar.
@@ -323,9 +312,9 @@
323 312 public function admin_bar_purge_cache($menu_items) {
324 313 global $pagenow;
325 314 if (!$this->can_purge_cache()) return $menu_items;
326 315
327 - $act_url = remove_query_arg(array('wpo_single_page_cache_purged', 'wpo_all_pages_cache_purged'));
316 + $act_url = WP_Optimize_Utils::get_url_without_cache_purge_params();
328 317
329 318 $cache_size = $this->get_cache_size();
330 319 $cache_size_info = '<h4>'.__('Page cache', 'wp-optimize').'</h4>';
331 320 // translators: %d is the number of files in the cache
@@ -376,16 +365,29 @@
376 365 if (isset($_GET['wpo_single_page_cache_purged']) || isset($_GET['wpo_all_pages_cache_purged'])) {
377 366 // phpcs:disable
378 367 // We are not using $_GET values, just checks if the variable is set and then use hard coded string
379 368 if (isset($_GET['wpo_single_page_cache_purged'])) {
380 - $notice_function = $_GET['wpo_single_page_cache_purged'] ? 'notice_purge_single_page_cache_success' : 'notice_purge_single_page_cache_error';
369 + $message = $_GET['wpo_single_page_cache_purged'] ? __('Cache purged for this page', 'wp-optimize') : __('Error purging cache for this page', 'wp-optimize');
370 + $type = $_GET['wpo_single_page_cache_purged'] ? 'success' : 'error';
381 371 } else {
382 - $notice_function = $_GET['wpo_all_pages_cache_purged'] ? 'notice_purge_all_pages_cache_success' : 'notice_purge_all_pages_cache_error';
372 + $message = $_GET['wpo_all_pages_cache_purged'] ? __('Cache purged for all pages', 'wp-optimize') : __('Error purging cache for all pages', 'wp-optimize');
373 + $type = $_GET['wpo_all_pages_cache_purged'] ? 'success' : 'error';
383 374 }
384 375 // phpcs:enable
385 376
386 - add_action('admin_notices', array($this, $notice_function));
377 + if (is_admin()) {
378 + $admin_notices_hook = is_network_admin() ? 'network_admin_notices' : 'admin_notices';
387 379
380 + add_action($admin_notices_hook, function() use ($message, $type) {
381 + $this->show_notice($message, $type);
382 + });
383 +
384 + add_action('admin_head', array('WP_Optimize_Utils', 'script_to_remove_cache_purge_params_from_url'));
385 + } else {
386 + printf('<script>window.onload = function() {alert("%s");}</script>', esc_js($message));
387 + WP_Optimize_Utils::script_to_remove_cache_purge_params_from_url();
388 + }
389 +
388 390 return;
389 391 }
390 392
391 393 if (!isset($_GET['_wpo_purge'])) return;
@@ -404,10 +406,13 @@
404 406 $success = self::delete_cache_by_url($url);
405 407 if ($success) $this->file_log("Cache for URL: " . self::remove_query_params($url) . " has been purged, triggered by: " . __METHOD__);
406 408 }
407 409
408 - // remove nonce from url and reload page.
409 - wp_redirect(add_query_arg('wpo_single_page_cache_purged', $success, remove_query_arg('_wpo_purge')));
410 + // Remove all existing purge-related parameters and add the new one
411 + $redirect_url = WP_Optimize_Utils::get_url_without_cache_purge_params();
412 + $redirect_url = add_query_arg('wpo_single_page_cache_purged', $success, $redirect_url);
413 +
414 + wp_redirect($redirect_url);
410 415 exit;
411 416
412 417 } elseif (wp_verify_nonce(sanitize_key($_GET['_wpo_purge']), 'wpo_purge_all_pages_cache')) {
413 418 $success = self::purge();
@@ -413,10 +418,13 @@
413 418 $success = self::purge();
414 419 $this->maybe_set_preload_cron_job();
415 420 if ($success) $this->file_log("Full Cache Purge triggered by: ". __METHOD__);
416 421
417 - // remove nonce from url and reload page.
418 - wp_redirect(add_query_arg('wpo_all_pages_cache_purged', $success, remove_query_arg('_wpo_purge')));
422 + // Remove all existing purge-related parameters and add the new one
423 + $redirect_url = WP_Optimize_Utils::get_url_without_cache_purge_params();
424 + $redirect_url = add_query_arg('wpo_all_pages_cache_purged', $success, $redirect_url);
425 +
426 + wp_redirect($redirect_url);
419 427 exit;
420 428 }
421 429 }
422 430
@@ -436,38 +444,10 @@
436 444 wp_schedule_single_event(time() + 30, 'wpo_page_cache_run_preload');
437 445 }
438 446 }
439 447 }
440 -
448 +
441 449 /**
442 - * Show notification when page cache purged successfully.
443 - */
444 - public function notice_purge_single_page_cache_success() {
445 - $this->show_notice(__('The page cache was successfully purged.', 'wp-optimize'), 'success');
446 - }
447 -
448 - /**
449 - * Show notification when page cache wasn't purged.
450 - */
451 - public function notice_purge_single_page_cache_error() {
452 - $this->show_notice(__('The page cache was not purged.', 'wp-optimize'), 'error');
453 - }
454 -
455 - /**
456 - * Show notification when all pages cache purged successfully.
457 - */
458 - public function notice_purge_all_pages_cache_success() {
459 - $this->show_notice(__('The page cache was successfully purged.', 'wp-optimize'), 'success');
460 - }
461 -
462 - /**
463 - * Show notification when all pages cache wasn't purged.
464 - */
465 - public function notice_purge_all_pages_cache_error() {
466 - $this->show_notice(__('The page cache was not purged.', 'wp-optimize'), 'error');
467 - }
468 -
469 - /**
470 450 * Show notification in WordPress admin.
471 451 *
472 452 * @param string $message HTML (no further escaping is performed)
473 453 * @param string $type error, warning, success, or info
@@ -574,11 +554,12 @@
574 554
575 555 /**
576 556 * Disables page cache
577 557 *
558 + * @param bool $keep_option_enabled - Whether to keep the option `enable_page_caching` enabled or not. This is useful when we want to disable the cache temporarily, e.g. when deactivating the plugin, but we want to keep the option enabled so that it can be re-enabled when the plugin is reactivated.
578 559 * @return bool|WP_Error - true on success or WP_Error on failure.
579 560 */
580 - public function disable() {
561 + public function disable($keep_option_enabled = false) {
581 562 global $is_apache;
582 563
583 564 $ret = true;
584 565
@@ -620,11 +601,18 @@
620 601 wp_clear_scheduled_hook('wpo_purge_old_cache');
621 602
622 603 if (!is_wp_error($ret)) {
623 604 wp_clear_scheduled_hook('wpo_prune_cache_logs');
624 - $ret = $this->update_page_cache_enabled_state(false);
605 +
606 + if (!$keep_option_enabled) {
607 + $ret = $this->update_page_cache_enabled_state(false);
608 + }
625 609 }
626 610
611 + if (!is_wp_error($ret)) {
612 + do_action('wpo_page_cache_disabled');
613 + }
614 +
627 615 return $ret;
628 616 }
629 617
630 618 /**
@@ -643,8 +631,9 @@
643 631 return true;
644 632 }
645 633
646 634 $cache_config['enable_page_caching'] = $enabled;
635 +
647 636 return $config->update($cache_config, true);
648 637 }
649 638
650 639 /**
@@ -749,36 +738,40 @@
749 738 return true;
750 739 }
751 740
752 741 /**
753 - * Check if cache is enabled and working
742 + * Checks whether page caching is turned on in settings.
754 743 *
755 - * @return bool - true on success, false otherwise
744 + * @return bool true if the `enable_page_caching` option is set & environment is ready to cache, false otherwise.
756 745 */
757 746 public function is_enabled() {
747 + return $this->config->get_option('enable_page_caching') && $this->is_environment_functional();
748 + }
758 749
759 - if (!$this->config->get_option('enable_page_caching')) return false;
750 + /**
751 + * Checks whether the cache delivery chain is actually intact and able to serve cached pages.
752 + *
753 + * Verifies the WP_CACHE and WPO_ADVANCED_CACHE constants are defined and true, and that the cache config file exists on disk.
754 + *
755 + * @return bool True if the delivery chain is functional, false otherwise.
756 + */
757 + private function is_environment_functional() {
758 + $is_cli_or_ajax = (defined('WP_CLI') && WP_CLI) || (defined('DOING_AJAX') && DOING_AJAX);
760 759
761 - if (!defined('WP_CACHE') || !WP_CACHE) {
762 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
763 - $this->log("WP_CACHE constant is not present in wp-config.php");
764 - return false;
765 - }
760 + if (!$is_cli_or_ajax && (!defined('WP_CACHE') || !WP_CACHE)) {
761 + $this->file_log("WP_CACHE constant is not present in wp-config.php");
762 + return false;
766 763 }
767 764
768 - if (!defined('WPO_ADVANCED_CACHE') || !WPO_ADVANCED_CACHE) {
769 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
770 - $this->log("WPO_ADVANCED_CACHE constant is not present in advanced-cache.php");
771 - return false;
772 - }
765 + if (!$is_cli_or_ajax && (!defined('WPO_ADVANCED_CACHE') || !WPO_ADVANCED_CACHE)) {
766 + $this->file_log("WPO_ADVANCED_CACHE constant is not present in advanced-cache.php");
767 + return false;
773 768 }
774 769
775 770 $config_file = WPO_CACHE_CONFIG_DIR . '/'.$this->config->get_cache_config_filename();
776 - if (!file_exists($config_file)) {
777 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
778 - $this->log("Cache config file $config_file is not present");
779 - return false;
780 - }
771 + if (!$is_cli_or_ajax && !file_exists($config_file)) {
772 + $this->file_log("Cache config file $config_file is not present");
773 + return false;
781 774 }
782 775
783 776 return true;
784 777 }
@@ -1046,8 +1039,13 @@
1046 1039 if (!$config_path) {
1047 1040 return false;
1048 1041 }
1049 1042
1043 + // Bail early if wp-config.php is not writable, to avoid a PHP warning.
1044 + if (!wp_is_writable($config_path)) {
1045 + return false;
1046 + }
1047 +
1050 1048 $config_file_string = file_get_contents($config_path);
1051 1049
1052 1050 // Config file is empty. Maybe couldn't read it?
1053 1051 if (empty($config_file_string)) {
@@ -1176,8 +1174,17 @@
1176 1174 delete_site_transient('wpo_get_cache_size');
1177 1175 }
1178 1176
1179 1177 /**
1178 + * Update cache cleared time
1179 + */
1180 + public function update_cache_cleared_time(): void {
1181 + $config = $this->config->get();
1182 + $config['last_cleared'] = time();
1183 + $this->config->update($config);
1184 + }
1185 +
1186 + /**
1180 1187 * Get current cache size.
1181 1188 *
1182 1189 * @return array
1183 1190 */
@@ -1286,8 +1293,10 @@
1286 1293 $preloader = WP_Optimize_Page_Cache_Preloader::instance();
1287 1294 $preloader->add_url_to_preload_list($url);
1288 1295 $url_task_creator = array($preloader, 'create_tasks_for_auto_preload_urls');
1289 1296
1297 + $preloader->maybe_dont_close_browser_connection();
1298 +
1290 1299 if (!has_action('shutdown', $url_task_creator)) {
1291 1300 add_action('shutdown', $url_task_creator);
1292 1301 }
1293 1302 }
@@ -1436,9 +1445,9 @@
1436 1445 * @return void
1437 1446 */
1438 1447 public function admin_init() {
1439 1448 // Maybe update the advanced cache.
1440 - if ((!defined('DOING_AJAX') || !DOING_AJAX) && current_user_can('update_plugins')) {
1449 + if ((!defined('DOING_AJAX') || !DOING_AJAX) && WP_Optimize()->current_user_can('update_plugins')) {
1441 1450 $this->maybe_update_advanced_cache();
1442 1451 $this->cron_activate();
1443 1452 }
1444 1453 }