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 -17 3.5.0 → 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,14 +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 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);
181 190 }
182 191 }
183 192
184 193 /**
@@ -198,24 +207,36 @@
198 207 $post_obj = get_post_type_object($post_type);
199 208
200 209 if (null === $post_obj) return;
201 210
202 - 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) {
203 217 // delete blog page cache
204 218 $blog_post_id = get_option('page_for_posts');
205 219 if ($blog_post_id) {
206 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);
207 222 }
208 223
209 224 // delete next and previous posts cache.
210 - $globals_post = isset($GLOBALS['post']) ? $GLOBALS['post'] : false;
225 + $globals_post = $GLOBALS['post'] ?? false;
211 226 $GLOBALS['post'] = get_post($post_id);
212 227 $previous_post = function_exists('get_previous_post') ? get_previous_post() : false;
213 228 $next_post = function_exists('get_next_post') ? get_next_post() : false;
214 229 if ($globals_post) $GLOBALS['post'] = $globals_post;
215 230
216 - if ($previous_post) WPO_Page_Cache::delete_cache_by_url(get_permalink($previous_post), true);
217 - 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 + }
218 239
219 240 // delete all archive pages for post.
220 241 $post_date = get_post_time('Y-m-j', false, $post_id);
221 242 list($year, $month, $day) = $post_date;
@@ -228,13 +249,26 @@
228 249
229 250 foreach ($archive_links as $link) {
230 251 WPO_Page_Cache::delete_cache_by_url($link, true);
231 252 }
232 - } 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) {
233 256 // delete archive page for custom post type.
234 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);
235 259 }
236 -
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 + }
237 271 }
238 272
239 273 /**
240 274 * We use it with edit_terms action filter to purge cached elements related
@@ -251,8 +285,9 @@
251 285 if (is_array($term)) {
252 286 $term_permalink = get_term_link($term['term_id']);
253 287 if (!is_wp_error($term_permalink)) {
254 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());
255 290 }
256 291 }
257 292
258 293 // get posts which belongs to updated term.
@@ -259,9 +294,9 @@
259 294 $posts = get_posts(array(
260 295 'numberposts' => -1,
261 296 'post_type' => 'any',
262 297 'fields' => 'ids',
263 - '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
264 299 'relation' => 'OR',
265 300 array(
266 301 'taxonomy' => $taxonomy,
267 302 'field' => 'term_id',
@@ -273,8 +308,11 @@
273 308 if (!empty($posts)) {
274 309 foreach ($posts as $post_id) {
275 310 WPO_Page_Cache::delete_single_post_cache($post_id);
276 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());
277 315 }
278 316 }
279 317
280 318 /**
@@ -297,9 +335,9 @@
297 335
298 336 /**
299 337 * Adds a way to exit the purge of terms permalink using the provided parameters.
300 338 *
301 - * @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
302 340 * @param int $object_id Object ID.
303 341 * @param array $terms An array of object terms.
304 342 * @param array $tt_ids An array of term taxonomy IDs.
305 343 * @param string $taxonomy Taxonomy slug.
@@ -314,8 +352,9 @@
314 352 $affected_terms_ids = array_unique(array_merge($tt_ids, $old_tt_ids));
315 353
316 354 if (!empty($affected_terms_ids)) {
317 355 // walk through all changed terms and purge cached pages for them.
356 + $is_cache_purged = false;
318 357 foreach ($affected_terms_ids as $tt_id) {
319 358 $term = get_term($tt_id, $taxonomy, ARRAY_A);
320 359 if (!is_array($term)) continue;
321 360
@@ -320,14 +359,16 @@
320 359 if (!is_array($term)) continue;
321 360
322 361 $term_permalink = get_term_link($term['term_id']);
323 362 if (!is_wp_error($term_permalink)) {
324 - $url = parse_url($term_permalink);
363 + $url = wp_parse_url($term_permalink);
325 364 // Check if the permalink contains a valid path, to avoid deleting the whole cache.
326 365 if (!isset($url['path']) || '/' === $url['path']) return;
327 366 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
367 + $is_cache_purged = true;
328 368 }
329 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());
330 371 }
331 372 }
332 373
333 374 /**
@@ -335,8 +376,9 @@
335 376 */
336 377 public function purge_product_page($product_with_stock) {
337 378 if (!empty($product_with_stock->get_id())) {
338 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());
339 381 }
340 382 }
341 383
342 384 /**
@@ -353,8 +395,9 @@
353 395 if ($old_value) {
354 396 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
355 397 }
356 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());
357 400 }
358 401
359 402 /**
360 403 * Purges relevant caches when the "Posts page" option is changed.
@@ -368,20 +411,52 @@
368 411 }
369 412 if ($value) {
370 413 WPO_Page_Cache::delete_cache_by_url(get_permalink($value));
371 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());
372 416 }
373 417
374 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 + /**
375 431 * Clears the cache.
376 432 */
377 433 public function purge_cache() {
378 434 if (!empty($this->config['enable_page_caching'])) {
379 435 wpo_cache_flush();
436 + WPO_Page_Cache::instance()->file_log("Full Cache Purge triggered by action: " . current_filter());
380 437 }
381 438 }
382 439
383 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 + /**
384 459 * Triggered by wpo_cache_config_updated.
385 460 *
386 461 * @param array $config
387 462 */
@@ -388,8 +463,9 @@
388 463 public function cache_config_updated($config) {
389 464 // delete front page form cache if defined in the settings
390 465 if (is_array($config['cache_exception_urls']) && in_array('/', $config['cache_exception_urls'])) {
391 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());
392 468 }
393 469 }
394 470
395 471 /**
@@ -394,9 +470,9 @@
394 470
395 471 /**
396 472 * Returns an instance of the current class, creates one if it doesn't exist
397 473 *
398 - * @return object
474 + * @return self
399 475 */
400 476 public static function instance() {
401 477 if (empty(self::$instance)) {
402 478 self::$instance = new self();