Hooks around add to cart for Woocommerce
Here below are the hooks involved in
WC_Cart
add_to_cart()
method:A) Before an item is added to cart:
- Validation filter hook
woocommerce_add_to_cart_validation
- Item Quantity change filter hook
woocommerce_add_to_cart_quantity
(not with ajax)- Item Data change filter hook
woocommerce_add_cart_item_data
(not with ajax)- and some others related to "sold individually" products (see here)
A) After an item is added to cart:
- Change cart Item filter hook
woocommerce_add_cart_item
- Add an event, action hook
woocommerce_add_to_cart
To be clear in your case:
- As you can see now
woocommerce_add_to_cart
is not a function but only an action hook. - Hook location: It's located inside
WC_Cart
add_to_cart()
method (at the end of the source code). - When the hook is fired: It's fired once the
WC_Cart
add_to_cart()
method is executed. - What is the purpose: To execute some custom code when this method is executed (event).
Regarding your code:
It should be better to use the dedicated filter hook
woocommerce_add_to_cart_validation
that will stop customer that want to add a new item to the cart if there is already a product in cart from a different vendor, displaying optionally a custom message:add_filter( 'woocommerce_add_to_cart_validation', 'filter_add_to_cart_validation', 10, 3 );
function filter_add_to_cart_validation( $passed, $product_id, $quantity ) {
if ( WC()->cart->is_empty() ) return $passed;
// Get the VendorId of the product being added to the cart.
$current_vendor = get_wcmp_product_vendors($product_id);
foreach( WC()->cart->get_cart() as $cart_item ) {
// Get the vendor Id of the item
$cart_vendor = get_wcmp_product_vendors($cart_item['product_id']);
// If two products do not have the same Vendor
if( $current_vendor->id != $cart_vendor->id ) {
// We set 'passed' argument to false
$passed = false ;
// Displaying a custom message
$message = __( "This is your custom message", "woocommerce" );
wc_add_notice( $message, 'error' );
// We stop the loop
break;
}
}
return $passed;
}
Code goes in function.php file of your active child theme (or active theme) or in any plugin file.Tested and works.
WooCommerce Add to cart, add second product from a custom select field
The problem was that I used global variable $product
in foreach loop. So it was breaking loop logics and using global $product
instead of desired array value. So all it takes to make the code work is changing foreach loop code to something like:
foreach ($products as $single_product) {
$product_id = $single_product->get_id();
$options[$product_id] = $single_product->get_name();
Otherwise the code is working fine, although I have to make a few remarks:- the code will only work if inserted via hooks which are called inside
<form> ... </form>
submitted by pressing add to cart button, i.e.woocommerce_before_add_to_cart_button
,woocommerce_before_add_to_cart_quantity
andwoocommerce_after_add_to_cart_quantity
(you can check it yourself in the template - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/simple.php) for simple product and also a few hooks called inside variation loop vor variable product which can be found here - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/variable.php - when inserted via
woocommerce_before_add_to_cart_button
input field is placed inbetween product stock text and add to cart button which is not the best place and it looks like you either have to edit template files or use JS to achieve better placement with current WC (4.1) hooks. wc_get_products ()
function is rather slow. In my test it was 10 times slower than similar query made through$wpdb->get_results
- it is better to insert
product_option_add_to_cart()
custom function code intoif (isset($_POST['chain_type'])) { ... }
to prevent PHP notices in case there's no $_POST value for some reason
- it is better to insert
Woocommerce 3 Filter Single Variation Add to cart button html
Please try the following code. I haven't tested it but it supposed to work. Please try this on your dev environment first.
add_action( 'woocommerce_before_template_part', function( $template_name ) {
if ( 'single-product/add-to-cart/variation-add-to-cart-button.php' === $template_name ) {
ob_start();
}
} );
add_action( 'woocommerce_after_template_part', function( $template_name ) {
if ( 'single-product/add-to-cart/variation-add-to-cart-button.php' === $template_name ) {
$content = ob_get_clean();
$content = str_replace( '<div class="woocommerce-variation-add-to-cart variations_button">', '', $content );
$content = str_replace( '</div>', '', $content );
echo $content;
}
} );
Adding content after add to cart button on woocommerce single page
Here, you need to echo content as it is add_action hook.
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart_button_func' );
/*
* Content below "Add to cart" Button.
*/
function add_content_after_addtocart_button_func() {
// Echo content.
echo '<div class="second_content">Other content here!</div>';
}
Woocommerce added to cart hook (after the product was successfully added to cart)
Answering this old question for Google Searchers:
The action woocommerce_add_to_cart
is fired after an item is added to the cart.
and can be used like:
add_action( 'woocommerce_add_to_cart', function ()
{
// your code here
});
related action woocommerce_cart_item_removed
fires after an item is removed Execute a piece of code before woocommerce_add_to_cart
Is not possible to make a redirection before add to cart in a simple way, but you can use woocommerce_add_to_cart_validation
hook to avoid add to cart and display a custom notice with a linked button to your specific verification page.
The code:Check that the correct
meta_key
for your verified status in the code is'woo_VerifyStatus'
add_action( 'woocommerce_add_to_cart_validation', 'custome_add_to_cart_validation', 10, 1 );
function custome_add_to_cart_validation( $passed ){
// When user is logged in in we get his verified status
if( is_user_logged_in() )
// Get user 'woo_VerifyStatus' postmeta value
$verified_user = get_user_meta( get_current_user_id(), 'woo_VerifyStatus', true );
// When user is not logged in we avoid add to cart and display a custom message
if( ! is_user_logged_in() ){
$message = __( "Please, you need to be registered and a verified user.", "woocommerce" );
$button_text = __("Login or register", "woocommerce");
$url = home_url('/gld/my-account');
$message .= ' <a href="'.$url.'" class="login-register button" style="float:right;">'.$button_text.'</a>';
$passed = false; // Set to false
$message .= ' <a href="#" class="login-register button" style="float:right;">'.$button_text.'</a>';
}
// When is not a verified user we avoid add to cart and display a custom message
elseif( $verified_user != 1 ) {
$message = __( "Please, you need to be a verified user.", "woocommerce" );
$button_text = __("proceed", "woocommerce");
$url = home_url('/gld/my-account');
$message .= ' <a href="'.$url.'" class="login-register button" style="float:right;">'.$button_text.'</a>';
$passed = false; // Set to false
}
if( ! $passed )
wc_add_notice( $message, 'error' );
return $passed;
}
Code goes in function.php file of your active child theme (or active theme).It should work.
Related Topics
The Behaviour of the or Operator in PHP
PHP - Swiftmailer Using Starttls and Self Signed Certificates
(When) Should I Use Type Hinting in PHP
Laravel Catch Eloquent "Unique" Field Error
Converting Nsarray -> JSON -> Nsdata -> PHP Server ->JSON Representation
PHP MySQL Group by to Get Latest Record, Not First Record
How to Avoid Request Entity Too Large 413 Error
Php: How to Set Current Working Directory to Be Same as Directory Executing the Script
Why a Full Stop, "." and Not a Plus Symbol, "+", for String Concatenation in PHP
PHP to Easyphp MySQL Server 1 Second Connection Delay
What Is the Js Equivalent to the PHP Function Number_Format
How to Get the Root Url of the Site
Calling a PHP Function from an HTML Form in the Same File
Apache Virtual Host Not Parsing PHP
How to Display HTML to the Browser Incrementally Over a Long Period of Time
Find Windows 32 or 64 Bit Using PHP