PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 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 All 256 releases
← All changes | includes/payments/class-payments-query.php +180 -78 2.3.0 → 4.17.0 View file →
@@ -3,9 +3,9 @@
3 3 * Payments Query
4 4 *
5 5 * @package Give
6 6 * @subpackage Classes/Stats
7 - * @copyright Copyright (c) 2016, WordImpress
7 + * @copyright Copyright (c) 2016, GiveWP
8 8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 9 * @since 1.0
10 10 */
11 11
@@ -32,9 +32,9 @@
32 32 * @access public
33 33 *
34 34 * @var array
35 35 */
36 - public $_args = array();
36 + public $_args = [];
37 37
38 38 /**
39 39 * The args to pass to the give_get_payments() query
40 40 *
@@ -42,9 +42,9 @@
42 42 * @access public
43 43 *
44 44 * @var array
45 45 */
46 - public $args = array();
46 + public $args = [];
47 47
48 48 /**
49 49 * The payments found based on the criteria set
50 50 *
@@ -52,9 +52,9 @@
52 52 * @access public
53 53 *
54 54 * @var array
55 55 */
56 - public $payments = array();
56 + public $payments = [];
57 57
58 58 /**
59 59 * Default query arguments.
60 60 *
@@ -65,12 +65,12 @@
65 65 * @access public
66 66 *
67 67 * @param $args array The array of arguments that can be passed in and used for setting up this payment query.
68 68 */
69 - public function __construct( $args = array() ) {
70 - $defaults = array(
69 + public function __construct( $args = [] ) {
70 + $defaults = [
71 71 'output' => 'payments',
72 - 'post_type' => array( 'give_payment' ),
72 + 'post_type' => [ 'give_payment' ],
73 73 'start_date' => false,
74 74 'end_date' => false,
75 75 'number' => 20,
76 76 'page' => null,
@@ -93,10 +93,14 @@
93 93
94 94 // Currently these params only works with get_payment_by_group
95 95 'group_by' => '',
96 96 'count' => false,
97 - );
97 + ];
98 98
99 + // We do not want WordPress to handle meta cache because WordPress stores in under `post_meta` key and cache object while we want it under `donation_meta`.
100 + // Similar for term cache
101 + $args['update_post_meta_cache'] = false;
102 +
99 103 $this->args = $this->_args = wp_parse_args( $args, $defaults );
100 104
101 105 $this->init();
102 106 }
@@ -110,9 +114,9 @@
110 114 * @param $query_var
111 115 * @param $value
112 116 */
113 117 public function __set( $query_var, $value ) {
114 - if ( in_array( $query_var, array( 'meta_query', 'tax_query' ) ) ) {
118 + if ( in_array( $query_var, [ 'meta_query', 'tax_query' ] ) ) {
115 119 $this->args[ $query_var ][] = $value;
116 120 } else {
117 121 $this->args[ $query_var ] = $value;
118 122 }
@@ -152,8 +156,11 @@
152 156 // Reset param to apply filters.
153 157 // While set filters $args will get override and multiple get_payments call will not work.
154 158 $this->args = $this->_args;
155 159
160 + // Whitelist order.
161 + $this->args['order'] = in_array( strtoupper( $this->args['order'] ), [ 'ASC', 'DESC' ] ) ? $this->args['order'] : 'DESC';
162 +
156 163 $this->date_filter_pre();
157 164 $this->orderby();
158 165 $this->status();
159 166 $this->month();
@@ -166,9 +173,9 @@
166 173 $this->children();
167 174 $this->give_forms();
168 175 $this->gateway_filter();
169 176
170 - add_filter( 'posts_orderby', array( $this, 'custom_orderby' ), 10, 2 );
177 + add_filter( 'posts_orderby', [ $this, 'custom_orderby' ], 10, 2 );
171 178
172 179 /**
173 180 * Fires after setup filters.
174 181 *
@@ -185,9 +192,9 @@
185 192 * @since 1.8.9
186 193 * @access private
187 194 */
188 195 private function unset_filters() {
189 - remove_filter( 'posts_orderby', array( $this, 'custom_orderby' ) );
196 + remove_filter( 'posts_orderby', [ $this, 'custom_orderby' ] );
190 197
191 198 /**
192 199 * Fires after retrieving payments.
193 200 *
@@ -206,8 +213,10 @@
206 213 * query is run, or the filter on the arguments (existing mainly for backwards
207 214 * compatibility).
208 215 *
209 216 * @since 1.0
217 + * @since 2.9.6 Normalize post IDs from either an array of IDs or Post objects.
218 + *
210 219 * @access public
211 220 *
212 221 * @return array
213 222 */
@@ -213,8 +222,10 @@
213 222 */
214 223 public function get_payments() {
215 224 global $post;
216 225
226 + $results = [];
227 + $this->payments = [];
217 228 $cache_key = Give_Cache::get_key( 'give_payment_query', $this->args, false );
218 229 $this->payments = Give_Cache::get_db_query( $cache_key );
219 230
220 231 // Return cached result.
@@ -221,51 +232,69 @@
221 232 if ( ! is_null( $this->payments ) ) {
222 233 return $this->payments;
223 234 }
224 235
225 -
226 236 // Modify the query/query arguments before we retrieve payments.
227 237 $this->set_filters();
228 238
229 - $query = new WP_Query( $this->args );
230 - $this->payments = array();
239 + /* @var WP_Query $query */
240 + $query = new WP_Query( $this->args );
231 241
232 - $custom_output = array(
242 + $custom_output = [
233 243 'payments',
234 244 'give_payments',
235 - );
245 + ];
236 246
237 - if ( ! in_array( $this->args['output'], $custom_output ) ) {
238 - return $query->posts;
239 - }
247 + if ( $query->have_posts() ) {
240 248
241 - if ( $query->have_posts() ) {
242 - $previous_post = $post;
249 + // Update meta cache only if query is not for all donations.
250 + // @see https://github.com/impress-org/give/issues/4104
251 + if (
252 + ( isset( $this->args['nopaging'] ) && true !== (bool) $this->args['nopaging'] )
253 + || ( isset( $this->args['posts_per_page'] ) && 0 < $this->args['posts_per_page'] )
254 + ) {
255 + $postIDs = array_map(
256 + function( $postOrID ) {
257 + return is_object( $postOrID ) ? $postOrID->ID : $postOrID;
258 + },
259 + $query->posts
260 + );
261 + self::update_meta_cache( $postIDs );
262 + }
243 263
244 - while ( $query->have_posts() ) {
245 - $query->the_post();
264 + if ( ! in_array( $this->args['output'], $custom_output ) ) {
265 + $results = $query->posts;
246 266
247 - $payment_id = get_post()->ID;
248 - $payment = new Give_Payment( $payment_id );
267 + } else {
268 + $previous_post = $post;
249 269
250 - $this->payments[] = apply_filters( 'give_payment', $payment, $payment_id, $this );
251 - }
270 + while ( $query->have_posts() ) {
271 + $query->the_post();
252 272
253 - wp_reset_postdata();
273 + $payment_id = get_post()->ID;
274 + $payment = new Give_Payment( $payment_id );
254 275
255 - // Prevent nest loop from producing unexpected results.
256 - if( $previous_post instanceof WP_Post ) {
257 - $post = $previous_post;
258 - setup_postdata( $post );
276 + $this->payments[] = apply_filters( 'give_payment', $payment, $payment_id, $this );
277 + }
278 +
279 + wp_reset_postdata();
280 +
281 + // Prevent nest loop from producing unexpected results.
282 + if ( $previous_post instanceof WP_Post ) {
283 + $post = $previous_post;
284 + setup_postdata( $post );
285 + }
286 +
287 + $results = $this->payments;
259 288 }
260 289 }
261 290
262 - Give_Cache::set_db_query( $cache_key, $this->payments );
291 + Give_Cache::set_db_query( $cache_key, $results );
263 292
264 293 // Remove query filters after we retrieve payments.
265 294 $this->unset_filters();
266 295
267 - return $this->payments;
296 + return $results;
268 297 }
269 298
270 299 /**
271 300 * Get payments by group
@@ -277,12 +306,11 @@
277 306 */
278 307 public function get_payment_by_group() {
279 308 global $wpdb;
280 309
281 - $allowed_groups = array( 'post_status' );
282 - $result = array();
310 + $allowed_groups = [ 'post_status' ];
311 + $result = [];
283 312
284 -
285 313 if ( in_array( $this->args['group_by'], $allowed_groups ) ) {
286 314 // Set only count in result.
287 315 if ( $this->args['count'] ) {
288 316
@@ -297,9 +325,8 @@
297 325 }
298 326
299 327 switch ( $this->args['group_by'] ) {
300 328 case 'post_status':
301 -
302 329 /* @var Give_Payment $donation */
303 330 foreach ( give_get_payment_status_keys() as $status ) {
304 331 if ( ! isset( $result[ $status ] ) ) {
305 332 $result[ $status ] = 0;
@@ -317,9 +344,8 @@
317 344 }
318 345 }
319 346 }
320 347
321 -
322 348 /**
323 349 * Filter the result
324 350 *
325 351 * @since 1.8.17
@@ -340,13 +366,14 @@
340 366 return;
341 367 }
342 368
343 369 $this->setup_dates( $this->args['start_date'], $this->args['end_date'] );
370 +
344 371 $is_start_date = property_exists( __CLASS__, 'start_date' );
345 372 $is_end_date = property_exists( __CLASS__, 'end_date' );
346 373
347 374 if ( $is_start_date || $is_end_date ) {
348 - $date_query = array();
375 + $date_query = [];
349 376
350 377 if ( $is_start_date && ! is_wp_error( $this->start_date ) ) {
351 378 $date_query['after'] = date( 'Y-m-d H:i:s', $this->start_date );
352 379 }
@@ -481,9 +508,9 @@
481 508 */
482 509 public function custom_orderby( $order, $query ) {
483 510
484 511 if ( ! empty( $query->query['post_type'] ) ) {
485 - $post_types = is_array( $query->query['post_type'] ) ? $query->query['post_type'] : array( $query->query['post_type'] );
512 + $post_types = is_array( $query->query['post_type'] ) ? $query->query['post_type'] : [ $query->query['post_type'] ];
486 513
487 514 if ( ! in_array( 'give_payment', $post_types ) || ! isset( $query->query['orderby'] ) || is_array( $query->query['orderby'] ) ) {
488 515 return $order;
489 516 }
@@ -511,27 +538,26 @@
511 538 if ( is_null( $this->args['user'] ) ) {
512 539 return;
513 540 }
514 541
542 + $args = [];
515 543
516 - $args = array();
517 -
518 544 if ( is_numeric( $this->args['user'] ) ) {
519 545 // Backward compatibility: user donor param to get payment attached to donor instead of user
520 - $donor_id = Give()->donors->get_column_by( 'id', is_numeric( $this->args['user'] ) ? 'user_id' : 'email', $this->args['user'] );
546 + $donor_id = Give()->donors->get_column_by( 'id', 'user_id', $this->args['user'] );
521 547
522 - $args = array(
548 + $args = [
523 549 'key' => '_give_payment_donor_id',
524 - 'value' => absint( $donor_id ),
525 - );
550 + 'value' => $donor_id ?: -1,
551 + ];
526 552 } elseif ( is_email( $this->args['user'] ) ) {
527 - $args = array(
553 + $args = [
528 554 'key' => '_give_payment_donor_email',
529 555 'value' => $this->args['user'],
530 - );
556 + ];
531 557 }
532 558
533 - $this->__set( 'meta_query',$args );
559 + $this->__set( 'meta_query', $args );
534 560 }
535 561
536 562 /**
537 563 * Specific donor id
@@ -546,12 +572,15 @@
546 572 }
547 573
548 574 $donor_meta_type = Give()->donor_meta->meta_type;
549 575
550 - $this->__set( 'meta_query', array(
551 - 'key' => "_give_payment_{$donor_meta_type}_id",
552 - 'value' => (int) $this->args['donor'],
553 - ) );
576 + $this->__set(
577 + 'meta_query',
578 + [
579 + 'key' => "_give_payment_{$donor_meta_type}_id",
580 + 'value' => (int) $this->args['donor'],
581 + ]
582 + );
554 583 }
555 584
556 585 /**
557 586 * Search
@@ -591,13 +620,13 @@
591 620
592 621 } elseif ( $is_email || strlen( $search ) == 32 ) {
593 622
594 623 $key = $is_email ? '_give_payment_donor_email' : '_give_payment_purchase_key';
595 - $search_meta = array(
624 + $search_meta = [
596 625 'key' => $key,
597 626 'value' => $search,
598 627 'compare' => 'LIKE',
599 - );
628 + ];
600 629
601 630 $this->__set( 'meta_query', $search_meta );
602 631 $this->__unset( 's' );
603 632
@@ -602,12 +631,12 @@
602 631 $this->__unset( 's' );
603 632
604 633 } elseif ( $is_user ) {
605 634
606 - $search_meta = array(
635 + $search_meta = [
607 636 'key' => '_give_payment_donor_id',
608 637 'value' => trim( str_replace( 'user:', '', strtolower( $search ) ) ),
609 - );
638 + ];
610 639
611 640 $this->__set( 'meta_query', $search_meta );
612 641
613 642 $this->__unset( 's' );
@@ -617,9 +646,9 @@
617 646 $post = get_post( $search );
618 647
619 648 if ( is_object( $post ) && $post->post_type == 'give_payment' ) {
620 649
621 - $arr = array();
650 + $arr = [];
622 651 $arr[] = $search;
623 652 $this->__set( 'post__in', $arr );
624 653 $this->__unset( 's' );
625 654 }
@@ -629,8 +658,45 @@
629 658 $search = str_replace( '#', '', $search );
630 659 $this->__set( 'give_forms', $search );
631 660 $this->__unset( 's' );
632 661
662 + } elseif ( ! empty( $search ) ) {
663 + $search_parts = preg_split( '/\s+/', $search );
664 +
665 + if ( is_array( $search_parts ) && 2 === count( $search_parts ) ) {
666 + $search_meta = [
667 + 'relation' => 'AND',
668 + [
669 + 'key' => '_give_donor_billing_first_name',
670 + 'value' => $search_parts[0],
671 + 'compare' => 'LIKE',
672 + ],
673 + [
674 + 'key' => '_give_donor_billing_last_name',
675 + 'value' => $search_parts[1],
676 + 'compare' => 'LIKE',
677 + ],
678 + ];
679 + } else {
680 + $search_meta = [
681 + 'relation' => 'OR',
682 + [
683 + 'key' => '_give_donor_billing_first_name',
684 + 'value' => $search,
685 + 'compare' => 'LIKE',
686 + ],
687 + [
688 + 'key' => '_give_donor_billing_last_name',
689 + 'value' => $search,
690 + 'compare' => 'LIKE',
691 + ],
692 + ];
693 + }
694 +
695 + $this->__set( 'meta_query', $search_meta );
696 +
697 + $this->__unset( 's' );
698 +
633 699 } else {
634 700 $this->__set( 's', $search );
635 701
636 702 }
@@ -652,12 +718,13 @@
652 718 return;
653 719 }
654 720
655 721 $this->__set(
656 - 'meta_query', array(
722 + 'meta_query',
723 + [
657 724 'key' => '_give_payment_mode',
658 725 'value' => $this->args['mode'],
659 - )
726 + ]
660 727 );
661 728 }
662 729
663 730 /**
@@ -696,13 +763,13 @@
696 763 }
697 764
698 765 $this->__set(
699 766 'meta_query',
700 - array(
767 + [
701 768 'key' => '_give_payment_form_id',
702 769 'value' => $this->args['give_forms'],
703 770 'compare' => $compare,
704 - )
771 + ]
705 772 );
706 773
707 774 $this->__unset( 'give_forms' );
708 775
@@ -728,15 +795,14 @@
728 795 $compare = 'IN';
729 796 }
730 797
731 798 $this->__set(
732 - 'meta_query', array(
733 - array(
734 - 'key' => '_give_payment_gateway',
735 - 'value' => $this->args['gateway'],
736 - 'compare' => $compare,
737 - ),
738 - )
799 + 'meta_query',
800 + [
801 + 'key' => '_give_payment_gateway',
802 + 'value' => $this->args['gateway'],
803 + 'compare' => $compare,
804 + ]
739 805 );
740 806
741 807 $this->__unset( 'gateway' );
742 808
@@ -756,12 +822,32 @@
756 822 */
757 823 private function get_sql() {
758 824 global $wpdb;
759 825
760 - $where = "WHERE {$wpdb->posts}.post_type = 'give_payment'";
826 + $allowed_keys = [
827 + 'post_name',
828 + 'post_author',
829 + 'post_date',
830 + 'post_title',
831 + 'post_status',
832 + 'post_modified',
833 + 'post_parent',
834 + 'post_type',
835 + 'menu_order',
836 + 'comment_count',
837 + ];
838 +
839 + $this->args['orderby'] = 'post_parent__in';
840 +
841 + // Whitelist orderby.
842 + if ( ! in_array( $this->args['orderby'], $allowed_keys ) ) {
843 + $this->args['orderby'] = 'ID';
844 + }
845 +
846 + $where = "WHERE {$wpdb->posts}.post_type = 'give_payment'";
761 847 $where .= " AND {$wpdb->posts}.post_status IN ('" . implode( "','", $this->args['post_status'] ) . "')";
762 848
763 - if( is_numeric( $this->args['post_parent'] ) ) {
849 + if ( is_numeric( $this->args['post_parent'] ) ) {
764 850 $where .= " AND {$wpdb->posts}.post_parent={$this->args['post_parent']}";
765 851 }
766 852
767 853 // Set orderby.
@@ -803,19 +889,19 @@
803 889
804 890 // Date query.
805 891 if ( ! empty( $this->args['date_query'] ) ) {
806 892 $date_query_obj = new WP_Date_Query( $this->args['date_query'] );
807 - $where .= str_replace(
808 - array(
893 + $where .= str_replace(
894 + [
809 895 "\n",
810 896 '( (',
811 897 '))',
812 - ),
813 - array(
898 + ],
899 + [
814 900 '',
815 901 '( (',
816 902 ') )',
817 - ),
903 + ],
818 904 $date_query_obj->get_sql()
819 905 );
820 906 }
821 907
@@ -822,9 +908,9 @@
822 908 // Meta query.
823 909 if ( ! empty( $this->args['meta_query'] ) ) {
824 910 $meta_query_obj = new WP_Meta_Query( $this->args['meta_query'] );
825 911 $where = implode( ' ', $meta_query_obj->get_sql( 'post', $wpdb->posts, 'ID' ) ) . " {$where}";
826 - $where = Give()->payment_meta->__rename_meta_table_name( $where, 'posts_where' );
912 + $where = Give()->payment_meta->rename_meta_table_name( $where, 'posts_where' );
827 913 }
828 914
829 915 // Set sql query.
830 916 $sql = $wpdb->prepare(
@@ -839,5 +925,21 @@
839 925
840 926 return $sql;
841 927 }
842 928
929 + /**
930 + * Update donations meta cache
931 + *
932 + * @since 2.5.0
933 + * @access private
934 + *
935 + * @param $donation_ids
936 + */
937 + public static function update_meta_cache( $donation_ids ) {
938 + // Exit.
939 + if ( empty( $donation_ids ) ) {
940 + return;
941 + }
942 +
943 + update_meta_cache( Give()->payment_meta->get_meta_type(), $donation_ids );
944 + }
843 945 }