Completed
Pull Request — master (#10110)
by Claudio
13:32
created

WC_Query::get_endpoint_title()   C

Complexity

Conditions 13
Paths 13

Size

Total Lines 46
Code Lines 41

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 46
rs 5.1118
cc 13
eloc 41
nc 13
nop 1

How to fix   Complexity   

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