Get fields from checkout form into calculate_shipping
calculate_shipping()
is not always called
First off, you should know that the calculate_shipping()
method of your shipping method class will only be called when the shipping rates are calculated for the first time (in the current WooCommerce session), each time after a product is added to the cart, and whenever the shipping address is changed — from the cart or checkout page.
But of course, a plugin or custom code can programmatically call the method (or re-calculate the rates) at any times. However, the default behavior is as follows:
Rates are stored in the session based on the package hash to avoid re-calculation every page load.
And the calculate_shipping()
method is executed by the WC_Shipping
class through its calculate_shipping_for_package()
method. In fact, the above quote was taken from the description of WC_Shipping::calculate_shipping_for_package()
which calls WC_Shipping_Method::get_rates_for_package()
and eventually the calculate_shipping()
method in your own class.
How to get the submitted value of a form field in the checkout form from the calculate_shipping()
method
So if you have this in the checkout form:
<input type="text" name="my_field"...>
Then you can get the submitted (POST
ed) value using either the $_POST
superglobal or the WC_Checkout::get_value()
method:
$_POST['my_field']
WC()->checkout->get_value( 'my_field' )
It's as simple as that. :)
To ensure calculate_shipping is called
Run something similar to the following to clear out the session information, which will indicate that calculation still needs to be done. Be aware that if you do this on every page, it will mean that the shipping is constantly being recalculated when it doesn't need to be.
$packages = WC()->cart->get_shipping_packages();
foreach( $packages as $package_key => $package ) {
$session_key = 'shipping_for_package_'.$package_key;
$stored_rates = WC()->session->__unset( $session_key );
}