Test Failed
Push — issues/1944 ( f13954...e5d7bc )
by Ravinder
05:26
created

Give_Payments_Query::get_payments()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 63
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 25
nc 4
nop 0
dl 0
loc 63
rs 8.6498
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Payments Query
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Stats
7
 * @copyright   Copyright (c) 2016, WordImpress
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,
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
		);
93
94
		$this->args = $this->_args = wp_parse_args( $args, $defaults );
95
96
		$this->init();
97
	}
98
99
	/**
100
	 * Set a query variable.
101
	 *
102
	 * @since  1.0
103
	 * @access public
104
	 *
105
	 * @param $query_var
106
	 * @param $value
107
	 */
108
	public function __set( $query_var, $value ) {
109
		if ( in_array( $query_var, array( 'meta_query', 'tax_query' ) ) ) {
110
			$this->args[ $query_var ][] = $value;
111
		} else {
112
			$this->args[ $query_var ] = $value;
113
		}
114
	}
115
116
	/**
117
	 * Unset a query variable.
118
	 *
119
	 * @since  1.0
120
	 * @access public
121
	 *
122
	 * @param $query_var
123
	 */
124
	public function __unset( $query_var ) {
125
		unset( $this->args[ $query_var ] );
126
	}
127
128
	/**
129
	 * Modify the query/query arguments before we retrieve payments.
130
	 *
131
	 * @since  1.0
132
	 * @access public
133
	 *
134
	 * @return void
135
	 */
136
	public function init() {
137
	}
138
139
140
	/**
141
	 * Set query filter.
142
	 *
143
	 * @since  1.8.9
144
	 * @access private
145
	 */
146
	private function set_filters() {
147
		// Reset param to apply filters.
148
		// While set filters $args will get override and multiple get_payments call will not work.
149
		$this->args = $this->_args;
150
151
		$this->date_filter_pre();
152
		$this->orderby();
153
		$this->status();
154
		$this->month();
155
		$this->per_page();
156
		$this->page();
157
		$this->user();
158
		$this->donor();
159
		$this->search();
160
		$this->mode();
161
		$this->children();
162
		$this->give_forms();
163
		$this->gateway_filter();
164
165
		add_filter( 'posts_orderby', array( $this, 'custom_orderby' ), 10, 2 );
166
	}
167
168
	/**
169
	 * Unset query filter.
170
	 *
171
	 * @since  1.8.9
172
	 * @access private
173
	 */
174
	private function unset_filters() {
175
		$this->date_filter_post();
176
		remove_filter( 'posts_orderby', array( $this, 'custom_orderby' ) );
177
	}
178
179
180
	/**
181
	 * Retrieve payments.
182
	 *
183
	 * The query can be modified in two ways; either the action before the
184
	 * query is run, or the filter on the arguments (existing mainly for backwards
185
	 * compatibility).
186
	 *
187
	 * @since  1.0
188
	 * @access public
189
	 *
190
	 * @return array
191
	 */
192
	public function get_payments() {
193
		$cache_key      = Give_Cache::get_key( 'give_payment_query', $this->args, false );
194
		$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...
195
196
		// Return cached result.
197
		if ( ! is_null( $this->payments ) ) {
198
			return $this->payments;
199
		}
200
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
201
202
		// Modify the query/query arguments before we retrieve payments.
203
		$this->set_filters();
204
205
		/**
206
		 * Fires before retrieving payments.
207
		 *
208
		 * @since 1.0
209
		 *
210
		 * @param Give_Payments_Query $this Payments query object.
211
		 */
212
		do_action( 'give_pre_get_payments', $this );
213
214
		$query          = new WP_Query( $this->args );
215
		$this->payments = array();
216
217
		$custom_output = array(
218
			'payments',
219
			'give_payments',
220
		);
221
222
		if ( ! in_array( $this->args['output'], $custom_output ) ) {
223
			return $query->posts;
224
		}
225
226
		if ( $query->have_posts() ) {
227
			while ( $query->have_posts() ) {
228
				$query->the_post();
229
230
				$payment_id = get_post()->ID;
231
				$payment    = new Give_Payment( $payment_id );
232
233
				$this->payments[] = apply_filters( 'give_payment', $payment, $payment_id, $this );
234
			}
235
236
			wp_reset_postdata();
237
		}
238
239
		Give_Cache::set_db_query( $cache_key, $this->payments );
240
241
		// Remove query filters after we retrieve payments.
242
		$this->unset_filters();
243
244
		/**
245
		 * Fires after retrieving payments.
246
		 *
247
		 * @since 1.0
248
		 *
249
		 * @param Give_Payments_Query $this Payments query object.
250
		 */
251
		do_action( 'give_post_get_payments', $this );
252
253
		return $this->payments;
254
	}
255
	
256
	/**
257
	 * If querying a specific date, add the proper filters.
258
	 *
259
	 * @since  1.0
260
	 * @access public
261
	 *
262
	 * @return void
263
	 */
264
	public function date_filter_pre() {
265
		if ( ! ( $this->args['start_date'] || $this->args['end_date'] ) ) {
266
			return;
267
		}
268
269
		$this->setup_dates( $this->args['start_date'], $this->args['end_date'] );
270
271
		add_filter( 'posts_where', array( $this, 'payments_where' ) );
272
	}
273
274
	/**
275
	 * If querying a specific date, remove filters after the query has been run
276
	 * to avoid affecting future queries.
277
	 *
278
	 * @since  1.0
279
	 * @access public
280
	 *
281
	 * @return void
282
	 */
283
	public function date_filter_post() {
284
		if ( ! ( $this->args['start_date'] || $this->args['end_date'] ) ) {
285
			return;
286
		}
287
288
		remove_filter( 'posts_where', array( $this, 'payments_where' ) );
289
	}
290
291
	/**
292
	 * Post Status
293
	 *
294
	 * @since  1.0
295
	 * @access public
296
	 *
297
	 * @return void
298
	 */
299
	public function status() {
300
		if ( ! isset( $this->args['status'] ) ) {
301
			return;
302
		}
303
304
		$this->__set( 'post_status', $this->args['status'] );
305
		$this->__unset( 'status' );
306
	}
307
308
	/**
309
	 * Current Page
310
	 *
311
	 * @since  1.0
312
	 * @access public
313
	 *
314
	 * @return void
315
	 */
316
	public function page() {
317
		if ( ! isset( $this->args['page'] ) ) {
318
			return;
319
		}
320
321
		$this->__set( 'paged', $this->args['page'] );
322
		$this->__unset( 'page' );
323
	}
324
325
	/**
326
	 * Posts Per Page
327
	 *
328
	 * @since  1.0
329
	 * @access public
330
	 *
331
	 * @return void
332
	 */
333
	public function per_page() {
334
335
		if ( ! isset( $this->args['number'] ) ) {
336
			return;
337
		}
338
339
		if ( $this->args['number'] == - 1 ) {
340
			$this->__set( 'nopaging', true );
341
		} else {
342
			$this->__set( 'posts_per_page', $this->args['number'] );
343
		}
344
345
		$this->__unset( 'number' );
346
	}
347
348
	/**
349
	 * Current Month
350
	 *
351
	 * @since  1.0
352
	 * @access public
353
	 *
354
	 * @return void
355
	 */
356
	public function month() {
357
		if ( ! isset( $this->args['month'] ) ) {
358
			return;
359
		}
360
361
		$this->__set( 'monthnum', $this->args['month'] );
362
		$this->__unset( 'month' );
363
	}
364
365
	/**
366
	 * Order by
367
	 *
368
	 * @since  1.0
369
	 * @access public
370
	 *
371
	 * @return void
372
	 */
373
	public function orderby() {
374
		switch ( $this->args['orderby'] ) {
375
			case 'amount':
376
				$this->__set( 'orderby', 'meta_value_num' );
377
				$this->__set( 'meta_key', '_give_payment_total' );
378
				break;
379
380
			case 'status':
381
				$this->__set( 'orderby', 'post_status' );
382
				break;
383
384
			case 'donation_form':
385
				$this->__set( 'orderby', 'meta_value' );
386
				$this->__set( 'meta_key', '_give_payment_form_title' );
387
				break;
388
389
			default:
390
				$this->__set( 'orderby', $this->args['orderby'] );
391
				break;
392
		}
393
	}
394
395
	/**
396
	 * Custom orderby.
397
	 * Note: currently custom sorting is only used for donation listing page.
398
	 *
399
	 * @since  1.8
400
	 * @access public
401
	 *
402
	 * @param string $order
403
	 * @param WP_Query $query
404
	 *
405
	 * @return mixed
406
	 */
407
	public function custom_orderby( $order, $query ) {
408
409
		if ( ! empty( $query->query['post_type'] ) ) {
410
			$post_types = is_array( $query->query['post_type'] ) ? $query->query['post_type'] : array( $query->query['post_type'] );
411
412
			if ( ! in_array( 'give_payment', $post_types ) || is_array( $query->query['orderby'] ) ) {
413
				return $order;
414
			}
415
416
			global $wpdb;
417
			switch ( $query->query['orderby'] ) {
418
				case 'post_status':
419
					$order = $wpdb->posts . '.post_status ' . strtoupper( $query->query['order'] );
420
					break;
421
			}
422
		}
423
424
		return $order;
425
	}
426
427
	/**
428
	 * Specific User
429
	 *
430
	 * @since  1.0
431
	 * @access public
432
	 *
433
	 * @return void
434
	 */
435
	public function user() {
436
		if ( is_null( $this->args['user'] ) ) {
437
			return;
438
		}
439
440
		if ( is_numeric( $this->args['user'] ) ) {
441
			$user_key = '_give_payment_donor_id';
442
		} else {
443
			$user_key = '_give_payment_donor_email';
444
		}
445
446
		$this->__set(
447
			'meta_query', array(
448
				'key'   => $user_key,
449
				'value' => $this->args['user'],
450
			)
451
		);
452
	}
453
454
	/**
455
	 * Specific donor id
456
	 *
457
	 * @access  public
458
	 * @since   1.8.9
459
	 * @return  void
460
	 */
461
	public function donor() {
462
		if ( is_null( $this->args['donor'] ) || ! is_numeric( $this->args['donor'] ) ) {
463
			return;
464
		}
465
466
		$donor_meta_type = Give()->donor_meta->meta_type;
467
468
		$this->__set( 'meta_query', array(
469
			'key'   => "_give_payment_{$donor_meta_type}_id",
470
			'value' => (int) $this->args['donor'],
471
		) );
472
	}
473
474
	/**
475
	 * Search
476
	 *
477
	 * @since  1.0
478
	 * @access public
479
	 *
480
	 * @return void
481
	 */
482
	public function search() {
483
484
		if ( ! isset( $this->args['s'] ) ) {
485
			return;
486
		}
487
488
		$search = trim( $this->args['s'] );
489
490
		if ( empty( $search ) ) {
491
			return;
492
		}
493
494
		$is_email = is_email( $search ) || strpos( $search, '@' ) !== false;
495
		$is_user  = strpos( $search, strtolower( 'user:' ) ) !== false;
496
497
		if ( ! empty( $this->args['search_in_notes'] ) ) {
498
499
			$notes = give_get_payment_notes( 0, $search );
500
501
			if ( ! empty( $notes ) ) {
502
503
				$payment_ids = wp_list_pluck( (array) $notes, 'comment_post_ID' );
504
505
				$this->__set( 'post__in', $payment_ids );
506
			}
507
508
			$this->__unset( 's' );
509
510
		} elseif ( $is_email || strlen( $search ) == 32 ) {
511
512
			$key         = $is_email ? '_give_payment_donor_email' : '_give_payment_purchase_key';
513
			$search_meta = array(
514
				'key'     => $key,
515
				'value'   => $search,
516
				'compare' => 'LIKE',
517
			);
518
519
			$this->__set( 'meta_query', $search_meta );
520
			$this->__unset( 's' );
521
522
		} elseif ( $is_user ) {
523
524
			$search_meta = array(
525
				'key'   => '_give_payment_donor_id',
526
				'value' => trim( str_replace( 'user:', '', strtolower( $search ) ) ),
527
			);
528
529
			$this->__set( 'meta_query', $search_meta );
530
531
			if ( give_get_option( 'enable_sequential' ) ) {
532
533
				$search_meta = array(
534
					'key'     => '_give_payment_number',
535
					'value'   => $search,
536
					'compare' => 'LIKE',
537
				);
538
539
				$this->__set( 'meta_query', $search_meta );
540
541
				$this->args['meta_query']['relation'] = 'OR';
542
543
			}
544
545
			$this->__unset( 's' );
546
547
		} elseif (
548
			give_get_option( 'enable_sequential' ) &&
549
			(
550
				false !== strpos( $search, give_get_option( 'sequential_prefix' ) ) ||
551
				false !== strpos( $search, give_get_option( 'sequential_postfix' ) )
552
			)
553
		) {
554
555
			$search_meta = array(
556
				'key'     => '_give_payment_number',
557
				'value'   => $search,
558
				'compare' => 'LIKE',
559
			);
560
561
			$this->__set( 'meta_query', $search_meta );
562
			$this->__unset( 's' );
563
564
		} elseif ( is_numeric( $search ) ) {
565
566
			$post = get_post( $search );
567
568
			if ( is_object( $post ) && $post->post_type == 'give_payment' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
569
570
				$arr   = array();
571
				$arr[] = $search;
572
				$this->__set( 'post__in', $arr );
573
				$this->__unset( 's' );
574
			}
575
		} elseif ( '#' == substr( $search, 0, 1 ) ) {
576
577
			$search = str_replace( '#:', '', $search );
578
			$search = str_replace( '#', '', $search );
579
			$this->__set( 'give_forms', $search );
580
			$this->__unset( 's' );
581
582
		} else {
583
			$this->__set( 's', $search );
584
585
		}
586
587
	}
588
589
	/**
590
	 * Payment Mode
591
	 *
592
	 * @since  1.0
593
	 * @access public
594
	 *
595
	 * @return void
596
	 */
597
	public function mode() {
598
		if ( empty( $this->args['mode'] ) || $this->args['mode'] == 'all' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
599
			$this->__unset( 'mode' );
600
601
			return;
602
		}
603
604
		$this->__set(
605
			'meta_query', array(
606
				'key'   => '_give_payment_mode',
607
				'value' => $this->args['mode'],
608
			)
609
		);
610
	}
611
612
	/**
613
	 * Children
614
	 *
615
	 * @since  1.0
616
	 * @access public
617
	 *
618
	 * @return void
619
	 */
620
	public function children() {
621
		if ( empty( $this->args['children'] ) ) {
622
			$this->__set( 'post_parent', 0 );
623
		}
624
		$this->__unset( 'children' );
625
	}
626
627
	/**
628
	 * Specific Give Form
629
	 *
630
	 * @since  1.0
631
	 * @access public
632
	 *
633
	 * @return void
634
	 */
635 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...
636
637
		if ( empty( $this->args['give_forms'] ) ) {
638
			return;
639
		}
640
641
		$compare = '=';
642
643
		if ( is_array( $this->args['give_forms'] ) ) {
644
			$compare = 'IN';
645
		}
646
647
		$this->__set(
648
			'meta_query', array(
649
				array(
650
					'key'     => '_give_payment_form_id',
651
					'value'   => $this->args['give_forms'],
652
					'compare' => $compare,
653
				),
654
			)
655
		);
656
657
		$this->__unset( 'give_forms' );
658
659
	}
660
661
	/**
662
	 * Specific Gateway
663
	 *
664
	 * @since  1.8.17
665
	 * @access public
666
	 *
667
	 * @return void
668
	 */
669 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...
670
671
		if ( empty( $this->args['gateway'] ) ) {
672
			return;
673
		}
674
675
		$compare = '=';
676
677
		if ( is_array( $this->args['gateway'] ) ) {
678
			$compare = 'IN';
679
		}
680
681
		$this->__set(
682
			'meta_query', array(
683
				array(
684
					'key'     => '_give_payment_gateway',
685
					'value'   => $this->args['gateway'],
686
					'compare' => $compare,
687
				),
688
			)
689
		);
690
691
		$this->__unset( 'gateway' );
692
693
	}
694
695
}
696