Disable Place Order button conditionally in Woocom

2019-05-29 09:26发布

问题:

I have some code in a function that displays a message to the end user when the total added value of a custom field exceeds a certain value. Basically its a message telling the customer that they have ordered too much furniture to fit into a 68m3 container.

I also have code which is suppose to disable the add to cart button on products - this doesn't seem to work.

So is there a visible issue in the code below to disable the add to cart button when my custom field total value exceeds 68 and is there a way to totally disable the submit order so it's not possible to submit the order until the value of the custom field total is below 68?

The code to display the message is as follows and works fine.

  // display message when cart volume exceeds 68mcube
add_action('woocommerce_before_calculate_totals', 'display_custom_notice', 
50, 1);
function display_custom_notice( $cart ) {
if ( is_admin() && !defined('DOING_AJAX') )
    return;

 $total_volume = 0;

 // Loop through cart items and calculate total volume
 foreach( WC()->cart->get_cart() as $cart_item ){
    $product_volume = (float) get_post_meta( $cart_item['product_id'], 
'_item_volume', true );
    $total_volume  += $product_volume * $cart_item['quantity'];
}
if( $total_volume > 68 && $total_volume != 0 ){
    // Display a custom notice
    wc_add_notice( __("Note: Your order total volume has reached a full 40ft 
 container - 68 m3 - Please submit order with volume no greater than 68m3", 
"woocommerce"), 'notice' );
 }
 }

The function below are not appearing to work

// function to disable add to cart when volume exceeds 68m3
function get_total_volume(){
$total_volume = 0;

 // Loop through cart items and calculate total volume
foreach( WC()->cart->get_cart() as $cart_item ){
    $product_volume = (float) get_post_meta( $cart_item['product_id'], 
 '_item_volume', true );
    $total_volume  += $product_volume * $cart_item['quantity'];
 }
 return $total_volume;
 }

 // Replacing the button add to cart by a link to the product in Shop and 
 archives pages
 add_filter( 'woocommerce_loop_add_to_cart_link', 
'replace_loop_add_to_cart_button', 10, 2 );
function replace_loop_add_to_cart_button( $button, $product  ) {

if( get_total_volume() > 68 ){
    $button_text = __( "View product", "woocommerce" );
    $button = '<a class="button" href="' . $product->get_permalink() . '">' 
 . $button_text . '</a>';
 }

 return $button;
 }

add_action( 'woocommerce_single_product_summary', 
'remove_add_to_cart_button', 1 );
 function remove_add_to_cart_button() {
// Only when total volume is up to 68
if( get_total_volume() <= 68 ) return;

global $product;

// For variable product types (keeping attribute select fields)
if( $product->is_type( 'variable' ) ) {
    remove_action( 'woocommerce_single_variation', 
'woocommerce_single_variation_add_to_cart_button', 20 );
    add_action( 'woocommerce_single_product_summary', 
'innactive_add_to_cart_button', 20 );
}
// For all other product types
else {
    remove_action( 'woocommerce_single_product_summary', 
'woocommerce_template_single_add_to_cart', 30 );
    add_action( 'woocommerce_single_product_summary', 
'innactive_add_to_cart_button', 30 );
}
}

回答1:

To replace "Place Order" button in checkout page when total cart volume exceed 68 m3 we will need to use your utility function get_total_volume() in the following code:

// Utility function to disable add to cart when volume exceeds 68m3
function get_total_volume(){
    $total_volume = 0;

     // Loop through cart items and calculate total volume
    foreach( WC()->cart->get_cart() as $cart_item ){
        $product_volume = (float) get_post_meta( $cart_item['product_id'], '_item_volume', true );
        $total_volume  += $product_volume * $cart_item['quantity'];
    }
    return $total_volume;
}

// Replacing the Place order button when total volume exceed 68 m3
add_filter( 'woocommerce_order_button_html', 'replace_order_button_html', 10, 2 );
function replace_order_button_html( $order_button ) {
    // Only when total volume is up to 68
    if( get_total_volume() <= 68 ) return $order_button;

    $order_button_text = __( "Max volume reached", "woocommerce" );

    $style = ' style="color:#fff;cursor:not-allowed;background-color:#999;"';
    return '<a class="button alt"'.$style.' name="woocommerce_checkout_place_order" id="place_order" >' . esc_html( $order_button_text ) . '</a>';
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

When total volume exceed 68 m3, you will get an inactive custom button instead:

Check that the utility function get_total_volume() is defined only once, to avoid errors…


Now, to disable add to cart buttons, there is some missing things in your code like the function inactive_add_to_cart_button() and other little things… Try this:

// display message when cart volume exceeds 68mcube
add_action('woocommerce_before_calculate_totals', 'display_custom_notice', 50, 1);
function display_custom_notice( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

     $total_volume = 0;

     // Loop through cart items and calculate total volume
     foreach( WC()->cart->get_cart() as $cart_item ){
        $product_volume = (float) get_post_meta( $cart_item['product_id'], '_item_volume', true );
        $total_volume  += $product_volume * $cart_item['quantity'];
    }
    if( $total_volume > 68 && $total_volume != 0 ){
        // Display a custom notice
        wc_clear_notices();
        wc_add_notice( __("Note: Your order total volume has reached a full 40ft container - 68 m3 - Please submit order with volume no greater than 68m3",  "woocommerce"), 'notice' );
     }
 }

// Utility function to disable add to cart when volume exceeds 68m3
function get_total_volume(){
    $total_volume = 0;

     // Loop through cart items and calculate total volume
    foreach( WC()->cart->get_cart() as $cart_item ){
        $product_volume = (float) get_post_meta( $cart_item['product_id'], '_item_volume', true );
        $total_volume  += $product_volume * $cart_item['quantity'];
    }
    return $total_volume;
}

// Replacing the button add to cart by a link to the product in Shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_loop_add_to_cart_button', 10, 2 );
function replace_loop_add_to_cart_button( $button, $product  ) {
    // Only when total volume is up to 68
    if( get_total_volume() <= 68 ) return $button;

    $small_text = '<br><em style="font-size:85%;">(' . __( "Max volume reached", "woocommerce" ) . ')</em>';
    $button_text = __( "View product", "woocommerce" ) . $small_text;
    return '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
}

// Replacing the button add to cart by an inactive button on single product pages
add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_button', 1 );
function remove_add_to_cart_button() {
    // Only when total volume is up to 68
    if( get_total_volume() <= 68 ) return;

    global $product;

    // For variable product types (keeping attribute select fields)
    if( $product->is_type( 'variable' ) ) {
        remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
        add_action( 'woocommerce_single_product_summary', 'inactive_add_to_cart_button', 20 );
    }
    // For all other product types
    else {
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
        add_action( 'woocommerce_single_product_summary', 'inactive_add_to_cart_button', 30 );
    }
}

// Utility function: displays a custom innactive add to cart button replacement
function inactive_add_to_cart_button(){
    global $product;

    $style = 'style="color:#fff;cursor:not-allowed;background-color:#999;"';
    echo '<a class="button" '.$style.'>' . __ ( 'Max volume reached', 'woocommerce' ) . '</a>';
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

Check that the utility function get_total_volume() is defined only once, to avoid errors…


When the total cart volume is up to 68m3 you will get:

1) On shop and archives pages:

2) On single product pages: