function uc_usps_quote in Ubercart 7.3
Same name and namespace in other branches
- 5 shipping/uc_usps/uc_usps.module \uc_usps_quote()
- 6.2 shipping/uc_usps/uc_usps.module \uc_usps_quote()
Callback for retrieving USPS shipping quote.
Parameters
$products: Array of cart contents.
$details: Order details other than product information.
$method: The shipping method to create the quote.
Return value
JSON object containing rate, error, and debugging information.
1 string reference to 'uc_usps_quote'
- uc_usps_uc_shipping_method in shipping/
uc_usps/ uc_usps.module - Implements hook_uc_shipping_method().
File
- shipping/
uc_usps/ uc_usps.module, line 269 - United States Postal Service (USPS) shipping quote module.
Code
function uc_usps_quote($products, $details, $method) {
// The uc_quote AJAX query can fire before the customer has completely
// filled out the destination address, so check to see whether the address
// has all needed fields. If not, abort.
$destination = (object) $details;
// Country code is always needed.
if (empty($destination->country)) {
// Skip this shipping method.
return array();
}
// Shipments to the US also need zone and postal_code.
if ($destination->country == 840 && (empty($destination->zone) || empty($destination->postal_code))) {
// Skip this shipping method.
return array();
}
// USPS Production server.
$connection_url = 'http://production.shippingapis.com/ShippingAPI.dll';
// Initialize $debug_data to prevent PHP notices here and in uc_quote.
$debug_data = array(
'debug' => NULL,
'error' => array(),
);
$services = array();
$addresses = array(
variable_get('uc_quote_store_default_address', new UcAddress()),
);
$packages = _uc_usps_package_products($products, $addresses);
if (!count($packages)) {
return array();
}
foreach ($packages as $key => $ship_packages) {
$orig = $addresses[$key];
$orig->email = uc_store_email();
if (strpos($method['id'], 'intl') && $destination->country != 840) {
// Build XML for international rate request.
$request = uc_usps_intl_rate_request($ship_packages, $orig, $destination);
}
elseif ($destination->country == 840) {
// Build XML for domestic rate request.
$request = uc_usps_rate_request($ship_packages, $orig, $destination);
}
if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) {
$debug_data['debug'] .= htmlentities(urldecode($request)) . "<br />\n";
}
$result = drupal_http_request($connection_url, array(
'method' => 'POST',
'data' => $request,
));
if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) {
$debug_data['debug'] .= htmlentities($result->data) . "<br />\n";
}
$rate_type = variable_get('uc_usps_online_rates', FALSE);
$response = new SimpleXMLElement($result->data);
// Map double-encoded HTML markup in service names to Unicode characters.
$service_markup = array(
'<sup>&reg;</sup>' => '®',
'<sup>&trade;</sup>' => '™',
'<sup>®</sup>' => '®',
'<sup>™</sup>' => '™',
'**' => '',
);
// Use this map to fix USPS service names.
if (strpos($method['id'], 'intl')) {
// Find and replace markup in International service names.
foreach ($response
->xpath('//Service') as $service) {
$service->SvcDescription = str_replace(array_keys($service_markup), $service_markup, $service->SvcDescription);
}
}
else {
// Find and replace markup in Domestic service names.
foreach ($response
->xpath('//Postage') as $postage) {
$postage->MailService = str_replace(array_keys($service_markup), $service_markup, $postage->MailService);
}
}
if (isset($response->Package)) {
foreach ($response->Package as $package) {
if (isset($package->Error)) {
$debug_data['error'][] = (string) $package->Error[0]->Description . '<br />';
}
else {
if (strpos($method['id'], 'intl')) {
foreach ($package->Service as $service) {
$id = (string) $service['ID'];
$services[$id]['label'] = t('U.S.P.S. @service', array(
'@service' => (string) $service->SvcDescription,
));
// Markup rate before customer sees it.
if (!isset($services[$id]['rate'])) {
$services[$id]['rate'] = 0;
}
$services[$id]['rate'] += uc_usps_rate_markup((string) $service->Postage);
}
}
else {
foreach ($package->Postage as $postage) {
$classid = (string) $postage['CLASSID'];
if ($classid === '0') {
if ((string) $postage->MailService == "First-Class Mail® Parcel") {
$classid = 'zeroParcel';
}
elseif ((string) $postage->MailService == "First-Class Mail® Letter") {
$classid = 'zeroFlat';
}
else {
$classid = 'zero';
}
}
if (!isset($services[$classid]['rate'])) {
$services[$classid]['rate'] = 0;
}
$services[$classid]['label'] = t('U.S.P.S. @service', array(
'@service' => (string) $postage->MailService,
));
// Markup rate before customer sees it.
// Rates are stored differently if ONLINE $rate_type is requested.
// First Class doesn't have online rates, so if CommercialRate
// is missing use Rate instead.
if ($rate_type && !empty($postage->CommercialRate)) {
$services[$classid]['rate'] += uc_usps_rate_markup((string) $postage->CommercialRate);
}
else {
$services[$classid]['rate'] += uc_usps_rate_markup((string) $postage->Rate);
}
}
}
}
}
}
}
$method_services = 'uc_' . $method['id'] . '_services';
$usps_services = array_filter(variable_get($method_services, array_keys(call_user_func('_' . $method_services))));
foreach ($services as $service => $quote) {
if (!in_array($service, $usps_services)) {
unset($services[$service]);
}
}
foreach ($services as $key => $quote) {
if (isset($quote['rate'])) {
$services[$key]['rate'] = $quote['rate'];
$services[$key]['option_label'] = theme('uc_usps_option_label', array(
'service' => $quote['label'],
'packages' => $packages,
));
}
}
uasort($services, 'uc_quote_price_sort');
// Merge debug data into $services. This is necessary because
// $debug_data is not sortable by a 'rate' key, so it has to be
// kept separate from the $services data until this point.
if (isset($debug_data['debug']) || isset($debug_data['error']) && count($debug_data['error'])) {
$services['data'] = $debug_data;
}
return $services;
}