I need to add an event to the quantity selector on the cross-sells on my cart since there bizarrely seems to be no onchange event there.
Normally this would be easy but with WP and WC it's all shortcodes etc so impossible to find the actual place where I can a) correct this and b) not have it overwritten every update, especially since every qty selector should change the data-quantity by default.
cross-sells.php just gives me wc_get_template_part( 'content', 'product' ) which just leads me on to content-product.php which just gives me a load of do_actions.
Specifically, I'd like to correct an error where my content-product.php doesn't seem to have quantity event triggers (ie it doesn't change the data-quantity), but ideally, I'd like to know how I edit any section I want, even if only to improve the awful layout of WC.
Thanks.
You may be looking for some hook like this if am not wrong.
add_action( 'woocommerce_after_cart_item_quantity_update', 'limit_cart_item_quantity', 20, 4 );
function limit_cart_item_quantity( $cart_item_key, $quantity, $old_quantity, $cart ){
if( ! is_cart() ) return; // At Cart page
// Limit quantity
$limit = 5;
if( $quantity > $limit ){
$cart->cart_contents[ $cart_item_key ]['quantity'] = $limit;
wc_add_notice( __('Quantity limit reached for this item'), 'notice' );
}
}
Related
I'm trying to fire a function when the quantity of a product is changed in cart.
More specifically I want to run this function when a customer modify the amount in a cart.
I'm looking to find the amount left in a cart then to intercept the update cart event
Currently I'm using:
add_action( 'woocommerce_remove_cart_item', 'my function');
When I press "update_cart", it doesn't seem to work.
Any advice?
Thank you!
You should use woocommerce_after_cart_item_quantity_update action hook that has 4 arguments. But when quantity is changed to zero, woocommerce_before_cart_item_quantity_zero action hook need to be used instead (and has 2 arguments).
Below is a working example that will limit the updated quantity to a certain amount and will display a custom notice:
add_action( 'woocommerce_after_cart_item_quantity_update', 'limit_cart_item_quantity', 20, 4 );
function limit_cart_item_quantity( $cart_item_key, $quantity, $old_quantity, $cart ){
if( ! is_cart() ) return; // Only on cart page
// Here the quantity limit
$limit = 5;
if( $quantity > $limit ){
// Change the quantity to the limit allowed
$cart->cart_contents[ $cart_item_key ]['quantity'] = $limit;
// Add a custom notice
wc_add_notice( __('Quantity limit reached for this item'), 'notice' );
}
}
This code goes on function.php file of your active child theme (or theme). Tested and works.
As this hook is located in WC_Cart set_quantity() method, is not possible to use that method inside the hook, as it will throw an error.
To trigger some action when quantity is set to Zero use:
add_action( 'woocommerce_before_cart_item_quantity_zero', 'action_before_cart_item_quantity_zero', 20, 4 );
function action_before_cart_item_quantity_zero( $cart_item_key, $cart ){
// Your code goes here
}
Maybe this hook? do_action( 'woocommerce_after_cart_item_quantity_update', $cart_item_key, $quantity, $old_quantity );
http://hookr.io/actions/woocommerce_after_cart_item_quantity_update/
I have found similar solutions to this, for example: "How to limit orders to one category". I have tried to modify the code but it's not specific enough.
In my case, each Vendor is defined by a product attribute value, 8 Terms at all. If the cart contains products from more than 3 different Terms, I need to set up a message that says "Sorry, you may only order from 3 different Vendors at a time".
This is what I'm using as a starting point:
add_action( 'woocommerce_add_to_cart', 'three_vendors' );
function three_vendors() {
if ATTRIBUTE = SELECT A VENDOR; NUMBER OF TERMS > 3 {
echo "Sorry! You can only order from 3 Vendors at a time.”;
}
}
The middle line is me filling in the blanks using non-php language.
I am looking for a way to define the amount of variations in the cart. If this is not possible to do with Attributes, I am open to use Categories instead.
Does anyone know how to do this?
Update: Is not possible to manage variations with woocommerce_add_to_cart_valisation hook
Instead we can use a custom function hooked in woocommerce_add_to_cart filter hook, removing the last added cart item when more than 3 vendors (items) are in cart:
// Remove the cart item and display a notice when more than 3 values for "pa_vendor" attibute.
add_action( 'woocommerce_add_to_cart', 'no_more_than_three_vendors', 10, 6 );
function no_more_than_three_vendors( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
// Check only when there is more than 3 cart items
if ( WC()->cart->get_cart_contents_count() < 4 ) return;
// SET BELOW your attribute slug… always begins by "pa_"
$attribute_slug = 'pa_vendor'; // (like for "Color" attribute the slug is "pa_color")
// The current product object
$product = wc_get_product( $variation_id );
// the current attribute value of the product
$curr_attr_value = $product->get_attribute( $attribute_slug );
// We store that value in an indexed array (as key /value)
$attribute_values[ $curr_attr_value ] = $curr_attr_value;
//Iterating through each cart item
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// The attribute value for the current cart item
$attr_value = $cart_item[ 'data' ]->get_attribute( $attribute_slug );
// We store the values in an array: Each different value will be stored only one time
$attribute_values[ $attr_value ] = $attr_value;
}
// We count the "different" values stored
$count = count($attribute_values);
// if there is more than 3 different values
if( $count > 3 ){
// We remove last cart item
WC()->cart->remove_cart_item( $cart_item_key );
// We display an error message
wc_clear_notices();
wc_add_notice( __( "Sorry, you may only order from 3 different Vendors at a time. This item has been removed", "woocommerce" ), 'error' );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and should works for you. It will check for the attribute values regarding your specific attribute and will remove last added cart item for more than 3 attribute values.
The only annoying thing is that I can't remove the classic added to cart notice for the moment. I will try to find another way…
I have a custom field in my products, that needs to be updated through a function, whenever the stock in any of the variations change.
Are there hooks for this? If so, which ones and what is their output ($post_id for example)?
I think you are looking for woocommerce_reduce_order_stock action.
More info about this hook.
Here is a whole list of available hooks.
-- EDIT
Function should look like this:
function test( $order ) { // you get an object $order as an argument
$items = $order->get_items();
$items_ids = array();
foreach( $items as $item ) {
$items_ids[] = $item['product_id'];
}
die( print_r($items_ids) ); // it should break script while reduce stock
}
add_action( 'woocommerce_reduce_order_stock', 'test' );
I have achieved the same using woocommerce_product_set_stock and woocommerce_variation_set_stock hook.
These hooks run when the stock is changed (either increased, or decreased). Even after the stock is decreased after product purchase.
add_action( 'woocommerce_product_set_stock', 'stock_changed' );
add_action( 'woocommerce_variation_set_stock', 'stock_changed' );
function stock_changed( $product ) {
// Do something
}
Since WooCommerce 4.9+, woocommerce_product_before_set_stock and woocommerce_variation_before_set_stock are added to signal that the value of stock_quantity for a product/variation is about to change.
add_action( 'woocommerce_product_before_set_stock', 'stock_about_to_change' );
add_action( 'woocommerce_variation_before_set_stock', 'stock_about_to_change' );
function stock_about_to_change( $product ) {
// Do something
}
I'm building an e-commerce site. I'm having some trouble with WooCommerce Variable Product.
The "Add to Cart" button works fine with simple products, but does not work with variable products. It gives a "Please choose product options…" notice.
I looked everywhere and tried several suggestions online, none of them work. So I looked into WooCommerce source file: class-wc-form-handler.php.
In the function add_to_cart_handler_variable:
function add_to_cart_handler_variable( $product_id ) {
$adding_to_cart = wc_get_product( $product_id );
$variation_id = empty( $_REQUEST['variation_id'] ) ? '' : absint( $_REQUEST['variation_id'] );
$quantity = empty( $_REQUEST['quantity'] ) ? 1 : wc_stock_amount( $_REQUEST['quantity'] );
$missing_attributes = array();
$variations = array();
$attributes = $adding_to_cart->get_attributes();
$variation = wc_get_product( $variation_id );
...
if ( $missing_attributes ) {
wc_add_notice( sprintf( _n( '%s is a required field', '%s are required fields', sizeof( $missing_attributes ), 'woocommerce' ), wc_format_list_of_items( $missing_attributes ) ), 'error' );
} elseif ( empty( $variation_id ) ) {
wc_add_notice( __( 'Please choose product options…', 'woocommerce' ), 'error' );
} else {
// Add to cart validation
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) !== false ) {
wc_add_to_cart_message( $product_id );
return true;
}
}
return false;
}
The error is caught in the elseif clause.
So I tried to echo out $variation_id, $variations, and $variation. None of them has anything in it because when I echo $variation_id: it doesn't output anything.
How can the error be resolved?
On shop page you can't use add-to-cart button for variable products, because you need first to go on single product page to chose the options for this variable product before adding it to cart.
On variable product pages, normally you have some displayed options to chose for a variable product, before using "add to cart" button. If you don't do it, you get the error message… So at this point:
The options are not displayed in the product page (Bad settings in your backend product page, a bug with your theme or some additional plugin):
Check your product backend settings
Try to switch to default wordpress theme (to see if this issue is still there)
Try to disable most of all plugins.
the options are displayed: So chose your options first for this product, then add to cart
If this issue is related to your theme, contact the author of your theme and open a support thread or ticket…
OUPUTTING PRODUCT VARIATIONS FOR A PRODUCT ID:
To get product variations programmatically for a variable product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
echo var_dump($product_variations); // Displaying the array
Then to get the first variation ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$variation_product_id = $product_variations [0]['variation_id'];
echo $variation_product_id; // Displaying the variation ID
Or to get an array of all variations ID of this product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
array_push( $arr_variations_id, $product_variation_id );
}
echo var_dump($arr_variations_id); // Displaying the array of variations ID
A reference : Change "Add to Cart" button to "Go to Product" in the Shop Page
Just in case anyone else is building a custom theme and encounters this issue with variations not adding to the cart as expected - you may need to check your theme is loading the /woocommerce/assets/js/frontend/add-to-cart-variation.min.js script - add the following to wherever you enqueue your scripts to manually add it:
wp_enqueue_script('wc-add-to-cart-variation');
This solved the issue for me.
While we all have variation swatches in common the error (bizarre as this sounds) lays with the theme being incompatible. To test simply switch to 2020 theme and the ordering should work. I would recommend then making 2020 suite your needs and stop using the theme where the developers take days off when woocommerce updates are rolled out! Disabling the swatches wont help as the code is already there. Good luck.
I was facing the same issue.....delete your variation swatches plugin and the problem will be solved
Had the same issue....deactivated the autoptimize plugin and the problem was solved.
Also,to know which plugin to disable, you can simply load the page or the website, inspect element or developers mode, then check the console to see the source of the error which you can then relate to the relevant plugin and then disable from your wp dashboard.
I use wishlist plugin and when I tried to add variable product to cart I have got: 'The selected product isn't a variation of Product name, please choose product options by visiting Product name.'
The problem was that my product haven't default variation. So user added to wishlist product without selected variation. So when after user tries to add this product to cart error appears.
Here is FIX: just set default variation to all cariation products!
(Manually or via code). So user COULD NOT add product with EMPTY variation. Variation will be selected by default or user changes variation by himself.
So now in wishlist we have variation selected and all works as it should. It will work on all pages, archives, wishlists etc. Good luck! ;)
you’ll need to modify the functions.php file. Simply go to wp-content/yourtheme/functions.php on your child theme. Here, we’ll show you the full code and then we’ll explain its main parts. So the full PHP script to create WooCommerce default product attributes programmatically is the following:
add_action('woocommerce_before_single_product_summary', 'quadlayers_product_default_attributes');
function quadlayers_product_default_attributes() {
global $product;
if (!count($default_attributes = get_post_meta($product->get_id(), '_default_attributes'))) {
$new_defaults = array();
$product_attributes = $product->get_attributes();
if (count($product_attributes)) {
foreach ($product_attributes as $key => $attributes) {
$values = explode(',', $product->get_attribute($key));
if (isset($values[0]) && !isset($default_attributes[$key])) {
$new_defaults[$key] = sanitize_key($values[0]);
}
}
update_post_meta($product->get_id(), '_default_attributes', $new_defaults);
}
}
}
I am fairly new to WooCommerce so I dont know what could be of use to answer my question, this is why I have not added any codeblocks.
I would like to let customers only add one product to the cart and if they add another product the current product in cart is replaced by the last one.
Do I need to make changes in the code or is it possible with a plugin or WooCommerce setting?
I am looking forward to helpful replies.
Thanks
/**
* When an item is added to the cart, remove other products
*/
function custom_maybe_empty_cart( $valid, $product_id, $quantity ) {
if( ! empty ( WC()->cart->get_cart() ) && $valid ){
WC()->cart->empty_cart();
wc_add_notice( 'Only allowed 1 item in cart.', 'error' );
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'custom_maybe_empty_cart', 10, 3 );
Add this code your theme functions.php file.
Hope It's useful !! Enjoy