We want to hide/exclude a few specific woocommerce category from the woocommerce shop as well as all pages.
So far we managed to achieve this using code I found on the internet.
The code bellow hide the correct category from the shop page but when we do a search using the woocommerve search, the category are not hidden in the result page.
//Insert excluded category ids here
$excludes = array(3380,3308);
$includes = explode(",",$widget_args['include']);
$includes = array_filter($includes, function($value) use ($excludes) {
return !in_array($value, $excludes);
});
$widget_args["include"] = implode(",", $includes);
return $widget_args;
}
add_filter( 'woocommerce_product_categories_widget_dropdown_args', 'exclude_woocommerce_widget_product_categories');
add_filter( 'woocommerce_product_categories_widget_args', 'exclude_woocommerce_widget_product_categories');
The code bellow does hide the category from the search page but not from the shop page
add_filter( 'woocommerce_product_categories_widget_dropdown_args', 'organicweb_exclude_widget_category');
add_filter( 'woocommerce_product_categories_widget_args', 'organicweb_exclude_widget_category' );
function organicweb_exclude_widget_category( $args ) {
$args['exclude'] = array('15', '3380', '3308' ); // Enter the id of the category you want to exclude in place of '30'
return $args;
}
Could anyone please help me merge the 2 pieces of code together?
Thank you in advance.
Both of the code snippets you posted only hide categories from the widget, it has no effect on hiding the category otherwise. Not 100% on what your goal is, two things seem likely to me:
If you want to Exclude products from a particular category on the shop page do it with below code (does not hide the category, if you selected to show them under Design > Customizer > WooCommerce > Product Catalogue in the backend) as seen in the WooCommerce docs.
/**
* Exclude products from a particular category on the shop page
*/
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'clothing' ), // Don't display products in the clothing category on the shop page.
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
To actually hide the category itself, do the following as documented here Hide a WooCommerce Category from Shop Page, which does not hide the products of this category.
/**
* Show products only of selected category.
*/
function get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
$hide_category = array( 126 ); // Ids of the category you don't want to display on the shop page
// if a product category and on the shop page
if ( in_array( 'product_cat', $taxonomies ) && !is_admin() && is_shop() ) {
foreach ( $terms as $key => $term ) {
if ( ! in_array( $term->term_id, $hide_category ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
Related
For example, there are 2 different catalogs - men and women (clothes).
There is a widget in sidebar.
Is it possible to hide 'men' category with its child subcategories in all 'women' category pages and subcategory pages, and the same in 'men' catalog in all parent categories and child subcategories hide all from 'women'? From product cat widget.
I tried conditions like
if( has_term(267, 'product_cat' ) ) {
add_filter( 'woocommerce_product_categories_widget_args', 'organicweb_exclude_widget_category' );
function organicweb_exclude_widget_category( $args ) {
// Enter the id of the category you want to exclude in place of '30'
$args['exclude'] = array('262' );
return $args;
}
}
if( is_product_category( array( '267',) ) ) {
add_filter( 'woocommerce_product_categories_widget_args', 'organicweb_exclude_widget_category' );
function organicweb_exclude_widget_category( $args ) {
// Enter the id of the category you want to exclude in place of '30'
$args['exclude'] = array('262' );
return $args;
}
}
The filter works without 'if///{}', hides excluded category from widget at all, but not with if.
I start to think that the simplest way is to hide them using css(body class+parent li id), but maybe it is a correct way?
You can solve it like this way:
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
'product_cat' => 'your-cat-name'
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<br />' . woocommerce_get_product_thumbnail().' '.get_the_title().'';
endwhile;
wp_reset_query();
Also this article will help you https://www.codecheef.org/article/how-to-display-category-wise-product-in-woocommerce
Thank you
I'm currently using the porto theme on wordpress with woocommerce, and it doesn't have an option to show the product description in the mini cart or checkout page. I was able to find the following css code to add that worked, but I'm trying to limit this to display the product descriptions for most products while excluding only items from one specific category slug.
For example, we have cart items and would like the description to be hidden only for the pats in that one category 'carts'. Here's the code I found that blanket worked for every product.
add_filter( 'woocommerce_get_item_data', 'customizing_cart_item_data', 10, 2 );
function customizing_cart_item_data( $cart_data, $cart_item ) {
$description = $cart_item['data']->get_description(); // Get the product description
// For product variations when description is empty
if( $cart_item['variation_id'] > 0 && empty( $description ) ){
// Get the parent variable product object
$parent_product = wc_get_product( $cart_item['product_id'] );
// Get the variable product description
$description = $parent_product->get_description();
}
// If product or variation description exists we display it
if( ! empty( $description ) ){
$cart_data[] = array(
'key' => __( 'Description', 'woocommerce' ),
'value' => $description,
'display' => $description,
);
}
return $cart_data;
}
Does anyone have a recommendation? Thanks in advance I really appreciate it!
Possibly just insert the following in the function before processing anything else:
if ( has_term( 'your-slug', 'product_cat', $cart_item ) ) {
return $cart_data ;
}
See https://developer.wordpress.org/reference/functions/has_term/
I am trying to find a way to hide a product from the Woocommerce shop page. If the logged in user has already purchased said product.
I have already been able to block the user from purchasing again using woocommerce_is_purchasable, and woocommerce_variation_is_purchasable. But I would like to hide it all together not even shown to them in the shop page. I have been coming up empty on this one. So any help would be appreciated.
You can change the product query using the pre_get_posts action hook and then you can get current user products that they already purchased. pass all products id to post__not_in. check the below code. code will go active theme function.php file.
add_action( 'pre_get_posts', 'hide_product_from_shop_page_if_user_already_purchased', 20 );
function hide_product_from_shop_page_if_user_already_purchased( $query ) {
if ( ! $query->is_main_query() ) return;
if ( ! is_admin() && is_shop() ) {
$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) return;
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'post_type' => 'shop_order',
'post_status' => array( 'wc-processing', 'wc-completed' ),
) );
if ( ! $customer_orders ) return;
$product_ids = array();
foreach ( $customer_orders as $customer_order ) {
$order = wc_get_order( $customer_order->ID );
if( $order ){
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$product_ids[] = $product_id;
}
}
}
$product_ids = array_unique( $product_ids );
$query->set( 'post__not_in', $product_ids );
}
}
Bhautik's answer is technically correct based on the question asked. Hide product if user bought before.
However as mentioned in my question I'm already disabling purchase of said products using woocommerce_is_purchasable .
Meaning the logic of what should be hidden is already in the software. Using his idea as a template I have made the answer more generic to operate off of woocommerce_is_purchasable . Meaning I only have to implement any conditional logic in that function and the shop will reflect by hiding said products (that are not purchasable).
I am posting this as a second answer in case it helps others searching this problem. But will keep his as the selected answer to the question.
add_action( 'woocommerce_product_query', 'hide_product_from_shop_page_if_user_already_purchased', 20 );
function hide_product_from_shop_page_if_user_already_purchased( $query ) {
//Get all the products in the store.
$products = wc_get_products(['limit' => -1]);
//Blank exclusion array.
$product_ids = array();
//Check each product to see if it is purchasable or not.
foreach($products as $product){
if(!$product->is_purchasable()){
//If product is not purchasable then add to exclusion array.
$product_ids[] = $product->get_id();
}
}
//Use array of id's to exclude products in the shop page.
$query->set( 'post__not_in', $product_ids );
}
I am using the following code:
/* Woocommerce - Add Product Count View in Each Category */
add_action( 'woocommerce_before_shop_loop', 'add_product_count_view', 20);
function add_product_count_view() {
$terms = get_the_terms( $post->ID, 'product_cat');
foreach( $terms as $term ) {
if(is_tax('product_cat', $term->name)) {
echo '<span class="count-view">'.$term->count
.__( ' items')
.'</span>';
}
}
}
This code shows the total items in the store of the categories.
If a category has 20 items, 15 active and 5 inactive, it shows that there are 20 items in that category.
What I need is that it only shows the number of active articles in that category.
How can I fix it?
Easy solution is wc_get_loop_prop( 'total' ), which is returns total products of any WooCommerce archive pages.
You can get the count of products published on the product category page visited via the WC_Product_Query class (using the wc_get_products function):
// shows the number of products published on the product category page
add_action( 'woocommerce_before_shop_loop', 'add_product_count_view', 20);
function add_product_count_view() {
// only on the product category page
if ( ! is_product_category() ) {
return;
}
// gets the slug of the current product category
$category_slug = get_queried_object()->slug;
// gets the number of products published in the current category
$args = array(
'status' => 'publish',
'category' => array( $category_slug ),
'return' => 'ids',
'limit' => -1,
);
$products = wc_get_products( $args );
echo '<span class="count-view">' . count($products) . __( ' items', 'woocommerce' ) . '</span>';
}
The code has been tested and works. Add it to your active theme's functions.php.
Looking for a plugin that helps me to restrict woocommerce products or product categories based on role.
Let's say that I only want to sell bulk products to whole sale buyers.
Any help is awesome, thanks!
Here is how I managed to hide products based on role:
First, I have added a checkbox in the product options inventory section to enable admins to hide the products based on their selection:
add_action( 'woocommerce_product_options_stock_status', 'hide_if_available_to_user_role' );
function hide_if_available_to_user_role(){
woocommerce_wp_checkbox( array( 'id' => '_hide_from_users', 'wrapper_class' => 'show_if_simple show_if_variable', 'label' => __( 'Hide this product from specific roles?', 'customhideplugin' ) ) );
}
I then saved this selection in the actual post when a post is updated.
add_action( 'woocommerce_process_product_meta', 'hide_save_product_meta' );
function hide_save_product_meta( $post_id ){
if( isset( $_POST['_hide_from_users'] ) ) {
update_post_meta( $post_id, '_hide_from_users', 'yes' );
} else {
delete_post_meta( $post_id, '_hide_from_users' );
}
}
This is how I got current user's role.
function getCurrentUserRole( $user = null ) {
$user = $user ? new WP_User( $user ) : wp_get_current_user();
return $user->roles ? $user->roles[0] : false;
}
Now query products. If the current user role matches the roles below, show the products as usual.
Otherwise, set the query based on the code above...
add_action( 'woocommerce_product_query', 'hide_product_query' );
function hide_product_query( $q ){
if((getCurrentUserRole() == 'editor' ) || (getCurrentUserRole() == 'administrator' )){
return false;
} else {
$meta_query = $q->get( 'meta_query' );
if ( get_option( 'woocommerce_hide_out_of_stock_items' ) == 'no' ) {
$meta_query[] = array(
'key' => '_hide_from_users',
'compare' => 'NOT EXISTS'
);
}
$q->set( 'meta_query', $meta_query );
}
}
To achieve this you can use the Free Groups plugin. But for that you must add all the wholesalers to one group say wholesale group 1. Then while editing any product you get an option to access to, add the wholesaler group 1 there. The product will now be only seen by the user who is in wholesalers group 1.
I tried a few different plugins to try to achieve that. I finally chose this one because it's easy to understand and can show/hide depending on procucts, tags, categories and custom taxonomies. WooCommerce Products Visibility