Reputation: 41
I've been struggling with a snippet for WooCommerce that I'd like to add to my child's theme functions but I am reaching the limits of my PHP knowledge.
I have set a custom attribute called pdt_volume
, that I will fill everytime I add a product. I would like to remove the Add_to_cart button when the sum of this attribute for all the items already in the cart have reach a max_volume limit.
For example, the Max_volume
is 100, I have 4 products of pdt_volume = 20
, therefore, the add_to_cart
button for a product with a pdt_volume
of 25 should be removed so that I cannot add it to the cart.
So I have come up with this snippet, with bits of code found here and there. But the functions.php won't save it, and others variations of this code has succeeded to register in the functions.php but the website would then give a 500 error...
Please, does someone has any idea how to achieve this?
What am I doing wrong?
Thanks.
EDIT 1 : Alright, so I got this code to actually be registered in the functions.php
by the editor without breaking, but on the site, I still get the internal server error. Like something is not computing or something.
EDIT 2 (29/01/2017)
I used the ACF plugin I had purchased a long time ago but didn't find any suitable purpose... so far.
Here is the working code I was able to come up with. This is not a code masterpiece and I won't get any award for this, but it seems to be working so far. At least, it allows me to get a TRUE/FALSE statement that I can use in a if condition to change the add_to_cart button to a Your_box_is_full button.
Indeed, I didn't need any global $woocommerce
or $product
!
function get_cart_volume() {
$cart_volume = 0;
foreach( WC()->cart->get_cart() as $cart_item ) {
$item_id = $cart_item['product_id'];
$item_volume = get_field('product_volume', $item_id);
$item_qty = $cart_item['quantity'];
$vol_by_qty = $item_volume * $item_qty;
$cart_volume += $vol_by_qty;
}
return $cart_volume;
}
function check_if_full($candidate) {
$max_volume = 100;
$candidate = $product->id;
$a_volume = get_field('product_volume', $candidate);
$b_volume = get_cart_volume();
$check_volume = $a_volume + $b_volume;
if ($check_volume > $max_volume)
return true;
else
return false;
}
//Just a function to see if it's working on the cart page fur debugging purpose
add_action( 'woocommerce_check_cart_items', 'current_volume');
function current_volume() {
if (is_cart() || is_checkout()) {
global $woocommerce;
$current_volume = get_cart_volume();
wc_add_notice( sprintf( '<strong>Volume is %s.</strong>', $current_volume ),
'error' );
}
}
Upvotes: 4
Views: 2310
Reputation: 254373
As Helgatheviking says, you get already, with woocommerce_is_purchasable
hook in your hooked function, the $product object as 2nd argument. So you don't need and you have to remove global $woocommerce, $product;
to make it work without throwing an error.
Your code is going to be:
add_filter('woocommerce_is_purchasable', 'if_room_is_purchasable', 10, 2);
function if_room_is_purchasable ($is_purchasable, $product){
$cart_volume = 0;
$max_volume = 100;
foreach( WC()->cart->get_cart() as $cart_item ){
$item_id = $cart_item['product_id'];
$terms = get_the_terms( $item_id, 'pa_pdt_volume');
foreach($terms as $key => $term){
$cart_volume += $term->name; // May be better with $term->slug;
}
}
$candidate_volume = $cart_volume + $product->get_attribute( 'pa_pdt_volume' );
if ( $candidate_volume > $max_volume )
return false;
else
return true;
}
This should work now without error.
Upvotes: 3