1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Handle caching using transients for GravityView |
5
|
|
|
*/ |
6
|
|
|
class GravityView_Cache { |
7
|
|
|
|
8
|
|
|
const BLACKLIST_OPTION_NAME = 'gravityview_cache_blacklist'; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Form ID, or array of Form IDs |
12
|
|
|
* |
13
|
|
|
* @var mixed |
14
|
|
|
*/ |
15
|
|
|
protected $form_ids; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Extra request parameters used to generate the query. This is used to generate the unique transient key. |
19
|
|
|
* |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $args; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* The transient key used to store the cached item. 45 characters long. |
26
|
|
|
* |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
private $key = ''; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @since 1.13.1 |
33
|
|
|
* @var array Columns in the database for leads |
34
|
|
|
*/ |
35
|
|
|
private $lead_db_columns = array( 'id', 'form_id', 'post_id', 'date_created', 'is_starred', 'is_read', 'ip', 'source_url', 'user_agent', 'currency', 'payment_status', 'payment_date', 'payment_amount', 'transaction_id', 'is_fulfilled', 'created_by', 'transaction_type', 'status' ); |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* |
39
|
|
|
* @param array|int $form_ids Form ID or array of form IDs used in a request |
40
|
|
|
* @param array $args Extra request parameters used to generate the query. This is used to generate the unique transient key. |
41
|
|
|
*/ |
42
|
2 |
|
function __construct( $form_ids = NULL, $args = array() ) { |
|
|
|
|
43
|
|
|
|
44
|
2 |
|
$this->add_hooks(); |
45
|
|
|
|
46
|
2 |
|
if ( ! is_null( $form_ids ) ) { |
47
|
|
|
|
48
|
2 |
|
$this->form_ids = $form_ids; |
49
|
|
|
|
50
|
2 |
|
$this->args = $args; |
51
|
|
|
|
52
|
2 |
|
$this->set_key(); |
53
|
|
|
} |
54
|
2 |
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Add actions for clearing out caches when entries are updated. |
58
|
|
|
*/ |
59
|
2 |
|
function add_hooks() { |
|
|
|
|
60
|
|
|
|
61
|
|
|
// Schedule cleanup of expired transients |
62
|
2 |
|
add_action( 'wp', array( $this, 'schedule_transient_cleanup' ) ); |
63
|
|
|
|
64
|
|
|
// Hook in to the scheduled cleanup, if scheduled |
65
|
2 |
|
add_action( 'gravityview-expired-transients', array( $this, 'delete_expired_transients' ) ); |
66
|
|
|
|
67
|
|
|
// Trigger this when you need to prevent any results from being cached with forms that have been modified |
68
|
2 |
|
add_action( 'gravityview_clear_form_cache', array( $this, 'blacklist_add' ) ); |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @since 1.14 |
72
|
|
|
*/ |
73
|
2 |
|
add_action( 'gravityview_clear_entry_cache', array( $this, 'entry_status_changed' ) ); |
74
|
|
|
|
75
|
2 |
|
add_action( 'gform_after_update_entry', array( $this, 'entry_updated' ), 10, 2 ); |
76
|
|
|
|
77
|
2 |
|
add_action( 'gform_entry_created', array( $this, 'entry_created' ), 10, 2 ); |
78
|
|
|
|
79
|
2 |
|
add_action( 'gform_post_add_entry', array( $this, 'entry_added' ), 10, 2 ); |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @see RGFormsModel::update_lead_property() Trigger when any entry property changes |
83
|
|
|
*/ |
84
|
2 |
|
foreach( $this->lead_db_columns as $column ) { |
85
|
2 |
|
add_action( 'gform_update_' . $column, array( $this, 'entry_status_changed' ), 10, 3 ); |
86
|
|
|
} |
87
|
|
|
|
88
|
2 |
|
add_action( 'gform_delete_lead', array( $this, 'entry_status_changed' ), 10 ); |
89
|
2 |
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Force refreshing a cache when an entry is deleted. |
93
|
|
|
* |
94
|
|
|
* The `gform_delete_lead` action is called before the lead is deleted; we fetch the entry to find out the form ID so it can be added to the blacklist. |
95
|
|
|
* |
96
|
|
|
* @since 1.5.1 |
97
|
|
|
* |
98
|
|
|
* @param int $lead_id Entry ID |
99
|
|
|
* @param string $property_value Previous value of the lead status passed by gform_update_status hook |
100
|
|
|
* @param string $previous_value Previous value of the lead status passed by gform_update_status hook |
101
|
|
|
* |
102
|
|
|
* @return void |
103
|
|
|
*/ |
104
|
1 |
|
public function entry_status_changed( $lead_id, $property_value = '', $previous_value = '' ) { |
105
|
|
|
|
106
|
|
|
/** @var array $entry */ |
107
|
1 |
|
$entry = GFAPI::get_entry( $lead_id ); |
108
|
|
|
|
109
|
1 |
|
if ( is_wp_error( $entry ) ) { |
110
|
|
|
|
111
|
|
|
/** @var WP_Error $entry */ |
112
|
|
|
gravityview()->log->error( 'Could not retrieve entry {entry_id} to delete it: {error}', array( 'entry_id' => $lead_id, 'error' => $entry->get_error_message() ) ); |
113
|
|
|
|
114
|
|
|
return; |
115
|
|
|
} |
116
|
|
|
|
117
|
1 |
|
gravityview()->log->debug( 'adding form {form_id} to blacklist because entry #{lead_id} was deleted', array( 'form_id' => $entry['form_id'], 'entry_id' => $lead_id, 'data' => array( 'value' => $property_value, 'previous' => $previous_value ) ) ); |
118
|
|
|
|
119
|
1 |
|
$this->blacklist_add( $entry['form_id'] ); |
120
|
1 |
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* When an entry is updated, add the entry's form to the cache blacklist |
124
|
|
|
* |
125
|
|
|
* @param array $form GF form array |
126
|
|
|
* @param int $lead_id Entry ID |
127
|
|
|
* |
128
|
|
|
* @return void |
129
|
|
|
*/ |
130
|
3 |
|
public function entry_updated( $form, $lead_id ) { |
131
|
|
|
|
132
|
3 |
|
gravityview()->log->debug(' adding form {form_id} to blacklist because entry #{entry_id} was updated', array( 'form_id' => $form['id'], 'entry_id' => $lead_id ) ); |
|
|
|
|
133
|
|
|
|
134
|
3 |
|
$this->blacklist_add( $form['id'] ); |
135
|
3 |
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* When an entry is created, add the entry's form to the cache blacklist |
139
|
|
|
* |
140
|
|
|
* We don't want old caches; when an entry is added, we want to clear the cache. |
141
|
|
|
* |
142
|
|
|
* @param array $entry GF entry array |
143
|
|
|
* @param array $form GF form array |
144
|
|
|
* |
145
|
|
|
* @return void |
146
|
|
|
*/ |
147
|
|
|
public function entry_created( $entry, $form ) { |
148
|
|
|
|
149
|
|
|
gravityview()->log->debug( 'adding form {form_id} to blacklist because entry #{entry_id} was created', array( 'form_id' => $form['id'], 'entry_id' => $entry['id'] ) ); |
150
|
|
|
|
151
|
|
|
$this->blacklist_add( $form['id'] ); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Clear the cache when entries are added via GFAPI::add_entry(). |
156
|
|
|
* |
157
|
|
|
* @param array $entry The GF Entry array |
158
|
|
|
* @param array $form The GF Form array |
159
|
|
|
* |
160
|
|
|
* @return void |
161
|
|
|
*/ |
162
|
64 |
|
public function entry_added( $entry, $form ) { |
163
|
64 |
|
if ( is_wp_error( $entry ) ) { |
164
|
|
|
return; |
165
|
|
|
} |
166
|
|
|
|
167
|
64 |
|
gravityview()->log->debug( 'adding form {form_id} to blacklist because entry #{entry_id} was added', array( 'form_id' => $form['id'], 'entry_id' => $entry['id'] ) ); |
168
|
|
|
|
169
|
64 |
|
$this->blacklist_add( $form['id'] ); |
170
|
64 |
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Calculate the prefix based on the Form IDs |
174
|
|
|
* |
175
|
|
|
* @param int|array $form_ids Form IDs to generate prefix for |
176
|
|
|
* |
177
|
|
|
* @return string Prefix for the cache string used in set_key() |
178
|
|
|
*/ |
179
|
2 |
|
protected function get_cache_key_prefix( $form_ids = NULL ) { |
|
|
|
|
180
|
|
|
|
181
|
2 |
|
if ( is_null( $form_ids ) ) { |
182
|
2 |
|
$form_ids = $this->form_ids; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
// Normally just one form, but supports multiple forms |
186
|
|
|
// |
187
|
|
|
// Array of IDs 12, 5, 14 would result in `f:12-f:5-f:14` |
188
|
2 |
|
$forms = 'f:' . implode( '-f:', (array) $form_ids ); |
189
|
|
|
|
190
|
|
|
// Prefix for transient keys |
191
|
|
|
// Now the prefix would be: `gv-cache-f:12-f:5-f:14-` |
192
|
2 |
|
return 'gv-cache-' . $forms . '-'; |
193
|
|
|
|
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Set the transient key based on the form IDs and the arguments passed to the class |
198
|
|
|
*/ |
199
|
2 |
|
protected function set_key() { |
200
|
|
|
|
201
|
|
|
// Don't set key if no forms have been set. |
202
|
2 |
|
if ( empty( $this->form_ids ) ) { |
203
|
|
|
return; |
204
|
|
|
} |
205
|
|
|
|
206
|
2 |
|
$key = $this->get_cache_key_prefix() . sha1( serialize( $this->args ) ); |
207
|
|
|
|
208
|
|
|
// The transient name column can handle up to 64 characters. |
209
|
|
|
// The `_transient_timeout_` prefix that is prepended to the string is 11 characters. |
210
|
|
|
// 64 - 19 = 45 |
211
|
|
|
// We make sure the key isn't too long or else WP doesn't store data. |
212
|
2 |
|
$this->key = substr( $key, 0, 45 ); |
213
|
2 |
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Allow public access to get transient key |
217
|
|
|
* |
218
|
|
|
* @return string Transient key |
219
|
|
|
*/ |
220
|
2 |
|
public function get_key() { |
221
|
2 |
|
return $this->key; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* Add form IDs to a "blacklist" to force the cache to be refreshed |
226
|
|
|
* |
227
|
|
|
* |
228
|
|
|
* |
229
|
|
|
* @param int|array $form_ids Form IDs to force to be updated |
230
|
|
|
* |
231
|
|
|
* @return boolean False if value was not updated and true if value was updated. |
232
|
|
|
*/ |
233
|
64 |
|
public function blacklist_add( $form_ids ) { |
234
|
|
|
|
235
|
64 |
|
$blacklist = get_option( self::BLACKLIST_OPTION_NAME, array() ); |
236
|
|
|
|
237
|
64 |
|
$form_ids = is_array( $form_ids ) ? $form_ids : array( $form_ids ); |
238
|
|
|
|
239
|
64 |
|
gravityview()->log->debug( 'Adding form IDs to cache blacklist', array( 'data' => array( |
|
|
|
|
240
|
64 |
|
'$form_ids' => $form_ids, |
241
|
64 |
|
'$blacklist' => $blacklist |
|
|
|
|
242
|
|
|
) ) ); |
243
|
|
|
|
244
|
|
|
// Add the passed form IDs |
245
|
64 |
|
$blacklist = array_merge( (array) $blacklist, $form_ids ); |
246
|
|
|
|
247
|
|
|
// Don't duplicate |
248
|
64 |
|
$blacklist = array_unique( $blacklist ); |
249
|
|
|
|
250
|
|
|
// Remove empty items from blacklist |
251
|
64 |
|
$blacklist = array_filter( $blacklist ); |
252
|
|
|
|
253
|
64 |
|
return update_option( self::BLACKLIST_OPTION_NAME, $blacklist ); |
254
|
|
|
|
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Remove Form IDs from blacklist |
259
|
|
|
* |
260
|
|
|
* @param int|array $form_ids Form IDs to add |
261
|
|
|
* |
262
|
|
|
* @return boolean Whether the removal was successful |
263
|
|
|
*/ |
264
|
|
|
public function blacklist_remove( $form_ids ) { |
265
|
|
|
|
266
|
|
|
$blacklist = get_option( self::BLACKLIST_OPTION_NAME, array() ); |
267
|
|
|
|
268
|
|
|
$updated_list = array_diff( $blacklist, (array) $form_ids ); |
269
|
|
|
|
270
|
|
|
gravityview()->log->debug( 'Removing form IDs from cache blacklist', array( 'data' => array( |
|
|
|
|
271
|
|
|
'$form_ids' => $form_ids, |
272
|
|
|
'$blacklist' => $blacklist, |
273
|
|
|
'$updated_list' => $updated_list |
|
|
|
|
274
|
|
|
) ) ); |
275
|
|
|
|
276
|
|
|
return update_option( self::BLACKLIST_OPTION_NAME, $updated_list ); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Is a form ID in the cache blacklist |
282
|
|
|
* |
283
|
|
|
* @param int|array $form_ids Form IDs to check if in blacklist |
284
|
|
|
* |
285
|
|
|
* @return [type] [description] |
|
|
|
|
286
|
|
|
*/ |
287
|
3 |
|
function in_blacklist( $form_ids = NULL ) { |
|
|
|
|
288
|
|
|
|
289
|
3 |
|
$blacklist = get_option( self::BLACKLIST_OPTION_NAME, array() ); |
290
|
|
|
|
291
|
|
|
// Use object var if exists |
292
|
3 |
|
$form_ids = is_null( $form_ids ) ? $this->form_ids : $form_ids; |
293
|
|
|
|
294
|
3 |
|
if ( empty( $form_ids ) ) { |
295
|
|
|
|
296
|
|
|
gravityview()->log->debug( 'Did not add form to blacklist; empty form ID', array( 'data' => $form_ids ) ); |
297
|
|
|
|
298
|
|
|
return false; |
299
|
|
|
} |
300
|
|
|
|
301
|
3 |
|
foreach ( (array) $form_ids as $form_id ) { |
302
|
|
|
|
303
|
3 |
|
if ( in_array( $form_id, $blacklist ) ) { |
304
|
|
|
|
305
|
1 |
|
gravityview()->log->debug( 'Form #{form_id} is in the cache blacklist', array( 'form_id' => $form_id ) ); |
306
|
|
|
|
307
|
3 |
|
return true; |
308
|
|
|
} |
309
|
|
|
} |
310
|
|
|
|
311
|
3 |
|
return false; |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Get transient result |
317
|
|
|
* |
318
|
|
|
* @param string $key Transient key to fetch |
319
|
|
|
* |
320
|
|
|
* @return mixed False: Not using cache or cache was a WP_Error object; NULL: no results found; Mixed: cache value |
321
|
|
|
*/ |
322
|
2 |
|
public function get( $key = NULL ) { |
|
|
|
|
323
|
|
|
|
324
|
2 |
|
$key = is_null( $key ) ? $this->key : $key; |
325
|
|
|
|
326
|
2 |
|
if ( ! $this->use_cache() ) { |
327
|
|
|
|
328
|
|
|
gravityview()->log->debug( 'Not using cached results because of GravityView_Cache->use_cache() results' ); |
329
|
|
|
|
330
|
|
|
return false; |
331
|
|
|
} |
332
|
|
|
|
333
|
2 |
|
gravityview()->log->debug( 'Fetching request with transient key {key}', array( 'key' => $key ) ); |
334
|
|
|
|
335
|
2 |
|
$result = get_transient( $key ); |
336
|
|
|
|
337
|
2 |
|
if ( is_wp_error( $result ) ) { |
338
|
|
|
|
339
|
|
|
gravityview()->log->debug( 'Fetching request resulted in error:', array( 'data' => $result ) ); |
340
|
|
|
|
341
|
|
|
return false; |
342
|
|
|
|
343
|
2 |
|
} elseif ( $result ) { |
344
|
|
|
|
345
|
2 |
|
gravityview()->log->debug( 'Cached results found for transient key {key}', array( 'key' => $key ) ); |
346
|
|
|
|
347
|
2 |
|
return $result; |
348
|
|
|
} |
349
|
|
|
|
350
|
2 |
|
gravityview()->log->debug( 'No cached results found for transient key {key}', array( 'key' => $key ) ); |
351
|
|
|
|
352
|
2 |
|
return NULL; |
|
|
|
|
353
|
|
|
|
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* Cache content as a transient. |
358
|
|
|
* |
359
|
|
|
* Cache time defaults to 1 week |
360
|
|
|
* |
361
|
|
|
* @param [type] $content [description] |
|
|
|
|
362
|
|
|
* @param [type] $filter_name Name used to modify the cache time. Will be set to `gravityview_cache_time_{$filter_name}`. |
|
|
|
|
363
|
|
|
*/ |
364
|
2 |
|
public function set( $content, $filter_name = '' ) { |
365
|
|
|
|
366
|
|
|
// Don't cache empty results |
367
|
2 |
|
if ( ! empty( $content ) ) { |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* @filter `gravityview_cache_time_{$filter_name}` Modify the cache time for a type of cache |
371
|
|
|
* @param int $time_in_seconds Default: `DAY_IN_SECONDS` |
372
|
|
|
*/ |
373
|
2 |
|
$cache_time = (int) apply_filters( 'gravityview_cache_time_' . $filter_name, DAY_IN_SECONDS ); |
374
|
|
|
|
375
|
2 |
|
gravityview()->log->debug( 'Setting cache with transient key {key} for {cache_time} seconds', array( 'key' => $this->key, 'cache_time' => $cache_time ) ); |
376
|
|
|
|
377
|
2 |
|
return set_transient( $this->key, $content, $cache_time ); |
378
|
|
|
|
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
gravityview()->log->debug( 'Cache not set; content is empty' ); |
382
|
|
|
|
383
|
|
|
return false; |
384
|
|
|
|
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
/** |
388
|
|
|
* Delete cached transients based on form IDs |
389
|
|
|
* |
390
|
|
|
* @todo Use REGEX to match forms when array of form IDs is passed, instead of using a simple LIKE |
391
|
|
|
* @todo Rate limit deleting to prevent abuse |
392
|
|
|
* |
393
|
|
|
* @param int|array $form_ids Form IDs to delete |
394
|
|
|
* |
395
|
|
|
* @return [type] [description] |
|
|
|
|
396
|
|
|
*/ |
397
|
2 |
|
public function delete( $form_ids = NULL ) { |
|
|
|
|
398
|
2 |
|
global $wpdb; |
|
|
|
|
399
|
|
|
|
400
|
|
|
// Use object var if exists |
401
|
2 |
|
$form_ids = is_null( $form_ids ) ? $this->form_ids : $form_ids; |
402
|
|
|
|
403
|
2 |
|
if ( empty( $form_ids ) ) { |
404
|
|
|
gravityview()->log->debug( 'Did not delete cache; empty form IDs' ); |
405
|
|
|
|
406
|
|
|
return; |
407
|
|
|
} |
408
|
|
|
|
409
|
2 |
|
foreach ( (array) $form_ids as $form_id ) { |
410
|
|
|
|
411
|
2 |
|
$key = '_transient_gv-cache-'; |
412
|
|
|
|
413
|
|
|
// WordPress 4.0+ |
414
|
2 |
|
if ( is_callable( array( $wpdb, 'esc_like' ) ) ) { |
415
|
2 |
|
$key = $wpdb->esc_like( $key ); |
416
|
|
|
} else { |
417
|
|
|
$key = like_escape( $key ); |
418
|
|
|
} |
419
|
|
|
|
420
|
2 |
|
$form_id = intval( $form_id ); |
421
|
|
|
|
422
|
|
|
// Find the transients containing this form |
423
|
2 |
|
$key = "$key%f:$form_id-%"; // \_transient\_gv-cache-%f:1-% for example |
424
|
2 |
|
$sql = $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE `option_name` LIKE %s", $key ); |
425
|
|
|
|
426
|
2 |
|
foreach ( ( $transients = $wpdb->get_col( $sql ) ) as $transient ) { |
|
|
|
|
427
|
|
|
// We have to delete it via the API to make sure the object cache is updated appropriately |
428
|
2 |
|
delete_transient( preg_replace( '#^_transient_#', '', $transient ) ); |
429
|
|
|
} |
430
|
|
|
|
431
|
2 |
|
gravityview()->log->debug( 'Deleting cache for form #{form_id}', array( 'form_id' => $form_id, 'data' => array( |
|
|
|
|
432
|
2 |
|
$sql, |
433
|
2 |
|
sprintf( 'Deleted results: %d', count( $transients ) ) |
|
|
|
|
434
|
|
|
) ) ); |
435
|
|
|
} |
436
|
|
|
|
437
|
2 |
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Schedule expired transient cleanup twice a day. |
441
|
|
|
* |
442
|
|
|
* Can be overruled by the `gravityview_cleanup_transients` filter (returns boolean) |
443
|
|
|
* |
444
|
|
|
* @return void |
445
|
|
|
*/ |
446
|
|
|
public function schedule_transient_cleanup() { |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* @filter `gravityview_cleanup_transients` Override GravityView cleanup of transients by setting this to false |
450
|
|
|
* @param boolean $cleanup Whether to run the GravityView auto-cleanup of transients. Default: `true` |
451
|
|
|
*/ |
452
|
|
|
$cleanup = apply_filters( 'gravityview_cleanup_transients', true ); |
453
|
|
|
|
454
|
|
|
if ( ! $cleanup ) { |
455
|
|
|
return; |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
if ( ! wp_next_scheduled( 'gravityview-expired-transients' ) ) { |
459
|
|
|
wp_schedule_event( time(), 'daily', 'gravityview-expired-transients' ); |
460
|
|
|
} |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* Delete expired transients. |
465
|
|
|
* |
466
|
|
|
* The code is copied from the Delete Expired Transients, with slight modifications to track # of results and to get the blog ID dynamically |
467
|
|
|
* |
468
|
|
|
* @see https://wordpress.org/plugins/delete-expired-transients/ Plugin where the code was taken from |
469
|
|
|
* @see DelxtransCleaners::clearBlogExpired() |
470
|
|
|
* @return void |
471
|
|
|
*/ |
472
|
|
|
public function delete_expired_transients() { |
473
|
|
|
global $wpdb; |
|
|
|
|
474
|
|
|
|
475
|
|
|
// Added this line, which isn't in the plugin |
476
|
|
|
$blog_id = get_current_blog_id(); |
477
|
|
|
|
478
|
|
|
$num_results = 0; |
479
|
|
|
|
480
|
|
|
// get current PHP time, offset by a minute to avoid clashes with other tasks |
481
|
|
|
$threshold = time() - 60; |
482
|
|
|
|
483
|
|
|
// get table name for options on specified blog |
484
|
|
|
$table = $wpdb->get_blog_prefix( $blog_id ) . 'options'; |
485
|
|
|
|
486
|
|
|
// delete expired transients, using the paired timeout record to find them |
487
|
|
|
$sql = " |
488
|
|
|
delete from t1, t2 |
489
|
|
|
using $table t1 |
490
|
|
|
join $table t2 on t2.option_name = replace(t1.option_name, '_timeout', '') |
491
|
|
|
where (t1.option_name like '\_transient\_timeout\_%' or t1.option_name like '\_site\_transient\_timeout\_%') |
492
|
|
|
and t1.option_value < '$threshold' |
493
|
|
|
"; |
494
|
|
|
|
495
|
|
|
$num_results = $wpdb->query( $sql ); |
|
|
|
|
496
|
|
|
|
497
|
|
|
// delete orphaned transient expirations |
498
|
|
|
// also delete NextGEN Gallery 2.x display cache timeout aliases |
499
|
|
|
$sql = " |
500
|
|
|
delete from $table |
501
|
|
|
where ( |
502
|
|
|
option_name like '\_transient\_timeout\_%' |
503
|
|
|
or option_name like '\_site\_transient\_timeout\_%' |
504
|
|
|
or option_name like 'displayed\_galleries\_%' |
505
|
|
|
or option_name like 'displayed\_gallery\_rendering\_%' |
506
|
|
|
) |
507
|
|
|
and option_value < '$threshold' |
508
|
|
|
"; |
509
|
|
|
|
510
|
|
|
$num_results += $wpdb->query( $sql ); |
|
|
|
|
511
|
|
|
|
512
|
|
|
gravityview()->log->debug( 'Deleted {count} expired transient records from the database', array( 'count' => $num_results ) ); |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* Check whether to use cached results, if available |
517
|
|
|
* |
518
|
|
|
* If the user can edit posts, they are able to override whether to cache results by adding `cache` or `nocache` to the URL requested. |
519
|
|
|
* |
520
|
|
|
* @return boolean True: use cache; False: don't use cache |
521
|
|
|
*/ |
522
|
2 |
|
public function use_cache() { |
523
|
|
|
|
524
|
|
|
// Exit early if debugging (unless running PHPUnit) |
525
|
2 |
|
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! ( defined('DOING_GRAVITYVIEW_TESTS' ) && DOING_GRAVITYVIEW_TESTS ) ) { |
|
|
|
|
526
|
|
|
return apply_filters( 'gravityview_use_cache', false, $this ); |
527
|
|
|
} |
528
|
|
|
|
529
|
2 |
|
$use_cache = true; |
530
|
|
|
|
531
|
2 |
|
if ( GVCommon::has_cap( 'edit_gravityviews' ) ) { |
532
|
|
|
|
533
|
|
|
if ( isset( $_GET['cache'] ) || isset( $_GET['nocache'] ) ) { |
|
|
|
|
534
|
|
|
|
535
|
|
|
gravityview()->log->debug( 'Not using cache: ?cache or ?nocache is in the URL' ); |
536
|
|
|
|
537
|
|
|
$use_cache = false; |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
} |
541
|
|
|
|
542
|
|
|
// Has the form been flagged as having changed items in it? |
543
|
2 |
|
if ( $this->in_blacklist() || ! $use_cache ) { |
544
|
|
|
|
545
|
|
|
// Delete caches for all items with form IDs XYZ |
546
|
|
|
$this->delete( $this->form_ids ); |
547
|
|
|
|
548
|
|
|
// Remove the form from |
549
|
|
|
$this->blacklist_remove( $this->form_ids ); |
550
|
|
|
|
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* @filter `gravityview_use_cache` Modify whether to use the cache or not |
555
|
|
|
* @param[out,in] boolean $use_cache Previous setting |
556
|
|
|
* @param[out] GravityView_Cache $this The GravityView_Cache object |
557
|
|
|
*/ |
558
|
2 |
|
$use_cache = apply_filters( 'gravityview_use_cache', $use_cache, $this ); |
559
|
|
|
|
560
|
2 |
|
return (boolean) $use_cache; |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
} |
564
|
|
|
|
565
|
|
|
new GravityView_Cache; |
566
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.