Completed
Branch BUG-10458-sql-injection-via-sh... (c8fb1e)
by
unknown
129:18 queued 116:23
created

EEH_Event_Query   C

Complexity

Total Complexity 79

Size/Duplication

Total Lines 634
Duplicated Lines 7.73 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
dl 49
loc 634
rs 5.3007
c 0
b 0
f 0
wmc 79
lcom 1
cbo 9

25 Methods

Rating   Name   Duplication   Size   Complexity  
A add_query_filters() 0 4 1
A apply_query_filters() 0 6 3
A filter_query_parts() 0 13 3
A set_query_params() 0 14 1
A _display_month() 0 3 1
A _event_category_slug() 0 3 1
A _show_expired() 0 7 1
A _orderby() 0 9 2
A _sort() 0 6 2
A posts_clauses() 0 7 2
A posts_fields() 0 7 2
C posts_fields_sql_for_orderby() 0 29 7
A posts_join() 0 9 2
A posts_join_sql_for_show_expired() 3 11 3
A posts_join_sql_for_terms() 9 9 2
C posts_join_for_orderby() 0 33 8
A _posts_join_for_datetime() 3 9 3
B _posts_join_for_event_venue() 0 26 2
B _posts_join_for_venue_state() 0 20 5
A posts_where() 0 11 2
A posts_where_sql_for_show_expired() 0 5 2
A posts_where_sql_for_event_category_slug() 0 7 2
A posts_where_sql_for_event_list_month() 0 11 2
A posts_orderby() 0 9 2
C posts_orderby_sql() 34 63 18

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EEH_Event_Query often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EEH_Event_Query, and based on these observations, apply Extract Interface, too.

1
<?php if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
	exit( 'No direct script access allowed' );
3
}
4
/**
5
 * Event Espresso
6
 *
7
 * Event Registration and Ticketing Management Plugin for WordPress
8
 *
9
 * @ package            Event Espresso
10
 * @ author                Event Espresso
11
 * @ copyright        (c) 2008-2014 Event Espresso  All Rights Reserved.
12
 * @ license            http://eventespresso.com/support/terms-conditions/   * see Plugin Licensing *
13
 * @ link                    http://www.eventespresso.com
14
 * @ version            $VID:$
15
 *
16
 * ------------------------------------------------------------------------
17
 */
18
19
20
21
22
23
/**
24
 *
25
 * Class EEH_Event_Query
26
 *
27
 * Description
28
 *
29
 * @package               Event Espresso
30
 * @subpackage            core
31
 * @author                Brent Christensen
32
 * @since                 4.3
33
 *
34
 */
35
class EEH_Event_Query {
36
37
	/**
38
	 *    Start Date
39
	 * @var    $_event_query_month
40
	 */
41
	protected static $_event_query_month;
42
43
	/**
44
	 *    Category
45
	 * @var    $_event_query_category
46
	 */
47
	protected static $_event_query_category;
48
49
	/**
50
	 *    whether to display expired events in the event list
51
	 * @var    bool $_show_expired
52
	 */
53
	protected static $_event_query_show_expired = false;
54
55
	/**
56
	 *    list of params for controlling how the query results are ordered
57
	 * @var    array $_event_query_orderby
58
	 */
59
	protected static $_event_query_orderby = array();
60
61
	/**
62
	 *    direction list is sorted
63
	 * @var    string $_event_query_sort
64
	 */
65
	protected static $_event_query_sort;
66
67
	/**
68
	 *    list of params used to build the query's various clauses
69
	 * @var    $_query_params
70
	 */
71
	protected static $_query_params = array();
72
73
74
75
	/**
76
	 * add_query_filters
77
	 *
78
	 */
79
	public static function add_query_filters() {
80
		//add query filters
81
		add_action( 'pre_get_posts', array( 'EEH_Event_Query', 'filter_query_parts' ), 10, 1 );
82
	}
83
84
85
86
	/**
87
	 * apply_query_filters
88
	 *
89
	 * @param \WP_Query $WP_Query
90
	 * @return bool
91
	 */
92
	public static function apply_query_filters( WP_Query $WP_Query ) {
93
		return (
94
		    isset( $WP_Query->query, $WP_Query->query['post_type'] )
95
            && $WP_Query->query['post_type'] === 'espresso_events'
96
        ) ||  apply_filters( 'FHEE__EEH_Event_Query__apply_query_filters', false ) ;
97
	}
98
99
100
	/**
101
	 * filter_query_parts
102
	 *
103
	 * @param \WP_Query $WP_Query
104
	 */
105
	public static function filter_query_parts( WP_Query $WP_Query ) {
106
		// ONLY add our filters if this isn't the main wp_query,
107
        // because if this is the main wp_query we already have
108
        // our cpt strategies take care of adding things in.
109
		if ( $WP_Query instanceof WP_Query && ! $WP_Query->is_main_query() ) {
0 ignored issues
show
Bug introduced by
The class WP_Query 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...
110
			// build event list query
111
			add_filter( 'posts_fields', array( 'EEH_Event_Query', 'posts_fields' ), 10, 2 );
112
			add_filter( 'posts_join', array( 'EEH_Event_Query', 'posts_join' ), 10, 2 );
113
			add_filter( 'posts_where', array( 'EEH_Event_Query', 'posts_where' ), 10, 2 );
114
			add_filter( 'posts_orderby', array( 'EEH_Event_Query', 'posts_orderby' ), 10, 2 );
115
			add_filter( 'posts_clauses_request', array( 'EEH_Event_Query', 'posts_clauses' ), 10, 2 );
116
		}
117
	}
118
119
120
121
	/**
122
	 * set_query_params
123
	 *
124
	 * @param string $month
125
	 * @param string $category
126
	 * @param bool   $show_expired
127
	 * @param string $orderby
128
	 * @param string $sort
129
	 */
130
    public static function set_query_params(
131
        $month = '',
132
        $category = '',
133
        $show_expired = false,
134
        $orderby = 'start_date',
135
        $sort = 'ASC'
136
    ) {
137
		self::$_query_params = array();
138
		EEH_Event_Query::$_event_query_month = EEH_Event_Query::_display_month( $month );
139
		EEH_Event_Query::$_event_query_category = EEH_Event_Query::_event_category_slug( $category );
140
		EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired( $show_expired );
141
		EEH_Event_Query::$_event_query_orderby = EEH_Event_Query::_orderby( $orderby );
142
		EEH_Event_Query::$_event_query_sort = EEH_Event_Query::_sort( $sort );
143
	}
144
145
146
147
	/**
148
	 *    _display_month - what month should the event list display events for?
149
	 *
150
	 * @param string $month
151
	 * @return    string
152
	 */
153
	private static function _display_month( $month = '' ) {
154
        return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_month', $month));
155
    }
156
157
158
159
	/**
160
	 *    _event_category_slug
161
	 *
162
	 * @param string $category
163
	 * @return    string
164
	 */
165
	private static function _event_category_slug( $category = '' ) {
166
		return sanitize_title_with_dashes(EE_Registry::instance()->REQ->get('event_query_category', $category));
167
	}
168
169
170
171
	/**
172
	 *    _show_expired
173
	 *
174
	 * @param bool $show_expired
175
	 * @return    boolean
176
	 */
177
	private static function _show_expired( $show_expired = false ) {
178
		// override default expired option if set via filter
179
		return filter_var(
180
		    EE_Registry::instance()->REQ->get('event_query_show_expired', $show_expired),
181
            FILTER_VALIDATE_BOOLEAN
182
        );
183
	}
184
185
186
187
	/**
188
	 *    _orderby
189
	 *
190
	 * @param    string $orderby
191
	 * @return    array
192
	 */
193
	private static function _orderby( $orderby = 'start_date' ) {
194
		$event_query_orderby = EE_Registry::instance()->REQ->get('event_query_orderby', $orderby);
195
		$event_query_orderby = is_array( $event_query_orderby )
196
            ? $event_query_orderby
197
            : explode( ',', $event_query_orderby );
198
		$event_query_orderby = array_map( 'trim', $event_query_orderby );
199
		$event_query_orderby = array_map( 'sanitize_text_field', $event_query_orderby );
200
		return $event_query_orderby;
201
	}
202
203
204
205
	/**
206
	 *    _sort
207
	 *
208
	 * @param string $sort
209
	 * @return string
210
	 */
211
	private static function _sort( $sort = 'ASC' ) {
212
		$sort = EE_Registry::instance()->REQ->get('event_query_sort', $sort);
213
		return in_array( $sort, array( 'ASC', 'asc', 'DESC', 'desc' ), true)
214
            ? strtoupper( $sort )
215
            : 'ASC';
216
	}
217
218
219
220
	/**
221
	 * Filters the clauses for the WP_Query object
222
	 *
223
	 * @param array   $clauses  array of clauses
224
	 * @param WP_Query $wp_query
225
	 *
226
	 * @return array   array of clauses
227
	 */
228
	public static function posts_clauses( $clauses, WP_Query $wp_query ) {
229
		if ( EEH_Event_Query::apply_query_filters( $wp_query ) ) {
230
			global $wpdb;
231
			$clauses['groupby'] = $wpdb->posts . '.ID ';
232
		}
233
		return $clauses;
234
	}
235
236
237
238
    /**
239
     *    posts_fields
240
     *
241
     * @param          $SQL
242
     * @param WP_Query $wp_query
243
     * @return    string
244
     * @throws \EE_Error
245
     */
246
	public static function posts_fields( $SQL, WP_Query $wp_query ) {
247
		if ( EEH_Event_Query::apply_query_filters( $wp_query ) ) {
248
			// adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
249
			$SQL .= EEH_Event_Query::posts_fields_sql_for_orderby( EEH_Event_Query::$_event_query_orderby );
250
		}
251
		return $SQL;
252
	}
253
254
255
256
    /**
257
     *    posts_join_sql_for_terms
258
     *
259
     * @param array $orderby_params
260
     * @return    string
261
     * @throws \EE_Error
262
     */
263
	public static function posts_fields_sql_for_orderby( $orderby_params = array() ) {
264
		$SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ' ;
265
		foreach( (array)$orderby_params as $orderby ) {
266
			switch ( $orderby ) {
267
268
				case 'ticket_start' :
269
					$SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date' ;
270
					break;
271
272
				case 'ticket_end' :
273
					$SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date' ;
274
					break;
275
276
				case 'venue_title' :
277
					$SQL .= ', Venue.post_title AS venue_title' ;
278
					break;
279
280
				case 'city' :
281
					$SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city' ;
282
					break;
283
284
				case 'state' :
285
					$SQL .= ', ' . EEM_State::instance()->table() . '.STA_name' ;
286
					break;
287
288
			}
289
		}
290
		return  $SQL;
291
	}
292
293
294
295
    /**
296
     *    posts_join
297
     *
298
     * @param string   $SQL
299
     * @param WP_Query $wp_query
300
     * @return    string
301
     * @throws \EE_Error
302
     */
303
	public static function posts_join( $SQL = '', WP_Query $wp_query ) {
304
		if ( EEH_Event_Query::apply_query_filters( $wp_query ) ) {
305
			// Category
306
			$SQL = EEH_Event_Query::posts_join_sql_for_show_expired( $SQL, EEH_Event_Query::$_event_query_show_expired );
307
			$SQL = EEH_Event_Query::posts_join_sql_for_terms( $SQL, EEH_Event_Query::$_event_query_category );
308
			$SQL = EEH_Event_Query::posts_join_for_orderby( $SQL, EEH_Event_Query::$_event_query_orderby );
309
		}
310
		return $SQL;
311
	}
312
313
314
315
    /**
316
     *    posts_join_sql_for_terms
317
     *
318
     * @param string     $SQL
319
     * @param    boolean $show_expired if TRUE, then displayed past events
320
     * @return string
321
     * @throws \EE_Error
322
     */
323
	public static function posts_join_sql_for_show_expired( $SQL = '', $show_expired = FALSE ) {
324
		if ( ! $show_expired ) {
325
			$join = EEM_Event::instance()->table() . '.ID = ';
326
			$join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
327
			// don't add if this is already in the SQL
328 View Code Duplication
			if ( strpos( $SQL, $join ) === FALSE ) {
329
				$SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) ';
330
			}
331
		}
332
		return $SQL;
333
	}
334
335
336
337
	/**
338
	 *    posts_join_sql_for_terms
339
	 *
340
	 * @param 	string   $SQL
341
	 * @param 	string $join_terms pass TRUE or term string, doesn't really matter since this value doesn't really get used for anything yet
342
	 * @return 	string
343
	 */
344 View Code Duplication
	public static function posts_join_sql_for_terms( $SQL = '', $join_terms = '' ) {
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...
345
		if ( ! empty( $join_terms ) ) {
346
			global $wpdb;
347
			$SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)";
348
			$SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
349
			$SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) ";
350
		}
351
		return $SQL;
352
	}
353
354
355
356
    /**
357
     *    posts_join_for_orderby
358
     *    usage:  $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params );
359
     *
360
     * @param    string $SQL
361
     * @param    array  $orderby_params
362
     * @return    string
363
     * @throws \EE_Error
364
     */
365
	public static function posts_join_for_orderby( $SQL = '', $orderby_params = array() ) {
366
		foreach ( (array)$orderby_params as $orderby ) {
367
			switch ( $orderby ) {
368
				case 'ticket_start' :
369
				case 'ticket_end' :
370
					$SQL .= EEH_Event_Query::_posts_join_for_datetime(
371
					    $SQL,
372
                        EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name()
373
                    );
374
					$SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table();
375
					$SQL .= ' ON (';
376
					$SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
377
					$SQL .= ' = ';
378
					$SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
379
					$SQL .=  ' )';
380
					break;
381
				case 'venue_title' :
382
				case 'city' :
383
					$SQL .= EEH_Event_Query::_posts_join_for_event_venue( $SQL );
384
					break;
385
				case 'state' :
386
					$SQL .= EEH_Event_Query::_posts_join_for_event_venue( $SQL );
387
					$SQL .= EEH_Event_Query::_posts_join_for_venue_state( $SQL );
388
					break;
389
				case 'start_date' :
390
				default :
391
					$SQL .= EEH_Event_Query::_posts_join_for_datetime( $SQL, EEM_Event::instance()->table() . '.ID' );
392
					break;
393
394
			}
395
		}
396
		return $SQL;
397
	}
398
399
400
401
    /**
402
     *    _posts_join_for_datetime
403
     *
404
     * @param string $SQL
405
     * @param string $join
406
     * @return string
407
     * @throws \EE_Error
408
     */
409
	protected static function _posts_join_for_datetime( $SQL = '', $join = '' ) {
410
		if ( ! empty( $join )) {
411
			$join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
412 View Code Duplication
			if ( strpos( $SQL, $join ) === FALSE ) {
413
				return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )';
414
			}
415
		}
416
		return '';
417
	}
418
419
420
421
    /**
422
     *    _posts_join_for_event_venue
423
     *
424
     * @param string $SQL
425
     * @return string
426
     * @throws \EE_Error
427
     */
428
	protected static function _posts_join_for_event_venue( $SQL = '' ) {
429
		// Event Venue table name
430
		$event_venue_table = EEM_Event_Venue::instance()->table();
431
		// generate conditions for:  Event <=> Event Venue  JOIN clause
432
		$event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = ';
433
		$event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name();
434
		// don't add joins if they have already been added
435
		if ( strpos( $SQL, $event_to_event_venue_join ) === FALSE ) {
436
			// Venue table name
437
			$venue_table = EEM_Venue::instance()->table();
438
			// Venue table pk
439
			$venue_table_pk = EEM_Venue::instance()->primary_key_name();
440
			// Venue Meta table name
441
			$venue_meta_table = EEM_Venue::instance()->second_table();
442
			// generate JOIN clause for: Event <=> Event Venue
443
			$venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )";
444
			// generate JOIN clause for: Event Venue <=> Venue
445
			$venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )";
446
			// generate JOIN clause for: Venue <=> Venue Meta
447
			$venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )";
448
			unset( $event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table );
449
			return $venue_SQL;
450
		}
451
		unset( $event_venue_table, $event_to_event_venue_join );
452
		return '';
453
	}
454
455
456
457
    /**
458
     *    _posts_join_for_venue_state
459
     *
460
     * @param string $SQL
461
     * @return string
462
     * @throws \EE_Error
463
     */
464
	protected static function _posts_join_for_venue_state( $SQL = '' ) {
465
		// Venue Meta table name
466
		$venue_meta_table = EEM_Venue::instance()->second_table();
467
		// State table name
468
		$state_table = EEM_State::instance()->table();
469
		// State table pk
470
		$state_table_pk = EEM_State::instance()->primary_key_name();
471
		// verify vars
472
		if ( $venue_meta_table && $state_table && $state_table_pk ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $venue_meta_table of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
473
			// like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID
474
			$join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk";
475
			// don't add join if it has already been added
476
			if ( strpos( $SQL, $join ) === FALSE ) {
477
				unset( $state_table_pk, $venue_meta_table, $venue_table_pk );
478
				return " LEFT JOIN $state_table ON ( $join )";
479
			}
480
		}
481
		unset( $join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk );
482
		return '';
483
	}
484
485
486
487
    /**
488
     *    posts_where
489
     *
490
     * @param string   $SQL
491
     * @param WP_Query $wp_query
492
     * @return    string
493
     * @throws \EE_Error
494
     */
495
	public static function posts_where( $SQL = '', WP_Query $wp_query ) {
496
		if ( EEH_Event_Query::apply_query_filters( $wp_query ) ) {
497
			// Show Expired ?
498
			$SQL .= EEH_Event_Query::posts_where_sql_for_show_expired( EEH_Event_Query::$_event_query_show_expired );
499
			// Category
500
			$SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug( EEH_Event_Query::$_event_query_category );
0 ignored issues
show
Documentation introduced by
\EEH_Event_Query::$_event_query_category is of type string, but the function expects a boolean|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
501
			// Start Date
502
			$SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month( EEH_Event_Query::$_event_query_month );
0 ignored issues
show
Documentation introduced by
\EEH_Event_Query::$_event_query_month is of type string, but the function expects a boolean|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
503
		}
504
		return $SQL;
505
	}
506
507
508
509
    /**
510
     *    posts_where_sql_for_show_expired
511
     *
512
     * @param    boolean $show_expired if TRUE, then displayed past events
513
     * @return    string
514
     * @throws \EE_Error
515
     */
516
	public static function posts_where_sql_for_show_expired( $show_expired = FALSE ) {
517
		return ! $show_expired
518
            ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time( 'mysql', TRUE ) . '\' '
519
            : '';
520
	}
521
522
523
524
	/**
525
	 *    posts_where_sql_for_event_category_slug
526
	 *
527
	 * @param    boolean $event_category_slug
528
	 * @return    string
529
	 */
530
	public static function posts_where_sql_for_event_category_slug( $event_category_slug = NULL ) {
531
		global $wpdb;
532
		$event_category_slug = esc_sql($event_category_slug);
533
		return ! empty( $event_category_slug )
534
            ? " AND {$wpdb->terms}.slug = '{$event_category_slug}' "
535
            : '';
536
	}
537
538
539
540
    /**
541
     *    posts_where_sql_for_event_list_month
542
     *
543
     * @param    boolean $month
544
     * @return    string
545
     * @throws \EE_Error
546
     */
547
	public static function posts_where_sql_for_event_list_month( $month = NULL ) {
548
		$SQL = '';
549
		if ( ! empty( $month ) ) {
550
			$datetime_table = EEM_Datetime::instance()->table();
551
			// event start date is LESS than the end of the month ( so nothing that doesn't start until next month )
552
			$SQL = " AND {$datetime_table}.DTT_EVT_start <= '" . date( 'Y-m-t 23:59:59', strtotime( $month . ' 1') ) . "'";
553
			// event end date is GREATER than the start of the month ( so nothing that ended before this month )
554
			$SQL .= " AND {$datetime_table}.DTT_EVT_end >= '" . date( 'Y-m-01 0:0:00', strtotime( $month . ' 1') ) . "' ";
555
		}
556
		return $SQL;
557
	}
558
559
560
561
    /**
562
     *    posts_orderby
563
     *
564
     * @param string   $SQL
565
     * @param WP_Query $wp_query
566
     * @return    string
567
     * @throws \EE_Error
568
     */
569
	public static function posts_orderby( $SQL = '', WP_Query $wp_query ) {
570
		if ( EEH_Event_Query::apply_query_filters( $wp_query ) ) {
571
			$SQL = EEH_Event_Query::posts_orderby_sql(
572
			    EEH_Event_Query::$_event_query_orderby,
573
                EEH_Event_Query::$_event_query_sort
574
            );
575
		}
576
		return $SQL;
577
	}
578
579
580
581
    /**
582
     *    posts_orderby_sql
583
     *    possible parameters:
584
     *    ID
585
     *    start_date
586
     *    end_date
587
     *    event_name
588
     *    category_slug
589
     *    ticket_start
590
     *    ticket_end
591
     *    venue_title
592
     *    city
593
     *    state
594
     *    **IMPORTANT**
595
     *    make sure to also send the $orderby_params array to the posts_join_for_orderby() method
596
     *    or else some of the table references below will result in MySQL errors
597
     *
598
     * @param array|bool $orderby_params
599
     * @param string     $sort
600
     * @return string
601
     * @throws \EE_Error
602
     */
603
	public static function posts_orderby_sql( $orderby_params = array(), $sort = 'ASC' ) {
604
		global $wpdb;
605
		$SQL = '';
606
		$counter = 0;
607
		$sort = in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true)
608
            ? strtoupper($sort)
609
            : 'ASC';
610
		//make sure 'orderby' is set in query params
611
		if ( ! isset( self::$_query_params['orderby'] )) {
612
			self::$_query_params['orderby'] = array();
613
		}
614
		// loop thru $orderby_params (type cast as array)
615
		foreach ( (array)$orderby_params as $orderby ) {
616
			// check if we have already added this param
617
			if ( isset( self::$_query_params['orderby'][ $orderby ] )) {
618
				// if so then remove from the $orderby_params so that the count() method below is accurate
619
				unset( $orderby_params[ $orderby ] );
620
				// then bump ahead to the next param
621
				continue;
622
			}
623
			// this will ad a comma depending on whether this is the first or last param
624
			$glue = $counter === 0 || $counter === count( $orderby_params ) ? ' ' : ', ';
625
			// ok what's we dealing with?
626 View Code Duplication
			switch ( $orderby ) {
627
				case 'id' :
628
				case 'ID' :
629
					$SQL .= $glue . $wpdb->posts . '.ID ' . $sort;
630
					break;
631
				case 'end_date' :
632
					$SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort;
633
					break;
634
				case 'event_name' :
635
					$SQL .= $glue . $wpdb->posts . '.post_title ' . $sort;
636
					break;
637
				case 'category_slug' :
638
					$SQL .= $glue . $wpdb->terms . '.slug ' . $sort;
639
					break;
640
				case 'ticket_start' :
641
					$SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort;
642
					break;
643
				case 'ticket_end' :
644
					$SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort;
645
					break;
646
				case 'venue_title' :
647
					$SQL .= $glue . 'venue_title ' . $sort;
648
					break;
649
				case 'city' :
650
					$SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort;
651
					break;
652
				case 'state' :
653
					$SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort;
654
					break;
655
				case 'start_date' :
656
				default :
657
					$SQL .= $glue . ' event_start_date ' . $sort;
658
					break;
659
			}
660
			// add to array of orderby params that have been added
661
			self::$_query_params['orderby'][ $orderby ] = TRUE;
662
			$counter ++;
663
		}
664
		return $SQL;
665
	}
666
667
668
}
669
670
671
672
// End of file EEH_Event_Query.helper.php
673
// Location: /EEH_Event_Query.helper.php
674