I've been trying to write my own shipping module based on this tutorial. The 'payment method' pane doesn't pick up all the accessorial information until the shipping quote is recalculated. Moving on to the 'review' page exposes a repeated error that was caused by the request for a shipping quote done via ajax on the previous page:
warning: in_array() expects parameter 2 to be array, null given in .../ubercart/shipping/uc_quote/uc_quote.module on line 351.
Obviously this is a very effective way of frightening off customers.
Line 351 (in_array($line_item['title'], $accessorials)
) is asking for the $accessorials
array, which I've defined correctly in my module, but which isn't being seen by this function because it looks for $accessorials
with
$accessorials = $methods[$settings['method']]['quote']['accessorials'];
When I use dpr($settings)
, I find that it is an array containing two arrays, each pertaining to shipping quotes that have been deleted and had their methods disabled and uninstalled: ucflatrate_1
and minpercentrate_2
.
Where is this information coming from?
How can I delete it, or replace it with my own?
My module code is below. I'm really stressing about this one.
<?php
/**
* Implementation of Ubercart's hook_shipping_method().
*/
function uc_lathes_delivery_shipping_method() {
$methods = array();
$enabled = variable_get('uc_quote_enabled', array());
$methods['lathes_delivery'] = array(
'id' => 'lathes_delivery',
'module' => 'uc_lathes_delivery',
'title' => t('Royal Mail first class'),
'enabled' => $enabled['lathes_delivery'],
'quote' => array(
'type' => 'order',
'callback' => 'uc_lathes_delivery_quote',
'accessorials' => uc_lathes_delivery_accessorials(),
),
'weight' => $weight['lathes_delivery'],
);
return $methods;
}
function uc_lathes_delivery_accessorials() {
return array(
"uk" => t('Postage and Packing within the UK (1st class Royal Mail)'),
"eu" => t('Postage and Packing within the EU (1st class Royal Mail)'),
"world" => t('Postage and Packing (Airmail)'),
);
}
/**
* Implementation of hook_ca_predicate().
*
* Connect the quote action with the quote event.
*/
function uc_lathes_delivery_ca_predicate() {
$enabled = variable_get('uc_quote_enabled', array());
$predicates = array();
$predicates['uc_lathes_delivery_get_quote'] = array(
'#title' => t('Lathes.co.uk shipping quote'),
'#trigger' => 'get_quote_from_lathes_delivery',
'#class' => 'uc_lathes_delivery',
'#status' => $enabled['lathes_delivery'],
'#actions' => array(
array(
'#name' => 'uc_quote_action_get_quote',
'#title' => t('Fetch a shipping quote from the custom lathes.co.uk module.'),
'#argument_map' => array(
'order' => 'order',
'method' => 'method',
),
),
),
);
return $predicates;
}
/**
* Papers! Is this order from within the EU?
*/
function uc_lathes_zone($country) {
$europe = array( 40, 56, 100, 196, 203,
208, 233, 246, 250, 276,
300, 348, 372, 380, 428,
440, 442, 470, 528, 616,
620, 642, 703, 705, 724,
752,
);
if ($country == 826) {return 'uk';}
elseif (in_array($country, $europe)) {return 'eu';}
else {return 'world';}
}
/**
* Get the rate
*/
function uc_lathes_rate ($zone, $product_type) {
$rates = array (
'uk' => array("print" => 2, // *each*
"product_book" => 0,
"drive_belt" => 0,),
'eu' => array("print" => 15, // percent
"product_book" => 1, // each
"drive_belt" => 1,), // per metre
'world' => array("print" => 20, // percent
"product_book" => 2, // each
"drive_belt" => 2,), // per metre
);
return $rates["$zone"]["$product_type"];
}
/**
* Standard callback to return a custom shipping rate.
*
* @param $products
* The order's products.
* @param $details
* Other order details including a shipping address.
* @param $method
* The shipping method to create the quote.
* @return
* An array containing the shipping quote for the order.
*/
function uc_lathes_delivery_quote($products, $details, $method) {
// Set some sensible defaults.
$quote = array(
'rate' => 5,
'option_label' => t('Delivery (custom)'),
'carrier' => 'uk',
);
// Let's do this thing.
$accessorials = uc_lathes_delivery_accessorials();
$zone = uc_lathes_zone($details['country']);
$amount = 0;
$rate = 0;
foreach ($products as $product) {
$rate = uc_lathes_rate($zone, $product->type);
switch ($product->type) {
case 'product_book':
$amount += $rate * $product->qty;
break;
case 'print':
switch ($zone) {
case 'uk':
$amount += $rate * $product->qty;
break;
case 'eu':
$pct = ($product->price / 100) * $rate;
if ($pct < 2) {$pct = 2;}
$amount += $pct * $product->qty;
break;
case 'world':
$pct = ($product->price / 100) * $rate;
if ($pct < 4) {$pct = 4;}
$amount += $pct * $product->qty;
break;
}
break;
case 'drive_belt':
$lenth = $product->data['attributes'][5];
if ($lenth < 1000) {$lenth = 1000;}
$lenth = $lenth / 1000;
$amount += $lenth * $rate * $product->qty;
break;
}
}
$quote['option_label'] = $accessorials["$zone"];
$quote['rate'] = $amount;
$quote['carrier'] = $zone;
// Format the shipping rate for display.
$quote['format'] = uc_price(
$quote['rate'],
array('revision' => 'formatted-original', 'type' => 'amount')
);
// Bundle it into a 1-element array so Ubercart can use it.
$quotes[$quote['carrier']] = $quote;
return $quotes;
}