class-wcs-cache-manager-tlc.php
5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
/**
* Subscription Cache Manager Class using TLC transients
*
* Implements methods to deal with the soft caching layer
*
* @class WCS_Cache_Manager_TLC
* @version 2.0
* @package WooCommerce Subscriptions/Classes
* @category Class
* @author Gabor Javorszky
*/
class WCS_Cache_Manager_TLC extends WCS_Cache_Manager {
public $logger = null;
public function __construct() {
add_action( 'woocommerce_loaded', array( $this, 'load_logger' ) );
// Add filters for update / delete / trash post to purge cache
add_action( 'trashed_post', array( $this, 'purge_delete' ), 9999 ); // trashed posts aren't included in 'any' queries
add_action( 'untrashed_post', array( $this, 'purge_delete' ), 9999 ); // however untrashed posts are
add_action( 'deleted_post', array( $this, 'purge_delete' ), 9999 ); // if forced delete is enabled
add_action( 'updated_post_meta', array( $this, 'purge_from_metadata' ), 9999, 4 ); // tied to _subscription_renewal
add_action( 'deleted_post_meta', array( $this, 'purge_from_metadata' ), 9999, 4 ); // tied to _subscription_renewal
add_action( 'added_post_meta', array( $this, 'purge_from_metadata' ), 9999, 4 ); // tied to _subscription_renewal
}
/**
* Attaches logger
*/
public function load_logger() {
$this->logger = new WC_Logger();
}
/**
* Wrapper function around WC_Logger->log
*
* @param string $message Message to log
*/
public function log( $message ) {
if ( defined( 'WCS_DEBUG' ) && WCS_DEBUG ) {
$this->logger->add( 'wcs-cache', $message );
}
}
/**
* Wrapper function around our cache library.
*
* @param string $key The key to cache the data with
* @param string|array $callback name of function, or array of class - method that fetches the data
* @param array $params arguments passed to $callback
*
* @return bool|mixed
*/
public function cache_and_get( $key, $callback, $params = array(), $expires = 0 ) {
$expires = absint( $expires );
$transient = tlc_transient( $key )
->updates_with( $callback, $params );
if ( $expires ) {
$transient->expires_in( $expires );
}
return $transient->get();
}
/**
* Clearing for orders / subscriptions with sanitizing bits
*
* @param $post_id integer the ID of an order / subscription
*/
public function purge_subscription_cache_on_update( $post_id ) {
$post_type = get_post_type( $post_id );
if ( 'shop_subscription' !== $post_type && 'shop_order' !== $post_type ) {
return;
}
if ( 'shop_subscription' === $post_type ) {
$this->log( 'ID is subscription, calling wcs_clear_related_order_cache for ' . $post_id );
$this->wcs_clear_related_order_cache( $post_id );
} else {
$this->log( 'ID is order, getting subscription.' );
$subscription = wcs_get_subscriptions_for_order( $post_id );
if ( empty( $subscription ) ) {
$this->log( 'No sub for this ID: ' . $post_id );
return;
}
$subscription = array_shift( $subscription );
$this->log( 'Got subscription, calling wcs_clear_related_order_cache for ' . $subscription->id );
$this->wcs_clear_related_order_cache( $subscription->id );
}
}
/**
* Clearing cache when a post is deleted
*
* @param $post_id integer the ID of a post
*/
public function purge_delete( $post_id ) {
if ( 'shop_order' !== get_post_type( $post_id ) ) {
return;
}
$linked_subscription = get_post_meta( $post_id, '_subscription_renewal', false );
// don't call this if there's nothing to call on
if ( $linked_subscription ) {
$this->log( 'Calling purge from ' . current_filter() . ' on ' . $linked_subscription[0] );
$this->purge_subscription_cache_on_update( $linked_subscription[0] );
}
}
/**
* When the _subscription_renewal metadata is added / deleted / updated on the Order, we need to initiate cache invalidation for both the new
* value of the meta ($_meta_value), and the object it's being added to: $object_id.
*
* @param $meta_id integer the ID of the meta in the meta table
* @param $object_id integer the ID of the post we're updating on
* @param $meta_key string the meta_key in the table
* @param $_meta_value mixed the value we're deleting / adding / updating
*/
public function purge_from_metadata( $meta_id, $object_id, $meta_key, $_meta_value ) {
if ( '_subscription_renewal' !== $meta_key || 'shop_order' !== get_post_type( $object_id ) ) {
return;
}
$this->log( 'Calling purge from ' . current_filter() . ' on object ' . $object_id . ' and meta value ' . $_meta_value . ' due to _subscription_renewal meta.' );
$this->purge_subscription_cache_on_update( $_meta_value );
$this->purge_subscription_cache_on_update( $object_id );
}
/**
* Wrapper function to clear cache that relates to related orders
*
* @param null $id
*/
public function wcs_clear_related_order_cache( $id = null ) {
// if nothing was passed in, there's nothing to delete
if ( null === $id ) {
return;
}
// if it's not a Subscription, we don't deal with it
if ( is_object( $id ) && $id instanceof WC_Subscription ) {
$id = $id->id;
} elseif ( is_numeric( $id ) ) {
$id = absint( $id );
} else {
return;
}
$key = tlc_transient( 'wcs-related-orders-to-' . $id )->key;
$this->log( 'In the clearing, key being purged is this: ' . "\n\n{$key}\n\n" );
$this->delete_cached( $key );
}
/**
* Delete cached data with key
*
* @param string $key Key that needs deleting
*/
public function delete_cached( $key ) {
if ( ! is_string( $key ) || empty( $key ) ) {
return;
}
// have to do this manually for now
delete_transient( 'tlc__' . $key );
delete_transient( 'tlc_up__' . $key );
}
}