Reputation: 63
I'm building a custom shipping method for Woocommerce, and the one thing I'm totally hung up on is how to pass custom values to the calculate_shipping() function, either when it's being used on the Cart page or Checkout page.
I need to pass a handful of user-defined variables that will impact the quote -- ie "Is Residential Address", "Is Trade Show", etc etc.
calculate_shipping receives the $package array which contains a 'destination' array, but this only includes the standard add1, add2, city, state, zip, country info. I've added custom fields to the checkout page under both billing and shipping but I still can't figure out how to make these values accessible to the calculate_shipping function.
I've added a custom field like so:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['is_residential'] = array(
'label' => __('Residential Address?', 'woocommerce'),
'type' => 'checkbox',
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
And I see this field show up on the Shipping section of the checkout form. However, I'm not seeing how I can access it anywhere. Even doing a print_r($_POST)
on the checkout page doesn't show this field as being part of the post data, even after I know the form has been updated and re-posted.
But most importantly, I need to add the contents of the submitted field into the $package object which Woocommerce passes to a shipping method's calculate_shipping() function.
I'm just really not sure where to even start with this.
Upvotes: 5
Views: 10236
Reputation: 350
You can't expect to add checkout fields and have them available at the cart page.
The correct way is to use cart packages.
Check function get_shipping_packages()
from class-wc-cart.php
public function get_shipping_packages() {
// Packages array for storing 'carts'
$packages = array();
$packages[0]['contents'] = $this->get_cart(); // Items in the package
$packages[0]['contents_cost'] = 0; // Cost of items in the package, set below
$packages[0]['applied_coupons'] = $this->applied_coupons;
$packages[0]['destination']['country'] = WC()->customer->get_shipping_country();
$packages[0]['destination']['state'] = WC()->customer->get_shipping_state();
$packages[0]['destination']['postcode'] = WC()->customer->get_shipping_postcode();
$packages[0]['destination']['city'] = WC()->customer->get_shipping_city();
$packages[0]['destination']['address'] = WC()->customer->get_shipping_address();
$packages[0]['destination']['address_2'] = WC()->customer->get_shipping_address_2();
foreach ( $this->get_cart() as $item )
if ( $item['data']->needs_shipping() )
if ( isset( $item['line_total'] ) )
$packages[0]['contents_cost'] += $item['line_total'];
return apply_filters( 'woocommerce_cart_shipping_packages', $packages );
}
You gotta hook into woocommerce_cart_shipping_packages
filter and add your fields there.
Most likely you will need to add them (your fields) at the shipping calculator and checkout pages.
Hope this helps.
Upvotes: 3