I would like that anybody who visits my Woocommerce shop finds a free product in his cart. I found this code and it works but it shows many php errors in logs.
Do you have an idea why is not "clean"?
Any help on this please.
/*
* AUTOMATICALLY ADD A PRODUCT TO CART ON VISIT
*/
function aaptc_add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 99999; // Product Id of the free product which will get added to cart
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
add_action( 'init', 'aaptc_add_product_to_cart' );
Try instead this revisited similar code using template_redirect action hook:
add_action( 'template_redirect', 'auto_add_product_to_cart' );
function auto_add_product_to_cart() {
if ( is_admin() ) return;
// Product Id of the free product which will get added to cart;
$product_id = 99999;
if ( WC()->cart->is_empty() )
{
// No products in cart, we add it
WC()->cart->add_to_cart( $product_id );
}
else
{
$found = false;
//check if product already in cart
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->get_id() == $product_id )
$found = true;
}
// if the product is not in cart, we add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: The init hook is not correct here and not to be used for this…
Related
I would like that anybody who visits my Woocommerce shop finds a free product in his cart. I found this code and it works but it shows many php errors in logs.
Do you have an idea why is not "clean"?
Any help on this please.
/*
* AUTOMATICALLY ADD A PRODUCT TO CART ON VISIT
*/
function aaptc_add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 99999; // Product Id of the free product which will get added to cart
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
add_action( 'init', 'aaptc_add_product_to_cart' );
Try instead this revisited similar code using template_redirect action hook:
add_action( 'template_redirect', 'auto_add_product_to_cart' );
function auto_add_product_to_cart() {
if ( is_admin() ) return;
// Product Id of the free product which will get added to cart;
$product_id = 99999;
if ( WC()->cart->is_empty() )
{
// No products in cart, we add it
WC()->cart->add_to_cart( $product_id );
}
else
{
$found = false;
//check if product already in cart
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->get_id() == $product_id )
$found = true;
}
// if the product is not in cart, we add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: The init hook is not correct here and not to be used for this…
So I can use this snippet from the woocommerce docs and it works to add a free product when a cart total is reached. However, our customers need to be able to remove the product from the cart if they don't want it (repeat customers that don't want the same gift every time). With this snippet, the remove from cart button doesn't work for the free product.
/**
* Add another product depending on the cart total
*/
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
global $woocommerce;
$product_id = 2831; //replace with your product id
$found = false;
$cart_total = 30; //replace with your cart total needed to add above item
if( $woocommerce->cart->total >= $cart_total ) {
//check if product already in cart
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
$woocommerce->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
$woocommerce->cart->add_to_cart( $product_id );
}
}
}
}
``
code above is from here: https://docs.woocommerce.com/document/automatically-add-product-to-cart-on-visit/
Removing the product from the cart will actually work, but the problem is that the code will also automatically re-add the product again.
One way to solve this would be to remember that the product has already been added once, and to not re-add the product if the product would be added another time (after it has been removed from the cart for example).
A simple way to do that would be to save that data inside of the WooCommerce session, using WC()->session. Modified code below:
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
global $woocommerce;
$product_id = 2831; //replace with your product id
$found = false;
$cart_total = 10; //replace with your cart total needed to add above item
if( $woocommerce->cart->total >= $cart_total && ! WC()->session->get( 'free_item_given', false ) ) { // <--- ADDED CHECK FOR free_item_given HERE
//check if product already in cart
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->get_id() == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found ) {
$woocommerce->cart->add_to_cart( $product_id );
WC()->session->set( 'free_item_given', true ); // <--- REMEMBER free_item_given HERE
}
} else {
// if no products in cart, add it
$woocommerce->cart->add_to_cart( $product_id );
WC()->session->set( 'free_item_given', true ); // <--- REMEMBER free_item_given HERE
}
}
}
}
I hope that it solves your problem!
In WooCommerce, I am currently using a function that auto add to cart a specific product (here product ID 87) on page visit, using this code snippet:
// add item to cart on visit
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 87;
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
How could I get dynamically the latest product id from woocommerce, in this function, instead of a specific product ID?
Any help or advice will be appreciated.
This is possible easily including a simple very light SQL query in your code snippet that will get the last published product ID.
WC official code snippet is outdated as $product->id has been replaced by $product->get_id().
The completed revisited code:
add_action( 'template_redirect', 'auto_add_to_cart_last_product' );
function auto_add_to_cart_last_product() {
if ( is_admin() ) return; // Not for admin area
$cart = WC()->cart;
global $wpdb;
$found = false;
// SQL Query: Get last published product ID
$result = $wpdb->get_col(" SELECT ID FROM {$wpdb->prefix}posts
WHERE post_type LIKE 'product' AND post_status LIKE 'publish' ORDER BY ID DESC LIMIT 1");
$newest_product_id = reset($result);
// Check if product already in cart
if ( ! $cart->is_empty() )
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Added Woocommerce 3+ compatibility (as $product->id si outdated)
$product_id = method_exists( $cart_item['data'], 'get_id' ) ? $cart_item['data']->get_id() : $cart_item['data']->id;
if ( $product_id == $newest_product_id ){
$found = true; // Found!
break; // We exit from the loop
}
}
// If product not found or if there is no product in cart, we add it.
if ( ! $found || $cart->is_empty() )
$cart->add_to_cart( $product_id );
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works from woocommerce version 2.4 to lastest.
I am aware that there's already an existing function where you can add a certain product on cart upon visiting the website. The problem is you can only do it with 1 product and I want it variable depending on the page you are visiting.
here's the existing code (added on functions.php file)
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 275;
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
Inside my landing page called page-template.php, there's a custom field that echos the ID of a certain product selected. So when my user visits this page, I want this ID to replace the $product_id on the functions.php file. How do I achieve this?
Many thanks in advance for the help.
maybe the global variable is loaded after the function. instead of just setting the variable initiate the function passing the variable and avoid the hook:
in functions.php:
function add_product_to_cart($product_id) {
if ( ! is_admin() ) {
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
in page-template.php:
add_product_to_cart(275);
I'm trying to implement the following solution:
/*
* goes in theme functions.php or a custom plugin
**/
// add item to cart on visit
add_action( 'init', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
global $woocommerce;
$product_id = 64;
$found = false;
//check if product already in cart
if ( sizeof( $woocommerce->cart->get_cart() ) > 0 ) {
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
$woocommerce->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
$woocommerce->cart->add_to_cart( $product_id );
}
}
}
from here:
http://docs.woothemes.com/document/automatically-add-product-to-cart-on-visit/
but it throws an error:
Sorry, this product cannot be purchased.
Anyone knows what am I doing wrong?
maybe your product stock quantity is zero or product is not there. Please check that.