PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.24.0
GiveWP – Donation Plugin and Fundraising Platform v2.24.0
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 / payments / class-payments-query.php
give / includes / payments Last commit date
actions.php 6 years ago backward-compatibility.php 6 years ago class-give-payment.php 5 years ago class-give-sequential-donation-number.php 4 years ago class-payment-stats.php 4 years ago class-payments-query.php 5 years ago functions.php 4 years ago
class-payments-query.php
946 lines
1 <?php
2 /**
3 * Payments Query
4 *
5 * @package Give
6 * @subpackage Classes/Stats
7 * @copyright Copyright (c) 2016, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 1.0
10 */
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Give_Payments_Query Class
19 *
20 * This class is for retrieving payments data.
21 *
22 * Payments can be retrieved for date ranges and pre-defined periods.
23 *
24 * @since 1.0
25 */
26 class Give_Payments_Query extends Give_Stats {
27
28 /**
29 * Preserve args
30 *
31 * @since 1.8.17
32 * @access public
33 *
34 * @var array
35 */
36 public $_args = [];
37
38 /**
39 * The args to pass to the give_get_payments() query
40 *
41 * @since 1.0
42 * @access public
43 *
44 * @var array
45 */
46 public $args = [];
47
48 /**
49 * The payments found based on the criteria set
50 *
51 * @since 1.0
52 * @access public
53 *
54 * @var array
55 */
56 public $payments = [];
57
58 /**
59 * Default query arguments.
60 *
61 * Not all of these are valid arguments that can be passed to WP_Query. The ones that are not, are modified before
62 * the query is run to convert them to the proper syntax.
63 *
64 * @since 1.0
65 * @access public
66 *
67 * @param $args array The array of arguments that can be passed in and used for setting up this payment query.
68 */
69 public function __construct( $args = [] ) {
70 $defaults = [
71 'output' => 'payments',
72 'post_type' => [ 'give_payment' ],
73 'start_date' => false,
74 'end_date' => false,
75 'number' => 20,
76 'page' => null,
77 'orderby' => 'ID',
78 'order' => 'DESC',
79 'user' => null, // deprecated, use donor
80 'donor' => null,
81 'status' => give_get_payment_status_keys(),
82 'meta_key' => null,
83 'year' => null,
84 'month' => null,
85 'day' => null,
86 's' => null,
87 'search_in_notes' => false,
88 'children' => false,
89 'fields' => null,
90 'gateway' => null,
91 'give_forms' => null,
92 'offset' => null,
93
94 // Currently these params only works with get_payment_by_group
95 'group_by' => '',
96 'count' => false,
97 ];
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
103 $this->args = $this->_args = wp_parse_args( $args, $defaults );
104
105 $this->init();
106 }
107
108 /**
109 * Set a query variable.
110 *
111 * @since 1.0
112 * @access public
113 *
114 * @param $query_var
115 * @param $value
116 */
117 public function __set( $query_var, $value ) {
118 if ( in_array( $query_var, [ 'meta_query', 'tax_query' ] ) ) {
119 $this->args[ $query_var ][] = $value;
120 } else {
121 $this->args[ $query_var ] = $value;
122 }
123 }
124
125 /**
126 * Unset a query variable.
127 *
128 * @since 1.0
129 * @access public
130 *
131 * @param $query_var
132 */
133 public function __unset( $query_var ) {
134 unset( $this->args[ $query_var ] );
135 }
136
137 /**
138 * Modify the query/query arguments before we retrieve payments.
139 *
140 * @since 1.0
141 * @access public
142 *
143 * @return void
144 */
145 public function init() {
146 }
147
148
149 /**
150 * Set query filter.
151 *
152 * @since 1.8.9
153 * @access private
154 */
155 private function set_filters() {
156 // Reset param to apply filters.
157 // While set filters $args will get override and multiple get_payments call will not work.
158 $this->args = $this->_args;
159
160 // Whitelist order.
161 $this->args['order'] = in_array( strtoupper( $this->args['order'] ), [ 'ASC', 'DESC' ] ) ? $this->args['order'] : 'DESC';
162
163 $this->date_filter_pre();
164 $this->orderby();
165 $this->status();
166 $this->month();
167 $this->per_page();
168 $this->page();
169 $this->user();
170 $this->donor();
171 $this->search();
172 $this->mode();
173 $this->children();
174 $this->give_forms();
175 $this->gateway_filter();
176
177 add_filter( 'posts_orderby', [ $this, 'custom_orderby' ], 10, 2 );
178
179 /**
180 * Fires after setup filters.
181 *
182 * @since 1.0
183 *
184 * @param Give_Payments_Query $this Payments query object.
185 */
186 do_action( 'give_pre_get_payments', $this );
187 }
188
189 /**
190 * Unset query filter.
191 *
192 * @since 1.8.9
193 * @access private
194 */
195 private function unset_filters() {
196 remove_filter( 'posts_orderby', [ $this, 'custom_orderby' ] );
197
198 /**
199 * Fires after retrieving payments.
200 *
201 * @since 1.0
202 *
203 * @param Give_Payments_Query $this Payments query object.
204 */
205 do_action( 'give_post_get_payments', $this );
206 }
207
208
209 /**
210 * Retrieve payments.
211 *
212 * The query can be modified in two ways; either the action before the
213 * query is run, or the filter on the arguments (existing mainly for backwards
214 * compatibility).
215 *
216 * @since 1.0
217 * @since 2.9.6 Normalize post IDs from either an array of IDs or Post objects.
218 *
219 * @access public
220 *
221 * @return array
222 */
223 public function get_payments() {
224 global $post;
225
226 $results = [];
227 $this->payments = [];
228 $cache_key = Give_Cache::get_key( 'give_payment_query', $this->args, false );
229 $this->payments = Give_Cache::get_db_query( $cache_key );
230
231 // Return cached result.
232 if ( ! is_null( $this->payments ) ) {
233 return $this->payments;
234 }
235
236 // Modify the query/query arguments before we retrieve payments.
237 $this->set_filters();
238
239 /* @var WP_Query $query */
240 $query = new WP_Query( $this->args );
241
242 $custom_output = [
243 'payments',
244 'give_payments',
245 ];
246
247 if ( $query->have_posts() ) {
248
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 }
263
264 if ( ! in_array( $this->args['output'], $custom_output ) ) {
265 $results = $query->posts;
266
267 } else {
268 $previous_post = $post;
269
270 while ( $query->have_posts() ) {
271 $query->the_post();
272
273 $payment_id = get_post()->ID;
274 $payment = new Give_Payment( $payment_id );
275
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;
288 }
289 }
290
291 Give_Cache::set_db_query( $cache_key, $results );
292
293 // Remove query filters after we retrieve payments.
294 $this->unset_filters();
295
296 return $results;
297 }
298
299 /**
300 * Get payments by group
301 *
302 * @since 1.8.17
303 * @access public
304 *
305 * @return array
306 */
307 public function get_payment_by_group() {
308 global $wpdb;
309
310 $allowed_groups = [ 'post_status' ];
311 $result = [];
312
313 if ( in_array( $this->args['group_by'], $allowed_groups ) ) {
314 // Set only count in result.
315 if ( $this->args['count'] ) {
316
317 $this->set_filters();
318
319 $new_results = $wpdb->get_results( $this->get_sql(), ARRAY_N );
320
321 $this->unset_filters();
322
323 foreach ( $new_results as $results ) {
324 $result[ $results[0] ] = $results[1];
325 }
326
327 switch ( $this->args['group_by'] ) {
328 case 'post_status':
329 /* @var Give_Payment $donation */
330 foreach ( give_get_payment_status_keys() as $status ) {
331 if ( ! isset( $result[ $status ] ) ) {
332 $result[ $status ] = 0;
333 }
334 }
335
336 break;
337 }
338 } else {
339 $donations = $this->get_payments();
340
341 /* @var $donation Give_Payment */
342 foreach ( $donations as $donation ) {
343 $result[ $donation->{$this->args['group_by']} ][] = $donation;
344 }
345 }
346 }
347
348 /**
349 * Filter the result
350 *
351 * @since 1.8.17
352 */
353 return apply_filters( 'give_get_payment_by_group', $result, $this );
354 }
355
356 /**
357 * If querying a specific date, add the proper filters.
358 *
359 * @since 1.0
360 * @access public
361 *
362 * @return void
363 */
364 public function date_filter_pre() {
365 if ( ! ( $this->args['start_date'] || $this->args['end_date'] ) ) {
366 return;
367 }
368
369 $this->setup_dates( $this->args['start_date'], $this->args['end_date'] );
370
371 $is_start_date = property_exists( __CLASS__, 'start_date' );
372 $is_end_date = property_exists( __CLASS__, 'end_date' );
373
374 if ( $is_start_date || $is_end_date ) {
375 $date_query = [];
376
377 if ( $is_start_date && ! is_wp_error( $this->start_date ) ) {
378 $date_query['after'] = date( 'Y-m-d H:i:s', $this->start_date );
379 }
380
381 if ( $is_end_date && ! is_wp_error( $this->end_date ) ) {
382 $date_query['before'] = date( 'Y-m-d H:i:s', $this->end_date );
383 }
384
385 // Include Start Date and End Date while querying.
386 $date_query['inclusive'] = true;
387
388 $this->__set( 'date_query', $date_query );
389
390 }
391 }
392
393 /**
394 * Post Status
395 *
396 * @since 1.0
397 * @access public
398 *
399 * @return void
400 */
401 public function status() {
402 if ( ! isset( $this->args['status'] ) ) {
403 return;
404 }
405
406 $this->__set( 'post_status', $this->args['status'] );
407 $this->__unset( 'status' );
408 }
409
410 /**
411 * Current Page
412 *
413 * @since 1.0
414 * @access public
415 *
416 * @return void
417 */
418 public function page() {
419 if ( ! isset( $this->args['page'] ) ) {
420 return;
421 }
422
423 $this->__set( 'paged', $this->args['page'] );
424 $this->__unset( 'page' );
425 }
426
427 /**
428 * Posts Per Page
429 *
430 * @since 1.0
431 * @access public
432 *
433 * @return void
434 */
435 public function per_page() {
436
437 if ( ! isset( $this->args['number'] ) ) {
438 return;
439 }
440
441 if ( $this->args['number'] == - 1 ) {
442 $this->__set( 'nopaging', true );
443 } else {
444 $this->__set( 'posts_per_page', $this->args['number'] );
445 }
446
447 $this->__unset( 'number' );
448 }
449
450 /**
451 * Current Month
452 *
453 * @since 1.0
454 * @access public
455 *
456 * @return void
457 */
458 public function month() {
459 if ( ! isset( $this->args['month'] ) ) {
460 return;
461 }
462
463 $this->__set( 'monthnum', $this->args['month'] );
464 $this->__unset( 'month' );
465 }
466
467 /**
468 * Order by
469 *
470 * @since 1.0
471 * @access public
472 *
473 * @return void
474 */
475 public function orderby() {
476 switch ( $this->args['orderby'] ) {
477 case 'amount':
478 $this->__set( 'orderby', 'meta_value_num' );
479 $this->__set( 'meta_key', '_give_payment_total' );
480 break;
481
482 case 'status':
483 $this->__set( 'orderby', 'post_status' );
484 break;
485
486 case 'donation_form':
487 $this->__set( 'orderby', 'meta_value' );
488 $this->__set( 'meta_key', '_give_payment_form_title' );
489 break;
490
491 default:
492 $this->__set( 'orderby', $this->args['orderby'] );
493 break;
494 }
495 }
496
497 /**
498 * Custom orderby.
499 * Note: currently custom sorting is only used for donation listing page.
500 *
501 * @since 1.8
502 * @access public
503 *
504 * @param string $order
505 * @param WP_Query $query
506 *
507 * @return mixed
508 */
509 public function custom_orderby( $order, $query ) {
510
511 if ( ! empty( $query->query['post_type'] ) ) {
512 $post_types = is_array( $query->query['post_type'] ) ? $query->query['post_type'] : [ $query->query['post_type'] ];
513
514 if ( ! in_array( 'give_payment', $post_types ) || ! isset( $query->query['orderby'] ) || is_array( $query->query['orderby'] ) ) {
515 return $order;
516 }
517
518 global $wpdb;
519 switch ( $query->query['orderby'] ) {
520 case 'post_status':
521 $order = $wpdb->posts . '.post_status ' . strtoupper( $query->query['order'] );
522 break;
523 }
524 }
525
526 return $order;
527 }
528
529 /**
530 * Specific User
531 *
532 * @since 1.0
533 * @access public
534 *
535 * @return void
536 */
537 public function user() {
538 if ( is_null( $this->args['user'] ) ) {
539 return;
540 }
541
542 $args = [];
543
544 if ( is_numeric( $this->args['user'] ) ) {
545 // Backward compatibility: user donor param to get payment attached to donor instead of user
546 $donor_id = Give()->donors->get_column_by( 'id', 'user_id', $this->args['user'] );
547
548 $args = [
549 'key' => '_give_payment_donor_id',
550 'value' => $donor_id ?: -1,
551 ];
552 } elseif ( is_email( $this->args['user'] ) ) {
553 $args = [
554 'key' => '_give_payment_donor_email',
555 'value' => $this->args['user'],
556 ];
557 }
558
559 $this->__set( 'meta_query', $args );
560 }
561
562 /**
563 * Specific donor id
564 *
565 * @access public
566 * @since 1.8.9
567 * @return void
568 */
569 public function donor() {
570 if ( is_null( $this->args['donor'] ) || ! is_numeric( $this->args['donor'] ) ) {
571 return;
572 }
573
574 $donor_meta_type = Give()->donor_meta->meta_type;
575
576 $this->__set(
577 'meta_query',
578 [
579 'key' => "_give_payment_{$donor_meta_type}_id",
580 'value' => (int) $this->args['donor'],
581 ]
582 );
583 }
584
585 /**
586 * Search
587 *
588 * @since 1.0
589 * @access public
590 *
591 * @return void
592 */
593 public function search() {
594
595 if ( ! isset( $this->args['s'] ) ) {
596 return;
597 }
598
599 $search = trim( $this->args['s'] );
600
601 if ( empty( $search ) ) {
602 return;
603 }
604
605 $is_email = is_email( $search ) || strpos( $search, '@' ) !== false;
606 $is_user = strpos( $search, strtolower( 'user:' ) ) !== false;
607
608 if ( ! empty( $this->args['search_in_notes'] ) ) {
609
610 $notes = give_get_payment_notes( 0, $search );
611
612 if ( ! empty( $notes ) ) {
613
614 $payment_ids = wp_list_pluck( (array) $notes, 'comment_post_ID' );
615
616 $this->__set( 'post__in', $payment_ids );
617 }
618
619 $this->__unset( 's' );
620
621 } elseif ( $is_email || strlen( $search ) == 32 ) {
622
623 $key = $is_email ? '_give_payment_donor_email' : '_give_payment_purchase_key';
624 $search_meta = [
625 'key' => $key,
626 'value' => $search,
627 'compare' => 'LIKE',
628 ];
629
630 $this->__set( 'meta_query', $search_meta );
631 $this->__unset( 's' );
632
633 } elseif ( $is_user ) {
634
635 $search_meta = [
636 'key' => '_give_payment_donor_id',
637 'value' => trim( str_replace( 'user:', '', strtolower( $search ) ) ),
638 ];
639
640 $this->__set( 'meta_query', $search_meta );
641
642 $this->__unset( 's' );
643
644 } elseif ( is_numeric( $search ) ) {
645
646 $post = get_post( $search );
647
648 if ( is_object( $post ) && $post->post_type == 'give_payment' ) {
649
650 $arr = [];
651 $arr[] = $search;
652 $this->__set( 'post__in', $arr );
653 $this->__unset( 's' );
654 }
655 } elseif ( '#' == substr( $search, 0, 1 ) ) {
656
657 $search = str_replace( '#:', '', $search );
658 $search = str_replace( '#', '', $search );
659 $this->__set( 'give_forms', $search );
660 $this->__unset( 's' );
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
699 } else {
700 $this->__set( 's', $search );
701
702 }
703
704 }
705
706 /**
707 * Payment Mode
708 *
709 * @since 1.0
710 * @access public
711 *
712 * @return void
713 */
714 public function mode() {
715 if ( empty( $this->args['mode'] ) || $this->args['mode'] == 'all' ) {
716 $this->__unset( 'mode' );
717
718 return;
719 }
720
721 $this->__set(
722 'meta_query',
723 [
724 'key' => '_give_payment_mode',
725 'value' => $this->args['mode'],
726 ]
727 );
728 }
729
730 /**
731 * Children
732 *
733 * @since 1.0
734 * @access public
735 *
736 * @return void
737 */
738 public function children() {
739 if ( empty( $this->args['children'] ) ) {
740 $this->__set( 'post_parent', 0 );
741 }
742 $this->__unset( 'children' );
743 }
744
745 /**
746 * Specific Give Form
747 *
748 * @since 1.0
749 * @access public
750 *
751 * @return void
752 */
753 public function give_forms() {
754
755 if ( empty( $this->args['give_forms'] ) ) {
756 return;
757 }
758
759 $compare = '=';
760
761 if ( is_array( $this->args['give_forms'] ) ) {
762 $compare = 'IN';
763 }
764
765 $this->__set(
766 'meta_query',
767 [
768 'key' => '_give_payment_form_id',
769 'value' => $this->args['give_forms'],
770 'compare' => $compare,
771 ]
772 );
773
774 $this->__unset( 'give_forms' );
775
776 }
777
778 /**
779 * Specific Gateway
780 *
781 * @since 1.8.17
782 * @access public
783 *
784 * @return void
785 */
786 public function gateway_filter() {
787
788 if ( empty( $this->args['gateway'] ) ) {
789 return;
790 }
791
792 $compare = '=';
793
794 if ( is_array( $this->args['gateway'] ) ) {
795 $compare = 'IN';
796 }
797
798 $this->__set(
799 'meta_query',
800 [
801 'key' => '_give_payment_gateway',
802 'value' => $this->args['gateway'],
803 'compare' => $compare,
804 ]
805 );
806
807 $this->__unset( 'gateway' );
808
809 }
810
811
812 /**
813 * Get sql query
814 *
815 * Note: Internal purpose only. We are developing on this fn.
816 *
817 * @since 1.8.18
818 * @access public
819 * @global $wpdb
820 *
821 * @return string
822 */
823 private function get_sql() {
824 global $wpdb;
825
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'";
847 $where .= " AND {$wpdb->posts}.post_status IN ('" . implode( "','", $this->args['post_status'] ) . "')";
848
849 if ( is_numeric( $this->args['post_parent'] ) ) {
850 $where .= " AND {$wpdb->posts}.post_parent={$this->args['post_parent']}";
851 }
852
853 // Set orderby.
854 $orderby = "ORDER BY {$wpdb->posts}.{$this->args['orderby']}";
855 $group_by = '';
856
857 // Set group by.
858 if ( ! empty( $this->args['group_by'] ) ) {
859 $group_by = "GROUP BY {$wpdb->posts}.{$this->args['group_by']}";
860 }
861
862 // Set offset.
863 if (
864 empty( $this->args['nopaging'] ) &&
865 empty( $this->args['offset'] ) &&
866 ( ! empty( $this->args['page'] ) && 0 < $this->args['page'] )
867 ) {
868 $this->args['offset'] = $this->args['posts_per_page'] * ( $this->args['page'] - 1 );
869 }
870
871 // Set fields.
872 $fields = "{$wpdb->posts}.*";
873 if ( ! empty( $this->args['fields'] ) && 'all' !== $this->args['fields'] ) {
874 if ( is_string( $this->args['fields'] ) ) {
875 $fields = "{$wpdb->posts}.{$this->args['fields']}";
876 } elseif ( is_array( $this->args['fields'] ) ) {
877 $fields = "{$wpdb->posts}." . implode( " , {$wpdb->posts}.", $this->args['fields'] );
878 }
879 }
880
881 // Set count.
882 if ( ! empty( $this->args['count'] ) ) {
883 $fields = "COUNT({$wpdb->posts}.ID)";
884
885 if ( ! empty( $this->args['group_by'] ) ) {
886 $fields = "{$wpdb->posts}.{$this->args['group_by']}, {$fields}";
887 }
888 }
889
890 // Date query.
891 if ( ! empty( $this->args['date_query'] ) ) {
892 $date_query_obj = new WP_Date_Query( $this->args['date_query'] );
893 $where .= str_replace(
894 [
895 "\n",
896 '( (',
897 '))',
898 ],
899 [
900 '',
901 '( (',
902 ') )',
903 ],
904 $date_query_obj->get_sql()
905 );
906 }
907
908 // Meta query.
909 if ( ! empty( $this->args['meta_query'] ) ) {
910 $meta_query_obj = new WP_Meta_Query( $this->args['meta_query'] );
911 $where = implode( ' ', $meta_query_obj->get_sql( 'post', $wpdb->posts, 'ID' ) ) . " {$where}";
912 $where = Give()->payment_meta->__rename_meta_table_name( $where, 'posts_where' );
913 }
914
915 // Set sql query.
916 $sql = $wpdb->prepare(
917 "SELECT {$fields} FROM {$wpdb->posts} LIMIT %d,%d;",
918 absint( $this->args['offset'] ),
919 ( empty( $this->args['nopaging'] ) ? absint( $this->args['posts_per_page'] ) : 99999999999 )
920 );
921
922 // $where, $orderby and order already prepared query they can generate notice if you re prepare them in above.
923 // WordPress consider LIKE condition as placeholder if start with s,f, or d.
924 $sql = str_replace( 'LIMIT', "{$where} {$group_by} {$orderby} {$this->args['order']} LIMIT", $sql );
925
926 return $sql;
927 }
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 }
945 }
946