Completed
Pull Request — master (#10315)
by Mike
08:17
created

WC_Query::get_main_tax_query()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 7
Ratio 43.75 %
Metric Value
dl 7
loc 16
rs 9.2
cc 4
eloc 10
nc 4
nop 0
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 21 and the first side effect is on line 13.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Contains the query functions for WooCommerce which alter the front-end post queries and loops
4
 *
5
 * @class 		WC_Query
6
 * @version		2.6.0
7
 * @package		WooCommerce/Classes
8
 * @category	Class
9
 * @author 		WooThemes
10
 */
11
12
if ( ! defined( 'ABSPATH' ) ) {
13
	exit;
14
}
15
16
if ( ! class_exists( 'WC_Query' ) ) :
17
18
/**
19
 * WC_Query Class.
20
 */
21
class WC_Query {
22
23
	/** @public array Query vars to add to wp */
24
	public $query_vars = array();
25
26
	/**
27
	 * Stores chosen attributes
28
	 * @var array
29
	 */
30
	private static $_chosen_attributes;
31
32
	/**
33
	 * Constructor for the query class. Hooks in methods.
34
	 *
35
	 * @access public
36
	 */
37
	public function __construct() {
38
		add_action( 'init', array( $this, 'add_endpoints' ) );
39
		if ( ! is_admin() ) {
40
			add_action( 'init', array( $this, 'layered_nav_init' ) );
41
			add_action( 'wp_loaded', array( $this, 'get_errors' ), 20 );
42
			add_filter( 'query_vars', array( $this, 'add_query_vars'), 0 );
43
			add_action( 'parse_request', array( $this, 'parse_request'), 0 );
44
			add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
45
			add_action( 'wp', array( $this, 'remove_product_query' ) );
46
			add_action( 'wp', array( $this, 'remove_ordering_args' ) );
47
		}
48
		$this->init_query_vars();
49
	}
50
51
	/**
52
	 * Get any errors from querystring.
53
	 */
54
	public function get_errors() {
55
		if ( ! empty( $_GET['wc_error'] ) && ( $error = sanitize_text_field( $_GET['wc_error'] ) ) && ! wc_has_notice( $error, 'error' ) ) {
56
			wc_add_notice( $error, 'error' );
57
		}
58
	}
59
60
	/**
61
	 * Init query vars by loading options.
62
	 */
63
	public function init_query_vars() {
64
		// Query vars to add to WP
65
		$this->query_vars = array(
66
			// Checkout actions
67
			'order-pay'          => get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' ),
68
			'order-received'     => get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' ),
69
70
			// My account actions
71
			'view-order'         => get_option( 'woocommerce_myaccount_view_order_endpoint', 'view-order' ),
72
			'edit-account'       => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ),
73
			'edit-address'       => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ),
74
			'lost-password'      => get_option( 'woocommerce_myaccount_lost_password_endpoint', 'lost-password' ),
75
			'customer-logout'    => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ),
76
			'add-payment-method' => get_option( 'woocommerce_myaccount_add_payment_method_endpoint', 'add-payment-method' ),
77
		);
78
	}
79
80
	/**
81
	 * Get page title for an endpoint.
82
	 * @param  string
83
	 * @return string
84
	 */
85
	public function get_endpoint_title( $endpoint ) {
86
		global $wp;
87
88
		switch ( $endpoint ) {
89
			case 'order-pay' :
90
				$title = __( 'Pay for Order', 'woocommerce' );
91
			break;
92
			case 'order-received' :
93
				$title = __( 'Order Received', 'woocommerce' );
94
			break;
95
			case 'view-order' :
96
				$order = wc_get_order( $wp->query_vars['view-order'] );
97
				$title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : '';
98
			break;
99
			case 'edit-account' :
100
				$title = __( 'Edit Account Details', 'woocommerce' );
101
			break;
102
			case 'edit-address' :
103
				$title = __( 'Edit Address', 'woocommerce' );
104
			break;
105
			case 'add-payment-method' :
106
				$title = __( 'Add Payment Method', 'woocommerce' );
107
			break;
108
			case 'lost-password' :
109
				$title = __( 'Lost Password', 'woocommerce' );
110
			break;
111
			default :
112
				$title = '';
113
			break;
114
		}
115
		return $title;
116
	}
117
118
	/**
119
	 * Add endpoints for query vars.
120
	 */
121
	public function add_endpoints() {
122
		foreach ( $this->query_vars as $key => $var ) {
123
			add_rewrite_endpoint( $var, EP_ROOT | EP_PAGES );
124
		}
125
	}
126
127
	/**
128
	 * Add query vars.
129
	 *
130
	 * @access public
131
	 * @param array $vars
132
	 * @return array
133
	 */
134
	public function add_query_vars( $vars ) {
135
		foreach ( $this->query_vars as $key => $var ) {
136
			$vars[] = $key;
137
		}
138
		return $vars;
139
	}
140
141
	/**
142
	 * Get query vars.
143
	 *
144
	 * @return array
145
	 */
146
	public function get_query_vars() {
147
		return $this->query_vars;
148
	}
149
150
	/**
151
	 * Get query current active query var.
152
	 *
153
	 * @return string
154
	 */
155
	public function get_current_endpoint() {
156
		global $wp;
157
		foreach ( $this->get_query_vars() as $key => $value ) {
158
			if ( isset( $wp->query_vars[ $key ] ) ) {
159
				return $key;
160
			}
161
		}
162
		return '';
163
	}
164
165
	/**
166
	 * Parse the request and look for query vars - endpoints may not be supported.
167
	 */
168
	public function parse_request() {
169
		global $wp;
170
171
		// Map query vars to their keys, or get them if endpoints are not supported
172
		foreach ( $this->query_vars as $key => $var ) {
173
			if ( isset( $_GET[ $var ] ) ) {
174
				$wp->query_vars[ $key ] = $_GET[ $var ];
175
			}
176
177
			elseif ( isset( $wp->query_vars[ $var ] ) ) {
178
				$wp->query_vars[ $key ] = $wp->query_vars[ $var ];
179
			}
180
		}
181
	}
182
183
	/**
184
	 * Hook into pre_get_posts to do the main product query.
185
	 *
186
	 * @param mixed $q query object
187
	 */
188
	public function pre_get_posts( $q ) {
189
		// We only want to affect the main query
190
		if ( ! $q->is_main_query() ) {
191
			return;
192
		}
193
194
		// Fix for verbose page rules
195
		if ( $GLOBALS['wp_rewrite']->use_verbose_page_rules && isset( $q->queried_object->ID ) && $q->queried_object->ID === wc_get_page_id( 'shop' ) ) {
196
			$q->set( 'post_type', 'product' );
197
			$q->set( 'page', '' );
198
			$q->set( 'pagename', '' );
199
200
			// Fix conditional Functions
201
			$q->is_archive           = true;
202
			$q->is_post_type_archive = true;
203
			$q->is_singular          = false;
204
			$q->is_page              = false;
205
		}
206
207
		// Fix for endpoints on the homepage
208
		if ( $q->is_home() && 'page' === get_option( 'show_on_front' ) && absint( get_option( 'page_on_front' ) ) !== absint( $q->get( 'page_id' ) ) ) {
209
			$_query = wp_parse_args( $q->query );
210
			if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->query_vars ) ) ) {
211
				$q->is_page     = true;
212
				$q->is_home     = false;
213
				$q->is_singular = true;
214
				$q->set( 'page_id', (int) get_option( 'page_on_front' ) );
215
				add_filter( 'redirect_canonical', '__return_false' );
216
			}
217
		}
218
219
		// When orderby is set, WordPress shows posts. Get around that here.
220
		if ( $q->is_home() && 'page' === get_option( 'show_on_front' ) && absint( get_option( 'page_on_front' ) ) === wc_get_page_id( 'shop' ) ) {
221
			$_query = wp_parse_args( $q->query );
222
			if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) {
223
				$q->is_page = true;
224
				$q->is_home = false;
225
				$q->set( 'page_id', (int) get_option( 'page_on_front' ) );
226
				$q->set( 'post_type', 'product' );
227
			}
228
		}
229
230
		// Special check for shops with the product archive on front
231
		if ( $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) {
232
233
			// This is a front-page shop
234
			$q->set( 'post_type', 'product' );
235
			$q->set( 'page_id', '' );
236
237
			if ( isset( $q->query['paged'] ) ) {
238
				$q->set( 'paged', $q->query['paged'] );
239
			}
240
241
			// Define a variable so we know this is the front page shop later on
242
			define( 'SHOP_IS_ON_FRONT', true );
243
244
			// Get the actual WP page to avoid errors and let us use is_front_page()
245
			// This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
246
			global $wp_post_types;
247
248
			$shop_page 	= get_post( wc_get_page_id( 'shop' ) );
249
250
			$wp_post_types['product']->ID 			= $shop_page->ID;
251
			$wp_post_types['product']->post_title 	= $shop_page->post_title;
252
			$wp_post_types['product']->post_name 	= $shop_page->post_name;
253
			$wp_post_types['product']->post_type    = $shop_page->post_type;
254
			$wp_post_types['product']->ancestors    = get_ancestors( $shop_page->ID, $shop_page->post_type );
255
256
			// Fix conditional Functions like is_front_page
257
			$q->is_singular          = false;
258
			$q->is_post_type_archive = true;
259
			$q->is_archive           = true;
260
			$q->is_page              = true;
261
262
			// Remove post type archive name from front page title tag
263
			add_filter( 'post_type_archive_title', '__return_empty_string', 5 );
264
265
			// Fix WP SEO
266
			if ( class_exists( 'WPSEO_Meta' ) ) {
267
				add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) );
268
				add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) );
269
			}
270
271
		// Only apply to product categories, the product post archive, the shop page, product tags, and product attribute taxonomies
272
		} elseif ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( get_object_taxonomies( 'product' ) ) ) {
273
			return;
274
		}
275
276
		$this->product_query( $q );
277
278
		if ( is_search() ) {
279
			add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
280
			add_filter( 'wp', array( $this, 'remove_posts_where' ) );
281
		}
282
283
		// And remove the pre_get_posts hook
284
		$this->remove_product_query();
285
	}
286
287
	/**
288
	 * Search post excerpt.
289
	 *
290
	 * @access public
291
	 * @param string $where (default: '')
292
	 * @return string (modified where clause)
293
	 */
294
	public function search_post_excerpt( $where = '' ) {
295
		global $wp_the_query;
296
297
		// If this is not a WC Query, do not modify the query
298
		if ( empty( $wp_the_query->query_vars['wc_query'] ) || empty( $wp_the_query->query_vars['s'] ) )
299
			return $where;
300
301
		$where = preg_replace(
302
			"/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
303
			"post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
304
305
		return $where;
306
	}
307
308
	/**
309
	 * WP SEO meta description.
310
	 *
311
	 * Hooked into wpseo_ hook already, so no need for function_exist.
312
	 *
313
	 * @access public
314
	 * @return string
315
	 */
316
	public function wpseo_metadesc() {
317
		return WPSEO_Meta::get_value( 'metadesc', wc_get_page_id( 'shop' ) );
318
	}
319
320
	/**
321
	 * WP SEO meta key.
322
	 *
323
	 * Hooked into wpseo_ hook already, so no need for function_exist.
324
	 *
325
	 * @access public
326
	 * @return string
327
	 */
328
	public function wpseo_metakey() {
329
		return WPSEO_Meta::get_value( 'metakey', wc_get_page_id( 'shop' ) );
330
	}
331
332
	/**
333
	 * Query the products, applying sorting/ordering etc. This applies to the main wordpress loop.
334
	 *
335
	 * @param mixed $q
336
	 */
337
	public function product_query( $q ) {
338
		// Ordering query vars
339
		$ordering  = $this->get_catalog_ordering_args();
340
		$q->set( 'orderby', $ordering['orderby'] );
341
		$q->set( 'order', $ordering['order'] );
342
		if ( isset( $ordering['meta_key'] ) ) {
343
			$q->set( 'meta_key', $ordering['meta_key'] );
344
		}
345
346
		// Query vars that affect posts shown
347
		$q->set( 'meta_query', $this->get_meta_query( $q->get( 'meta_query' ) ) );
348
		$q->set( 'tax_query', $this->get_tax_query( $q->get( 'tax_query' ) ) );
349
		$q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) );
350
		$q->set( 'wc_query', 'product_query' );
351
		$q->set( 'post__in', array_unique( apply_filters( 'loop_shop_post_in', array() ) ) );
352
353
		do_action( 'woocommerce_product_query', $q, $this );
354
	}
355
356
357
	/**
358
	 * Remove the query.
359
	 */
360
	public function remove_product_query() {
361
		remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
362
	}
363
364
	/**
365
	 * Remove ordering queries.
366
	 */
367
	public function remove_ordering_args() {
368
		remove_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) );
369
		remove_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) );
370
	}
371
372
	/**
373
	 * Remove the posts_where filter.
374
	 */
375
	public function remove_posts_where() {
376
		remove_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
377
	}
378
379
	/**
380
	 * Returns an array of arguments for ordering products based on the selected values.
381
	 *
382
	 * @access public
383
	 * @return array
384
	 */
385
	public function get_catalog_ordering_args( $orderby = '', $order = '' ) {
386
		global $wpdb;
387
388
		// Get ordering from query string unless defined
389
		if ( ! $orderby ) {
390
			$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
391
392
			// Get order + orderby args from string
393
			$orderby_value = explode( '-', $orderby_value );
394
			$orderby       = esc_attr( $orderby_value[0] );
395
			$order         = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order;
396
		}
397
398
		$orderby = strtolower( $orderby );
399
		$order   = strtoupper( $order );
400
		$args    = array();
401
402
		// default - menu_order
403
		$args['orderby']  = 'menu_order title';
404
		$args['order']    = $order == 'DESC' ? 'DESC' : 'ASC';
405
		$args['meta_key'] = '';
406
407
		switch ( $orderby ) {
408
			case 'rand' :
409
				$args['orderby']  = 'rand';
410
			break;
411
			case 'date' :
412
				$args['orderby']  = 'date';
413
				$args['order']    = $order == 'ASC' ? 'ASC' : 'DESC';
414
			break;
415
			case 'price' :
416
				$args['orderby']  = "meta_value_num ID";
417
				$args['order']    = $order == 'DESC' ? 'DESC' : 'ASC';
418
				$args['meta_key'] = '_price';
419
			break;
420
			case 'popularity' :
421
				$args['meta_key'] = 'total_sales';
422
423
				// Sorting handled later though a hook
424
				add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) );
425
			break;
426
			case 'rating' :
427
				// Sorting handled later though a hook
428
				add_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) );
429
			break;
430
			case 'title' :
431
				$args['orderby']  = 'title';
432
				$args['order']    = $order == 'DESC' ? 'DESC' : 'ASC';
433
			break;
434
		}
435
436
		return apply_filters( 'woocommerce_get_catalog_ordering_args', $args );
437
	}
438
439
	/**
440
	 * WP Core doens't let us change the sort direction for invidual orderby params - http://core.trac.wordpress.org/ticket/17065.
441
	 *
442
	 * This lets us sort by meta value desc, and have a second orderby param.
443
	 *
444
	 * @access public
445
	 * @param array $args
446
	 * @return array
447
	 */
448
	public function order_by_popularity_post_clauses( $args ) {
449
		global $wpdb;
450
		$args['orderby'] = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_date DESC";
451
		return $args;
452
	}
453
454
	/**
455
	 * Order by rating post clauses.
456
	 *
457
	 * @access public
458
	 * @param array $args
459
	 * @return array
460
	 */
461
	public function order_by_rating_post_clauses( $args ) {
462
		global $wpdb;
463
464
		$args['fields'] .= ", AVG( $wpdb->commentmeta.meta_value ) as average_rating ";
465
		$args['where']  .= " AND ( $wpdb->commentmeta.meta_key = 'rating' OR $wpdb->commentmeta.meta_key IS null ) ";
466
		$args['join']   .= "
467
			LEFT OUTER JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
468
			LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
469
		";
470
		$args['orderby'] = "average_rating DESC, $wpdb->posts.post_date DESC";
471
		$args['groupby'] = "$wpdb->posts.ID";
472
473
		return $args;
474
	}
475
476
	/**
477
	 * Appends meta queries to an array.
478
	 * @access public
479
	 * @param array $meta_query
480
	 * @return array
481
	 */
482
	public function get_meta_query( $meta_query = array() ) {
483
		if ( ! is_array( $meta_query ) ) {
484
			$meta_query = array();
485
		}
486
487
		$meta_query[] = $this->visibility_meta_query();
488
		$meta_query[] = $this->stock_status_meta_query();
489
		$meta_query[] = $this->price_filter_meta_query();
490
		$meta_query[] = $this->rating_filter_meta_query();
491
492
		return array_filter( apply_filters( 'woocommerce_product_query_meta_query', $meta_query, $this ) );
493
	}
494
495
	/**
496
	 * Return a meta query for filtering by price.
497
	 * @return array
498
	 */
499
	private function price_filter_meta_query() {
500
		if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) {
501
			$min          = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0;
502
			$max          = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999;
503
504
			// If displaying prices in the shop including taxes, but prices don't include taxes..
505 View Code Duplication
			if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
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...
506
				$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
507
508
				foreach ( $tax_classes as $tax_class ) {
509
					$tax_rates = WC_Tax::get_rates( $tax_class );
510
					$class_min = $min - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $min, $tax_rates ) );
511
					$class_max = $max - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $max, $tax_rates ) );
512
					if ( $class_min < $min ) {
513
						$min = $class_min;
514
					}
515
					if ( $class_max > $max ) {
516
						$max = $class_max;
517
					}
518
				}
519
			}
520
521
			return array(
522
				'key'          => '_price',
523
				'value'        => array( $min, $max ),
524
				'compare'      => 'BETWEEN',
525
				'type'         => 'DECIMAL',
526
				'price_filter' => true
527
			);
528
		}
529
		return array();
530
	}
531
532
	/**
533
	 * Return a meta query for filtering by rating.
534
	 * @return array
535
	 */
536
	public function rating_filter_meta_query() {
537
		return isset( $_GET['min_rating'] ) ? array(
538
			'key'           => '_wc_average_rating',
539
			'value'         => isset( $_GET['min_rating'] ) ? floatval( $_GET['min_rating'] ) : 0,
540
			'compare'       => '>=',
541
			'type'          => 'DECIMAL',
542
			'rating_filter' => true
543
		) : array();
544
	}
545
546
	/**
547
	 * Returns a meta query to handle product visibility.
548
	 * @param string $compare (default: 'IN')
549
	 * @return array
550
	 */
551
	public function visibility_meta_query( $compare = 'IN' ) {
552
		return array(
553
			'key'     => '_visibility',
554
			'value'   => is_search() ? array( 'visible', 'search' ) : array( 'visible', 'catalog' ),
555
			'compare' => $compare
556
		);
557
	}
558
559
	/**
560
	 * Returns a meta query to handle product stock status.
561
	 *
562
	 * @access public
563
	 * @param string $status (default: 'instock')
564
	 * @return array
565
	 */
566
	public function stock_status_meta_query( $status = 'instock' ) {
567
		return 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ? array(
568
			'key' 		=> '_stock_status',
569
			'value' 	=> $status,
570
			'compare' 	=> '='
571
		) : array();
572
	}
573
574
	/**
575
	 * Appends tax queries to an array.
576
	 * @param array $tax_query
577
	 * @return array
578
	 */
579
	public function get_tax_query( $tax_query = array() ) {
580
		if ( ! is_array( $tax_query ) ) {
581
			$tax_query = array();
582
		}
583
584
		// Layered nav filters on terms
585
		if ( $_chosen_attributes = $this->get_layered_nav_chosen_attributes() ) {
586
			foreach ( $_chosen_attributes as $taxonomy => $data ) {
587
				$tax_query[] = array(
588
					'taxonomy' => $taxonomy,
589
					'field'    => 'slug',
590
					'terms'    => $data['terms'],
591
					'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN',
592
					'include_children' => false
593
				);
594
			}
595
		}
596
597
		return array_filter( apply_filters( 'woocommerce_product_query_tax_query', $tax_query, $this ) );
598
	}
599
600
	/**
601
	 * Get the tax query which was used by the main query.
602
	 * @return array
603
	 */
604
	public static function get_main_tax_query() {
605
		global $wp_the_query;
606
607
		$args      = $wp_the_query->query_vars;
608
		$tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array();
609
610 View Code Duplication
		if ( ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) {
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...
611
			$tax_query[] = array(
612
				'taxonomy' => $args['taxonomy'],
613
				'terms'    => array( $args['term'] ),
614
				'field'    => 'slug'
615
			);
616
		}
617
618
		return $tax_query;
619
	}
620
621
	/**
622
	 * Get the meta query which was used by the main query.
623
	 * @return array
624
	 */
625
	public static function get_main_meta_query() {
626
		global $wp_the_query;
627
628
		$args       = $wp_the_query->query_vars;
629
		$meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array();
630
631
		return $meta_query;
632
	}
633
634
	/**
635
	 * Layered Nav Init.
636
	 */
637
	public static function get_layered_nav_chosen_attributes() {
638
		if ( ! is_array( self::$_chosen_attributes ) ) {
639
			self::$_chosen_attributes = array();
640
641
			if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) {
642
				foreach ( $attribute_taxonomies as $tax ) {
643
					$attribute    = wc_sanitize_taxonomy_name( $tax->attribute_name );
644
					$taxonomy     = wc_attribute_taxonomy_name( $attribute );
645
					$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( $_GET[ 'filter_' . $attribute ] ) ) : array();
646
647
					if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) ) {
648
						continue;
649
					}
650
651
					$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ) ) ? wc_clean( $_GET[ 'query_type_' . $attribute ] ) : '';
652
					self::$_chosen_attributes[ $taxonomy ]['terms']      = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding
653
					self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
654
				}
655
			}
656
		}
657
		return self::$_chosen_attributes;
658
	}
659
660
	/**
661
	 * @deprecated 2.6.0
662
	 */
663
	public function layered_nav_init() {}
664
665
	/**
666
	 * Get an unpaginated list all product ID's (both filtered and unfiltered). Makes use of transients.
667
	 * @deprecated 2.6.0 due to performance concerns
668
	 */
669
	public function get_products_in_view() {
670
		_deprecated_function( 'get_products_in_view', '2.6', '' );
671
	}
672
673
	/**
674
	 * Layered Nav post filter.
675
	 * @deprecated 2.6.0 due to performance concerns
676
	 */
677
	public function layered_nav_query( $filtered_posts ) {
0 ignored issues
show
Unused Code introduced by
The parameter $filtered_posts is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
678
		_deprecated_function( 'layered_nav_query', '2.6', '' );
679
	}
680
}
681
682
endif;
683
684
return new WC_Query();
685