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

409 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_post_feed_cache($post_id);
181 }
182 }
183
184 /**
185 * Purge archive pages on post update.
186 *
187 * @param integer $post_id
188 */
189 public function purge_archive_pages_on_post_update($post_id) {
190 $post_type = get_post_type($post_id);
191
192 if (false === $post_type) return;
193
194 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type) {
195 return;
196 }
197
198 $post_obj = get_post_type_object($post_type);
199
200 if (null === $post_obj) return;
201
202 if ('post' == $post_type) {
203 // delete blog page cache
204 $blog_post_id = get_option('page_for_posts');
205 if ($blog_post_id) {
206 WPO_Page_Cache::delete_cache_by_url(get_permalink($blog_post_id), true);
207 }
208
209 // delete next and previous posts cache.
210 $globals_post = isset($GLOBALS['post']) ? $GLOBALS['post'] : false;
211 $GLOBALS['post'] = get_post($post_id);
212 $previous_post = function_exists('get_previous_post') ? get_previous_post() : false;
213 $next_post = function_exists('get_next_post') ? get_next_post() : false;
214 if ($globals_post) $GLOBALS['post'] = $globals_post;
215
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);
218
219 // delete all archive pages for post.
220 $post_date = get_post_time('Y-m-j', false, $post_id);
221 list($year, $month, $day) = $post_date;
222
223 $archive_links = array(
224 get_year_link($year),
225 get_month_link($year, $month),
226 get_day_link($year, $month, $day),
227 );
228
229 foreach ($archive_links as $link) {
230 WPO_Page_Cache::delete_cache_by_url($link, true);
231 }
232 } elseif ($post_obj->has_archive) {
233 // delete archive page for custom post type.
234 WPO_Page_Cache::delete_cache_by_url(get_post_type_archive_link($post_type), true);
235 }
236
237 }
238
239 /**
240 * We use it with edit_terms action filter to purge cached elements related
241 * to updated term when term updated.
242 *
243 * @param int $term_id Term taxonomy ID.
244 * @param string $taxonomy Taxonomy slug.
245 */
246 public function purge_related_elements_on_term_updated($term_id, $taxonomy) {
247 if ('nav_menu' === $taxonomy) return;
248
249 // purge cached page for term.
250 $term = get_term($term_id, $taxonomy, ARRAY_A);
251 if (is_array($term)) {
252 $term_permalink = get_term_link($term['term_id']);
253 if (!is_wp_error($term_permalink)) {
254 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
255 }
256 }
257
258 // get posts which belongs to updated term.
259 $posts = get_posts(array(
260 'numberposts' => -1,
261 'post_type' => 'any',
262 'fields' => 'ids',
263 'tax_query' => array(
264 'relation' => 'OR',
265 array(
266 'taxonomy' => $taxonomy,
267 'field' => 'term_id',
268 'terms' => $term_id,
269 )
270 ),
271 ));
272
273 if (!empty($posts)) {
274 foreach ($posts as $post_id) {
275 WPO_Page_Cache::delete_single_post_cache($post_id);
276 }
277 }
278 }
279
280 /**
281 * Triggered by set_object_terms action. Used to clear all the terms archives a post belongs to or belonged to before being saved.
282 *
283 * @param int $object_id Object ID.
284 * @param array $terms An array of object terms.
285 * @param array $tt_ids An array of term taxonomy IDs.
286 * @param string $taxonomy Taxonomy slug.
287 * @param bool $append Whether to append new terms to the old terms.
288 * @param array $old_tt_ids Old array of term taxonomy IDs.
289 */
290 public function purge_related_elements_on_post_terms_change($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) {
291
292 $post_type = get_post_type($object_id);
293
294 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || 'product_type' === $taxonomy || 'action-group' === $taxonomy) {
295 return;
296 }
297
298 /**
299 * Adds a way to exit the purge of terms permalink using the provided parameters.
300 *
301 * @param bool $purge The value filtered, whether or not to purge the related elements
302 * @param int $object_id Object ID.
303 * @param array $terms An array of object terms.
304 * @param array $tt_ids An array of term taxonomy IDs.
305 * @param string $taxonomy Taxonomy slug.
306 * @param bool $append Whether to append new terms to the old terms.
307 * @param array $old_tt_ids Old array of term taxonomy IDs.
308 * @default true
309 * @return boolean
310 */
311 if (!apply_filters('wpo_cache_purge_related_elements_on_post_terms_change', true, $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids)) return;
312
313 // get all affected terms.
314 $affected_terms_ids = array_unique(array_merge($tt_ids, $old_tt_ids));
315
316 if (!empty($affected_terms_ids)) {
317 // walk through all changed terms and purge cached pages for them.
318 foreach ($affected_terms_ids as $tt_id) {
319 $term = get_term($tt_id, $taxonomy, ARRAY_A);
320 if (!is_array($term)) continue;
321
322 $term_permalink = get_term_link($term['term_id']);
323 if (!is_wp_error($term_permalink)) {
324 $url = parse_url($term_permalink);
325 // Check if the permalink contains a valid path, to avoid deleting the whole cache.
326 if (!isset($url['path']) || '/' === $url['path']) return;
327 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
328 }
329 }
330 }
331 }
332
333 /**
334 * Purge product page upon stock update
335 */
336 public function purge_product_page($product_with_stock) {
337 if (!empty($product_with_stock->get_id())) {
338 WPO_Page_Cache::delete_single_post_cache($product_with_stock->get_id());
339 }
340 }
341
342 /**
343 * Purges relevant caches when the "Homepage" option is changed.
344 *
345 * This method is also triggered when the "Homepage displays" option is changed
346 * from a static page to latest posts. In this scenario, the "Homepage" option value
347 * becomes zero. Since the cache for the front-page is already purged here, there's no need
348 * to purge the cache using the`update_option_show_on_front` hook.
349 *
350 * @param string $old_value The old value of the "Homepage" option.
351 */
352 public function purge_cache_on_homepage_change($old_value) {
353 if ($old_value) {
354 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
355 }
356 WPO_Page_Cache::delete_homepage_cache();
357 }
358
359 /**
360 * Purges relevant caches when the "Posts page" option is changed.
361 *
362 * @param string $old_value The old value of the "Posts page" option.
363 * @param string $value The new value of the "Posts page" option.
364 */
365 public function purge_cache_on_blog_page_change($old_value, $value) {
366 if ($old_value) {
367 WPO_Page_Cache::delete_cache_by_url(get_permalink($old_value));
368 }
369 if ($value) {
370 WPO_Page_Cache::delete_cache_by_url(get_permalink($value));
371 }
372 }
373
374 /**
375 * Clears the cache.
376 */
377 public function purge_cache() {
378 if (!empty($this->config['enable_page_caching'])) {
379 wpo_cache_flush();
380 }
381 }
382
383 /**
384 * Triggered by wpo_cache_config_updated.
385 *
386 * @param array $config
387 */
388 public function cache_config_updated($config) {
389 // delete front page form cache if defined in the settings
390 if (is_array($config['cache_exception_urls']) && in_array('/', $config['cache_exception_urls'])) {
391 WPO_Page_Cache::delete_cache_by_url(home_url());
392 }
393 }
394
395 /**
396 * Returns an instance of the current class, creates one if it doesn't exist
397 *
398 * @return object
399 */
400 public static function instance() {
401 if (empty(self::$instance)) {
402 self::$instance = new self();
403 }
404 return self::$instance;
405 }
406 }
407
408 endif;
409