PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.0.0
GiveWP – Donation Plugin and Fundraising Platform v2.0.0
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
719 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 = 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 if ( empty( $option_name ) ) {
301 return array();
302 }
303
304 $field_names = $fields ? 'option_name, option_value' : 'option_name';
305
306 if ( $fields ) {
307 $options = $wpdb->get_results(
308 $wpdb->prepare(
309 "SELECT {$field_names }
310 FROM {$wpdb->options}
311 Where option_name
312 LIKE '%%%s%%'",
313 "give_cache_{$option_name}"
314 ),
315 ARRAY_A
316 );
317 } else {
318 $options = $wpdb->get_col(
319 $wpdb->prepare(
320 "SELECT *
321 FROM {$wpdb->options}
322 Where option_name
323 LIKE '%%%s%%'",
324 "give_cache_{$option_name}"
325 ),
326 1
327 );
328 }
329
330 if ( ! empty( $options ) && $fields ) {
331 foreach ( $options as $index => $option ) {
332 $option['option_value'] = maybe_unserialize( $option['option_value'] );
333 $options[ $index ] = $option;
334 }
335 }
336
337 return $options;
338 }
339
340 /**
341 * Check cache key validity.
342 *
343 * @since 1.8.7
344 * @access public
345 *
346 * @param $cache_key
347 *
348 * @return bool
349 */
350 public static function is_valid_cache_key( $cache_key ) {
351 $is_valid = ( false !== strpos( $cache_key, 'give_cache_' ) );
352
353
354 /**
355 * Filter the flag which tell about cache key valid or not
356 *
357 * @since 2.0
358 */
359 return apply_filters( 'give_is_valid_cache_key', $is_valid, $cache_key );
360 }
361
362
363 /**
364 * Get cache from group
365 *
366 * @since 2.0
367 * @access public
368 *
369 * @param int $id
370 * @param string $group
371 *
372 * @return mixed
373 */
374 public static function get_group( $id, $group = '' ) {
375 $cached_data = null;
376
377 // Bailout.
378 if ( self::$instance->is_cache && ! empty( $id ) ) {
379 $group = self::$instance->filter_group_name( $group );
380
381 $cached_data = wp_cache_get( $id, $group );
382 $cached_data = false !== $cached_data ? $cached_data : null;
383 }
384
385 return $cached_data;
386 }
387
388 /**
389 * Cache small chunks inside group
390 *
391 * @since 2.0
392 * @access public
393 *
394 * @param int $id
395 * @param mixed $data
396 * @param string $group
397 * @param int $expire
398 *
399 * @return bool
400 */
401 public static function set_group( $id, $data, $group = '', $expire = 0 ) {
402 $status = false;
403
404 // Bailout.
405 if ( ! self::$instance->is_cache || empty( $id ) ) {
406 return $status;
407 }
408
409 $group = self::$instance->filter_group_name( $group );
410
411 $status = wp_cache_set( $id, $data, $group, $expire );
412
413 return $status;
414 }
415
416 /**
417 * Cache small db query chunks inside group
418 *
419 * @since 2.0
420 * @access public
421 *
422 * @param int $id
423 * @param mixed $data
424 *
425 * @return bool
426 */
427 public static function set_db_query( $id, $data ) {
428 $status = false;
429
430 // Bailout.
431 if ( ! self::$instance->is_cache || empty( $id ) ) {
432 return $status;
433 }
434
435 return self::set_group( $id, $data, 'give-db-queries', 0 );
436 }
437
438 /**
439 * Get cache from group
440 *
441 * @since 2.0
442 * @access public
443 *
444 * @param int $id
445 *
446 * @return mixed
447 */
448 public static function get_db_query( $id ) {
449 return self::get_group( $id, 'give-db-queries' );
450 }
451
452 /**
453 * Delete group cache
454 *
455 * @since 2.0
456 * @access public
457 *
458 * @param int|array $ids
459 * @param string $group
460 * @param int $expire
461 *
462 * @return bool
463 */
464 public static function delete_group( $ids, $group = '', $expire = 0 ) {
465 $status = false;
466
467 // Bailout.
468 if ( ! self::$instance->is_cache || empty( $ids ) ) {
469 return $status;
470 }
471
472 $group = self::$instance->filter_group_name( $group );
473
474 // Delete single or multiple cache items from cache.
475 if ( ! is_array( $ids ) ) {
476 $status = wp_cache_delete( $ids, $group, $expire );
477 self::$instance->get_incrementer( true );
478
479 /**
480 * Fire action when cache deleted for specific id.
481 *
482 * @since 2.0
483 *
484 * @param string $ids
485 * @param string $group
486 * @param int $expire
487 */
488 do_action( "give_deleted_{$group}_cache", $ids, $group, $expire, $status );
489
490 } else {
491 foreach ( $ids as $id ) {
492 $status = wp_cache_delete( $id, $group, $expire );
493 self::$instance->get_incrementer( true );
494
495 /**
496 * Fire action when cache deleted for specific id .
497 *
498 * @since 2.0
499 *
500 * @param string $ids
501 * @param string $group
502 * @param int $expire
503 */
504 do_action( "give_deleted_{$group}_cache", $id, $group, $expire, $status );
505 }
506 }
507
508 return $status;
509 }
510
511
512 /**
513 * Delete form related cache
514 * Note: only use for internal purpose.
515 *
516 * @since 2.0
517 * @access public
518 *
519 * @param int $form_id
520 */
521 public function delete_form_related_cache( $form_id ) {
522 // If this is just a revision, don't send the email.
523 if ( wp_is_post_revision( $form_id ) ) {
524 return;
525 }
526
527 $donation_query = new Give_Payments_Query(
528 array(
529 'number' => - 1,
530 'give_forms' => $form_id,
531 )
532 );
533
534 $donations = $donation_query->get_payments();
535
536 if ( ! empty( $donations ) ) {
537 /* @var Give_Payment $donation */
538 foreach ( $donations as $donation ) {
539 wp_cache_delete( $donation->ID, 'give-donations' );
540 wp_cache_delete( $donation->donor_id, 'give-donors' );
541 }
542 }
543
544 self::$instance->get_incrementer( true );
545 }
546
547 /**
548 * Delete payment related cache
549 * Note: only use for internal purpose.
550 *
551 * @since 2.0
552 * @access public
553 *
554 * @param int $donation_id
555 */
556 public function delete_payment_related_cache( $donation_id ) {
557 // If this is just a revision, don't send the email.
558 if ( wp_is_post_revision( $donation_id ) ) {
559 return;
560 }
561
562 /* @var Give_Payment $donation */
563 $donation = new Give_Payment( $donation_id );
564
565 if ( $donation && $donation->donor_id ) {
566 wp_cache_delete( $donation->donor_id, 'give-donors' );
567 }
568
569 wp_cache_delete( $donation->ID, 'give-donations' );
570
571 self::$instance->get_incrementer( true );
572 }
573
574 /**
575 * Delete donor related cache
576 * Note: only use for internal purpose.
577 *
578 * @since 2.0
579 * @access public
580 *
581 * @param string $id
582 * @param string $group
583 * @param int $expire
584 */
585 public function delete_donor_related_cache( $id, $group, $expire ) {
586 $donor = new Give_Donor( $id );
587 $donation_ids = array_map( 'trim', (array) explode( ',', trim( $donor->payment_ids ) ) );
588
589 if ( ! empty( $donation_ids ) ) {
590 foreach ( $donation_ids as $donation ) {
591 wp_cache_delete( $donation, 'give-donations' );
592 }
593 }
594
595 self::$instance->get_incrementer( true );
596 }
597
598 /**
599 * Delete donations related cache
600 * Note: only use for internal purpose.
601 *
602 * @since 2.0
603 * @access public
604 *
605 * @param string $id
606 * @param string $group
607 * @param int $expire
608 */
609 public function delete_donations_related_cache( $id, $group, $expire ) {
610 /* @var Give_Payment $donation */
611 $donation = new Give_Payment( $id );
612
613 if ( $donation && $donation->donor_id ) {
614 wp_cache_delete( $donation->donor_id, 'give-donors' );
615 }
616
617 self::$instance->get_incrementer( true );
618 }
619
620
621 /**
622 * Get unique incrementer.
623 *
624 * @see https://core.trac.wordpress.org/ticket/4476
625 * @see https://www.tollmanz.com/invalidation-schemes/
626 *
627 * @since 2.0
628 * @access private
629 *
630 * @param bool $refresh
631 * @param string $incrementer_key
632 *
633 * @return string
634 */
635 private function get_incrementer( $refresh = false, $incrementer_key = 'give-cahce-incrementer-db-queries' ) {
636 $incrementer_value = wp_cache_get( $incrementer_key );
637
638 if ( false === $incrementer_value || true === $refresh ) {
639 $incrementer_value = microtime( true );
640 wp_cache_set( $incrementer_key, $incrementer_value );
641 }
642
643 return $incrementer_value;
644 }
645
646
647 /**
648 * Flush cache on cache setting enable/disable
649 * Note: only for internal use
650 *
651 * @since 2.0
652 * @access public
653 */
654 public function flush_cache() {
655 if (
656 Give_Admin_Settings::is_saving_settings() &&
657 isset( $_POST['cache'] ) &&
658 give_is_setting_enabled( give_clean( $_POST['cache'] ) )
659 ) {
660 $this->get_incrementer( true );
661 $this->get_incrementer( true, 'give-cahce-incrementer' );
662 }
663 }
664
665
666 /**
667 * Filter the group name
668 *
669 * @since 2.0
670 * @access private
671 *
672 * @param $group
673 *
674 * @return mixed
675 */
676 private function filter_group_name( $group ) {
677 if ( ! empty( $group ) ) {
678 $incrementer = self::$instance->get_incrementer( false, 'give-cahce-incrementer' );
679
680 if ( 'give-db-queries' === $group ) {
681 $incrementer = self::$instance->get_incrementer();
682 }
683
684 $group = "{$group}_{$incrementer}";
685 }
686
687 /**
688 * Filter the group name
689 *
690 * @since 2.0
691 */
692 return $group;
693 }
694
695
696 /**
697 * Disable cache.
698 *
699 * @since 2.0
700 * @access public
701 */
702 public static function disable() {
703 self::get_instance()->is_cache = false;
704 }
705
706 /**
707 * Enable cache.
708 *
709 * @since 2.0
710 * @access public
711 */
712 public static function enable() {
713 self::get_instance()->is_cache = true;
714 }
715 }
716
717 // Initialize
718 Give_Cache::get_instance()->setup();
719