WooCommerce get products based on specific taxonomy - php

I need to modify the WooCommerce product query because I want to filter the shown products on the shop pages based on product tag custom taxonomy.
So what I've tried is this here but it don't works:
add_filter( 'woocommerce_product_query_meta_query', 'filter', 10, 2 );
function filter( $meta_query, $query ) {
// Only on category pages
if ( ! is_product_category() ) {
return $meta_query;
}
$meta_query[] = array(
'key' => 'taxonomy',
'value' => 'product_tag',
'compare' => 'EXIST'
);
return $meta_query;
}
So I just want to display all products which have the taxonomy ABCSD in it.
The code is placed in my functions.php. What I'm doing wrong here?
Notice:
I mean the values I get when I call this function:
wp_get_post_terms( $product_id, 'product_tag' );

As it is about a taxonomy, you need to use a tax query and then the hook will be different. Also you can make it for specific product tags:
add_filter( 'woocommerce_product_query_tax_query', 'filter_products_with_specific_product_tags', 10, 2 );
function filter_products_with_specific_product_tags( $tax_query, $query ) {
// Only on category pages
if ( ! is_product_category() )
return $tax_query;
$tax_query[] = array(
'taxonomy' => 'product_tag',
'field' => 'name',
'terms' => array('Green', 'Yellow', 'Red'), // Defined product tags term names
);
return $tax_query;
};
Code goes in function.php file of your active child theme (or active theme). It should works.

Related

Hide out of stock WooCommerce products only on a widget with Elementor

I'm trying to add a product archive widget in Elementor but in this widget specifically must hide "Out of stock" products.
I try to modify this code but I have not succeeded.
add_filter( 'woocommerce_product_query_meta_query', 'shop_only_instock_products', 10, 2 );
function shop_only_instock_products( $meta_query, $query ) {
// Only on shop archive pages
if( '#outst' ) return $meta_query;
$meta_query[] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!='
);
return $meta_query;
}
Any ideas?
Sidebar of elementor:
Product Widget Archive:
For widgets you should use woocommerce_products_widget_query_args hook instead. To hide Out of stock products, there is 2 ways:
1). With a meta query:
add_filter( 'woocommerce_products_widget_query_args', 'custom_products_widget_query_arg', 10, 1 );
function custom_products_widget_query_arg( $query_args ) {
if( ! is_admin() ) {
$query_args['meta_query'][] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!='
);
}
return $query_args;
}
2). Or with a tax query:
add_filter( 'woocommerce_products_widget_query_args', 'custom_products_widget_query_arg', 10, 1 );
function custom_products_widget_query_arg( $query_args ) {
if( ! is_admin() ) {
$query_args['tax_query'][] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => array('outofstock'),
'operator' => 'NOT IN'
);
}
return $query_args;
}
Code goes in functions.php file of your active child theme (or active theme). Both could work.
Related:
Hide "out of stock" products on home page in WooCommerce
Exclude specific products from everywhere with a meta query in Woocommerce

Hide "out of stock" products on home page in WooCommerce

I don't want to display "out of stock" products on my home page.
I have tried some WooCommerce hooks and filter to alter product query but its not working.
I have also checked "hide out of stock" into woocommerce setting area.
but product are still appearing. Can I get the clue, wh its happening.
I tried this filter hook to alter main product query:
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! $q->is_post_type_archive() ) return;
if ( ! is_admin() ) {
$q->set( 'meta_query', array(array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I want to hide out of stock products but nothing is working. Any help is appreciated.
To exclude "Out of stock" products from your homepage, it can be done in different ways.
1) A Meta Query using dedicated woocommerce_product_query_meta_query filter hook:
add_filter( 'woocommerce_product_query_meta_query', 'filter_product_query_meta_query', 10, 2 );
function filter_product_query_meta_query( $meta_query, $query ) {
// On woocommerce home page only
if( is_front_page() ){
// Exclude products "out of stock"
$meta_query[] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!=',
);
}
return $meta_query;
}
2) A Tax Query using dedicated woocommerce_product_query_tax_query filter hook:
add_filter( 'woocommerce_product_query_tax_query', 'filter_product_query_tax_query', 10, 2 );
function filter_product_query_tax_query( $tax_query, $query ) {
// On woocommerce home page only
if( is_front_page() ){
// Exclude products "out of stock"
$tax_query[] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => array('outofstock'),
'operator' => 'NOT IN'
);
}
return $tax_query;
}
Code goes in functions.php file of your active child theme (or active theme). Both works.
Related: Hide out of stock products only on shop archive pages in Woocommerce
You are using code for old WooCommerce version. Try this approach.
add_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() || is_admin() || ! $q->is_front_page() ) {
return;
}
if ( $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' ) ) {
$tax_query = (array) $q->get('tax_query');
$tax_query[] = array(
'taxonomy' => 'product_visibility',
'field' => 'term_taxonomy_id',
'terms' => array( $outofstock_term->term_taxonomy_id ),
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
}
UPDATE
Check font-page.php file in your current theme folder, maybe your developers have added a custom code into your template files without calling any hook actions.
OLD ANSWER
Why don't use WooCommerce Settings?
Go to Woocommerce → Settings and click the Products tab
Click the Inventory link at the top
Check the Hide out of stock items from the catalog option to hide out of stock items

Filter Woocommerce products based on custom product attribute value

In Woocommerce, I have a product attribute called restriction_id. I am wanting to filter the products based on certain restriction id's. For example if a value is set to 35 in a php session variable I want to filter out any product that has the attribute for restriction_id set to 35.
What would I put in here?
Here is my starting code:
// Define the woocommerce_product_query callback
function action_woocommerce_product_query( $q, $instance ) {
// The code
};
// Add the action
add_action( 'woocommerce_product_query', __NAMESPACE__.'\\action_woocommerce_product_query', 10, 2 );
Any help is appreciated.
Updated: Try the following tax query instead:
add_filter( 'woocommerce_product_query_tax_query', 'custom_product_query_meta_query', 10, 2 );
function custom_product_query_meta_query( $tax_query, $query ) {
if( is_admin() ) return $tax_query;
// HERE set the taxonomy of your product attribute (custom taxonomy)
$taxonomy = 'pa_restriction_id'; // Note: always start with "pa_" in Woocommerce
// HERE Define your product attribute Terms to be excluded
$terms = array( '35' ); // Note: can be a 'term_id', 'slug' or 'name'
// The tax query
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug', // can be a 'term_id', 'slug' or 'name'
'terms' => $terms,
'operator' => 'NOT IN', // Excluded
);
return $tax_query;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Hide products having a specific product category in Woocommerce

We use the following code to hide products having categories "uncategorized":
add_action('pre_get_posts', 'custom_pre_get_posts_query');
function custom_pre_get_posts_query( $q ) {
if (!$q->is_main_query()) return;
if (!$q->is_post_type_archive()) return;
$q->set('tax_query', array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'ukategorisert',
'operator' => 'NOT IN',
)
));
remove_action('pre_get_posts', 'custom_pre_get_posts_query');
}
But for some reason, the archive ends up showing a different number of products on each page. It seems like the products are hidden, but still counted as products in the pagination?
We can't find a reason or solution for this problem. Please help.
Instead of using pre_get_posts hooked function, you should use one of the related dedicated Woocommerce action and filter hooks.
Try this instead:
add_filter('woocommerce_product_query_tax_query', 'custom_product_query_tax_query', 10, 2 );
function custom_product_query_tax_query( $tax_query, $query ) {
if( is_admin() ) return $tax_query;
// HERE Define your product category SLUGs to be excluded
$terms = array( 'ukategorisert' ); // SLUGs only
// The taxonomy for Product Categories
$taxonomy = 'product_cat';
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug', // Or 'name' or 'term_id'
'terms' => $terms,
'operator' => 'NOT IN', // Excluded
);
return $tax_query;
}
This code goes on function.php file of your active child theme (or theme). It should work.

How do I exclude a particular woocommerce product category from the list of displayed categores

I'm using the woocommerce shortcode [product_categories hide_empty=0] for woocommerce shortcode docs, to display all my product categories in my shop page name mysitename/sabiresearchshop. However, I want to exclude just a category called Premium Membership from this list of displayed product categories How can I do it.
I have tried the code below to no avail:
function sabi_customize_product_shortcode( $args, $atts ) {
if ( is_page (119) ) {
$args['tax_query'] = array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'premium-membership' ),
'operator' => 'NOT IN'
)
);
}
return $args;
}
add_filter( 'woocommerce_shortcode_products_query', 'sabi_customize_product_shortcode', 10, 2 );

Categories