1

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;

}
  • Wow, when the person with the highest rep drops by and effectively says "Good question." you know you're in trouble! – griz Apr 22 '12 at 9:23
0

It seems like the problem might be that my module doesn't have an admin page. If it means anything to anyone the $settings array contains the keys "negate" and "method", which suggests that it is to do with the CA condition provided by the module. "negate" is always 0 even if I change that within CA.

I've grepped /ubercart/ for 'negate' and found very little.

0

I found it. By exporting the database as a text file and searching it I found the references to the previously deleted shipping methods. For a while I wondered about editing the serialized array by hand but thought better of it. I realized that the condition that refers to them was actually a tax condition. I'd been using the countries shipping methods (which were split by countries in the EU or not) to decide if VAT should be applied. Once I'd deleted those methods and written my own module this error occurred.

Removing the conditions and creating another based on the delivery country has solved my problem. At last.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.