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-cache-rules.php +93 -18 3.2.20 → 4.7.0 View file →
@@ -21,9 +21,9 @@
21 21
22 22 /**
23 23 * Instance of this class
24 24 *
25 - * @var mixed
25 + * @var WPO_Cache_Rules | null
26 26 */
27 27 public static $instance;
28 28
29 29 public function __construct() {
@@ -47,12 +47,15 @@
47 47 add_action('import_start', array($this, 'remove_wp_insert_comment'));
48 48
49 49 add_action('update_option_page_on_front', array($this, 'purge_cache_on_homepage_change'));
50 50 add_action('update_option_page_for_posts', array($this, 'purge_cache_on_blog_page_change'), 10, 2);
51 + add_action('update_option_show_avatars', array($this, 'purge_cache_on_avatars_change'), 10, 2);
51 52
52 53 add_action('woocommerce_variation_set_stock', array($this, 'purge_product_page'), 10, 1);
53 54 add_action('woocommerce_product_set_stock', array($this, 'purge_product_page'), 10, 1);
54 55
56 + add_filter('wpo_page_cache_preloader_dont_close_browser_connection', array($this, 'preloader_dont_close_browser_connection'), 10, 1);
57 +
55 58 /**
56 59 * List of hooks for which when executed, the cache will be purged
57 60 *
58 61 * @param array $actions The actions
@@ -97,13 +100,14 @@
97 100 $post_id = $commentdata['comment_post_ID'];
98 101
99 102 WPO_Page_Cache::delete_single_post_cache($post_id);
100 103 WPO_Page_Cache::delete_comments_feed();
104 + WPO_Page_Cache::instance()->file_log("Cache for URL: {{URL}} has been purged, triggered by action: " . current_filter(), $post_id);
101 105 }
102 106 }
103 107
104 108 /**
105 - * Every time a comment's status changes, purge it's parent posts cache
109 + * Every time a comment's status changes, purge its parent posts cache
106 110 *
107 111 * @param int $comment_id Comment ID.
108 112 */
109 113 public function purge_post_on_comment_status_change($comment_id) {
@@ -111,8 +115,9 @@
111 115 $comment = get_comment($comment_id);
112 116 if (is_object($comment) && !empty($comment->comment_post_ID)) {
113 117 WPO_Page_Cache::delete_single_post_cache($comment->comment_post_ID);
114 118 WPO_Page_Cache::delete_comments_feed();
119 + WPO_Page_Cache::instance()->file_log("Cache for URL: {{URL}} has been purged, triggered by action: " . current_filter(), $comment->comment_post_ID);
115 120 }
116 121 }
117 122 }
118 123
@@ -132,14 +137,14 @@
132 137 * @param boolean $add_cookie
133 138 * @param WP_Comment $comment
134 139 * @return boolean
135 140 */
136 - $add_cookie = apply_filters('wpo_add_commented_post_cookie', '' == $comment->comment_type || 'comment' == $comment->comment_type, $comment);
141 + $add_cookie = apply_filters('wpo_add_commented_post_cookie', '' === $comment->comment_type || 'comment' === $comment->comment_type, $comment);
137 142 if (!$add_cookie) return;
138 143
139 144 $url = get_permalink($comment->comment_post_ID);
140 - $url_info = parse_url($url);
141 - setcookie('wpo_commented_post', 1, time() + WEEK_IN_SECONDS, isset($url_info['path']) ? $url_info['path'] : '/');
145 + $url_info = wp_parse_url($url);
146 + setcookie('wpo_commented_post', 1, time() + WEEK_IN_SECONDS, $url_info['path'] ?? '/');
142 147 }
143 148 }
144 149
145 150 /**
@@ -153,9 +158,9 @@
153 158 * Automatically purge all file based page cache on post changes
154 159 * We want the whole cache purged here as different parts
155 160 * of the site could potentially change on post updates
156 161 *
157 - * @param Integer $post_id - WP post id
162 + * @param int $post_id - WP post id
158 163 */
159 164 public function purge_post_on_update($post_id) {
160 165 $post_type = get_post_type($post_id);
161 166 $post_type_object = get_post_type_object($post_type);
@@ -162,8 +167,12 @@
162 167
163 168 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || null === $post_type_object || !$post_type_object->public) {
164 169 return;
165 170 }
171 + $post_status = get_post_status($post_id);
172 + if ('publish' !== $post_status) {
173 + return;
174 + }
166 175
167 176 /**
168 177 * Purge the whole cache if set to true, only the edited post otherwise. Default is false.
169 178 *
@@ -171,15 +180,14 @@
171 180 * @param integer $post_id The saved post ID
172 181 */
173 182 if (apply_filters('wpo_purge_all_cache_on_update', false, $post_id)) {
174 183 $this->purge_cache();
175 - return;
176 184 } else {
177 185 if (apply_filters('wpo_delete_cached_homepage_on_post_update', true, $post_id)) WPO_Page_Cache::delete_homepage_cache();
178 186 WPO_Page_Cache::delete_feed_cache();
179 187 WPO_Page_Cache::delete_single_post_cache($post_id);
180 - WPO_Page_Cache::delete_sitemap_cache();
181 188 WPO_Page_Cache::delete_post_feed_cache($post_id);
189 + WPO_Page_Cache::instance()->file_log("Cache for URL: {{URL}} has been purged, triggered by action: " . current_filter(), $post_id);
182 190 }
183 191 }
184 192
185 193 /**
@@ -199,24 +207,36 @@
199 207 $post_obj = get_post_type_object($post_type);
200 208
201 209 if (null === $post_obj) return;
202 210
203 - if ('post' == $post_type) {
211 + $post_status = get_post_status($post_id);
212 + if ('publish' !== $post_status) {
213 + return;
214 + }
215 +
216 + if ('post' === $post_type) {
204 217 // delete blog page cache
205 218 $blog_post_id = get_option('page_for_posts');
206 219 if ($blog_post_id) {
207 220 WPO_Page_Cache::delete_cache_by_url(get_permalink($blog_post_id), true);
221 + WPO_Page_Cache::instance()->file_log("Cache for blog post has been purged due to updates to post with Title: {{title}} and URL: {{URL}}, triggered by action: " . current_filter(), $post_id);
208 222 }
209 223
210 224 // delete next and previous posts cache.
211 - $globals_post = isset($GLOBALS['post']) ? $GLOBALS['post'] : false;
225 + $globals_post = $GLOBALS['post'] ?? false;
212 226 $GLOBALS['post'] = get_post($post_id);
213 227 $previous_post = function_exists('get_previous_post') ? get_previous_post() : false;
214 228 $next_post = function_exists('get_next_post') ? get_next_post() : false;
215 229 if ($globals_post) $GLOBALS['post'] = $globals_post;
216 230
217 - if ($previous_post) WPO_Page_Cache::delete_cache_by_url(get_permalink($previous_post), true);
218 - if ($next_post) WPO_Page_Cache::delete_cache_by_url(get_permalink($next_post), true);
231 + if ($previous_post) {
232 + WPO_Page_Cache::delete_cache_by_url(get_permalink($previous_post), true);
233 + WPO_Page_Cache::instance()->file_log("Cache for previous post (with URL: {{URL}}) adjacent to post with id: " . $post_id . " has been purged, triggered by action: " . current_filter(), $previous_post->ID);
234 + }
235 + if ($next_post) {
236 + WPO_Page_Cache::delete_cache_by_url(get_permalink($next_post), true);
237 + WPO_Page_Cache::instance()->file_log("Cache for next post (with URL: {{URL}}) adjacent to post with id: " . $post_id . " has been purged, triggered by action: " . current_filter(), $next_post->ID);
238 + }
219 239
220 240 // delete all archive pages for post.
221 241 $post_date = get_post_time('Y-m-j', false, $post_id);
222 242 list($year, $month, $day) = $post_date;
@@ -229,13 +249,26 @@
229 249
230 250 foreach ($archive_links as $link) {
231 251 WPO_Page_Cache::delete_cache_by_url($link, true);
232 252 }
233 - } elseif ($post_obj->has_archive) {
253 + WPO_Page_Cache::instance()->file_log("Cache for all archives page associated with post_type: " . $post_type . " and Title: {{title}} have been purged, triggered by action: " . current_filter(), $post_id);
254 + }
255 + if ($post_obj->has_archive) {
234 256 // delete archive page for custom post type.
235 257 WPO_Page_Cache::delete_cache_by_url(get_post_type_archive_link($post_type), true);
258 + WPO_Page_Cache::instance()->file_log("Cache for archive page associated with post_type: " . $post_type . " and Title: {{title}} has been purged, triggered by action: " . current_filter(), $post_id);
236 259 }
237 -
260 + if (post_type_supports($post_type, 'author')) {
261 + $author_id = get_post_field('post_author', $post_id);
262 + $post_author = get_user_by('id', $author_id);
263 + if ($author_id && $post_author) {
264 + $author_url = get_author_posts_url($author_id);
265 + if (!empty($author_url)) {
266 + WPO_Page_Cache::delete_cache_by_url($author_url, true);
267 + WPO_Page_Cache::instance()->file_log("Cache for author page URL: " . $author_url . " associated with post_type: " . $post_type . " and Title: {{title}} has been purged, triggered by action: " . current_filter(), $post_id);
268 + }
269 + }
270 + }
238 271 }
239 272
240 273 /**
241 274 * We use it with edit_terms action filter to purge cached elements related
@@ -252,8 +285,9 @@
252 285 if (is_array($term)) {
253 286 $term_permalink = get_term_link($term['term_id']);
254 287 if (!is_wp_error($term_permalink)) {
255 288 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
289 + WPO_Page_Cache::instance()->file_log("Cache for term page with URL: " . $term_permalink . " have been purged, triggered by action: " . current_filter());
256 290 }
257 291 }
258 292
259 293 // get posts which belongs to updated term.
@@ -260,9 +294,9 @@
260 294 $posts = get_posts(array(
261 295 'numberposts' => -1,
262 296 'post_type' => 'any',
263 297 'fields' => 'ids',
264 - 'tax_query' => array(
298 + 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- because we can't use `get_objects_in_term` for `OR` relationships
265 299 'relation' => 'OR',
266 300 array(
267 301 'taxonomy' => $taxonomy,
268 302 'field' => 'term_id',
@@ -274,8 +308,11 @@
274 308 if (!empty($posts)) {
275 309 foreach ($posts as $post_id) {
276 310 WPO_Page_Cache::delete_single_post_cache($post_id);
277 311 }
312 + $term_permalink = get_term_link($term_id);
313 + WPO_Page_Cache::instance()->file_log("Cache for associated posts for term with URL: "
314 + . $term_permalink. " have been purged, triggered by action: " . current_filter());
278 315 }
279 316 }
280 317
281 318 /**
@@ -298,9 +335,9 @@
298 335
299 336 /**
300 337 * Adds a way to exit the purge of terms permalink using the provided parameters.
301 338 *
302 - * @param bool $purge The value filtered, whether or not to purge the related elements
339 + * @param bool $purge The value filtered, whether to purge the related elements or not
303 340 * @param int $object_id Object ID.
304 341 * @param array $terms An array of object terms.
305 342 * @param array $tt_ids An array of term taxonomy IDs.
306 343 * @param string $taxonomy Taxonomy slug.
@@ -315,8 +352,9 @@
315 352 $affected_terms_ids = array_unique(array_merge($tt_ids, $old_tt_ids));
316 353
317 354 if (!empty($affected_terms_ids)) {
318 355 // walk through all changed terms and purge cached pages for them.
356 + $is_cache_purged = false;
319 357 foreach ($affected_terms_ids as $tt_id) {
320 358 $term = get_term($tt_id, $taxonomy, ARRAY_A);
321 359 if (!is_array($term)) continue;
322 360
@@ -321,14 +359,16 @@
321 359 if (!is_array($term)) continue;
322 360
323 361 $term_permalink = get_term_link($term['term_id']);
324 362 if (!is_wp_error($term_permalink)) {
325 - $url = parse_url($term_permalink);
363 + $url = wp_parse_url($term_permalink);
326 364 // Check if the permalink contains a valid path, to avoid deleting the whole cache.
327 365 if (!isset($url['path']) || '/' === $url['path']) return;
328 366 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
367 + $is_cache_purged = true;
329 368 }
330 369 }
370 + if ($is_cache_purged) WPO_Page_Cache::instance()->file_log("Cache for multiple term taxonomy have been purged due to post terms update, triggered by action: " . current_filter());
331 371 }
332 372 }
333 373
334 374 /**
@@ -336,8 +376,9 @@
336 376 */
337 377 public function purge_product_page($product_with_stock) {
338 378 if (!empty($product_with_stock->get_id())) {
339 379 WPO_Page_Cache::delete_single_post_cache($product_with_stock->get_id());
380 + WPO_Page_Cache::instance()->file_log("Cache for URL: {{URL}} has been purged, triggered by action: " . current_filter(), $product_with_stock->get_id());
340 381 }
341 382 }
342 383
343 384 /**
@@ -354,8 +395,9 @@
354 395 if ($old_value) {
355 396 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
356 397 }
357 398 WPO_Page_Cache::delete_homepage_cache();
399 + WPO_Page_Cache::instance()->file_log("Cache for homepage has been purged due to change in the Homepage displays options, triggered by action: " . current_filter());
358 400 }
359 401
360 402 /**
361 403 * Purges relevant caches when the "Posts page" option is changed.
@@ -369,20 +411,52 @@
369 411 }
370 412 if ($value) {
371 413 WPO_Page_Cache::delete_cache_by_url(get_permalink($value));
372 414 }
415 + WPO_Page_Cache::instance()->file_log("Cache for homepage has been purged due to changes in the Posts page options, triggered by action: " . current_filter());
373 416 }
374 417
375 418 /**
419 + * Purges cache if the avatars option is changed
420 + *
421 + * @param boolean $old_value
422 + * @param boolean $value
423 + */
424 + public function purge_cache_on_avatars_change($old_value, $value) {
425 + if ($old_value !== $value) {
426 + $this->purge_cache();
427 + }
428 + }
429 +
430 + /**
376 431 * Clears the cache.
377 432 */
378 433 public function purge_cache() {
379 434 if (!empty($this->config['enable_page_caching'])) {
380 435 wpo_cache_flush();
436 + WPO_Page_Cache::instance()->file_log("Full Cache Purge triggered by action: " . current_filter());
381 437 }
382 438 }
383 439
384 440 /**
441 + * Filter to set the flag to not close the browser connection when running via AJAX in the preloader.
442 + *
443 + * @param bool $dont_close_browser_connection The current value of the flag to not close the browser connection. Default is false.
444 + *
445 + * @return bool
446 + */
447 + public function preloader_dont_close_browser_connection($dont_close_browser_connection) {
448 + if ($dont_close_browser_connection) return $dont_close_browser_connection;
449 +
450 + // In WooCommerce, when the stock is updated for a product or a variation, it triggers an AJAX request in the background.
451 + // In this case, we want to avoid closing the browser connection in the preloader, to allow the product edit page to receive the response.
452 + if (did_action('woocommerce_variation_set_stock') || did_action('woocommerce_product_set_stock')) {
453 + return true;
454 + }
455 + return false;
456 + }
457 +
458 + /**
385 459 * Triggered by wpo_cache_config_updated.
386 460 *
387 461 * @param array $config
388 462 */
@@ -389,8 +463,9 @@
389 463 public function cache_config_updated($config) {
390 464 // delete front page form cache if defined in the settings
391 465 if (is_array($config['cache_exception_urls']) && in_array('/', $config['cache_exception_urls'])) {
392 466 WPO_Page_Cache::delete_cache_by_url(home_url());
467 + WPO_Page_Cache::instance()->file_log("Cache for homepage has been purged due to changes in the cache configurations, triggered by action: " . current_filter());
393 468 }
394 469 }
395 470
396 471 /**
@@ -395,9 +470,9 @@
395 470
396 471 /**
397 472 * Returns an instance of the current class, creates one if it doesn't exist
398 473 *
399 - * @return object
474 + * @return self
400 475 */
401 476 public static function instance() {
402 477 if (empty(self::$instance)) {
403 478 self::$instance = new self();