PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.21
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.21
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
wp-optimize / cache / class-wpo-cache-rules.php

class-wpo-cache-rules.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.21, at cache/class-wpo-cache-rules.php

410 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) die('No direct access allowed');
4
5 /**
6 * Page caching rules and exceptions
7 */
8
9 require_once dirname(__FILE__) . '/file-based-page-cache-functions.php';
10
11 if (!class_exists('WPO_Cache_Rules')) :
12
13 class WPO_Cache_Rules {
14
15 /**
16 * Cache config object
17 *
18 * @var mixed
19 */
20 public $config;
21
22 /**
23 * Instance of this class
24 *
25 * @var mixed
26 */
27 public static $instance;
28
29 public function __construct() {
30 $this->config = WPO_Cache_Config::instance()->get();
31 $this->setup_hooks();
32 }
33
34 /**
35 * Setup hooks/filters
36 */
37 public function setup_hooks() {
38 add_action('save_post', array($this, 'purge_post_on_update'), 10, 1);
39 add_action('save_post', array($this, 'purge_archive_pages_on_post_update'), 10, 1);
40 add_action('wp_trash_post', array($this, 'purge_post_on_update'), 10, 1);
41 add_action('comment_post', array($this, 'purge_post_on_comment'), 10, 3);
42 add_action('wp_set_comment_status', array($this, 'purge_post_on_comment_status_change'), 10, 1);
43 add_action('edit_terms', array($this, 'purge_related_elements_on_term_updated'), 10, 2);
44 add_action('set_object_terms', array($this, 'purge_related_elements_on_post_terms_change'), 10, 6);
45 add_action('wpo_cache_config_updated', array($this, 'cache_config_updated'), 10, 1);
46 add_action('wp_insert_comment', array($this, 'comment_inserted'), 10, 2);
47 add_action('import_start', array($this, 'remove_wp_insert_comment'));
48
49 add_action('update_option_page_on_front', array($this, 'purge_cache_on_homepage_change'));
50 add_action('update_option_page_for_posts', array($this, 'purge_cache_on_blog_page_change'), 10, 2);
51
52 add_action('woocommerce_variation_set_stock', array($this, 'purge_product_page'), 10, 1);
53 add_action('woocommerce_product_set_stock', array($this, 'purge_product_page'), 10, 1);
54
55 /**
56 * List of hooks for which when executed, the cache will be purged
57 *
58 * @param array $actions The actions
59 */
60 $actions = array(
61 'after_switch_theme',
62 'wp_update_nav_menu',
63 'customize_save_after',
64 array('wp_ajax_save-widget', 0),
65 array('wp_ajax_update-widget', 0),
66 'autoptimize_action_cachepurged',
67 'upgrader_overwrote_package',
68 'wpo_active_plugin_or_theme_updated',
69 'fusion_cache_reset_after',
70 'update_option_permalink_structure',
71 'update_option_posts_per_page',
72 'wpml_st_add_string_translation',
73 );
74 $purge_on_action = apply_filters('wpo_purge_cache_hooks', $actions);
75 foreach ($purge_on_action as $action) {
76 if (is_array($action)) {
77 add_action($action[0], array($this, 'purge_cache'), $action[1]);
78 } else {
79 add_action($action, array($this, 'purge_cache'));
80 }
81 }
82 }
83
84 /**
85 * Purge post cache when there is a new approved comment
86 *
87 * @param int $comment_id Comment ID.
88 * @param int|string $approved Comment approved status. can be 0, 1 or 'spam'.
89 * @param array $commentdata Comment data array. Always sent be WP core, but a plugin was found that does not send it - https://wordpress.org/support/topic/critical-problems-with-version-3-0-10/
90 */
91 public function purge_post_on_comment($comment_id, $approved, $commentdata = array()) {
92 if (1 !== $approved) {
93 return;
94 }
95
96 if (!empty($this->config['enable_page_caching']) && !empty($commentdata['comment_post_ID'])) {
97 $post_id = $commentdata['comment_post_ID'];
98
99 WPO_Page_Cache::delete_single_post_cache($post_id);
100 WPO_Page_Cache::delete_comments_feed();
101 }
102 }
103
104 /**
105 * Every time a comment's status changes, purge it's parent posts cache
106 *
107 * @param int $comment_id Comment ID.
108 */
109 public function purge_post_on_comment_status_change($comment_id) {
110 if (!empty($this->config['enable_page_caching'])) {
111 $comment = get_comment($comment_id);
112 if (is_object($comment) && !empty($comment->comment_post_ID)) {
113 WPO_Page_Cache::delete_single_post_cache($comment->comment_post_ID);
114 WPO_Page_Cache::delete_comments_feed();
115 }
116 }
117 }
118
119 /**
120 * Action when a comment is inserted
121 *
122 * @param integer $comment_id - The comment ID
123 * @param boolean|WP_Comment $comment - The comment object (from WP 4.4)
124 * @return void
125 */
126 public function comment_inserted($comment_id, $comment = false) {
127 if ($comment && is_a($comment, 'WP_Comment')) {
128 /**
129 * Filters whether to add a cookie when a comment is posted, in order to exclude the page from caching.
130 * Regular comments have the property comment_type set to '' or 'comment'. So by default, only add the cookie in those cases.
131 *
132 * @param boolean $add_cookie
133 * @param WP_Comment $comment
134 * @return boolean
135 */
136 $add_cookie = apply_filters('wpo_add_commented_post_cookie', '' == $comment->comment_type || 'comment' == $comment->comment_type, $comment);
137 if (!$add_cookie) return;
138
139 $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'] : '/');
142 }
143 }
144
145 /**
146 * Comment posted cookie is not needed for imports. So remove the action
147 */
148 public function remove_wp_insert_comment() {
149 remove_action('wp_insert_comment', array($this, 'comment_inserted'), 10);
150 }
151
152 /**
153 * Automatically purge all file based page cache on post changes
154 * We want the whole cache purged here as different parts
155 * of the site could potentially change on post updates
156 *
157 * @param Integer $post_id - WP post id
158 */
159 public function purge_post_on_update($post_id) {
160 $post_type = get_post_type($post_id);
161 $post_type_object = get_post_type_object($post_type);
162
163 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || null === $post_type_object || !$post_type_object->public) {
164 return;
165 }
166
167 /**
168 * Purge the whole cache if set to true, only the edited post otherwise. Default is false.
169 *
170 * @param boolean $purge_all_cache The default filter value
171 * @param integer $post_id The saved post ID
172 */
173 if (apply_filters('wpo_purge_all_cache_on_update', false, $post_id)) {
174 $this->purge_cache();
175 return;
176 } else {
177 if (apply_filters('wpo_delete_cached_homepage_on_post_update', true, $post_id)) WPO_Page_Cache::delete_homepage_cache();
178 WPO_Page_Cache::delete_feed_cache();
179 WPO_Page_Cache::delete_single_post_cache($post_id);
180 WPO_Page_Cache::delete_sitemap_cache();
181 WPO_Page_Cache::delete_post_feed_cache($post_id);
182 }
183 }
184
185 /**
186 * Purge archive pages on post update.
187 *
188 * @param integer $post_id
189 */
190 public function purge_archive_pages_on_post_update($post_id) {
191 $post_type = get_post_type($post_id);
192
193 if (false === $post_type) return;
194
195 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type) {
196 return;
197 }
198
199 $post_obj = get_post_type_object($post_type);
200
201 if (null === $post_obj) return;
202
203 if ('post' == $post_type) {
204 // delete blog page cache
205 $blog_post_id = get_option('page_for_posts');
206 if ($blog_post_id) {
207 WPO_Page_Cache::delete_cache_by_url(get_permalink($blog_post_id), true);
208 }
209
210 // delete next and previous posts cache.
211 $globals_post = isset($GLOBALS['post']) ? $GLOBALS['post'] : false;
212 $GLOBALS['post'] = get_post($post_id);
213 $previous_post = function_exists('get_previous_post') ? get_previous_post() : false;
214 $next_post = function_exists('get_next_post') ? get_next_post() : false;
215 if ($globals_post) $GLOBALS['post'] = $globals_post;
216
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);
219
220 // delete all archive pages for post.
221 $post_date = get_post_time('Y-m-j', false, $post_id);
222 list($year, $month, $day) = $post_date;
223
224 $archive_links = array(
225 get_year_link($year),
226 get_month_link($year, $month),
227 get_day_link($year, $month, $day),
228 );
229
230 foreach ($archive_links as $link) {
231 WPO_Page_Cache::delete_cache_by_url($link, true);
232 }
233 } elseif ($post_obj->has_archive) {
234 // delete archive page for custom post type.
235 WPO_Page_Cache::delete_cache_by_url(get_post_type_archive_link($post_type), true);
236 }
237
238 }
239
240 /**
241 * We use it with edit_terms action filter to purge cached elements related
242 * to updated term when term updated.
243 *
244 * @param int $term_id Term taxonomy ID.
245 * @param string $taxonomy Taxonomy slug.
246 */
247 public function purge_related_elements_on_term_updated($term_id, $taxonomy) {
248 if ('nav_menu' === $taxonomy) return;
249
250 // purge cached page for term.
251 $term = get_term($term_id, $taxonomy, ARRAY_A);
252 if (is_array($term)) {
253 $term_permalink = get_term_link($term['term_id']);
254 if (!is_wp_error($term_permalink)) {
255 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
256 }
257 }
258
259 // get posts which belongs to updated term.
260 $posts = get_posts(array(
261 'numberposts' => -1,
262 'post_type' => 'any',
263 'fields' => 'ids',
264 'tax_query' => array(
265 'relation' => 'OR',
266 array(
267 'taxonomy' => $taxonomy,
268 'field' => 'term_id',
269 'terms' => $term_id,
270 )
271 ),
272 ));
273
274 if (!empty($posts)) {
275 foreach ($posts as $post_id) {
276 WPO_Page_Cache::delete_single_post_cache($post_id);
277 }
278 }
279 }
280
281 /**
282 * Triggered by set_object_terms action. Used to clear all the terms archives a post belongs to or belonged to before being saved.
283 *
284 * @param int $object_id Object ID.
285 * @param array $terms An array of object terms.
286 * @param array $tt_ids An array of term taxonomy IDs.
287 * @param string $taxonomy Taxonomy slug.
288 * @param bool $append Whether to append new terms to the old terms.
289 * @param array $old_tt_ids Old array of term taxonomy IDs.
290 */
291 public function purge_related_elements_on_post_terms_change($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) {
292
293 $post_type = get_post_type($object_id);
294
295 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || 'product_type' === $taxonomy || 'action-group' === $taxonomy) {
296 return;
297 }
298
299 /**
300 * Adds a way to exit the purge of terms permalink using the provided parameters.
301 *
302 * @param bool $purge The value filtered, whether or not to purge the related elements
303 * @param int $object_id Object ID.
304 * @param array $terms An array of object terms.
305 * @param array $tt_ids An array of term taxonomy IDs.
306 * @param string $taxonomy Taxonomy slug.
307 * @param bool $append Whether to append new terms to the old terms.
308 * @param array $old_tt_ids Old array of term taxonomy IDs.
309 * @default true
310 * @return boolean
311 */
312 if (!apply_filters('wpo_cache_purge_related_elements_on_post_terms_change', true, $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids)) return;
313
314 // get all affected terms.
315 $affected_terms_ids = array_unique(array_merge($tt_ids, $old_tt_ids));
316
317 if (!empty($affected_terms_ids)) {
318 // walk through all changed terms and purge cached pages for them.
319 foreach ($affected_terms_ids as $tt_id) {
320 $term = get_term($tt_id, $taxonomy, ARRAY_A);
321 if (!is_array($term)) continue;
322
323 $term_permalink = get_term_link($term['term_id']);
324 if (!is_wp_error($term_permalink)) {
325 $url = parse_url($term_permalink);
326 // Check if the permalink contains a valid path, to avoid deleting the whole cache.
327 if (!isset($url['path']) || '/' === $url['path']) return;
328 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
329 }
330 }
331 }
332 }
333
334 /**
335 * Purge product page upon stock update
336 */
337 public function purge_product_page($product_with_stock) {
338 if (!empty($product_with_stock->get_id())) {
339 WPO_Page_Cache::delete_single_post_cache($product_with_stock->get_id());
340 }
341 }
342
343 /**
344 * Purges relevant caches when the "Homepage" option is changed.
345 *
346 * This method is also triggered when the "Homepage displays" option is changed
347 * from a static page to latest posts. In this scenario, the "Homepage" option value
348 * becomes zero. Since the cache for the front-page is already purged here, there's no need
349 * to purge the cache using the`update_option_show_on_front` hook.
350 *
351 * @param string $old_value The old value of the "Homepage" option.
352 */
353 public function purge_cache_on_homepage_change($old_value) {
354 if ($old_value) {
355 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
356 }
357 WPO_Page_Cache::delete_homepage_cache();
358 }
359
360 /**
361 * Purges relevant caches when the "Posts page" option is changed.
362 *
363 * @param string $old_value The old value of the "Posts page" option.
364 * @param string $value The new value of the "Posts page" option.
365 */
366 public function purge_cache_on_blog_page_change($old_value, $value) {
367 if ($old_value) {
368 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
369 }
370 if ($value) {
371 WPO_Page_Cache::delete_cache_by_url(get_permalink($value));
372 }
373 }
374
375 /**
376 * Clears the cache.
377 */
378 public function purge_cache() {
379 if (!empty($this->config['enable_page_caching'])) {
380 wpo_cache_flush();
381 }
382 }
383
384 /**
385 * Triggered by wpo_cache_config_updated.
386 *
387 * @param array $config
388 */
389 public function cache_config_updated($config) {
390 // delete front page form cache if defined in the settings
391 if (is_array($config['cache_exception_urls']) && in_array('/', $config['cache_exception_urls'])) {
392 WPO_Page_Cache::delete_cache_by_url(home_url());
393 }
394 }
395
396 /**
397 * Returns an instance of the current class, creates one if it doesn't exist
398 *
399 * @return object
400 */
401 public static function instance() {
402 if (empty(self::$instance)) {
403 self::$instance = new self();
404 }
405 return self::$instance;
406 }
407 }
408
409 endif;
410