Test Failed
Push — issues/2397 ( 942cc4...f0e197 )
by Ravinder
05:30
created

Give_Payments_Query::orderby()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 4
nop 0
dl 0
loc 21
rs 9.0534
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, 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 the query is run to convert them to the proper syntax.
62
	 *
63
	 * @since  1.0
64
	 * @access public
65
	 *
66
	 * @param  $args array The array of arguments that can be passed in and used for setting up this payment query.
67
	 */
68
	public function __construct( $args = array() ) {
69
		$defaults = array(
70
			'output'          => 'payments',
71
			'post_type'       => array( 'give_payment' ),
72
			'start_date'      => false,
73
			'end_date'        => false,
74
			'number'          => 20,
75
			'page'            => null,
76
			'orderby'         => 'ID',
77
			'order'           => 'DESC',
78
			'user'            => null,
79
			'donor'           => null,
80
			'status'          => give_get_payment_status_keys(),
81
			'meta_key'        => null,
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
82
			'year'            => null,
83
			'month'           => null,
84
			'day'             => null,
85
			's'               => null,
86
			'search_in_notes' => false,
87
			'children'        => false,
88
			'fields'          => null,
89
			'gateway'         => null,
90
			'give_forms'      => null,
91
			'offset'          => 0,
92
			'paged'           => 0,
93
			'post_parent'     => 0,
94
95
			// Currently these params only works with get_payment_by_group
96
			'group_by'        => '',
97
			'count'           => false,
98
		);
99
100
		$this->args = $this->_args = wp_parse_args( $args, $defaults );
101
102
		$this->init();
103
	}
104
105
	/**
106
	 * Set a query variable.
107
	 *
108
	 * @since  1.0
109
	 * @access public
110
	 *
111
	 * @param $query_var
112
	 * @param $value
113
	 */
114
	public function __set( $query_var, $value ) {
115
		if ( in_array( $query_var, array( 'meta_query', 'tax_query' ) ) ) {
116
			$this->args[ $query_var ][] = $value;
117
		} else {
118
			$this->args[ $query_var ] = $value;
119
		}
120
	}
121
122
	/**
123
	 * Unset a query variable.
124
	 *
125
	 * @since  1.0
126
	 * @access public
127
	 *
128
	 * @param $query_var
129
	 */
130
	public function __unset( $query_var ) {
131
		unset( $this->args[ $query_var ] );
132
	}
133
134
	/**
135
	 * Modify the query/query arguments before we retrieve payments.
136
	 *
137
	 * @since  1.0
138
	 * @access public
139
	 *
140
	 * @return void
141
	 */
142
	public function init() {
143
	}
144
145
146
	/**
147
	 * Set query filter.
148
	 *
149
	 * @since  1.8.9
150
	 * @access private
151
	 */
152
	private function set_filters() {
153
		// Reset param to apply filters.
154
		// While set filters $args will get override and multiple get_payments call will not work.
155
		$this->args = $this->_args;
156
157
		$this->date_filter_pre();
158
		$this->orderby();
159
		$this->status();
160
		$this->month();
161
		$this->per_page();
162
		$this->page();
163
		$this->user();
164
		$this->donor();
165
		$this->search();
166
		$this->mode();
167
		$this->children();
168
		$this->give_forms();
169
		$this->gateway_filter();
170
171
		add_filter( 'posts_orderby', array( $this, 'custom_orderby' ), 10, 2 );
172
	}
173
174
	/**
175
	 * Unset query filter.
176
	 *
177
	 * @since  1.8.9
178
	 * @access private
179
	 */
180
	private function unset_filters() {
181
		remove_filter( 'posts_orderby', array( $this, 'custom_orderby' ) );
182
	}
183
184
185
	/**
186
	 * Retrieve payments.
187
	 *
188
	 * The query can be modified in two ways; either the action before the
189
	 * query is run, or the filter on the arguments (existing mainly for backwards
190
	 * compatibility).
191
	 *
192
	 * @since  1.0
193
	 * @access public
194
	 *
195
	 * @return array
196
	 */
197
	public function get_payments() {
198
		// Modify the query/query arguments before we retrieve payments.
199
		$this->set_filters();
200
201
		/**
202
		 * Fires before retrieving payments.
203
		 *
204
		 * @since 1.0
205
		 *
206
		 * @param Give_Payments_Query $this Payments query object.
207
		 */
208
		do_action( 'give_pre_get_payments', $this );
209
210
		$query          = new WP_Query( $this->args );
211
		$this->payments = array();
212
213
		$custom_output = array(
214
			'payments',
215
			'give_payments',
216
		);
217
218
		if ( ! in_array( $this->args['output'], $custom_output ) ) {
219
			return $query->posts;
220
		}
221
222
		if ( $query->have_posts() ) {
223
			while ( $query->have_posts() ) {
224
				$query->the_post();
225
226
				$payment_id = get_post()->ID;
227
				$payment    = new Give_Payment( $payment_id );
228
229
				$this->payments[] = apply_filters( 'give_payment', $payment, $payment_id, $this );
230
			}
231
232
			wp_reset_postdata();
233
		}
234
235
		// Remove query filters after we retrieve payments.
236
		$this->unset_filters();
237
238
		/**
239
		 * Fires after retrieving payments.
240
		 *
241
		 * @since 1.0
242
		 *
243
		 * @param Give_Payments_Query $this Payments query object.
244
		 */
245
		do_action( 'give_post_get_payments', $this );
246
247
		return $this->payments;
248
	}
249
250
	/**
251
	 * Get payments by group
252
	 *
253
	 * @since  1.8.17
254
	 * @access public
255
	 *
256
	 * @return array
257
	 */
258
	public function get_payment_by_group() {
259
		global $wpdb;
260
261
		$allowed_groups = array( 'post_status' );
262
		$result         = array();
263
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
264
265
		if ( in_array( $this->args['group_by'], $allowed_groups ) ) {
266
			// Set only count in result.
267
			if ( $this->args['count'] ) {
268
				$statuses     = get_post_stati();
269
				$status_query = '';
270
271
				$counter = 0;
272
				foreach ( $statuses as $status ) {
273
					$prefix       = $counter ? " OR " : '';
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal OR does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

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