Skip to content

Instantly share code, notes, and snippets.

@thegallagher
Created April 11, 2016 10:31
Show Gist options
  • Save thegallagher/bb1b1fb90d4f5799f0a5e42144e69340 to your computer and use it in GitHub Desktop.
Save thegallagher/bb1b1fb90d4f5799f0a5e42144e69340 to your computer and use it in GitHub Desktop.
WooCommerce - Get a shipping estimate for a product
<?php
/**
* Get a shipping estimate for a product
*
* @param \WC_Product|int|null $product
*
* @return array|null
*/
function get_product_shipping_estimate($product = null) {
if ($product === null) {
$product = $GLOBALS['product'];
} elseif (is_int($product)) {
$product = wc_get_product($product);
}
if (!$product->exists() || !$product->needs_shipping() || get_option('woocommerce_calc_shipping') === 'no') {
return null;
}
/** @var \WC_Product[] $products */
$products = [$product];
if ($product->is_type('variable')) {
/** @var \WC_Product_Variable $product */
foreach ($product->get_children(true) as $id) {
$products[] = $product->get_child($id);
}
}
if (\WC()->customer->get_shipping_country()) {
$destination = [
'country' => \WC()->customer->get_shipping_country(),
'state' => \WC()->customer->get_shipping_state(),
'postcode' => \WC()->customer->get_shipping_postcode(),
'city' => \WC()->customer->get_shipping_city(),
'address' => \WC()->customer->get_shipping_address(),
'address_2' => \WC()->customer->get_shipping_address_2(),
];
} else {
$destination = \wc_get_customer_default_location();
}
$package = [
'destination' => $destination,
'applied_coupons' => \WC()->cart->applied_coupons,
'user' => ['ID' => \get_current_user_id()],
];
$count = 0;
$minimum = null;
$maximum = null;
$mean = 0;
foreach ($products as $data) {
$cartId = WC()->cart->generate_cart_id($data->id, $product->is_type('variable') ? $data->variation_id : 0);
$price = $data->get_price_excluding_tax();
$tax = $data->get_price_including_tax() - $price;
$package['contents'] = [
$cartId => [
'product_id' => $data->id,
'data' => $data,
'quantity' => 1,
'line_total' => $price,
'line_tax' => $tax,
'line_subtotal' => $price,
'line_subtotal_tax' => $tax,
'contents_cost' => $price,
]
];
$packageRates = \WC_Shipping::instance()->calculate_shipping_for_package($package);
/** @var \WC_Shipping_Rate $rate */
foreach ($packageRates['rates'] as $rate) {
if ($minimum === null || (float)$minimum->cost < (float)$rate->cost) {
$minimum = $rate;
}
if ($maximum === null || (float)$maximum->cost > (float)$rate->cost) {
$maximum = $rate;
}
$mean = (($mean * $count) + (float)$rate->cost) / ($count + 1);
$count++;
}
}
return compact('minimum', 'maximum', 'mean');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment