PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.0.2
GiveWP – Donation Plugin and Fundraising Platform v2.0.2
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / class-give-cache.php
give / includes Last commit date
admin 8 years ago api 8 years ago deprecated 8 years ago donors 8 years ago emails 8 years ago forms 8 years ago gateways 8 years ago libraries 8 years ago payments 8 years ago actions.php 8 years ago ajax-functions.php 8 years ago class-give-async-process.php 8 years ago class-give-background-updater.php 8 years ago class-give-cache.php 8 years ago class-give-cli-commands.php 8 years ago class-give-cron.php 8 years ago class-give-db-donor-meta.php 8 years ago class-give-db-donors.php 8 years ago class-give-db-form-meta.php 8 years ago class-give-db-logs-meta.php 8 years ago class-give-db-logs.php 8 years ago class-give-db-meta.php 8 years ago class-give-db-payment-meta.php 8 years ago class-give-db.php 8 years ago class-give-donate-form.php 8 years ago class-give-donor.php 8 years ago class-give-email-access.php 8 years ago class-give-gravatars.php 8 years ago class-give-html-elements.php 8 years ago class-give-license-handler.php 8 years ago class-give-logging.php 8 years ago class-give-roles.php 8 years ago class-give-session.php 8 years ago class-give-stats.php 8 years ago class-give-template-loader.php 9 years ago class-give-tooltips.php 8 years ago class-give-translation.php 8 years ago class-notices.php 8 years ago country-functions.php 8 years ago currency-functions.php 8 years ago error-tracking.php 8 years ago filters.php 8 years ago formatting.php 8 years ago import-functions.php 8 years ago install.php 8 years ago login-register.php 8 years ago misc-functions.php 8 years ago plugin-compatibility.php 8 years ago post-types.php 8 years ago price-functions.php 8 years ago process-donation.php 8 years ago scripts.php 8 years ago shortcodes.php 8 years ago template-functions.php 8 years ago user-functions.php 8 years ago
class-give-cache.php
715 lines
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 {
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
84 /**
85 * Get cache key.
86 *
87 * @since 1.8.7
88 *
89 * @param string $action Cache key prefix.
90 * @param array $query_args (optional) Query array.
91 * @param bool $is_prefix
92 *
93 * @return string
94 */
95 public static function get_key( $action, $query_args = null, $is_prefix = true ) {
96 // Bailout.
97 if ( empty( $action ) ) {
98 return new WP_Error( 'give_invalid_cache_key_action', __( 'Do not pass empty action to generate cache key.', 'give' ) );
99 }
100
101 // Set cache key.
102 $cache_key = $is_prefix ? "give_cache_{$action}" : $action;
103
104 // Bailout.
105 if ( ! empty( $query_args ) ) {
106 $cache_key = "{$cache_key}_" . substr( md5( serialize( $query_args ) ), 0, 15 );
107 }
108
109 /**
110 * Filter the cache key name.
111 *
112 * @since 2.0
113 */
114 return apply_filters( 'give_get_cache_key', $cache_key, $action, $query_args );
115 }
116
117 /**
118 * Get cache.
119 *
120 * @since 1.8.7
121 *
122 * @param string $cache_key
123 * @param bool $custom_key
124 * @param mixed $query_args
125 *
126 * @return mixed
127 */
128 public static function get( $cache_key, $custom_key = false, $query_args = array() ) {
129 if ( ! self::is_valid_cache_key( $cache_key ) ) {
130 if ( ! $custom_key ) {
131 return new WP_Error( 'give_invalid_cache_key', __( 'Cache key format should be give_cache_*', 'give' ) );
132 }
133
134 $cache_key = self::get_key( $cache_key, $query_args );
135 }
136
137 $option = get_option( $cache_key );
138
139 // Backward compatibility (<1.8.7).
140 if ( ! is_array( $option ) || empty( $option ) || ! array_key_exists( 'expiration', $option ) ) {
141 return $option;
142 }
143
144 // Get current time.
145 $current_time = current_time( 'timestamp', 1 );
146
147 if ( empty( $option['expiration'] ) || ( $current_time < $option['expiration'] ) ) {
148 $option = $option['data'];
149 } else {
150 $option = false;
151 }
152
153 return $option;
154 }
155
156 /**
157 * Set cache.
158 *
159 * @since 1.8.7
160 *
161 * @param string $cache_key
162 * @param mixed $data
163 * @param int|null $expiration Timestamp should be in GMT format.
164 * @param bool $custom_key
165 * @param mixed $query_args
166 *
167 * @return mixed
168 */
169 public static function set( $cache_key, $data, $expiration = null, $custom_key = false, $query_args = array() ) {
170 if ( ! self::is_valid_cache_key( $cache_key ) ) {
171 if ( ! $custom_key ) {
172 return new WP_Error( 'give_invalid_cache_key', __( 'Cache key format should be give_cache_*', 'give' ) );
173 }
174
175 $cache_key = self::get_key( $cache_key, $query_args );
176 }
177
178 $option_value = array(
179 'data' => $data,
180 'expiration' => ! is_null( $expiration )
181 ? ( $expiration + current_time( 'timestamp', 1 ) )
182 : null,
183 );
184
185 $result = update_option( $cache_key, $option_value, 'no' );
186
187 return $result;
188 }
189
190 /**
191 * Delete cache.
192 *
193 * Note: only for internal use
194 *
195 * @since 1.8.7
196 *
197 * @param string|array $cache_keys
198 *
199 * @return bool|WP_Error
200 */
201 public static function delete( $cache_keys ) {
202 $result = true;
203 $invalid_keys = array();
204
205 if ( ! empty( $cache_keys ) ) {
206 $cache_keys = is_array( $cache_keys ) ? $cache_keys : array( $cache_keys );
207
208 foreach ( $cache_keys as $cache_key ) {
209 if ( ! self::is_valid_cache_key( $cache_key ) ) {
210 $invalid_keys[] = $cache_key;
211 $result = false;
212 }
213
214 delete_option( $cache_key );
215 }
216 }
217
218 if ( ! $result ) {
219 $result = new WP_Error(
220 'give_invalid_cache_key',
221 __( 'Cache key format should be give_cache_*', 'give' ),
222 $invalid_keys
223 );
224 }
225
226 return $result;
227 }
228
229 /**
230 * Delete all logging cache.
231 *
232 * Note: only for internal use
233 *
234 * @since 1.8.7
235 * @access public
236 * @global wpdb $wpdb
237 *
238 * @param bool $force If set to true then all cached values will be delete instead of only expired
239 *
240 * @return bool
241 */
242 public static function delete_all_expired( $force = false ) {
243 global $wpdb;
244 $options = $wpdb->get_results(
245 $wpdb->prepare(
246 "SELECT option_name, option_value
247 FROM {$wpdb->options}
248 Where option_name
249 LIKE '%%%s%%'",
250 'give_cache'
251 ),
252 ARRAY_A
253 );
254
255 // Bailout.
256 if ( empty( $options ) ) {
257 return false;
258 }
259
260 $current_time = current_time( 'timestamp', 1 );
261
262 // Delete log cache.
263 foreach ( $options as $option ) {
264 $option['option_value'] = maybe_unserialize( $option['option_value'] );
265
266 if (
267 (
268 ! self::is_valid_cache_key( $option['option_name'] )
269 || ! is_array( $option['option_value'] ) // Backward compatibility (<1.8.7).
270 || ! array_key_exists( 'expiration', $option['option_value'] ) // Backward compatibility (<1.8.7).
271 || empty( $option['option_value']['expiration'] )
272 || ( $current_time < $option['option_value']['expiration'] )
273 )
274 && ! $force
275 ) {
276 continue;
277 }
278
279 self::delete( $option['option_name'] );
280 }
281 }
282
283
284 /**
285 * Get list of options like.
286 *
287 * Note: only for internal use
288 *
289 * @since 1.8.7
290 * @access public
291 *
292 * @param string $option_name
293 * @param bool $fields
294 *
295 * @return array
296 */
297 public static function get_options_like( $option_name, $fields = false ) {
298 global $wpdb;
299
300 $field_names = $fields ? 'option_name, option_value' : 'option_name';
301
302 if ( $fields ) {
303 $options = $wpdb->get_results(
304 $wpdb->prepare(
305 "SELECT {$field_names }
306 FROM {$wpdb->options}
307 Where option_name
308 LIKE '%%%s%%'",
309 "give_cache_{$option_name}"
310 ),
311 ARRAY_A
312 );
313 } else {
314 $options = $wpdb->get_col(
315 $wpdb->prepare(
316 "SELECT *
317 FROM {$wpdb->options}
318 Where option_name
319 LIKE '%%%s%%'",
320 "give_cache_{$option_name}"
321 ),
322 1
323 );
324 }
325
326 if ( ! empty( $options ) && $fields ) {
327 foreach ( $options as $index => $option ) {
328 $option['option_value'] = maybe_unserialize( $option['option_value'] );
329 $options[ $index ] = $option;
330 }
331 }
332
333 return $options;
334 }
335
336 /**
337 * Check cache key validity.
338 *
339 * @since 1.8.7
340 * @access public
341 *
342 * @param $cache_key
343 *
344 * @return bool
345 */
346 public static function is_valid_cache_key( $cache_key ) {
347 $is_valid = ( false !== strpos( $cache_key, 'give_cache_' ) );
348
349
350 /**
351 * Filter the flag which tell about cache key valid or not
352 *
353 * @since 2.0
354 */
355 return apply_filters( 'give_is_valid_cache_key', $is_valid, $cache_key );
356 }
357
358
359 /**
360 * Get cache from group
361 *
362 * @since 2.0
363 * @access public
364 *
365 * @param int $id
366 * @param string $group
367 *
368 * @return mixed
369 */
370 public static function get_group( $id, $group = '' ) {
371 $cached_data = null;
372
373 // Bailout.
374 if ( self::$instance->is_cache && ! empty( $id ) ) {
375 $group = self::$instance->filter_group_name( $group );
376
377 $cached_data = wp_cache_get( $id, $group );
378 $cached_data = false !== $cached_data ? $cached_data : null;
379 }
380
381 return $cached_data;
382 }
383
384 /**
385 * Cache small chunks inside group
386 *
387 * @since 2.0
388 * @access public
389 *
390 * @param int $id
391 * @param mixed $data
392 * @param string $group
393 * @param int $expire
394 *
395 * @return bool
396 */
397 public static function set_group( $id, $data, $group = '', $expire = 0 ) {
398 $status = false;
399
400 // Bailout.
401 if ( ! self::$instance->is_cache || empty( $id ) ) {
402 return $status;
403 }
404
405 $group = self::$instance->filter_group_name( $group );
406
407 $status = wp_cache_set( $id, $data, $group, $expire );
408
409 return $status;
410 }
411
412 /**
413 * Cache small db query chunks inside group
414 *
415 * @since 2.0
416 * @access public
417 *
418 * @param int $id
419 * @param mixed $data
420 *
421 * @return bool
422 */
423 public static function set_db_query( $id, $data ) {
424 $status = false;
425
426 // Bailout.
427 if ( ! self::$instance->is_cache || empty( $id ) ) {
428 return $status;
429 }
430
431 return self::set_group( $id, $data, 'give-db-queries', 0 );
432 }
433
434 /**
435 * Get cache from group
436 *
437 * @since 2.0
438 * @access public
439 *
440 * @param int $id
441 *
442 * @return mixed
443 */
444 public static function get_db_query( $id ) {
445 return self::get_group( $id, 'give-db-queries' );
446 }
447
448 /**
449 * Delete group cache
450 *
451 * @since 2.0
452 * @access public
453 *
454 * @param int|array $ids
455 * @param string $group
456 * @param int $expire
457 *
458 * @return bool
459 */
460 public static function delete_group( $ids, $group = '', $expire = 0 ) {
461 $status = false;
462
463 // Bailout.
464 if ( ! self::$instance->is_cache || empty( $ids ) ) {
465 return $status;
466 }
467
468 $group = self::$instance->filter_group_name( $group );
469
470 // Delete single or multiple cache items from cache.
471 if ( ! is_array( $ids ) ) {
472 $status = wp_cache_delete( $ids, $group, $expire );
473 self::$instance->get_incrementer( true );
474
475 /**
476 * Fire action when cache deleted for specific id.
477 *
478 * @since 2.0
479 *
480 * @param string $ids
481 * @param string $group
482 * @param int $expire
483 */
484 do_action( "give_deleted_{$group}_cache", $ids, $group, $expire, $status );
485
486 } else {
487 foreach ( $ids as $id ) {
488 $status = wp_cache_delete( $id, $group, $expire );
489 self::$instance->get_incrementer( true );
490
491 /**
492 * Fire action when cache deleted for specific id .
493 *
494 * @since 2.0
495 *
496 * @param string $ids
497 * @param string $group
498 * @param int $expire
499 */
500 do_action( "give_deleted_{$group}_cache", $id, $group, $expire, $status );
501 }
502 }
503
504 return $status;
505 }
506
507
508 /**
509 * Delete form related cache
510 * Note: only use for internal purpose.
511 *
512 * @since 2.0
513 * @access public
514 *
515 * @param int $form_id
516 */
517 public function delete_form_related_cache( $form_id ) {
518 // If this is just a revision, don't send the email.
519 if ( wp_is_post_revision( $form_id ) ) {
520 return;
521 }
522
523 $donation_query = new Give_Payments_Query(
524 array(
525 'number' => - 1,
526 'give_forms' => $form_id,
527 )
528 );
529
530 $donations = $donation_query->get_payments();
531
532 if ( ! empty( $donations ) ) {
533 /* @var Give_Payment $donation */
534 foreach ( $donations as $donation ) {
535 wp_cache_delete( $donation->ID, $this->filter_group_name( 'give-donations' ) );
536 wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
537 }
538 }
539
540 self::$instance->get_incrementer( true );
541 }
542
543 /**
544 * Delete payment related cache
545 * Note: only use for internal purpose.
546 *
547 * @since 2.0
548 * @access public
549 *
550 * @param int $donation_id
551 */
552 public function delete_payment_related_cache( $donation_id ) {
553 // If this is just a revision, don't send the email.
554 if ( wp_is_post_revision( $donation_id ) ) {
555 return;
556 }
557
558 /* @var Give_Payment $donation */
559 $donation = new Give_Payment( $donation_id );
560
561 if ( $donation && $donation->donor_id ) {
562 wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
563 }
564
565 wp_cache_delete( $donation->ID, $this->filter_group_name( 'give-donations' ) );
566
567 self::$instance->get_incrementer( true );
568 }
569
570 /**
571 * Delete donor related cache
572 * Note: only use for internal purpose.
573 *
574 * @since 2.0
575 * @access public
576 *
577 * @param string $id
578 * @param string $group
579 * @param int $expire
580 */
581 public function delete_donor_related_cache( $id, $group, $expire ) {
582 $donor = new Give_Donor( $id );
583 $donation_ids = array_map( 'trim', (array) explode( ',', trim( $donor->payment_ids ) ) );
584
585 if ( ! empty( $donation_ids ) ) {
586 foreach ( $donation_ids as $donation ) {
587 wp_cache_delete( $donation, $this->filter_group_name( 'give-donations' ) );
588 }
589 }
590
591 self::$instance->get_incrementer( true );
592 }
593
594 /**
595 * Delete donations related cache
596 * Note: only use for internal purpose.
597 *
598 * @since 2.0
599 * @access public
600 *
601 * @param string $id
602 * @param string $group
603 * @param int $expire
604 */
605 public function delete_donations_related_cache( $id, $group, $expire ) {
606 /* @var Give_Payment $donation */
607 $donation = new Give_Payment( $id );
608
609 if ( $donation && $donation->donor_id ) {
610 wp_cache_delete( $donation->donor_id, $this->filter_group_name( 'give-donors' ) );
611 }
612
613 self::$instance->get_incrementer( true );
614 }
615
616
617 /**
618 * Get unique incrementer.
619 *
620 * @see https://core.trac.wordpress.org/ticket/4476
621 * @see https://www.tollmanz.com/invalidation-schemes/
622 *
623 * @since 2.0
624 * @access private
625 *
626 * @param bool $refresh
627 * @param string $incrementer_key
628 *
629 * @return string
630 */
631 private function get_incrementer( $refresh = false, $incrementer_key = 'give-cache-incrementer-db-queries' ) {
632 $incrementer_value = wp_cache_get( $incrementer_key );
633
634 if ( false === $incrementer_value || true === $refresh ) {
635 $incrementer_value = microtime( true );
636 wp_cache_set( $incrementer_key, $incrementer_value );
637 }
638
639 return $incrementer_value;
640 }
641
642
643 /**
644 * Flush cache on cache setting enable/disable
645 * Note: only for internal use
646 *
647 * @since 2.0
648 * @access public
649 */
650 public function flush_cache() {
651 if (
652 Give_Admin_Settings::is_saving_settings() &&
653 isset( $_POST['cache'] ) &&
654 give_is_setting_enabled( give_clean( $_POST['cache'] ) )
655 ) {
656 $this->get_incrementer( true );
657 $this->get_incrementer( true, 'give-cache-incrementer' );
658 }
659 }
660
661
662 /**
663 * Filter the group name
664 *
665 * @since 2.0
666 * @access private
667 *
668 * @param $group
669 *
670 * @return mixed
671 */
672 private function filter_group_name( $group ) {
673 if ( ! empty( $group ) ) {
674 $incrementer = self::$instance->get_incrementer( false, 'give-cache-incrementer' );
675
676 if ( 'give-db-queries' === $group ) {
677 $incrementer = self::$instance->get_incrementer();
678 }
679
680 $group = "{$group}_{$incrementer}";
681 }
682
683 /**
684 * Filter the group name
685 *
686 * @since 2.0
687 */
688 return $group;
689 }
690
691
692 /**
693 * Disable cache.
694 *
695 * @since 2.0
696 * @access public
697 */
698 public static function disable() {
699 self::get_instance()->is_cache = false;
700 }
701
702 /**
703 * Enable cache.
704 *
705 * @since 2.0
706 * @access public
707 */
708 public static function enable() {
709 self::get_instance()->is_cache = true;
710 }
711 }
712
713 // Initialize
714 Give_Cache::get_instance()->setup();
715