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

361 lines 11.9 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('woocommerce_variation_set_stock', array($this, 'purge_product_page'), 10, 1);
50 add_action('woocommerce_product_set_stock', array($this, 'purge_product_page'), 10, 1);
51
52 /**
53 * List of hooks for which when executed, the cache will be purged
54 *
55 * @param array $actions The actions
56 */
57 $purge_on_action = apply_filters('wpo_purge_cache_hooks', array('after_switch_theme', 'wp_update_nav_menu', 'customize_save_after', array('wp_ajax_save-widget', 0), array('wp_ajax_update-widget', 0), 'autoptimize_action_cachepurged', 'upgrader_overwrote_package', 'wpo_active_plugin_or_theme_updated', 'fusion_cache_reset_after', 'update_option_permalink_structure'));
58 foreach ($purge_on_action as $action) {
59 if (is_array($action)) {
60 add_action($action[0], array($this, 'purge_cache'), $action[1]);
61 } else {
62 add_action($action, array($this, 'purge_cache'));
63 }
64 }
65 }
66
67 /**
68 * Purge post cache when there is a new approved comment
69 *
70 * @param int $comment_id Comment ID.
71 * @param int|string $approved Comment approved status. can be 0, 1 or 'spam'.
72 * @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/
73 */
74 public function purge_post_on_comment($comment_id, $approved, $commentdata = array()) {
75 if (1 !== $approved) {
76 return;
77 }
78
79 if (!empty($this->config['enable_page_caching']) && !empty($commentdata['comment_post_ID'])) {
80 $post_id = $commentdata['comment_post_ID'];
81
82 WPO_Page_Cache::delete_single_post_cache($post_id);
83 WPO_Page_Cache::delete_comments_feed();
84 }
85 }
86
87 /**
88 * Every time a comment's status changes, purge it's parent posts cache
89 *
90 * @param int $comment_id Comment ID.
91 */
92 public function purge_post_on_comment_status_change($comment_id) {
93 if (!empty($this->config['enable_page_caching'])) {
94 $comment = get_comment($comment_id);
95 if (is_object($comment) && !empty($comment->comment_post_ID)) {
96 WPO_Page_Cache::delete_single_post_cache($comment->comment_post_ID);
97 WPO_Page_Cache::delete_comments_feed();
98 }
99 }
100 }
101
102 /**
103 * Action when a comment is inserted
104 *
105 * @param integer $comment_id - The comment ID
106 * @param boolean|WP_Comment $comment - The comment object (from WP 4.4)
107 * @return void
108 */
109 public function comment_inserted($comment_id, $comment = false) {
110 if ($comment && is_a($comment, 'WP_Comment')) {
111 /**
112 * Filters whether to add a cookie when a comment is posted, in order to exclude the page from caching.
113 * Regular comments have the property comment_type set to '' or 'comment'. So by default, only add the cookie in those cases.
114 *
115 * @param boolean $add_cookie
116 * @param WP_Comment $comment
117 * @return boolean
118 */
119 $add_cookie = apply_filters('wpo_add_commented_post_cookie', '' == $comment->comment_type || 'comment' == $comment->comment_type, $comment);
120 if (!$add_cookie) return;
121
122 $url = get_permalink($comment->comment_post_ID);
123 $url_info = parse_url($url);
124 setcookie('wpo_commented_post', 1, time() + WEEK_IN_SECONDS, isset($url_info['path']) ? $url_info['path'] : '/');
125 }
126 }
127
128 /**
129 * Comment posted cookie is not needed for imports. So remove the action
130 */
131 public function remove_wp_insert_comment() {
132 remove_action('wp_insert_comment', array($this, 'comment_inserted'), 10);
133 }
134
135 /**
136 * Automatically purge all file based page cache on post changes
137 * We want the whole cache purged here as different parts
138 * of the site could potentially change on post updates
139 *
140 * @param Integer $post_id - WP post id
141 */
142 public function purge_post_on_update($post_id) {
143 $post_type = get_post_type($post_id);
144 $post_type_object = get_post_type_object($post_type);
145
146 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || !$post_type_object->public) {
147 return;
148 }
149
150 /**
151 * Purge the whole cache if set to true, only the edited post otherwise. Default is false.
152 *
153 * @param boolean $purge_all_cache The default filter value
154 * @param integer $post_id The saved post ID
155 */
156 if (apply_filters('wpo_purge_all_cache_on_update', false, $post_id)) {
157 $this->purge_cache();
158 return;
159 } else {
160 if (apply_filters('wpo_delete_cached_homepage_on_post_update', true, $post_id)) WPO_Page_Cache::delete_homepage_cache();
161 WPO_Page_Cache::delete_feed_cache();
162 WPO_Page_Cache::delete_single_post_cache($post_id);
163 WPO_Page_Cache::delete_sitemap_cache();
164 WPO_Page_Cache::delete_post_feed_cache($post_id);
165 }
166 }
167
168 /**
169 * Purge archive pages on post update.
170 *
171 * @param integer $post_id
172 */
173 public function purge_archive_pages_on_post_update($post_id) {
174 $post_type = get_post_type($post_id);
175
176 if (false === $post_type) return;
177
178 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type) {
179 return;
180 }
181
182 $post_obj = get_post_type_object($post_type);
183
184 if (null === $post_obj) return;
185
186 if ('post' == $post_type) {
187 // delete blog page cache
188 $blog_post_id = get_option('page_for_posts');
189 if ($blog_post_id) {
190 WPO_Page_Cache::delete_cache_by_url(get_permalink($blog_post_id), true);
191 }
192
193 // delete next and previus posts cache.
194 $globals_post = isset($GLOBALS['post']) ? $GLOBALS['post'] : false;
195 $GLOBALS['post'] = get_post($post_id);
196 $previous_post = function_exists('get_previous_post') ? get_previous_post() : false;
197 $next_post = function_exists('get_next_post') ? get_next_post() : false;
198 if ($globals_post) $GLOBALS['post'] = $globals_post;
199
200 if ($previous_post) WPO_Page_Cache::delete_cache_by_url(get_permalink($previous_post), true);
201 if ($next_post) WPO_Page_Cache::delete_cache_by_url(get_permalink($next_post), true);
202
203 // delete all archive pages for post.
204 $post_date = get_post_time('Y-m-j', false, $post_id);
205 list($year, $month, $day) = $post_date;
206
207 $archive_links = array(
208 get_year_link($year),
209 get_month_link($year, $month),
210 get_day_link($year, $month, $day),
211 );
212
213 foreach ($archive_links as $link) {
214 WPO_Page_Cache::delete_cache_by_url($link, true);
215 }
216 } elseif ($post_obj->has_archive) {
217 // delete archive page for custom post type.
218 WPO_Page_Cache::delete_cache_by_url(get_post_type_archive_link($post_type), true);
219 }
220
221 }
222
223 /**
224 * We use it with edit_terms action filter to purge cached elements related
225 * to updated term when term updated.
226 *
227 * @param int $term_id Term taxonomy ID.
228 * @param string $taxonomy Taxonomy slug.
229 */
230 public function purge_related_elements_on_term_updated($term_id, $taxonomy) {
231 if ('nav_menu' === $taxonomy) return;
232
233 // purge cached page for term.
234 $term = get_term($term_id, $taxonomy, ARRAY_A);
235 if (is_array($term)) {
236 $term_permalink = get_term_link($term['term_id']);
237 if (!is_wp_error($term_permalink)) {
238 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
239 }
240 }
241
242 // get posts which belongs to updated term.
243 $posts = get_posts(array(
244 'numberposts' => -1,
245 'post_type' => 'any',
246 'fields' => 'ids',
247 'tax_query' => array(
248 'relation' => 'OR',
249 array(
250 'taxonomy' => $taxonomy,
251 'field' => 'term_id',
252 'terms' => $term_id,
253 )
254 ),
255 ));
256
257 if (!empty($posts)) {
258 foreach ($posts as $post_id) {
259 WPO_Page_Cache::delete_single_post_cache($post_id);
260 }
261 }
262 }
263
264 /**
265 * Triggered by set_object_terms action. Used to clear all the terms archives a post belongs to or belonged to before being saved.
266 *
267 * @param int $object_id Object ID.
268 * @param array $terms An array of object terms.
269 * @param array $tt_ids An array of term taxonomy IDs.
270 * @param string $taxonomy Taxonomy slug.
271 * @param bool $append Whether to append new terms to the old terms.
272 * @param array $old_tt_ids Old array of term taxonomy IDs.
273 */
274 public function purge_related_elements_on_post_terms_change($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) {
275
276 $post_type = get_post_type($object_id);
277
278 if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || 'revision' === $post_type || 'product_type' === $taxonomy || 'action-group' === $taxonomy) {
279 return;
280 }
281
282 /**
283 * Adds a way to exit the purge of terms permalink using the provided parameters.
284 *
285 * @param bool $purge The value filtered, whether or not to purge the related elements
286 * @param int $object_id Object ID.
287 * @param array $terms An array of object terms.
288 * @param array $tt_ids An array of term taxonomy IDs.
289 * @param string $taxonomy Taxonomy slug.
290 * @param bool $append Whether to append new terms to the old terms.
291 * @param array $old_tt_ids Old array of term taxonomy IDs.
292 * @default true
293 * @return boolean
294 */
295 if (!apply_filters('wpo_cache_purge_related_elements_on_post_terms_change', true, $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids)) return;
296
297 // get all affected terms.
298 $affected_terms_ids = array_unique(array_merge($tt_ids, $old_tt_ids));
299
300 if (!empty($affected_terms_ids)) {
301 // walk through all changed terms and purge cached pages for them.
302 foreach ($affected_terms_ids as $tt_id) {
303 $term = get_term($tt_id, $taxonomy, ARRAY_A);
304 if (!is_array($term)) continue;
305
306 $term_permalink = get_term_link($term['term_id']);
307 if (!is_wp_error($term_permalink)) {
308 $url = parse_url($term_permalink);
309 // Check if the permalink contains a valid path, to avoid deleting the whole cache.
310 if (!isset($url['path']) || '/' === $url['path']) return;
311 WPO_Page_Cache::delete_cache_by_url($term_permalink, true);
312 }
313 }
314 }
315 }
316
317 /**
318 * Purge product page upon stock update
319 */
320 public function purge_product_page($product_with_stock) {
321 if (!empty($product_with_stock->get_id())) {
322 WPO_Page_Cache::delete_single_post_cache($product_with_stock->get_id());
323 }
324 }
325
326 /**
327 * Clears the cache.
328 */
329 public function purge_cache() {
330 if (!empty($this->config['enable_page_caching'])) {
331 wpo_cache_flush();
332 }
333 }
334
335 /**
336 * Triggered by wpo_cache_config_updated.
337 *
338 * @param array $config
339 */
340 public function cache_config_updated($config) {
341 // delete front page form cache if defined in the settings
342 if (is_array($config['cache_exception_urls']) && in_array('/', $config['cache_exception_urls'])) {
343 WPO_Page_Cache::delete_cache_by_url(home_url());
344 }
345 }
346
347 /**
348 * Returns an instance of the current class, creates one if it doesn't exist
349 *
350 * @return object
351 */
352 public static function instance() {
353 if (empty(self::$instance)) {
354 self::$instance = new self();
355 }
356 return self::$instance;
357 }
358 }
359
360 endif;
361