Woocommerce URL to hide out of stock product - wordpress

I create a catalog website using Woocommerce to display all the product. When the product is sell, i dont remove it from the website (because we dont have a lot of product and we want to show to the customer what we sell before).
So, when you go on "All the products" you see the Sell products and the products available. I want, on the sidebar create a button "Show only available product". I dont find a plugin who can do this..
Whis woocommerce, can i create a URL like "mywebsite.com/products&instock=true" for example or something like this ? or if you know another solution. Thanks

You can use pre_get_posts to achieve it. Set the tax_query to not get the term outofstock of the product_visibility taxonomy.
In addition to my code, you will of course need to create a link with the prefix_instock=true parameter. You also can store it in a cookie, so it will be easily persistent.
add_action( 'pre_get_posts', 'prefix_hide_out_of_stock_products' );
function prefix_hide_out_of_stock_products( $q ) {
if ( ! $q->is_main_query() || is_admin() || empty($_GET['prefix_instock'])) {
return;
}
if ( $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' ) && $_GET['prefix_instock'] == 'true') {
$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 );
}
remove_action( 'pre_get_posts', 'prefix_hide_out_of_stock_products' );
}

Related

woocommerce_product_query dont work on pages with shop (dont show specific product)

i have some categories, product can be in some of them but when its in cat with ID 46 its should not list anymore in the product list.
The following code work in the shop sites but not when i add the shop over the bb/shortshort , thanks
<!-- wp:woocommerce/product-category {"columns":4,"rows":6,"categories":[31]} /-->
add_action( 'woocommerce_product_query','custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => [46],
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
edit:
after some research i found a way, not the best but solved the problem.
Its seems like the data used for these pages are written in the options, so maybe here is a way to block adding the id of the unwanted
The working code is following and on this way it would be maybe a good hook for use same html/functions like used in the shop pages because all the product hooks of wc don't work usually on none shop pages.
Maybe WC adds someday direct a ignore product cats in the code, im sure im not the only one who need it
function my_product_block( $html, $data, $product ) {
if(in_array(46, $product->category_ids) || $product->stock_status === "outofstock"){
return "";
}
return $html;
}
add_filter( 'woocommerce_blocks_product_grid_item_html','my_product_block', 10,3)

WooCommerce product filter for an attribute in the backend

I want to have a filter for an attribute "brand" in the WooCommerce products section in the backend.
I am using the following code:
function custom_woocommerce_product_filters( $output ) {
global $wp_query;
$output .= wc_product_dropdown_categories(
array(
'show_option_none' => 'Filter by brand',
'taxonomy' => 'pa_brand',
'name' => 'pa_brand',
'selected' => isset( $wp_query->query_vars['pa_brand'] ) ? $wp_query->query_vars['pa_brand'] : ''
)
);
return $output;
}
add_filter( 'woocommerce_product_filters', 'custom_woocommerce_product_filters' );
This code displays the dropdown list for the filter with all brands inside it, but clicking on "Filter" does not return the filtered products. It simply shows all the products.
Can someone help please?
Thanks
I recently discovered that you have to actually filter the results using the pre_get_posts() filter, having the dropdown alone is not enough. What I was able to come up with after searching similar questions on stackoverflow:
// Filter woocommerce admin products by artist
function apply_artist_custom_product_filters( $query ) {
global $pagenow;
// Ensure it is an edit.php admin page, the filter exists and has a value, and that it's the products page
if ( $query->is_admin && $pagenow == 'edit.php' && isset( $_GET['pa_artist'] ) && $_GET['pa_artist'] != '' && $_GET['post_type'] == 'product' ) {
// Create meta query array and add to WP_Query
$meta_key_query = array(
array(
'taxonomy' => 'pa_artist',
'field' => 'slug',
'terms' => esc_attr( $_GET['pa_artist'] ),
'operator' => 'IN',
)
);
$query->set( 'tax_query', $meta_key_query );
}
}
add_action( 'pre_get_posts', 'apply_artist_custom_product_filters' );
The snippet that did most of the work is found here:WooCommerce: Adding a custom filter to the Product Admin area. I only changed the meta query to be a tax query. Not sure if it's the best way to do it, but it works for me. What I can't figure out is the "selected" part of the wc_product_dropdown_categories, for me when I select an artist and hit filter, the filter works but it doesn't save the selection.

WooCommerce: Display on-sale products in shop

There are plenty of questions and answers regarding making only on-sale products display, but no matter what one I try, it doesn't work.
I have the following query
function my_modify_main_query($query) {
if ($query -> query['post_type'] == 'product' && $query -> is_main_query() && is_shop()) {// Run only on the shop
if (isset($_GET['sale'])):
$query -> set('meta_query',
array(
'relation' => 'OR',
array(// Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
),
array(// Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
endif;
}
}
// Hook my above function to the pre_get_posts action
add_action( 'pre_get_posts', 'my_modify_main_query' );
The query itself is being applied, BUT the problem is.
If the Product has been a variable with a sale price, the Product is then changed to a Simple Product, the "_min_variation_sale_price" meta value is still in the database.
Does anybody know of a workaround for this? I believe it to be a bug, but their support is closed currently.
Thanks.
EDIT
What I think I need is a way to only check _sale_price if the product is in the "simple" or "external" terms, then do similar for _min_variation_sale_price.
I have created an issue on their github.
https://github.com/woothemes/woocommerce/issues/10096
EDIT
Issue is fixed using #helgatheviking answer.
Although, take note that to resolve the issue completely, you must delete the variations, save, change the type, save, run delete_transient( 'wc_products_onsale' );
Only then did it work for me.
From my tutorial on modifying the product query
I believe this should modify the loop to only show the on-sale products:
add_action( 'woocommerce_product_query', 'so_20990199_product_query' );
function so_20990199_product_query( $q ){
$product_ids_on_sale = wc_get_product_ids_on_sale();
$q->set( 'post__in', (array) $product_ids_on_sale );
}

Woocommerce filter products by custom taxonomy

I am new to wordpress and woocommerce. I have created custom taxonomy 'city' for product.
Now on my website I want to filter the products by this custom taxonomy.
Please help me.
This plugin might help. I haven't tested it but in the video it looks like it can filter by multiple taxonomies.
https://wordpress.org/plugins/wp-meta-data-filter-and-taxonomy-filter/
Maybe this will help someone, I did something similar by adding action to woocommerce_product_query, of course you probably want to use $_GET variables for taxonomy and terms:
function my_pre_get_posts( $query ) {
if ( is_admin() ) {
return $query;
}
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'product') {
$tax_query = array(
array(
'taxonomy' => 'producer',
'field' => 'slug',
'terms' => array('company1, company2'),
'operator'=> 'IN',
'include_children'=> true,
)
);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'][] = $tax_query;
}
return $query;
}
add_action('woocommerce_product_query', 'my_pre_get_posts');

Hide 'out of stock' products in Woocommerce

Under "Products" and "Inventory" I have checked the following setting:
"Hide out of stock items from the catalog"
Now all sold out products are hidden in the archive/category view. So far so good.
The problem is that the hidden (out of stock) products are counted per page. So if there are 3 products that are sold out on the first page, only the ones in stock are showing (6).
It also seems that these "hidden" products still are searchable as well, and visible through the different widgets.
Any ideas how to fix this? I mean to REALLY hide products that are out of stock. Or do I need to manuallly remove them?
You can try adding this to your theme's functions.php file:
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 modified the code from this URL: http://www.wptaskforce.com/how-to-exclude-one-or-more-category-in-woocommerce-shop-page/
Saved here again just in case that site goes offline: (this code excludes certain product categories)
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( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'PUT YOUR CATEGORY HERE' ), // Don't display products in the membership category on the shop page . For multiple category , separate it with comma.
'operator' => 'NOT IN'
)));
}
remove_action( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
Note to self: Always read the changelog from developer.
Found the answer here: http://develop.woothemes.com/woocommerce/2014/02/solving-common-issues-after-updating-to-woocommerce-2-1/#category-counts-incorrect
In case the product counts for categories are showing a too high or
too low number, after updating to WooCommerce 2.1 there is an easy
workaround.
Go to the ‘Tools’ tab inside the WooCommerce > System Status of your
WordPress administration panel. Here you first use the ‘Recount terms’
button and after that use the ‘Clear transients’ button. This will
force the system to recount all the products the next time a category
is loaded.
Update: Also remember that it is not enough to change stock quantity to 0. You must also set "Stock status" to "Out of stock". If not the product will be counted in the shop, even if there are no products in stock.
I found easier way, if anybody is still looking for hiding out of stock products in woocommerce, follow these easy steps without editing html !
Go to WooCommerce -> Settings
Go to Inventory
There's a checkbox that says something about our problem, however it goes in english :-) you'll find what you need
Save
that will only work if you are using the official woocommerce shortcodes , but if you creating a page with visual composer and using customized plugins or 3rd party plugins or shortcodes , the first step is to for the query that run from the loop then you modify it to something like this
$params = array(
'posts_per_page' => 5,
'post_type' => array('product', 'product_variation'),
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock'
)
)
);
the most important part that you have to be sure of is
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock'
)
)
Steps to Hide Out of Stock Products
Go to WooCommerce -> Settings submenu in the WordPress dashboard
Click on the Products Tab > Inventory sub-tab
Check the option Out Of Stock Visibility that hides the out of stock products
I know that this question was asked long time ago but the solution of the problem is now different, so I post this for people who had the same problem as I did. Tested on WooCommerce 5.3.0
SOLUTION:
First of all make sure that checkbox "Hide products that are out of stock" in Woocomerce > Settings is unchecked than add this PHP code to your child-theme functions.php file:
add_action('woocommerce_product_query', 'show_only_instock_products');
function show_only_instock_products($query) {
$meta_query = $query->get( 'meta_query' );
$meta_query[] = array(
'key' => '_stock_status',
'compare' => '=',
'value' => 'instock'
);
$query->set( 'meta_query', $meta_query );
}
It works well in my store, which is integrated with a wholesaler, where inventory levels are updated every hour and there are thousands of products.
You can place PHP snippet at the bottom of your child theme functions.php file.
add_action('woocommerce_product_query', 'custom_woocommerce_product_query');
function custom_woocommerce_product_query($q)
{
if (!is_admin())
{
$oos_query = new WP_Query(['meta_query' => [['key' => '_stock_status', 'value' => 'outofstock', 'compare' => '=', ], ], 'post_type' => 'product', 'posts_per_page' => - 1, 'fields' => 'ids', ]);
$exclude_ids = $oos_query->posts;
$q->set('post__not_in', $exclude_ids);
}
}

Resources