Test Failed
Push — master ( 76928d...4654fc )
by Devin
09:23
created

Give_Payments_Query::update_meta_cache()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
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 = array();
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 = array();
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 = array();
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 = array() ) {
70
		$defaults = array(
71
			'output'          => 'payments',
72
			'post_type'       => array( '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,
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
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 View Code Duplication
	public function __set( $query_var, $value ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
118
		if ( in_array( $query_var, array( '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
		$this->date_filter_pre();
161
		$this->orderby();
162
		$this->status();
163
		$this->month();
164
		$this->per_page();
165
		$this->page();
166
		$this->user();
167
		$this->donor();
168
		$this->search();
169
		$this->mode();
170
		$this->children();
171
		$this->give_forms();
172
		$this->gateway_filter();
173
174
		add_filter( 'posts_orderby', array( $this, 'custom_orderby' ), 10, 2 );
175
176
		/**
177
		 * Fires after setup filters.
178
		 *
179
		 * @since 1.0
180
		 *
181
		 * @param Give_Payments_Query $this Payments query object.
182
		 */
183
		do_action( 'give_pre_get_payments', $this );
184
	}
185
186
	/**
187
	 * Unset query filter.
188
	 *
189
	 * @since  1.8.9
190
	 * @access private
191
	 */
192
	private function unset_filters() {
193
		remove_filter( 'posts_orderby', array( $this, 'custom_orderby' ) );
194
195
		/**
196
		 * Fires after retrieving payments.
197
		 *
198
		 * @since 1.0
199
		 *
200
		 * @param Give_Payments_Query $this Payments query object.
201
		 */
202
		do_action( 'give_post_get_payments', $this );
203
	}
204
205
206
	/**
207
	 * Retrieve payments.
208
	 *
209
	 * The query can be modified in two ways; either the action before the
210
	 * query is run, or the filter on the arguments (existing mainly for backwards
211
	 * compatibility).
212
	 *
213
	 * @since  1.0
214
	 * @access public
215
	 *
216
	 * @return array
217
	 */
218 View Code Duplication
	public function get_payments() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
219
		global $post;
220
221
		$results        = array();
222
		$this->payments = array();
223
		$cache_key      = Give_Cache::get_key( 'give_payment_query', $this->args, false );
224
		$this->payments = Give_Cache::get_db_query( $cache_key );
0 ignored issues
show
Documentation Bug introduced by
It seems like \Give_Cache::get_db_query($cache_key) of type * is incompatible with the declared type array of property $payments.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
225
226
		// Return cached result.
227
		if ( ! is_null( $this->payments ) ) {
228
			return $this->payments;
229
		}
230
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
231
232
		// Modify the query/query arguments before we retrieve payments.
233
		$this->set_filters();
234
235
		/* @var WP_Query $query */
236
		$query = new WP_Query( $this->args );
237
238
		$custom_output = array(
239
			'payments',
240
			'give_payments',
241
		);
242
243
		if ( $query->have_posts() ) {
244
			$this->update_meta_cache( wp_list_pluck( $query->posts, 'ID' ) );
245
246
			if ( ! in_array( $this->args['output'], $custom_output ) ) {
247
				$results = $query->posts;
248
249
			} else{
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
250
				$previous_post = $post;
251
252
				while ( $query->have_posts() ) {
253
					$query->the_post();
254
255
					$payment_id = get_post()->ID;
256
					$payment    = new Give_Payment( $payment_id );
257
258
					$this->payments[] = apply_filters( 'give_payment', $payment, $payment_id, $this );
259
				}
260
261
				wp_reset_postdata();
262
263
				// Prevent nest loop from producing unexpected results.
264
				if ( $previous_post instanceof WP_Post ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
265
					$post = $previous_post;
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
266
					setup_postdata( $post );
267
				}
268
269
				$results = $this->payments;
270
			}
271
		}
272
273
		Give_Cache::set_db_query( $cache_key, $results );
274
275
		// Remove query filters after we retrieve payments.
276
		$this->unset_filters();
277
278
		return $results;
279
	}
280
281
	/**
282
	 * Get payments by group
283
	 *
284
	 * @since  1.8.17
285
	 * @access public
286
	 *
287
	 * @return array
288
	 */
289
	public function get_payment_by_group() {
290
		global $wpdb;
291
292
		$allowed_groups = array( 'post_status' );
293
		$result         = array();
294
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
295
296
		if ( in_array( $this->args['group_by'], $allowed_groups ) ) {
297
			// Set only count in result.
298
			if ( $this->args['count'] ) {
299
300
				$this->set_filters();
301
302
				$new_results = $wpdb->get_results( $this->get_sql(), ARRAY_N );
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...
303
304
				$this->unset_filters();
305
306
				foreach ( $new_results as $results ) {
307
					$result[ $results[0] ] = $results[1];
308
				}
309
310
				switch ( $this->args['group_by'] ) {
311
					case 'post_status':
312
313
						/* @var Give_Payment $donation */
314
						foreach ( give_get_payment_status_keys() as $status ) {
315
							if ( ! isset( $result[ $status ] ) ) {
316
								$result[ $status ] = 0;
317
							}
318
						}
319
320
						break;
321
				}
322
			} else {
323
				$donations = $this->get_payments();
324
325
				/* @var $donation Give_Payment */
326
				foreach ( $donations as $donation ) {
327
					$result[ $donation->{$this->args['group_by']} ][] = $donation;
328
				}
329
			}
330
		}
331
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
332
333
		/**
334
		 * Filter the result
335
		 *
336
		 * @since 1.8.17
337
		 */
338
		return apply_filters( 'give_get_payment_by_group', $result, $this );
339
	}
340
341
	/**
342
	 * If querying a specific date, add the proper filters.
343
	 *
344
	 * @since  1.0
345
	 * @access public
346
	 *
347
	 * @return void
348
	 */
349
	public function date_filter_pre() {
350
		if ( ! ( $this->args['start_date'] || $this->args['end_date'] ) ) {
351
			return;
352
		}
353
354
		$this->setup_dates( $this->args['start_date'], $this->args['end_date'] );
355
356
		$is_start_date = property_exists( __CLASS__, 'start_date' );
357
		$is_end_date   = property_exists( __CLASS__, 'end_date' );
358
359
		if ( $is_start_date || $is_end_date ) {
360
			$date_query = array();
361
362
			if ( $is_start_date && ! is_wp_error( $this->start_date ) ) {
363
				$date_query['after'] = date( 'Y-m-d H:i:s', $this->start_date );
364
			}
365
366
			if ( $is_end_date && ! is_wp_error( $this->end_date ) ) {
367
				$date_query['before'] = date( 'Y-m-d H:i:s', $this->end_date );
368
			}
369
370
			// Include Start Date and End Date while querying.
371
			$date_query['inclusive'] = true;
372
373
			$this->__set( 'date_query', $date_query );
374
375
		}
376
	}
377
378
	/**
379
	 * Post Status
380
	 *
381
	 * @since  1.0
382
	 * @access public
383
	 *
384
	 * @return void
385
	 */
386
	public function status() {
387
		if ( ! isset( $this->args['status'] ) ) {
388
			return;
389
		}
390
391
		$this->__set( 'post_status', $this->args['status'] );
392
		$this->__unset( 'status' );
393
	}
394
395
	/**
396
	 * Current Page
397
	 *
398
	 * @since  1.0
399
	 * @access public
400
	 *
401
	 * @return void
402
	 */
403
	public function page() {
404
		if ( ! isset( $this->args['page'] ) ) {
405
			return;
406
		}
407
408
		$this->__set( 'paged', $this->args['page'] );
409
		$this->__unset( 'page' );
410
	}
411
412
	/**
413
	 * Posts Per Page
414
	 *
415
	 * @since  1.0
416
	 * @access public
417
	 *
418
	 * @return void
419
	 */
420
	public function per_page() {
421
422
		if ( ! isset( $this->args['number'] ) ) {
423
			return;
424
		}
425
426
		if ( $this->args['number'] == - 1 ) {
427
			$this->__set( 'nopaging', true );
428
		} else {
429
			$this->__set( 'posts_per_page', $this->args['number'] );
430
		}
431
432
		$this->__unset( 'number' );
433
	}
434
435
	/**
436
	 * Current Month
437
	 *
438
	 * @since  1.0
439
	 * @access public
440
	 *
441
	 * @return void
442
	 */
443
	public function month() {
444
		if ( ! isset( $this->args['month'] ) ) {
445
			return;
446
		}
447
448
		$this->__set( 'monthnum', $this->args['month'] );
449
		$this->__unset( 'month' );
450
	}
451
452
	/**
453
	 * Order by
454
	 *
455
	 * @since  1.0
456
	 * @access public
457
	 *
458
	 * @return void
459
	 */
460
	public function orderby() {
461
		switch ( $this->args['orderby'] ) {
462
			case 'amount':
463
				$this->__set( 'orderby', 'meta_value_num' );
464
				$this->__set( 'meta_key', '_give_payment_total' );
465
				break;
466
467
			case 'status':
468
				$this->__set( 'orderby', 'post_status' );
469
				break;
470
471
			case 'donation_form':
472
				$this->__set( 'orderby', 'meta_value' );
473
				$this->__set( 'meta_key', '_give_payment_form_title' );
474
				break;
475
476
			default:
477
				$this->__set( 'orderby', $this->args['orderby'] );
478
				break;
479
		}
480
	}
481
482
	/**
483
	 * Custom orderby.
484
	 * Note: currently custom sorting is only used for donation listing page.
485
	 *
486
	 * @since  1.8
487
	 * @access public
488
	 *
489
	 * @param string   $order
490
	 * @param WP_Query $query
491
	 *
492
	 * @return mixed
493
	 */
494
	public function custom_orderby( $order, $query ) {
495
496
		if ( ! empty( $query->query['post_type'] ) ) {
497
			$post_types = is_array( $query->query['post_type'] ) ? $query->query['post_type'] : array( $query->query['post_type'] );
498
499
			if ( ! in_array( 'give_payment', $post_types ) || ! isset( $query->query['orderby'] ) || is_array( $query->query['orderby'] ) ) {
500
				return $order;
501
			}
502
503
			global $wpdb;
504
			switch ( $query->query['orderby'] ) {
505
				case 'post_status':
506
					$order = $wpdb->posts . '.post_status ' . strtoupper( $query->query['order'] );
507
					break;
508
			}
509
		}
510
511
		return $order;
512
	}
513
514
	/**
515
	 * Specific User
516
	 *
517
	 * @since  1.0
518
	 * @access public
519
	 *
520
	 * @return void
521
	 */
522
	public function user() {
523
		if ( is_null( $this->args['user'] ) ) {
524
			return;
525
		}
526
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
527
528
		$args = array();
529
530
		if ( is_numeric( $this->args['user'] ) ) {
531
			// Backward compatibility: user donor param to get payment attached to donor instead of user
532
			$donor_id = Give()->donors->get_column_by( 'id', is_numeric( $this->args['user'] ) ? 'user_id' : 'email', $this->args['user'] );
533
534
			$args = array(
535
				'key'   => '_give_payment_donor_id',
536
				'value' => absint( $donor_id ),
537
			);
538
		} elseif ( is_email( $this->args['user'] ) ) {
539
			$args = array(
540
				'key'   => '_give_payment_donor_email',
541
				'value' => $this->args['user'],
542
			);
543
		}
544
545
		$this->__set( 'meta_query', $args );
546
	}
547
548
	/**
549
	 * Specific donor id
550
	 *
551
	 * @access  public
552
	 * @since   1.8.9
553
	 * @return  void
554
	 */
555
	public function donor() {
556
		if ( is_null( $this->args['donor'] ) || ! is_numeric( $this->args['donor'] ) ) {
557
			return;
558
		}
559
560
		$donor_meta_type = Give()->donor_meta->meta_type;
561
562
		$this->__set( 'meta_query', array(
563
			'key'   => "_give_payment_{$donor_meta_type}_id",
564
			'value' => (int) $this->args['donor'],
565
		) );
566
	}
567
568
	/**
569
	 * Search
570
	 *
571
	 * @since  1.0
572
	 * @access public
573
	 *
574
	 * @return void
575
	 */
576
	public function search() {
577
578
		if ( ! isset( $this->args['s'] ) ) {
579
			return;
580
		}
581
582
		$search = trim( $this->args['s'] );
583
584
		if ( empty( $search ) ) {
585
			return;
586
		}
587
588
		$is_email = is_email( $search ) || strpos( $search, '@' ) !== false;
589
		$is_user  = strpos( $search, strtolower( 'user:' ) ) !== false;
590
591
		if ( ! empty( $this->args['search_in_notes'] ) ) {
592
593
			$notes = give_get_payment_notes( 0, $search );
594
595
			if ( ! empty( $notes ) ) {
596
597
				$payment_ids = wp_list_pluck( (array) $notes, 'comment_post_ID' );
598
599
				$this->__set( 'post__in', $payment_ids );
600
			}
601
602
			$this->__unset( 's' );
603
604
		} elseif ( $is_email || strlen( $search ) == 32 ) {
605
606
			$key         = $is_email ? '_give_payment_donor_email' : '_give_payment_purchase_key';
607
			$search_meta = array(
608
				'key'     => $key,
609
				'value'   => $search,
610
				'compare' => 'LIKE',
611
			);
612
613
			$this->__set( 'meta_query', $search_meta );
614
			$this->__unset( 's' );
615
616
		} elseif ( $is_user ) {
617
618
			$search_meta = array(
619
				'key'   => '_give_payment_donor_id',
620
				'value' => trim( str_replace( 'user:', '', strtolower( $search ) ) ),
621
			);
622
623
			$this->__set( 'meta_query', $search_meta );
624
625
			$this->__unset( 's' );
626
627
		} elseif ( is_numeric( $search ) ) {
628
629
			$post = get_post( $search );
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
630
631
			if ( is_object( $post ) && $post->post_type == 'give_payment' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
632
633
				$arr   = array();
634
				$arr[] = $search;
635
				$this->__set( 'post__in', $arr );
636
				$this->__unset( 's' );
637
			}
638
		} elseif ( '#' == substr( $search, 0, 1 ) ) {
639
640
			$search = str_replace( '#:', '', $search );
641
			$search = str_replace( '#', '', $search );
642
			$this->__set( 'give_forms', $search );
643
			$this->__unset( 's' );
644
645
		} else if ( ! empty( $search ) ) {
646
			$search_parts = preg_split( '/\s+/', $search );
647
648
			if ( is_array( $search_parts ) && 2 === count( $search_parts ) ) {
649
				$search_meta = array(
650
					'relation' => 'AND',
651
					array(
652
						'key'     => '_give_donor_billing_first_name',
653
						'value'   => $search_parts[0],
654
						'compare' => '=',
655
					),
656
					array(
657
						'key'     => '_give_donor_billing_last_name',
658
						'value'   => $search_parts[1],
659
						'compare' => '=',
660
					),
661
				);
662
			} else {
663
				$search_meta = array(
664
					'relation' => 'OR',
665
					array(
666
						'key'     => '_give_donor_billing_first_name',
667
						'value'   => $search,
668
						'compare' => 'LIKE',
669
					),
670
					array(
671
						'key'     => '_give_donor_billing_last_name',
672
						'value'   => $search,
673
						'compare' => 'LIKE',
674
					),
675
				);
676
			}
677
678
			$this->__set( 'meta_query', $search_meta );
679
680
			$this->__unset( 's' );
681
682
		} else {
683
			$this->__set( 's', $search );
684
685
		}
686
687
	}
688
689
	/**
690
	 * Payment Mode
691
	 *
692
	 * @since  1.0
693
	 * @access public
694
	 *
695
	 * @return void
696
	 */
697
	public function mode() {
698
		if ( empty( $this->args['mode'] ) || $this->args['mode'] == 'all' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
699
			$this->__unset( 'mode' );
700
701
			return;
702
		}
703
704
		$this->__set(
705
			'meta_query', array(
706
				'key'   => '_give_payment_mode',
707
				'value' => $this->args['mode'],
708
			)
709
		);
710
	}
711
712
	/**
713
	 * Children
714
	 *
715
	 * @since  1.0
716
	 * @access public
717
	 *
718
	 * @return void
719
	 */
720
	public function children() {
721
		if ( empty( $this->args['children'] ) ) {
722
			$this->__set( 'post_parent', 0 );
723
		}
724
		$this->__unset( 'children' );
725
	}
726
727
	/**
728
	 * Specific Give Form
729
	 *
730
	 * @since  1.0
731
	 * @access public
732
	 *
733
	 * @return void
734
	 */
735 View Code Duplication
	public function give_forms() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
736
737
		if ( empty( $this->args['give_forms'] ) ) {
738
			return;
739
		}
740
741
		$compare = '=';
742
743
		if ( is_array( $this->args['give_forms'] ) ) {
744
			$compare = 'IN';
745
		}
746
747
		$this->__set(
748
			'meta_query',
749
			array(
750
				'key'     => '_give_payment_form_id',
751
				'value'   => $this->args['give_forms'],
752
				'compare' => $compare,
753
			)
754
		);
755
756
		$this->__unset( 'give_forms' );
757
758
	}
759
760
	/**
761
	 * Specific Gateway
762
	 *
763
	 * @since  1.8.17
764
	 * @access public
765
	 *
766
	 * @return void
767
	 */
768 View Code Duplication
	public function gateway_filter() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
769
770
		if ( empty( $this->args['gateway'] ) ) {
771
			return;
772
		}
773
774
		$compare = '=';
775
776
		if ( is_array( $this->args['gateway'] ) ) {
777
			$compare = 'IN';
778
		}
779
780
		$this->__set(
781
			'meta_query', array(
782
				array(
783
					'key'     => '_give_payment_gateway',
784
					'value'   => $this->args['gateway'],
785
					'compare' => $compare,
786
				),
787
			)
788
		);
789
790
		$this->__unset( 'gateway' );
791
792
	}
793
794
795
	/**
796
	 * Get sql query
797
	 *
798
	 * Note: Internal purpose only. We are developing on this fn.
799
	 *
800
	 * @since  1.8.18
801
	 * @access public
802
	 * @global $wpdb
803
	 *
804
	 * @return string
805
	 */
806
	private function get_sql() {
807
		global $wpdb;
808
809
		$where = "WHERE {$wpdb->posts}.post_type = 'give_payment'";
810
		$where .= " AND {$wpdb->posts}.post_status IN ('" . implode( "','", $this->args['post_status'] ) . "')";
811
812
		if ( is_numeric( $this->args['post_parent'] ) ) {
813
			$where .= " AND {$wpdb->posts}.post_parent={$this->args['post_parent']}";
814
		}
815
816
		// Set orderby.
817
		$orderby  = "ORDER BY {$wpdb->posts}.{$this->args['orderby']}";
818
		$group_by = '';
819
820
		// Set group by.
821 View Code Duplication
		if ( ! empty( $this->args['group_by'] ) ) {
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...
822
			$group_by = "GROUP BY {$wpdb->posts}.{$this->args['group_by']}";
823
		}
824
825
		// Set offset.
826
		if (
827
			empty( $this->args['nopaging'] ) &&
828
			empty( $this->args['offset'] ) &&
829
			( ! empty( $this->args['page'] ) && 0 < $this->args['page'] )
830
		) {
831
			$this->args['offset'] = $this->args['posts_per_page'] * ( $this->args['page'] - 1 );
832
		}
833
834
		// Set fields.
835
		$fields = "{$wpdb->posts}.*";
836
		if ( ! empty( $this->args['fields'] ) && 'all' !== $this->args['fields'] ) {
837
			if ( is_string( $this->args['fields'] ) ) {
838
				$fields = "{$wpdb->posts}.{$this->args['fields']}";
839 View Code Duplication
			} elseif ( is_array( $this->args['fields'] ) ) {
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...
840
				$fields = "{$wpdb->posts}." . implode( " , {$wpdb->posts}.", $this->args['fields'] );
841
			}
842
		}
843
844
		// Set count.
845
		if ( ! empty( $this->args['count'] ) ) {
846
			$fields = "COUNT({$wpdb->posts}.ID)";
847
848 View Code Duplication
			if ( ! empty( $this->args['group_by'] ) ) {
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...
849
				$fields = "{$wpdb->posts}.{$this->args['group_by']}, {$fields}";
850
			}
851
		}
852
853
		// Date query.
854
		if ( ! empty( $this->args['date_query'] ) ) {
855
			$date_query_obj = new WP_Date_Query( $this->args['date_query'] );
856
			$where          .= str_replace(
857
				array(
858
					"\n",
859
					'(   (',
860
					'))',
861
				),
862
				array(
863
					'',
864
					'( (',
865
					') )',
866
				),
867
				$date_query_obj->get_sql()
868
			);
869
		}
870
871
		// Meta query.
872
		if ( ! empty( $this->args['meta_query'] ) ) {
873
			$meta_query_obj = new WP_Meta_Query( $this->args['meta_query'] );
874
			$where          = implode( ' ', $meta_query_obj->get_sql( 'post', $wpdb->posts, 'ID' ) ) . " {$where}";
875
			$where          = Give()->payment_meta->__rename_meta_table_name( $where, 'posts_where' );
876
		}
877
878
		// Set sql query.
879
		$sql = $wpdb->prepare(
880
			"SELECT {$fields} FROM {$wpdb->posts} LIMIT %d,%d;",
881
			absint( $this->args['offset'] ),
882
			( empty( $this->args['nopaging'] ) ? absint( $this->args['posts_per_page'] ) : 99999999999 )
883
		);
884
885
		// $where, $orderby and order already prepared query they can generate notice if you re prepare them in above.
886
		// WordPress consider LIKE condition as placeholder if start with s,f, or d.
887
		$sql = str_replace( 'LIMIT', "{$where} {$group_by} {$orderby} {$this->args['order']} LIMIT", $sql );
888
889
		return $sql;
890
	}
891
892
	/**
893
	 * Update donations meta cache
894
	 *
895
	 * @since  2.5.0
896
	 * @access private
897
	 *
898
	 * @param $donation_ids
899
	 */
900
	public static function update_meta_cache( $donation_ids ) {
901
		// Exit.
902
		if ( empty( $donation_ids ) ) {
903
			return;
904
		}
905
906
		update_meta_cache( Give()->payment_meta->get_meta_type(), $donation_ids );
907
	}
908
}
909