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 +141 -98 4.5.2 → 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,52 @@
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;
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;
224 + }
225 + wpo_cache_add_footer_output(sprintf("Page not served from cache %s", $not_cached_details));
226 + }
227 + }
211 228
212 - if (!empty($no_cache_because)) {
213 - do_action('wpo_page_not_cached', $no_cache_because);
229 + /**
230 + * Handle cache settings update
231 + *
232 + * @param array $new_settings
233 + * @return void
234 + */
235 + public function cache_settings_updated($new_settings) {
214 236
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);
237 + $this->unschedule_purge_old_cache();
219 238
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));
227 - }
228 -
229 - return false;
239 + if ($new_settings['enable_page_caching']) {
240 + $this->schedule_purge_old_cache();
230 241 }
231 -
232 - return true;
233 242 }
234 243
235 244 /**
236 245 * Activate cron job when the cache is enabled for deleting expired cache files
@@ -235,23 +244,42 @@
235 244 /**
236 245 * Activate cron job when the cache is enabled for deleting expired cache files
237 246 */
238 247 public function cron_activate() {
239 - $page_cache_length = $this->config->get_option('page_cache_length');
240 248 if ($this->is_enabled()) {
241 - if (!wp_next_scheduled('wpo_purge_old_cache')) {
242 - wp_schedule_event(time() + (false === $page_cache_length ? '86400' : $page_cache_length), 'wpo_purge_old_cache', 'wpo_purge_old_cache');
243 - }
244 - if (!wp_next_scheduled('wpo_prune_cache_logs')) {
245 - wp_schedule_event(time(), 'weekly', 'wpo_prune_cache_logs');
246 - }
249 + $this->schedule_purge_old_cache();
247 250 } else {
248 - wp_clear_scheduled_hook('wpo_purge_old_cache');
249 - wp_clear_scheduled_hook('wpo_prune_cache_logs');
251 + $this->unschedule_purge_old_cache();
250 252 }
251 253 }
252 254
253 255 /**
256 + * Schedules events to purge old cache
257 + *
258 + * @return void
259 + */
260 + private function schedule_purge_old_cache() {
261 + $page_cache_length = $this->config->get_option('page_cache_length');
262 +
263 + if (!wp_next_scheduled('wpo_purge_old_cache')) {
264 + wp_schedule_event(time() + (false === $page_cache_length ? 86400 : $page_cache_length), 'wpo_purge_old_cache', 'wpo_purge_old_cache');
265 + }
266 + if (!wp_next_scheduled('wpo_prune_cache_logs')) {
267 + wp_schedule_event(time(), 'weekly', 'wpo_prune_cache_logs');
268 + }
269 + }
270 +
271 + /**
272 + * Unschedules events to purge old cache
273 + *
274 + * @return void
275 + */
276 + private function unschedule_purge_old_cache() {
277 + wp_clear_scheduled_hook('wpo_purge_old_cache');
278 + wp_clear_scheduled_hook('wpo_prune_cache_logs');
279 + }
280 +
281 + /**
254 282 * Do required actions on activate/deactivate any plugin.
255 283 */
256 284 public function activate_deactivate_plugin() {
257 285
@@ -270,15 +298,10 @@
270 298 * @return bool
271 299 */
272 300 public function can_purge_cache() {
273 301 if (!$this->is_enabled()) return false;
274 - $required_capability = is_multisite() ? 'manage_network_options' : 'manage_options';
275 302
276 - if (WP_Optimize::is_premium()) {
277 - return current_user_can($required_capability) || WP_Optimize_Premium()->can_purge_the_cache();
278 - } else {
279 - return current_user_can($required_capability);
280 - }
303 + return WP_Optimize_Utils::current_user_can_purge_cache();
281 304 }
282 305
283 306 /**
284 307 * Add Purge from cache in admin bar.
@@ -289,9 +312,9 @@
289 312 public function admin_bar_purge_cache($menu_items) {
290 313 global $pagenow;
291 314 if (!$this->can_purge_cache()) return $menu_items;
292 315
293 - $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();
294 317
295 318 $cache_size = $this->get_cache_size();
296 319 $cache_size_info = '<h4>'.__('Page cache', 'wp-optimize').'</h4>';
297 320 // translators: %d is the number of files in the cache
@@ -342,16 +365,29 @@
342 365 if (isset($_GET['wpo_single_page_cache_purged']) || isset($_GET['wpo_all_pages_cache_purged'])) {
343 366 // phpcs:disable
344 367 // We are not using $_GET values, just checks if the variable is set and then use hard coded string
345 368 if (isset($_GET['wpo_single_page_cache_purged'])) {
346 - $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';
347 371 } else {
348 - $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';
349 374 }
350 375 // phpcs:enable
351 376
352 - add_action('admin_notices', array($this, $notice_function));
377 + if (is_admin()) {
378 + $admin_notices_hook = is_network_admin() ? 'network_admin_notices' : 'admin_notices';
353 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 +
354 390 return;
355 391 }
356 392
357 393 if (!isset($_GET['_wpo_purge'])) return;
@@ -370,10 +406,13 @@
370 406 $success = self::delete_cache_by_url($url);
371 407 if ($success) $this->file_log("Cache for URL: " . self::remove_query_params($url) . " has been purged, triggered by: " . __METHOD__);
372 408 }
373 409
374 - // remove nonce from url and reload page.
375 - 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);
376 415 exit;
377 416
378 417 } elseif (wp_verify_nonce(sanitize_key($_GET['_wpo_purge']), 'wpo_purge_all_pages_cache')) {
379 418 $success = self::purge();
@@ -379,10 +418,13 @@
379 418 $success = self::purge();
380 419 $this->maybe_set_preload_cron_job();
381 420 if ($success) $this->file_log("Full Cache Purge triggered by: ". __METHOD__);
382 421
383 - // remove nonce from url and reload page.
384 - 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);
385 427 exit;
386 428 }
387 429 }
388 430
@@ -402,38 +444,10 @@
402 444 wp_schedule_single_event(time() + 30, 'wpo_page_cache_run_preload');
403 445 }
404 446 }
405 447 }
406 -
448 +
407 449 /**
408 - * Show notification when page cache purged successfully.
409 - */
410 - public function notice_purge_single_page_cache_success() {
411 - $this->show_notice(__('The page cache was successfully purged.', 'wp-optimize'), 'success');
412 - }
413 -
414 - /**
415 - * Show notification when page cache wasn't purged.
416 - */
417 - public function notice_purge_single_page_cache_error() {
418 - $this->show_notice(__('The page cache was not purged.', 'wp-optimize'), 'error');
419 - }
420 -
421 - /**
422 - * Show notification when all pages cache purged successfully.
423 - */
424 - public function notice_purge_all_pages_cache_success() {
425 - $this->show_notice(__('The page cache was successfully purged.', 'wp-optimize'), 'success');
426 - }
427 -
428 - /**
429 - * Show notification when all pages cache wasn't purged.
430 - */
431 - public function notice_purge_all_pages_cache_error() {
432 - $this->show_notice(__('The page cache was not purged.', 'wp-optimize'), 'error');
433 - }
434 -
435 - /**
436 450 * Show notification in WordPress admin.
437 451 *
438 452 * @param string $message HTML (no further escaping is performed)
439 453 * @param string $type error, warning, success, or info
@@ -540,11 +554,12 @@
540 554
541 555 /**
542 556 * Disables page cache
543 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.
544 559 * @return bool|WP_Error - true on success or WP_Error on failure.
545 560 */
546 - public function disable() {
561 + public function disable($keep_option_enabled = false) {
547 562 global $is_apache;
548 563
549 564 $ret = true;
550 565
@@ -586,11 +601,18 @@
586 601 wp_clear_scheduled_hook('wpo_purge_old_cache');
587 602
588 603 if (!is_wp_error($ret)) {
589 604 wp_clear_scheduled_hook('wpo_prune_cache_logs');
590 - $ret = $this->update_page_cache_enabled_state(false);
605 +
606 + if (!$keep_option_enabled) {
607 + $ret = $this->update_page_cache_enabled_state(false);
608 + }
591 609 }
592 610
611 + if (!is_wp_error($ret)) {
612 + do_action('wpo_page_cache_disabled');
613 + }
614 +
593 615 return $ret;
594 616 }
595 617
596 618 /**
@@ -609,8 +631,9 @@
609 631 return true;
610 632 }
611 633
612 634 $cache_config['enable_page_caching'] = $enabled;
635 +
613 636 return $config->update($cache_config, true);
614 637 }
615 638
616 639 /**
@@ -715,36 +738,40 @@
715 738 return true;
716 739 }
717 740
718 741 /**
719 - * Check if cache is enabled and working
742 + * Checks whether page caching is turned on in settings.
720 743 *
721 - * @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.
722 745 */
723 746 public function is_enabled() {
747 + return $this->config->get_option('enable_page_caching') && $this->is_environment_functional();
748 + }
724 749
725 - 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);
726 759
727 - if (!defined('WP_CACHE') || !WP_CACHE) {
728 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
729 - $this->log("WP_CACHE constant is not present in wp-config.php");
730 - return false;
731 - }
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;
732 763 }
733 764
734 - if (!defined('WPO_ADVANCED_CACHE') || !WPO_ADVANCED_CACHE) {
735 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
736 - $this->log("WPO_ADVANCED_CACHE constant is not present in advanced-cache.php");
737 - return false;
738 - }
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;
739 768 }
740 769
741 770 $config_file = WPO_CACHE_CONFIG_DIR . '/'.$this->config->get_cache_config_filename();
742 - if (!file_exists($config_file)) {
743 - if ((!(defined('WP_CLI') && WP_CLI)) && (!defined('DOING_AJAX') || !DOING_AJAX)) {
744 - $this->log("Cache config file $config_file is not present");
745 - return false;
746 - }
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;
747 774 }
748 775
749 776 return true;
750 777 }
@@ -1012,8 +1039,13 @@
1012 1039 if (!$config_path) {
1013 1040 return false;
1014 1041 }
1015 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 +
1016 1048 $config_file_string = file_get_contents($config_path);
1017 1049
1018 1050 // Config file is empty. Maybe couldn't read it?
1019 1051 if (empty($config_file_string)) {
@@ -1142,8 +1174,17 @@
1142 1174 delete_site_transient('wpo_get_cache_size');
1143 1175 }
1144 1176
1145 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 + /**
1146 1187 * Get current cache size.
1147 1188 *
1148 1189 * @return array
1149 1190 */
@@ -1252,8 +1293,10 @@
1252 1293 $preloader = WP_Optimize_Page_Cache_Preloader::instance();
1253 1294 $preloader->add_url_to_preload_list($url);
1254 1295 $url_task_creator = array($preloader, 'create_tasks_for_auto_preload_urls');
1255 1296
1297 + $preloader->maybe_dont_close_browser_connection();
1298 +
1256 1299 if (!has_action('shutdown', $url_task_creator)) {
1257 1300 add_action('shutdown', $url_task_creator);
1258 1301 }
1259 1302 }
@@ -1402,9 +1445,9 @@
1402 1445 * @return void
1403 1446 */
1404 1447 public function admin_init() {
1405 1448 // Maybe update the advanced cache.
1406 - 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')) {
1407 1450 $this->maybe_update_advanced_cache();
1408 1451 $this->cron_activate();
1409 1452 }
1410 1453 }