Cart total not updating with overridden cart prices - php

I have been overriding the price of products dynamically based on specific criteria, but the ajax and mini-cart doesn't seem to see the price change when the product is getting added in the cart. It shows the original price total. I can override the prices in the cart itself no problem, but you have to be on the cart or checkout page to see it. Not sure what approach to take. I felt as though I've tried everything.
Seems as though $woocommerce->cart->get_cart_total() is called to display current cart total, but it doesn't seem to run add_action( 'woocommerce_before_calculate_totals', 'woo_add_discount'); hook when called.
If you go to the actual cart page, it is the proper pricing.
This code added will display the right individual price but not the subtotal. You have to refresh the cart page by clicking on the Cart URL for it to update the $woocommerce->cart->get_cart_total() object.
I've also tried add_action( 'woocommerce_before_mini_cart', 'woo_add_discount'); which does the same thing.. you have to refresh the page after loading. I'm sure I'm not the only one who had overriden prices and can't get all the peices to fall into place.
I've tried this and see that the second comment down on the answer, someone is having the same issue but no answers.
WooCommerce: Add product to cart with price override?

Try to use apply_filters instead of add_action

I ended up fixing this myself. I tried Paul de Koning's answer. Changing to apply_filters caused the prices to go to $0. I think this is because the order they need to go in.
Here was my solution. The root cause was that I was using the change price_html function to provide the change prices for the cart. Inside that function there were add_action calls etc. Somehow, there must have been an ordering issue. This is a multi step process to ensure all areas are done correctly.
If you want to change woocommerce prices without using sessions to store the changed price for the cart while changing the display price and hiding prices, perform something like the following:
functions.php
add_action('woocommerce_get_price_html','special_price');
function special_price($price) {
//put any if statements for hiding the cart button and discounting pricing below and return true or false
$displayprice = true;
$alterprice = true;
if($displayprice === true) {
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10, 2);
add_action( 'init', 'woocommerce_add_to_cart_action', 10);
add_action( 'init', 'woocommerce_checkout_action', 10 );
} else {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10, 2);
remove_action( 'woocommerce_before_add_to_cart_form', 'woocommerce_template_single_product_add_to_cart', 10, 2); //
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
//return blank or something like 'Signup to view price'
return '';
}
//if you are displaying the price (altered)
if($displayprice === true && $alterprice === true){
$price = price_manipulator($theid);
return $price;
//display add to cart and price
}
//if you are displaying the price (unaltered)
return $price
}
function price_manipulator($theid = '') {
if(empty($theid)){
$theid = get_the_ID();
}
$product = wc_get_product($theid);
//30% off example
$newprice = floatval($product->price * (1-0.3));
return $newprice;
}
/*version of pricing if you are adding something to cart*/
function special_price_cart($theid){
$price = price_manipulator($theid);
return $price;
}
add_action( 'woocommerce_before_calculate_totals', 'woo_add_discount');
add_action( 'woocommerce_before_mini_cart', 'woo_add_discount'); //this is if you are using the mini-cart woocommerce widget
function woo_add_discount() {
global $woocommerce;
//create if statements same as if you were displaying the price
$displayprice = true;
if($displayprice === true){
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$price = special_price_cart($cart_item['data']->id);
$price = str_replace('$','',$price);
$price = str_replace(',','',$price);
if($price > 0){
$cart_item['data']->price = floatval($price);
}
}
}
}

Related

Woocommerce hide add to cart button EXCEPT for variable products

Im trying to hide the add to cart button in woocommerce for all products except a varibale product i have. I have tried the following which leaves the variable select options (which is what i want) but it hides the add to cart button (which i don't want).
add_filter( 'woocommerce_is_purchasable', '__return_false' );
add_action( 'woocommerce_single_product_summary', 'hide_add_to_cart_button_variable_product', 1, 0 );
function hide_add_to_cart_button_variable_product() {
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20);
}
Is there a way to do this?
All my products are simple products except for this single variable products, so maybe there is a function to hide the cart button for all simples except variables?
add_action('woocommerce_single_product_summary', 'wp66176371_remove_product_description_add_cart_button', 1 );
function wp66176371_remove_product_description_add_cart_button() {
global $product;
if ( !empty($product) && $product->is_type( 'simple' ) ) {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}
I think you can just edit the simple.php template file in the add-to-cart directory so it wouldn't show the button for simple products.

Which Hook to alter quantity update in WooCommerce cart page?

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/

woocommerce product addon - empty cart upon going to product page

Right now I am trying to get it so that whenever someone gets to my site's product page their cart is automatically emptied.
I am using a woocommerce product addon called "Product & Checkout Options for WooCommerce" that allows me to use radiobuttons/checkboxes for my products, I don't know if that will alter any of the code.
I've tried php code such as this but it hasn't worked:
add_filter( 'woocommerce_add_to_cart_validation', 'only_one_in_cart' , 10, 1);
function only_one_in_cart( $cart_item_data ) {
global $woocommerce;
$woocommerce->cart->empty_cart();
unset($cart_item_data['product_meta']);
return true;
}
It's better to add the hook on your single product page, do it with the action woocommerce_before_single_product:
add_action( 'woocommerce_before_single_product', `only_one_in );
function only_one_in_cart() {
global $woocommerce;
$woocommerce->cart->empty_cart();
}
This will empty your cart each time you visit the page, if it's late, then you can add the function into the wp_head hook and validate if you are in the product page by is_product():
add_action( 'wp_head', `only_one_in );
function only_one_in_cart() {
if ( is_product() ){
global $woocommerce;
$woocommerce->cart->empty_cart();
}
}

Woocommerce Update Price Doesn't Save In Cart Session

I'm having issues in Wordpress Woocommerce whereby I have programmatically updated prices of products based on whatever conditions they need. Below is a simple example. I have it displaying and then adding to the cart just fine. My problem is, when the user logs out and logs back in, the cart ends up returning the full prices of the product. Either I'm updating the price incorrectly, or there is a better way to ensure the cart has the correct discounted price.
Here is what I have in functions.php
add_action('woocommerce_get_price_html','pricechanger');
function pricechanger($price){
$theid = get_the_ID();
$product = wc_get_product($theid);
$price = $product->price;
$price = //do something to the price here
//save the productid/price in session for cart
$_SESSION['pd']['$theid'] = $price;
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10, 2);
add_action( 'init', 'woocommerce_add_to_cart_action', 10);
add_action( 'init', 'woocommerce_checkout_action', 10 );
return $price;
}
Because the price wouldn't transition to the add to cart button, I've had to save them in a session. I haven't found anywhere that sends that price to the cart.
add_action( 'woocommerce_before_calculate_totals', 'woo_add_discount');
function woo_add_discount() {
if(isset($_SESSION['pd'])) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
foreach($_SESSION['pd'] as $key => $val) {
if($cart_item['data']->id == $key){
$cart_item['data']->set_price($val);
}
}
}
}
}
Help is greatly appreciated!
Thanks!
I forgot to post my concluded answer here.
You need to run these hooks against your price change code:
add_action( 'woocommerce_before_calculate_totals', 'your_function_here');
add_action( 'woocommerce_before_mini_cart', 'your_function_here');
function your_function_here(){
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
//do something to your price here
$price = 'some calculation here';
//set your price
$cart_item['data']->price = floatval($price);
}
}
Hope that helps someone!

Woocommerce hide pricing for unregistered customer

I'm trying to set up my woocommerce shop to hide prices to logged out users. I have two different codes that each only to a part of what I want.
This code hides the price but when they click a variant it still shows the add to cart button and they can see the price in the cart:
add_filter('woocommerce_get_price_html','members_only_price');
function members_only_price($price){
if(is_user_logged_in() ){
return $price;
}
else return '<a href="' .get_permalink(woocommerce_get_page_id('myaccount')).
'">Login</a> or <a href="'.site_url('/wp-login.php?
action=register&redirect_to=' .
get_permalink()).'">Register</a> to see price!';
}
This bit of code hides the add to cart and price, but doesn't show the color options/variations:
add_filter('woocommerce_get_price_html','members_only_price');
function members_only_price($price){
if(is_user_logged_in() ){
return $price;
}
else .remove_action( 'woocommerce_after_shop_loop_item',
'woocommerce_template_loop_add_to_cart' ).remove_action(
'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10
).remove_action( 'woocommerce_single_product_summary',
'woocommerce_template_single_add_to_cart', 30 ).remove_action(
'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price',
10 );
}
this is a link to the product page: http://69.195.124.58/~creatfs4/?product=wood
My PHP coding skills are novice... I keep trying to add bits here and there but it doesn't work.
Any help is greatly appreciated!!

Categories