WC_Query::visibility_meta_query()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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