admin管理员组

文章数量:1023738

I am using the following code to add custom fee on checkout:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

if ($_REQUEST['s-baby-seats'] || $_REQUEST['s-taxi-return-id']) {
    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    if ($_REQUEST['s-taxi-return-id']) {
        $return_fee = intval($c_return_fare);
    } else {
        $return_fee = 0;
    }
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
} 
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

The fee is added as expected but the order_review section of checkout stays disabled with blockUI. I can't see any php ('WP_DEBUG' is true ) or js console errors. I don't know how to debug this behaviour.

If instead of my code just add $woocommerce->cart->add_fee( 'test', 5 ); the order review is not blocked/disabled and the user can place order normally.

Any ideas what in my code may cause this and how to solve the issue? Thanks!

Edit 1:

I changed my function and removed the conditional and the $_requests to this:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    $return_fee = intval($c_return_fare);
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

Now the blockUI is removed within seconds but the fee, while it renders correct at first, it is then turned to 0 by js.

Edit 2:

Turns out I had to use sessions all along. Solved thanks to this post: Add a cart fee from an url variable in Woocommerce

I am using the following code to add custom fee on checkout:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

if ($_REQUEST['s-baby-seats'] || $_REQUEST['s-taxi-return-id']) {
    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    if ($_REQUEST['s-taxi-return-id']) {
        $return_fee = intval($c_return_fare);
    } else {
        $return_fee = 0;
    }
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
} 
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

The fee is added as expected but the order_review section of checkout stays disabled with blockUI. I can't see any php ('WP_DEBUG' is true ) or js console errors. I don't know how to debug this behaviour.

If instead of my code just add $woocommerce->cart->add_fee( 'test', 5 ); the order review is not blocked/disabled and the user can place order normally.

Any ideas what in my code may cause this and how to solve the issue? Thanks!

Edit 1:

I changed my function and removed the conditional and the $_requests to this:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    $return_fee = intval($c_return_fare);
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

Now the blockUI is removed within seconds but the fee, while it renders correct at first, it is then turned to 0 by js.

Edit 2:

Turns out I had to use sessions all along. Solved thanks to this post: Add a cart fee from an url variable in Woocommerce

Share Improve this question edited Apr 9, 2019 at 8:20 thepi asked Apr 8, 2019 at 11:45 thepithepi 131 silver badge4 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 0

You can not keep posted values directly in your hooked function as it's not stored anywhere, and you loose them when customer leaves cart page. So blockUI has nothing to do with it.

There is 2 ways to keep (store) that posted values:

  1. On Woocommerce sessions if that custom data is posted outside Woocommerce single product pages.
  2. On add to cart event, if that custom values are posted when customer clicks add to cart (in Single product pages).

Also you code is a bit outdated as $global woocommerce is not anymore needed and replaced by WC(). Now on woocommerce_cart_calculate_fees hooked function, there is a missing argument in your code which is the variable $cart (the WC_Cart Object).

Your code is not really testable as we don't know what are:

global $c_seats;
global $c_return_fare;

You can try one of this 2 ways:

1) The data is posted outside Woocommerce single product pages:

// Add custom cart item data on add to cart
add_filter( 'init', 'set_custom_data_requested_to_wc_sessions', 10, 3 );
function set_custom_data_requested_to_wc_sessions() {

    if( isset($_REQUEST['s-baby-seats']) || isset($_REQUEST['s-taxi-return-id']) ) {
        // Enable Woocommerce sessions (if not done yet)
        if ( ! WC()->session->has_session() ) {
            WC()->session->set_customer_session_cookie( true );
        }

        $session_data = []; // initializing

        if( isset($_REQUEST['s-baby-seats']) && ! empty($_REQUEST['s-baby-seats']) ) {
            // Add the dropdown value as custom cart item data
            $session_data['baby_seats'] = wc_clean( esc_attr($_REQUEST['s-baby-seats']) );
        }

        if( isset($_REQUEST['s-taxi-return-id']) && ! empty($_REQUEST['s-taxi-return-id']) ) {
            // Add the dropdown value as custom cart item data
            $session_data['return_id'] = wc_clean( esc_attr($_REQUEST['s-taxi-return-id']) );
        }

        // Set the data to custom wc_sessions
        if( sizeof($session_data) > 0 ) {
            WC()->session->set('fee_data', $session_data);
        }
    }
}

// Add a fee
add_action( 'woocommerce_cart_calculate_fees','add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    global $c_seats, $c_return_fare;

    $surcharge = 0; // Initializing
    $fee_data  = WC()->session->get('fee_data'); // Get the data from Woocommerce session

    if( isset($fee_data['baby_seats']) || isset($fee_data['return_id']) ) {
        $baby_seats_fee  = isset($fee_data['baby_seats']) ? intval($c_seats[1]) : 0;
        $return_id_fee =  isset($fee_data['return_id']) && $fee_data['return_id'] ? intval($c_return_fare) : 0;

        $surcharge = $baby_seats_fee + $return_id_fee; // Add to the fee cost
    }

    // Add the calculated fee
    if ( $surcharge > 0 ) {
        $cart->add_fee( esc_html__('Extra + Return', 'woocommerce'), $surcharge );
    }
}

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


2) Data posted on add to cart in single product pages (cart item based):

// Add custom cart item data on add to cart
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 );
function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id) {
    if( isset($_REQUEST['s-baby-seats']) && ! empty($_REQUEST['s-baby-seats']) ) {
        // Add the dropdown value as custom cart item data
        $cart_item_data['s-baby-seats'] = wc_clean( esc_attr($_REQUEST['s-baby-seats']) );
        $unique_key = true;
    }

    if( isset($_REQUEST['s-taxi-return-id']) && ! empty($_REQUEST['s-taxi-return-id']) ) {
        // Add the dropdown value as custom cart item data
        $cart_item_data['s-taxi-rid'] = wc_clean( esc_attr($_REQUEST['s-taxi-return-id']) );
        $unique_key = true;
    }

    if( isset($unique_key) && $unique_key )
        $cart_item_data['unique-key'] = md5(microtime().rand()); // Make each item unique

    return $cart_item_data;
}

// Add a fee
add_action( 'woocommerce_cart_calculate_fees','add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    global $c_seats, $c_return_fare;

    $surcharge = 0; // Initializing

    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['s-baby-seats']) || isset($cart_item['s-taxi-rid']) ) {
            $baby_seats_fee  = isset($cart_item['s-baby-seats']) ? intval($c_seats[1]) : 0;
            $taxi_return_fee =  isset($cart_item['s-taxi-rid']) && $cart_item['s-taxi-rid'] ? intval($c_return_fare) : 0;

            $surcharge += $baby_seats_fee + $return_fee; // Add to the fee cost
        }
    }

    // Add the calculated fee
    if ( $surcharge > 0 ) {
        $cart->add_fee( esc_html__('Extra + Return', 'woocommerce'), $surcharge );
    }
}

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


Related answer on SO: Add a cart fee from an url variable in Woocommerce

I am using the following code to add custom fee on checkout:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

if ($_REQUEST['s-baby-seats'] || $_REQUEST['s-taxi-return-id']) {
    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    if ($_REQUEST['s-taxi-return-id']) {
        $return_fee = intval($c_return_fare);
    } else {
        $return_fee = 0;
    }
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
} 
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

The fee is added as expected but the order_review section of checkout stays disabled with blockUI. I can't see any php ('WP_DEBUG' is true ) or js console errors. I don't know how to debug this behaviour.

If instead of my code just add $woocommerce->cart->add_fee( 'test', 5 ); the order review is not blocked/disabled and the user can place order normally.

Any ideas what in my code may cause this and how to solve the issue? Thanks!

Edit 1:

I changed my function and removed the conditional and the $_requests to this:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    $return_fee = intval($c_return_fare);
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

Now the blockUI is removed within seconds but the fee, while it renders correct at first, it is then turned to 0 by js.

Edit 2:

Turns out I had to use sessions all along. Solved thanks to this post: Add a cart fee from an url variable in Woocommerce

I am using the following code to add custom fee on checkout:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

if ($_REQUEST['s-baby-seats'] || $_REQUEST['s-taxi-return-id']) {
    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    if ($_REQUEST['s-taxi-return-id']) {
        $return_fee = intval($c_return_fare);
    } else {
        $return_fee = 0;
    }
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
} 
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

The fee is added as expected but the order_review section of checkout stays disabled with blockUI. I can't see any php ('WP_DEBUG' is true ) or js console errors. I don't know how to debug this behaviour.

If instead of my code just add $woocommerce->cart->add_fee( 'test', 5 ); the order review is not blocked/disabled and the user can place order normally.

Any ideas what in my code may cause this and how to solve the issue? Thanks!

Edit 1:

I changed my function and removed the conditional and the $_requests to this:

function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

    global $c_seats;
    global $c_return_fare;
    $baby_seats_fee = intval($c_seats[1]);
    $return_fee = intval($c_return_fare);
    $surcharge = $baby_seats_fee + $return_fee;
    $surcharge_label = esc_html__('Extra + Return', 'berrytaxiplon');
    $woocommerce->cart->add_fee( $surcharge_label, $surcharge );
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );

Now the blockUI is removed within seconds but the fee, while it renders correct at first, it is then turned to 0 by js.

Edit 2:

Turns out I had to use sessions all along. Solved thanks to this post: Add a cart fee from an url variable in Woocommerce

Share Improve this question edited Apr 9, 2019 at 8:20 thepi asked Apr 8, 2019 at 11:45 thepithepi 131 silver badge4 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 0

You can not keep posted values directly in your hooked function as it's not stored anywhere, and you loose them when customer leaves cart page. So blockUI has nothing to do with it.

There is 2 ways to keep (store) that posted values:

  1. On Woocommerce sessions if that custom data is posted outside Woocommerce single product pages.
  2. On add to cart event, if that custom values are posted when customer clicks add to cart (in Single product pages).

Also you code is a bit outdated as $global woocommerce is not anymore needed and replaced by WC(). Now on woocommerce_cart_calculate_fees hooked function, there is a missing argument in your code which is the variable $cart (the WC_Cart Object).

Your code is not really testable as we don't know what are:

global $c_seats;
global $c_return_fare;

You can try one of this 2 ways:

1) The data is posted outside Woocommerce single product pages:

// Add custom cart item data on add to cart
add_filter( 'init', 'set_custom_data_requested_to_wc_sessions', 10, 3 );
function set_custom_data_requested_to_wc_sessions() {

    if( isset($_REQUEST['s-baby-seats']) || isset($_REQUEST['s-taxi-return-id']) ) {
        // Enable Woocommerce sessions (if not done yet)
        if ( ! WC()->session->has_session() ) {
            WC()->session->set_customer_session_cookie( true );
        }

        $session_data = []; // initializing

        if( isset($_REQUEST['s-baby-seats']) && ! empty($_REQUEST['s-baby-seats']) ) {
            // Add the dropdown value as custom cart item data
            $session_data['baby_seats'] = wc_clean( esc_attr($_REQUEST['s-baby-seats']) );
        }

        if( isset($_REQUEST['s-taxi-return-id']) && ! empty($_REQUEST['s-taxi-return-id']) ) {
            // Add the dropdown value as custom cart item data
            $session_data['return_id'] = wc_clean( esc_attr($_REQUEST['s-taxi-return-id']) );
        }

        // Set the data to custom wc_sessions
        if( sizeof($session_data) > 0 ) {
            WC()->session->set('fee_data', $session_data);
        }
    }
}

// Add a fee
add_action( 'woocommerce_cart_calculate_fees','add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    global $c_seats, $c_return_fare;

    $surcharge = 0; // Initializing
    $fee_data  = WC()->session->get('fee_data'); // Get the data from Woocommerce session

    if( isset($fee_data['baby_seats']) || isset($fee_data['return_id']) ) {
        $baby_seats_fee  = isset($fee_data['baby_seats']) ? intval($c_seats[1]) : 0;
        $return_id_fee =  isset($fee_data['return_id']) && $fee_data['return_id'] ? intval($c_return_fare) : 0;

        $surcharge = $baby_seats_fee + $return_id_fee; // Add to the fee cost
    }

    // Add the calculated fee
    if ( $surcharge > 0 ) {
        $cart->add_fee( esc_html__('Extra + Return', 'woocommerce'), $surcharge );
    }
}

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


2) Data posted on add to cart in single product pages (cart item based):

// Add custom cart item data on add to cart
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 );
function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id) {
    if( isset($_REQUEST['s-baby-seats']) && ! empty($_REQUEST['s-baby-seats']) ) {
        // Add the dropdown value as custom cart item data
        $cart_item_data['s-baby-seats'] = wc_clean( esc_attr($_REQUEST['s-baby-seats']) );
        $unique_key = true;
    }

    if( isset($_REQUEST['s-taxi-return-id']) && ! empty($_REQUEST['s-taxi-return-id']) ) {
        // Add the dropdown value as custom cart item data
        $cart_item_data['s-taxi-rid'] = wc_clean( esc_attr($_REQUEST['s-taxi-return-id']) );
        $unique_key = true;
    }

    if( isset($unique_key) && $unique_key )
        $cart_item_data['unique-key'] = md5(microtime().rand()); // Make each item unique

    return $cart_item_data;
}

// Add a fee
add_action( 'woocommerce_cart_calculate_fees','add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    global $c_seats, $c_return_fare;

    $surcharge = 0; // Initializing

    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item ) {
        if( isset($cart_item['s-baby-seats']) || isset($cart_item['s-taxi-rid']) ) {
            $baby_seats_fee  = isset($cart_item['s-baby-seats']) ? intval($c_seats[1]) : 0;
            $taxi_return_fee =  isset($cart_item['s-taxi-rid']) && $cart_item['s-taxi-rid'] ? intval($c_return_fare) : 0;

            $surcharge += $baby_seats_fee + $return_fee; // Add to the fee cost
        }
    }

    // Add the calculated fee
    if ( $surcharge > 0 ) {
        $cart->add_fee( esc_html__('Extra + Return', 'woocommerce'), $surcharge );
    }
}

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


Related answer on SO: Add a cart fee from an url variable in Woocommerce

本文标签: woocommerce offtopicCheckout is blocked with blockUI when using action woocommercecartcalculatefees