function uc_usps_quote in Ubercart 6.2
Same name and namespace in other branches
- 5 shipping/uc_usps/uc_usps.module \uc_usps_quote()
- 7.3 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_shipping_method in shipping/
uc_usps/ uc_usps.module - Implements hook_shipping_method().
File
- shipping/
uc_usps/ uc_usps.module, line 340 - Shipping quote method module that receives quotes from the United States Postal Service via XML web service.
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 $services to prevent PHP notices here and in uc_quote.
$services['data'] = array(
'debug' => NULL,
'error' => '',
);
$addresses = array(
(array) variable_get('uc_quote_store_default_address', new stdClass()),
);
$packages = _uc_usps_package_products($products, $addresses);
if (!count($packages)) {
return array();
}
foreach ($packages as $key => $ship_packages) {
$orig = (object) $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)) {
$services['data']['debug'] .= htmlentities(urldecode($request)) . "<br />\n";
}
$result = drupal_http_request($connection_url, array(), 'POST', $request);
if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) {
$services['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)) {
$services['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_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_markup((string) $postage->CommercialRate);
}
else {
$services[$classid]['rate'] += uc_usps_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 ($service != 'data' && !in_array($service, $usps_services)) {
unset($services[$service]);
}
}
$context = array(
'revision' => 'themed',
'type' => 'amount',
);
foreach ($services as $key => $quote) {
if (isset($quote['rate'])) {
$context['subject']['quote'] = $quote;
$context['revision'] = 'altered';
$services[$key]['rate'] = uc_price($quote['rate'], $context);
$context['revision'] = 'formatted';
$services[$key]['format'] = uc_price($quote['rate'], $context);
$services[$key]['option_label'] = theme('uc_usps_option_label', $quote['label'], $packages);
}
}
// Separate debug data out of $services. This is necessary because
// $services['data'] is not sortable by a 'rate' key, so it has to be
// kept separate from the reset of the $services array until after the sort.
$debug_data = $services['data'];
unset($services['data']);
uasort($services, 'uc_quote_price_sort');
if (isset($debug_data['debug']) || isset($debug_data['error']) && count($debug_data['error'])) {
$services['data'] = $debug_data;
}
return $services;
}