Test Failed
Pull Request — master (#2854)
by Devin
05:38
created

Give_Cache::delete_donations_related_cache()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 3
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class for managing cache
4
 * Note: only use for internal purpose.
5
 *
6
 * @package     Give
7
 * @subpackage  Classes/Give_Cache
8
 * @copyright   Copyright (c) 2017, WordImpress
9
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
10
 * @since       1.8.7
11
 */
12
13
// Exit if accessed directly.
14
if ( ! defined( 'ABSPATH' ) ) {
15
	exit;
16
}
17
18
class Give_Cache {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
19
	/**
20
	 * Instance.
21
	 *
22
	 * @since  1.8.7
23
	 * @access private
24
	 * @var Give_Cache
25
	 */
26
	static private $instance;
27
28
	/**
29
	 * Flag to check if caching enabled or not.
30
	 *
31
	 * @since  2.0
32
	 * @access private
33
	 * @var
34
	 */
35
	private $is_cache;
36
37
	/**
38
	 * Singleton pattern.
39
	 *
40
	 * @since  1.8.7
41
	 * @access private
42
	 * Give_Cache constructor.
43
	 */
44
	private function __construct() {
45
	}
46
47
48
	/**
49
	 * Get instance.
50
	 *
51
	 * @since  1.8.7
52
	 * @access public
53
	 * @return static
54
	 */
55
	public static function get_instance() {
56
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Give_Cache ) ) {
57
			self::$instance = new Give_Cache();
58
		}
59
60
		return self::$instance;
61
	}
62
63
	/**
64
	 * Setup hooks.
65
	 *
66
	 * @since  1.8.7
67
	 * @access public
68
	 */
69
	public function setup() {
70
		// Currently enable cache only for backend.
71
		self::$instance->is_cache = ( defined( 'GIVE_CACHE' ) ? GIVE_CACHE : give_is_setting_enabled( give_get_option( 'cache', 'enabled' ) ) ) && is_admin();
72
73
		// weekly delete all expired cache.
74
		Give_Cron::add_weekly_event( array( $this, 'delete_all_expired' ) );
75
76
		add_action( 'save_post_give_forms', array( $this, 'delete_form_related_cache' ) );
77
		add_action( 'save_post_give_payment', array( $this, 'delete_payment_related_cache' ) );
78
		add_action( 'give_deleted_give-donors_cache', array( $this, 'delete_donor_related_cache' ), 10, 3 );
79
		add_action( 'give_deleted_give-donations_cache', array( $this, 'delete_donations_related_cache' ), 10, 3 );
80
81
		add_action( 'give_save_settings_give_settings', array( $this, 'flush_cache' ) );
82
83
		add_action( 'wp', array( __CLASS__,  'prevent_caching' ) );
0 ignored issues
show
introduced by
Expected 1 space between comma and "'prevent_caching'"; 2 found
Loading history...
84
		add_action( 'admin_notices', array( $this, '__notices' ) );
85
	}
86
87
	/**
88
	 * Prevent caching on certain pages
89
	 *
90
	 * @since  2.0.5
91
	 * @access public
92
	 * @credit WooCommerce
93
	 */
94
	public static function prevent_caching() {
95
		if ( ! is_blog_installed() ) {
96
			return;
97
		}
98
99
		$page_ids = array_filter( array(
100
			give_get_option( 'success_page' ),
101
			give_get_option( 'failure_page' ),
102
			give_get_option( 'history_page' ),
103
		) );
104
105
		if (
106
			is_page( $page_ids )
107
			|| is_singular( 'give_forms' )
108
		) {
109
			self::set_nocache_constants();
110
			nocache_headers();
111
		}
112
	}
113
114
	/**
115
	 * Set constants to prevent caching by some plugins.
116
	 *
117
	 * @since  2.0.5
118
	 * @access public
119
	 * @credit WooCommerce
120
	 *
121
	 * @param  mixed $return Value to return. Previously hooked into a filter.
122
	 *
123
	 * @return mixed
124
	 */
125
	public static function set_nocache_constants( $return = true ) {
126
		give_maybe_define_constant( 'DONOTCACHEPAGE', true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
127
		give_maybe_define_constant( 'DONOTCACHEOBJECT', true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
128
		give_maybe_define_constant( 'DONOTCACHEDB', true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
129
130
		return $return;
131
	}
132
133
	/**
134
	 * Notices function.
135
	 *
136
	 * @since  2.0.5
137
	 * @access public
138
	 * @credit WooCommerce
139
	 */
140
	public function __notices() {
0 ignored issues
show
Coding Style introduced by
Method name "Give_Cache::__notices" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
141
		if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) {
142
			return;
143
		}
144
145
		$config   = w3_instance( 'W3_Config' );
146
		$enabled  = $config->get_integer( 'dbcache.enabled' );
147
		$settings = array_map( 'trim', $config->get_array( 'dbcache.reject.sql' ) );
148
149
		if ( $enabled && ! in_array( 'give', $settings, true ) ) {
150
			?>
151
			<div class="error">
152
				<p><?php echo wp_kses_post( sprintf( __( 'In order for <strong>database caching</strong> to work with Give you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'give' ), '<code>give</code>', esc_url( admin_url( 'admin.php?page=w3tc_dbcache' ) ) ) ); ?></p>
153
			</div>
154
			<?php
155
		}
156
	}
157
158
	/**
159
	 * Get cache key.
160
	 *
161
	 * @since  1.8.7
162
	 *
163
	 * @param  string $action     Cache key prefix.
164
	 * @param  array  $query_args (optional) Query array.
165
	 * @param  bool   $is_prefix
166
	 *
167
	 * @return string
168
	 */
169
	public static function get_key( $action, $query_args = null, $is_prefix = true ) {
170
		// Bailout.
171
		if ( empty( $action ) ) {
172
			return new WP_Error( 'give_invalid_cache_key_action', __( 'Do not pass empty action to generate cache key.', 'give' ) );
173
		}
174
175
		// Set cache key.
176
		$cache_key = $is_prefix ? "give_cache_{$action}" : $action;
177
178
		// Bailout.
179
		if ( ! empty( $query_args ) ) {
180
			$cache_key = "{$cache_key}_" . substr( md5( serialize( $query_args ) ), 0, 15 );
181
		}
182
183
		/**
184
		 * Filter the cache key name.
185
		 *
186
		 * @since 2.0
187
		 */
188
		return apply_filters( 'give_get_cache_key', $cache_key, $action, $query_args );
189
	}
190
191
	/**
192
	 * Get cache.
193
	 *
194
	 * @since  1.8.7
195
	 *
196
	 * @param  string $cache_key
197
	 * @param  bool   $custom_key
198
	 * @param  mixed  $query_args
199
	 *
200
	 * @return mixed
201
	 */
202
	public static function get( $cache_key, $custom_key = false, $query_args = array() ) {
203 View Code Duplication
		if ( ! self::is_valid_cache_key( $cache_key ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
204
			if ( ! $custom_key ) {
205
				return new WP_Error( 'give_invalid_cache_key', __( 'Cache key format should be give_cache_*', 'give' ) );
206
			}
207
208
			$cache_key = self::get_key( $cache_key, $query_args );
209
		}
210
211
		$option = get_option( $cache_key );
212
213
		// Backward compatibility (<1.8.7).
214
		if ( ! is_array( $option ) || empty( $option ) || ! array_key_exists( 'expiration', $option ) ) {
215
			return $option;
216
		}
217
218
		// Get current time.
219
		$current_time = current_time( 'timestamp', 1 );
220
221
		if ( empty( $option['expiration'] ) || ( $current_time < $option['expiration'] ) ) {
222
			$option = $option['data'];
223
		} else {
224
			$option = false;
225
		}
226
227
		return $option;
228
	}
229
230
	/**
231
	 * Set cache.
232
	 *
233
	 * @since  1.8.7
234
	 *
235
	 * @param  string   $cache_key
236
	 * @param  mixed    $data
237
	 * @param  int|null $expiration Timestamp should be in GMT format.
238
	 * @param  bool     $custom_key
239
	 * @param  mixed    $query_args
240
	 *
241
	 * @return mixed
242
	 */
243
	public static function set( $cache_key, $data, $expiration = null, $custom_key = false, $query_args = array() ) {
244 View Code Duplication
		if ( ! self::is_valid_cache_key( $cache_key ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
			if ( ! $custom_key ) {
246
				return new WP_Error( 'give_invalid_cache_key', __( 'Cache key format should be give_cache_*', 'give' ) );
247
			}
248
249
			$cache_key = self::get_key( $cache_key, $query_args );
250
		}
251
252
		$option_value = array(
253
			'data'       => $data,
254
			'expiration' => ! is_null( $expiration )
255
				? ( $expiration + current_time( 'timestamp', 1 ) )
256
				: null,
257
		);
258
259
		$result = update_option( $cache_key, $option_value, 'no' );
260
261
		return $result;
262
	}
263
264
	/**
265
	 * Delete cache.
266
	 *
267
	 * Note: only for internal use
268
	 *
269
	 * @since  1.8.7
270
	 *
271
	 * @param  string|array $cache_keys
272
	 *
273
	 * @return bool|WP_Error
274
	 */
275
	public static function delete( $cache_keys ) {
276
		$result       = true;
277
		$invalid_keys = array();
278
279
		if ( ! empty( $cache_keys ) ) {
280
			$cache_keys = is_array( $cache_keys ) ? $cache_keys : array( $cache_keys );
281
282
			foreach ( $cache_keys as $cache_key ) {
283
				if ( ! self::is_valid_cache_key( $cache_key ) ) {
284
					$invalid_keys[] = $cache_key;
285
					$result         = false;
286
				}
287
288
				delete_option( $cache_key );
289
			}
290
		}
291
292
		if ( ! $result ) {
293
			$result = new WP_Error(
294
				'give_invalid_cache_key',
295
				__( 'Cache key format should be give_cache_*', 'give' ),
296
				$invalid_keys
297
			);
298
		}
299
300
		return $result;
301
	}
302
303
	/**
304
	 * Delete all logging cache.
305
	 *
306
	 * Note: only for internal use
307
	 *
308
	 * @since  1.8.7
309
	 * @access public
310
	 * @global wpdb $wpdb
311
	 *
312
	 * @param bool  $force If set to true then all cached values will be delete instead of only expired
313
	 *
314
	 * @return bool
315
	 */
316
	public static function delete_all_expired( $force = false ) {
317
		global $wpdb;
318
		$options = $wpdb->get_results(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
319
			$wpdb->prepare(
320
				"SELECT option_name, option_value
321
						FROM {$wpdb->options}
322
						Where option_name
323
						LIKE '%%%s%%'",
324
				'give_cache'
325
			),
326
			ARRAY_A
327
		);
328
329
		// Bailout.
330
		if ( empty( $options ) ) {
331
			return false;
332
		}
333
334
		$current_time = current_time( 'timestamp', 1 );
335
336
		// Delete log cache.
337
		foreach ( $options as $option ) {
338
			$option['option_value'] = maybe_unserialize( $option['option_value'] );
339
340
			if (
341
				(
342
					! self::is_valid_cache_key( $option['option_name'] )
343
					|| ! is_array( $option['option_value'] ) // Backward compatibility (<1.8.7).
344
					|| ! array_key_exists( 'expiration', $option['option_value'] ) // Backward compatibility (<1.8.7).
345
					|| empty( $option['option_value']['expiration'] )
346
					|| ( $current_time < $option['option_value']['expiration'] )
347
				)
348
				&& ! $force
349
			) {
350
				continue;
351
			}
352
353
			self::delete( $option['option_name'] );
354
		}
355
	}
356
357
358
	/**
359
	 * Get list of options like.
360
	 *
361
	 * Note: only for internal use
362
	 *
363
	 * @since  1.8.7
364
	 * @access public
365
	 *
366
	 * @param string $option_name
367
	 * @param bool   $fields
368
	 *
369
	 * @return array
370
	 */
371
	public static function get_options_like( $option_name, $fields = false ) {
372
		global $wpdb;
373
374
		$field_names = $fields ? 'option_name, option_value' : 'option_name';
375
376
		if ( $fields ) {
377
			$options = $wpdb->get_results(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
378
				$wpdb->prepare(
379
					"SELECT {$field_names }
380
						FROM {$wpdb->options}
381
						Where option_name
382
						LIKE '%%%s%%'",
383
					"give_cache_{$option_name}"
384
				),
385
				ARRAY_A
386
			);
387
		} else {
388
			$options = $wpdb->get_col(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
389
				$wpdb->prepare(
390
					"SELECT *
391
						FROM {$wpdb->options}
392
						Where option_name
393
						LIKE '%%%s%%'",
394
					"give_cache_{$option_name}"
395
				),
396
				1
397
			);
398
		}
399
400
		if ( ! empty( $options ) && $fields ) {
401
			foreach ( $options as $index => $option ) {
402
				$option['option_value'] = maybe_unserialize( $option['option_value'] );
403
				$options[ $index ]      = $option;
404
			}
405
		}
406
407
		return $options;
408
	}
409
410
	/**
411
	 * Check cache key validity.
412
	 *
413
	 * @since  1.8.7
414
	 * @access public
415
	 *
416
	 * @param $cache_key
417
	 *
418
	 * @return bool
419
	 */
420
	public static function is_valid_cache_key( $cache_key ) {
421
		$is_valid = ( false !== strpos( $cache_key, 'give_cache_' ) );
422
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
423
424
		/**
425
		 * Filter the flag which tell about cache key valid or not
426
		 *
427
		 * @since 2.0
428
		 */
429
		return apply_filters( 'give_is_valid_cache_key', $is_valid, $cache_key );
430
	}
431
432
433
	/**
434
	 * Get cache from group
435
	 *
436
	 * @since  2.0
437
	 * @access public
438
	 *
439
	 * @param int    $id
440
	 * @param string $group
441
	 *
442
	 * @return mixed
443
	 */
444
	public static function get_group( $id, $group = '' ) {
445
		$cached_data = null;
446
447
		// Bailout.
448
		if ( self::$instance->is_cache && ! empty( $id ) ) {
449
			$group = self::$instance->filter_group_name( $group );
450
451
			$cached_data = wp_cache_get( $id, $group );
452
			$cached_data = false !== $cached_data ? $cached_data : null;
453
		}
454
455
		return $cached_data;
456
	}
457
458
	/**
459
	 * Cache small chunks inside group
460
	 *
461
	 * @since  2.0
462
	 * @access public
463
	 *
464
	 * @param int    $id
465
	 * @param mixed  $data
466
	 * @param string $group
467
	 * @param int    $expire
468
	 *
469
	 * @return bool
470
	 */
471
	public static function set_group( $id, $data, $group = '', $expire = 0 ) {
472
		$status = false;
473
474
		// Bailout.
475
		if ( ! self::$instance->is_cache || empty( $id ) ) {
476
			return $status;
477
		}
478
479
		$group = self::$instance->filter_group_name( $group );
480
481
		$status = wp_cache_set( $id, $data, $group, $expire );
482
483
		return $status;
484
	}
485
486
	/**
487
	 * Cache small db query chunks inside group
488
	 *
489
	 * @since  2.0
490
	 * @access public
491
	 *
492
	 * @param int   $id
493
	 * @param mixed $data
494
	 *
495
	 * @return bool
496
	 */
497
	public static function set_db_query( $id, $data ) {
498
		$status = false;
499
500
		// Bailout.
501
		if ( ! self::$instance->is_cache || empty( $id ) ) {
502
			return $status;
503
		}
504
505
		return self::set_group( $id, $data, 'give-db-queries', 0 );
506
	}
507
508
	/**
509
	 * Get cache from group
510
	 *
511
	 * @since  2.0
512
	 * @access public
513
	 *
514
	 * @param int $id
515
	 *
516
	 * @return mixed
517
	 */
518
	public static function get_db_query( $id ) {
519
		return self::get_group( $id, 'give-db-queries' );
520
	}
521
522
	/**
523
	 * Delete group cache
524
	 *
525
	 * @since  2.0
526
	 * @access public
527
	 *
528
	 * @param int|array $ids
529
	 * @param string    $group
530
	 * @param int       $expire
531
	 *
532
	 * @return bool
533
	 */
534
	public static function delete_group( $ids, $group = '', $expire = 0 ) {
535
		$status = false;
536
537
		// Bailout.
538
		if ( ! self::$instance->is_cache || empty( $ids ) ) {
539
			return $status;
540
		}
541
542
		$group = self::$instance->filter_group_name( $group );
543
544
		// Delete single or multiple cache items from cache.
545
		if ( ! is_array( $ids ) ) {
546
			$status = wp_cache_delete( $ids, $group, $expire );
547
			self::$instance->get_incrementer( true );
548
549
			/**
550
			 * Fire action when cache deleted for specific id.
551
			 *
552
			 * @since 2.0
553
			 *
554
			 * @param string $ids
555
			 * @param string $group
556
			 * @param int    $expire
557
			 */
558
			do_action( "give_deleted_{$group}_cache", $ids, $group, $expire, $status );
559
560
		} else {
561
			foreach ( $ids as $id ) {
562
				$status = wp_cache_delete( $id, $group, $expire );
563
				self::$instance->get_incrementer( true );
564
565
				/**
566
				 * Fire action when cache deleted for specific id .
567
				 *
568
				 * @since 2.0
569
				 *
570
				 * @param string $ids
571
				 * @param string $group
572
				 * @param int    $expire
573
				 */
574
				do_action( "give_deleted_{$group}_cache", $id, $group, $expire, $status );
575
			}
576
		}
577
578
		return $status;
579
	}
580
581
582
	/**
583
	 * Delete form related cache
584
	 * Note: only use for internal purpose.
585
	 *
586
	 * @since  2.0
587
	 * @access public
588
	 *
589
	 * @param int $form_id
590
	 */
591
	public function delete_form_related_cache( $form_id ) {
592
		// If this is just a revision, don't send the email.
593
		if ( wp_is_post_revision( $form_id ) ) {
594
			return;
595
		}
596
597
		$donation_query = new Give_Payments_Query(
598
			array(
599
				'number'     => - 1,
600
				'give_forms' => $form_id,
601
			)
602
		);
603
604
		$donations = $donation_query->get_payments();
605
606
		if ( ! empty( $donations ) ) {
607
			/* @var Give_Payment $donation */
608
			foreach ( $donations as $donation ) {
609
				wp_cache_delete( $donation->ID, $this->filter_group_name( 'give-donations' ) );
610
				wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
611
			}
612
		}
613
614
		self::$instance->get_incrementer( true );
615
	}
616
617
	/**
618
	 * Delete payment related cache
619
	 * Note: only use for internal purpose.
620
	 *
621
	 * @since  2.0
622
	 * @access public
623
	 *
624
	 * @param int $donation_id
625
	 */
626
	public function delete_payment_related_cache( $donation_id ) {
627
		// If this is just a revision, don't send the email.
628
		if ( wp_is_post_revision( $donation_id ) ) {
629
			return;
630
		}
631
632
		/* @var Give_Payment $donation */
633
		$donation = new Give_Payment( $donation_id );
634
635
		if ( $donation && $donation->donor_id ) {
636
			wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
637
		}
638
639
		wp_cache_delete( $donation->ID, $this->filter_group_name( 'give-donations' ) );
640
641
		self::$instance->get_incrementer( true );
642
	}
643
644
	/**
645
	 * Delete donor related cache
646
	 * Note: only use for internal purpose.
647
	 *
648
	 * @since  2.0
649
	 * @access public
650
	 *
651
	 * @param string $id
652
	 * @param string $group
653
	 * @param int    $expire
654
	 */
655
	public function delete_donor_related_cache( $id, $group, $expire ) {
0 ignored issues
show
Unused Code introduced by
The parameter $group is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expire is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
656
		$donor        = new Give_Donor( $id );
657
		$donation_ids = array_map( 'trim', (array) explode( ',', trim( $donor->payment_ids ) ) );
658
659
		if ( ! empty( $donation_ids ) ) {
660
			foreach ( $donation_ids as $donation ) {
661
				wp_cache_delete( $donation, $this->filter_group_name( 'give-donations' ) );
662
			}
663
		}
664
665
		self::$instance->get_incrementer( true );
666
	}
667
668
	/**
669
	 * Delete donations related cache
670
	 * Note: only use for internal purpose.
671
	 *
672
	 * @since  2.0
673
	 * @access public
674
	 *
675
	 * @param string $id
676
	 * @param string $group
677
	 * @param int    $expire
678
	 */
679
	public function delete_donations_related_cache( $id, $group, $expire ) {
0 ignored issues
show
Unused Code introduced by
The parameter $group is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $expire is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
680
		/* @var Give_Payment $donation */
681
		$donation = new Give_Payment( $id );
682
683
		if ( $donation && $donation->donor_id ) {
684
			wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
685
		}
686
687
		self::$instance->get_incrementer( true );
688
	}
689
690
691
	/**
692
	 * Get unique incrementer.
693
	 *
694
	 * @see    https://core.trac.wordpress.org/ticket/4476
695
	 * @see    https://www.tollmanz.com/invalidation-schemes/
696
	 *
697
	 * @since  2.0
698
	 * @access private
699
	 *
700
	 * @param bool   $refresh
701
	 * @param string $incrementer_key
702
	 *
703
	 * @return string
704
	 */
705
	private function get_incrementer( $refresh = false, $incrementer_key = 'give-cache-incrementer-db-queries' ) {
706
		$incrementer_value = wp_cache_get( $incrementer_key );
707
708
		if ( false === $incrementer_value || true === $refresh ) {
709
			$incrementer_value = microtime( true );
710
			wp_cache_set( $incrementer_key, $incrementer_value );
711
		}
712
713
		return $incrementer_value;
714
	}
715
716
717
	/**
718
	 * Flush cache on cache setting enable/disable
719
	 * Note: only for internal use
720
	 *
721
	 * @since  2.0
722
	 * @access public
723
	 */
724
	public function flush_cache() {
725
		if (
726
			Give_Admin_Settings::is_saving_settings() &&
727
			isset( $_POST['cache'] ) &&
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
728
			give_is_setting_enabled( give_clean( $_POST['cache'] ) )
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
729
		) {
730
			$this->get_incrementer( true );
731
			$this->get_incrementer( true, 'give-cache-incrementer' );
732
		}
733
	}
734
735
736
	/**
737
	 * Filter the group name
738
	 *
739
	 * @since  2.0
740
	 * @access private
741
	 *
742
	 * @param $group
743
	 *
744
	 * @return mixed
745
	 */
746
	private function filter_group_name( $group ) {
747
		$group = "{$group}_" . get_current_blog_id();
748
749
		if ( ! empty( $group ) ) {
750
			$incrementer = self::$instance->get_incrementer( false, 'give-cache-incrementer' );
751
752
			if ( 'give-db-queries' === $group ) {
753
				$incrementer = self::$instance->get_incrementer();
754
			}
755
756
			$group = "{$group}_{$incrementer}";
757
		}
758
759
		/**
760
		 * Filter the group name
761
		 *
762
		 * @since 2.0
763
		 */
764
		return $group;
765
	}
766
767
768
	/**
769
	 * Disable cache.
770
	 *
771
	 * @since  2.0
772
	 * @access public
773
	 */
774
	public static function disable() {
775
		self::get_instance()->is_cache = false;
776
	}
777
778
	/**
779
	 * Enable cache.
780
	 *
781
	 * @since  2.0
782
	 * @access public
783
	 */
784
	public static function enable() {
785
		self::get_instance()->is_cache = true;
786
	}
787
}
788
789
// Initialize
790
Give_Cache::get_instance()->setup();
791