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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
<?php /** * WPSEO plugin file. * * @package WPSEO\XML_Sitemaps */
/** * Handles sitemaps caching and invalidation. * * @since 3.2 */ class WPSEO_Sitemaps_Cache {
/** * Holds the options that, when updated, should cause the cache to clear. * * @var array */ protected static $cache_clear = array();
/** * Mirror of enabled status for static calls. * * @var bool */ protected static $is_enabled = false;
/** * Holds the flag to clear all cache. * * @var bool */ protected static $clear_all = false;
/** * Holds the array of types to clear. * * @var array */ protected static $clear_types = array();
/** * Hook methods for invalidation on necessary events. */ public function __construct() {
add_action( 'init', array( $this, 'init' ) );
add_action( 'deleted_term_relationships', array( __CLASS__, 'invalidate' ) );
add_action( 'update_option', array( __CLASS__, 'clear_on_option_update' ) );
add_action( 'edited_terms', array( __CLASS__, 'invalidate_helper' ), 10, 2 ); add_action( 'clean_term_cache', array( __CLASS__, 'invalidate_helper' ), 10, 2 ); add_action( 'clean_object_term_cache', array( __CLASS__, 'invalidate_helper' ), 10, 2 );
add_action( 'user_register', array( __CLASS__, 'invalidate_author' ) ); add_action( 'delete_user', array( __CLASS__, 'invalidate_author' ) );
add_action( 'shutdown', array( __CLASS__, 'clear_queued' ) ); }
/** * Setup context for static calls. */ public function init() {
self::$is_enabled = $this->is_enabled(); }
/** * If cache is enabled. * * @since 3.2 * * @return boolean */ public function is_enabled() {
/** * Filter if XML sitemap transient cache is enabled. * * @param bool $unsigned Enable cache or not, defaults to true. */ return apply_filters( 'wpseo_enable_xml_sitemap_transient_caching', false ); }
/** * Retrieve the sitemap page from cache. * * @since 3.2 * * @param string $type Sitemap type. * @param int $page Page number to retrieve. * * @return string|boolean */ public function get_sitemap( $type, $page ) {
$transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page ); if ( false === $transient_key ) { return false; }
return get_transient( $transient_key ); }
/** * Get the sitemap that is cached. * * @param string $type Sitemap type. * @param int $page Page number to retrieve. * * @return null|WPSEO_Sitemap_Cache_Data Null on no cache found otherwise object containing sitemap and meta data. */ public function get_sitemap_data( $type, $page ) {
$sitemap = $this->get_sitemap( $type, $page );
if ( empty( $sitemap ) ) { return null; }
// Unserialize Cache Data object (is_serialized doesn't recognize classes). if ( is_string( $sitemap ) && 0 === strpos( $sitemap, 'C:24:"WPSEO_Sitemap_Cache_Data"' ) ) {
$sitemap = unserialize( $sitemap ); }
// What we expect it to be if it is set. if ( $sitemap instanceof WPSEO_Sitemap_Cache_Data_Interface ) { return $sitemap; }
return null; }
/** * Store the sitemap page from cache. * * @since 3.2 * * @param string $type Sitemap type. * @param int $page Page number to store. * @param string $sitemap Sitemap body to store. * @param bool $usable Is this a valid sitemap or a cache of an invalid sitemap. * * @return bool */ public function store_sitemap( $type, $page, $sitemap, $usable = true ) {
$transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page );
if ( false === $transient_key ) { return false; }
$status = ( $usable ) ? WPSEO_Sitemap_Cache_Data::OK : WPSEO_Sitemap_Cache_Data::ERROR;
$sitemap_data = new WPSEO_Sitemap_Cache_Data(); $sitemap_data->set_sitemap( $sitemap ); $sitemap_data->set_status( $status );
return set_transient( $transient_key, $sitemap_data, DAY_IN_SECONDS ); }
/** * Delete cache transients for index and specific type. * * Always deletes the main index sitemaps cache, as that's always invalidated by any other change. * * @since 1.5.4 * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache() to method in this class. * * @param string $type Sitemap type to invalidate. * * @return void */ public static function invalidate( $type ) {
self::clear( array( $type ) ); }
/** * Helper to invalidate in hooks where type is passed as second argument. * * @since 3.2 * * @param int $unused Unused term ID value. * @param string $type Taxonomy to invalidate. * * @return void */ public static function invalidate_helper( $unused, $type ) {
if ( WPSEO_Options::get( 'noindex-' . $type ) === false || WPSEO_Options::get( 'noindex-tax-' . $type ) === false ) { self::invalidate( $type ); } }
/** * Invalidate sitemap cache for authors. * * @param int $user_id User ID. * * @return bool True if the sitemap was properly invalidated. False otherwise. */ public static function invalidate_author( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( $user === false ) { return false; }
if ( 'user_register' === current_action() ) { update_user_meta( $user_id, '_yoast_wpseo_profile_updated', time() ); }
if ( empty( $user->roles ) || in_array( 'subscriber', $user->roles, true ) ) { return false; }
self::invalidate( 'author' );
return true; }
/** * Invalidate sitemap cache for the post type of a post. * * Don't invalidate for revisions. * * @since 1.5.4 * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache_on_save_post() to method in this class. * * @param int $post_id Post ID to invalidate type for. * * @return void */ public static function invalidate_post( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) { return; }
self::invalidate( get_post_type( $post_id ) ); }
/** * Delete cache transients for given sitemaps types or all by default. * * @since 1.8.0 * @since 3.2 Moved from WPSEO_Utils to this class. * * @param array $types Set of sitemap types to delete cache transients for. * * @return void */ public static function clear( $types = array() ) {
if ( ! self::$is_enabled ) { return; }
// No types provided, clear all. if ( empty( $types ) ) { self::$clear_all = true;
return; }
// Always invalidate the index sitemap as well. if ( ! in_array( WPSEO_Sitemaps::SITEMAP_INDEX_TYPE, $types ) ) { array_unshift( $types, WPSEO_Sitemaps::SITEMAP_INDEX_TYPE ); }
foreach ( $types as $type ) { if ( ! in_array( $type, self::$clear_types ) ) { self::$clear_types[] = $type; } } }
/** * Invalidate storage for cache types queued to clear. */ public static function clear_queued() {
if ( self::$clear_all ) {
WPSEO_Sitemaps_Cache_Validator::invalidate_storage(); self::$clear_all = false; self::$clear_types = array();
return; }
foreach ( self::$clear_types as $type ) { WPSEO_Sitemaps_Cache_Validator::invalidate_storage( $type ); }
self::$clear_types = array(); }
/** * Adds a hook that when given option is updated, the cache is cleared. * * @since 3.2 * * @param string $option Option name. * @param string $type Sitemap type. */ public static function register_clear_on_option_update( $option, $type = '' ) {
self::$cache_clear[ $option ] = $type; }
/** * Clears the transient cache when a given option is updated, if that option has been registered before. * * @since 3.2 * * @param string $option The option name that's being updated. * * @return void */ public static function clear_on_option_update( $option ) {
if ( array_key_exists( $option, self::$cache_clear ) ) {
if ( empty( self::$cache_clear[ $option ] ) ) { // Clear all caches. self::clear(); } else { // Clear specific provided type(s). $types = (array) self::$cache_clear[ $option ]; self::clear( $types ); } } } }
|