Overview

Packages

  • currencysymbol
  • MAbout
  • Mage
    • Admin
    • Adminhtml
    • AdminNotification
    • Api
    • Api2
    • Authorizenet
    • Backup
    • Bundle
    • Captcha
    • Catalog
    • CatalogIndex
    • CatalogInventory
    • CatalogRule
    • CatalogSearch
    • Centinel
    • Checkout
    • Cms
    • Compiler
    • Connect
    • Contacts
    • Core
    • Cron
    • CurrencySymbol
    • Customer
    • Dataflow
    • Directory
    • DirtectPost
    • Downloadable
    • Eav
    • GiftMessage
    • GoogleAnalytics
    • GoogleBase
    • GoogleCheckout
    • ImportExport
    • Index
    • Install
    • Log
    • Media
    • Newsletter
    • Oauth
    • Page
    • PageCache
    • Paygate
    • Payment
    • Paypal
    • PaypalUk
    • Persistent
    • Poll
    • ProductAlert
    • Rating
    • Reports
    • Review
    • Rss
    • Rule
    • Sales
    • SalesRule
    • Sedfriend
    • Sendfriend
    • Shipping
    • Sitemap
    • Tag
    • Tax
    • Usa
    • Weee
    • Widget
    • Wishlist
    • XmlConnect
  • None
  • Phoenix
    • Moneybookers
  • PHP
  • Zend
    • Date
    • Mime
    • XmlRpc

Classes

  • Mage_Usa_Block_Adminhtml_Dhl_Unitofmeasure
  • Mage_Usa_Helper_Data
  • Mage_Usa_Model_Shipping_Carrier_Abstract
  • Mage_Usa_Model_Shipping_Carrier_Abstract_Source_Mode
  • Mage_Usa_Model_Shipping_Carrier_Abstract_Source_Requesttype
  • Mage_Usa_Model_Shipping_Carrier_Dhl
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Contenttype
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Abstract
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Doc
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Freedoc
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Freenondoc
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Nondoc
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Size
  • Mage_Usa_Model_Shipping_Carrier_Dhl_International_Source_Method_Unitofmeasure
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Label_Pdf
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Label_Pdf_Page
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Label_Pdf_PageBuilder
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Dutypaymenttype
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Freemethod
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Method
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Protection_Rounding
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Protection_Value
  • Mage_Usa_Model_Shipping_Carrier_Dhl_Source_Shipmenttype
  • Mage_Usa_Model_Shipping_Carrier_Fedex
  • Mage_Usa_Model_Shipping_Carrier_Fedex_Source_Dropoff
  • Mage_Usa_Model_Shipping_Carrier_Fedex_Source_Freemethod
  • Mage_Usa_Model_Shipping_Carrier_Fedex_Source_Method
  • Mage_Usa_Model_Shipping_Carrier_Fedex_Source_Packaging
  • Mage_Usa_Model_Shipping_Carrier_Ups
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Container
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_DestType
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Freemethod
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Method
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_OriginShipment
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Pickup
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Type
  • Mage_Usa_Model_Shipping_Carrier_Ups_Source_Unitofmeasure
  • Mage_Usa_Model_Shipping_Carrier_Usps
  • Mage_Usa_Model_Shipping_Carrier_Usps_Source_Container
  • Mage_Usa_Model_Shipping_Carrier_Usps_Source_Freemethod
  • Mage_Usa_Model_Shipping_Carrier_Usps_Source_Machinable
  • Mage_Usa_Model_Shipping_Carrier_Usps_Source_Method
  • Mage_Usa_Model_Shipping_Carrier_Usps_Source_Size
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: /**
   3:  * Magento
   4:  *
   5:  * NOTICE OF LICENSE
   6:  *
   7:  * This source file is subject to the Open Software License (OSL 3.0)
   8:  * that is bundled with this package in the file LICENSE.txt.
   9:  * It is also available through the world-wide-web at this URL:
  10:  * http://opensource.org/licenses/osl-3.0.php
  11:  * If you did not receive a copy of the license and are unable to
  12:  * obtain it through the world-wide-web, please send an email
  13:  * to license@magentocommerce.com so we can send you a copy immediately.
  14:  *
  15:  * DISCLAIMER
  16:  *
  17:  * Do not edit or add to this file if you wish to upgrade Magento to newer
  18:  * versions in the future. If you wish to customize Magento for your
  19:  * needs please refer to http://www.magentocommerce.com for more information.
  20:  *
  21:  * @category    Mage
  22:  * @package     Mage_Usa
  23:  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24:  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  25:  */
  26: 
  27: 
  28: /**
  29:  * USPS shipping rates estimation
  30:  *
  31:  * @link       http://www.usps.com/webtools/htm/Development-Guide-v3-0b.htm
  32:  * @category   Mage
  33:  * @package    Mage_Usa
  34:  * @author      Magento Core Team <core@magentocommerce.com>
  35:  */
  36: class Mage_Usa_Model_Shipping_Carrier_Usps
  37:     extends Mage_Usa_Model_Shipping_Carrier_Abstract
  38:     implements Mage_Shipping_Model_Carrier_Interface
  39: {
  40:     /**
  41:      * USPS containers
  42:      */
  43:     const CONTAINER_VARIABLE           = 'VARIABLE';
  44:     const CONTAINER_FLAT_RATE_BOX      = 'FLAT RATE BOX';
  45:     const CONTAINER_FLAT_RATE_ENVELOPE = 'FLAT RATE ENVELOPE';
  46:     const CONTAINER_RECTANGULAR        = 'RECTANGULAR';
  47:     const CONTAINER_NONRECTANGULAR     = 'NONRECTANGULAR';
  48: 
  49:     /**
  50:      * USPS size
  51:      */
  52:     const SIZE_REGULAR = 'REGULAR';
  53:     const SIZE_LARGE   = 'LARGE';
  54: 
  55:     /**
  56:      * Default api revision
  57:      *
  58:      * @var int
  59:      */
  60:     const DEFAULT_REVISION = 2;
  61: 
  62:     /**
  63:      * Code of the carrier
  64:      *
  65:      * @var string
  66:      */
  67:     const CODE = 'usps';
  68: 
  69:     /**
  70:      * Ounces in one pound for conversion
  71:      */
  72:     const OUNCES_POUND = 16;
  73: 
  74:     /**
  75:      * Code of the carrier
  76:      *
  77:      * @var string
  78:      */
  79:     protected $_code = self::CODE;
  80: 
  81:     /**
  82:      * Destination Zip Code required flag
  83:      *
  84:      * @var boolean
  85:      * @deprecated since 1.7.0 functionality implemented in Mage_Usa_Model_Shipping_Carrier_Abstract
  86:      */
  87:     protected $_isZipCodeRequired;
  88: 
  89:     /**
  90:      * Rate request data
  91:      *
  92:      * @var Mage_Shipping_Model_Rate_Request|null
  93:      */
  94:     protected $_request = null;
  95: 
  96:     /**
  97:      * Raw rate request data
  98:      *
  99:      * @var Varien_Object|null
 100:      */
 101:     protected $_rawRequest = null;
 102: 
 103:     /**
 104:      * Rate result data
 105:      *
 106:      * @var Mage_Shipping_Model_Rate_Result|null
 107:      */
 108:     protected $_result = null;
 109: 
 110:     /**
 111:      * Default cgi gateway url
 112:      *
 113:      * @var string
 114:      */
 115:     protected $_defaultGatewayUrl = 'http://production.shippingapis.com/ShippingAPI.dll';
 116: 
 117:     /**
 118:      * Container types that could be customized for USPS carrier
 119:      *
 120:      * @var array
 121:      */
 122:     protected $_customizableContainerTypes = array('VARIABLE', 'RECTANGULAR', 'NONRECTANGULAR');
 123: 
 124:     /**
 125:      * Collect and get rates
 126:      *
 127:      * @param Mage_Shipping_Model_Rate_Request $request
 128:      * @return Mage_Shipping_Model_Rate_Result|bool|null
 129:      */
 130:     public function collectRates(Mage_Shipping_Model_Rate_Request $request)
 131:     {
 132:         if (!$this->getConfigFlag($this->_activeFlag)) {
 133:             return false;
 134:         }
 135: 
 136:         $this->setRequest($request);
 137: 
 138:         $this->_result = $this->_getQuotes();
 139: 
 140:         $this->_updateFreeMethodQuote($request);
 141: 
 142:         return $this->getResult();
 143:     }
 144: 
 145:     /**
 146:      * Prepare and set request to this instance
 147:      *
 148:      * @param Mage_Shipping_Model_Rate_Request $request
 149:      * @return Mage_Usa_Model_Shipping_Carrier_Usps
 150:      */
 151:     public function setRequest(Mage_Shipping_Model_Rate_Request $request)
 152:     {
 153:         $this->_request = $request;
 154: 
 155:         $r = new Varien_Object();
 156: 
 157:         if ($request->getLimitMethod()) {
 158:             $r->setService($request->getLimitMethod());
 159:         } else {
 160:             $r->setService('ALL');
 161:         }
 162: 
 163:         if ($request->getUspsUserid()) {
 164:             $userId = $request->getUspsUserid();
 165:         } else {
 166:             $userId = $this->getConfigData('userid');
 167:         }
 168:         $r->setUserId($userId);
 169: 
 170:         if ($request->getUspsContainer()) {
 171:             $container = $request->getUspsContainer();
 172:         } else {
 173:             $container = $this->getConfigData('container');
 174:         }
 175:         $r->setContainer($container);
 176: 
 177:         if ($request->getUspsSize()) {
 178:             $size = $request->getUspsSize();
 179:         } else {
 180:             $size = $this->getConfigData('size');
 181:         }
 182:         $r->setSize($size);
 183: 
 184:         if ($request->getGirth()) {
 185:             $girth = $request->getGirth();
 186:         } else {
 187:             $girth = $this->getConfigData('girth');
 188:         }
 189:         $r->setGirth($girth);
 190: 
 191:         if ($request->getHeight()) {
 192:             $height = $request->getHeight();
 193:         } else {
 194:             $height = $this->getConfigData('height');
 195:         }
 196:         $r->setHeight($height);
 197: 
 198:         if ($request->getLength()) {
 199:             $length = $request->getLength();
 200:         } else {
 201:             $length = $this->getConfigData('length');
 202:         }
 203:         $r->setLength($length);
 204: 
 205:         if ($request->getWidth()) {
 206:             $width = $request->getWidth();
 207:         } else {
 208:             $width = $this->getConfigData('width');
 209:         }
 210:         $r->setWidth($width);
 211: 
 212:         if ($request->getUspsMachinable()) {
 213:             $machinable = $request->getUspsMachinable();
 214:         } else {
 215:             $machinable = $this->getConfigData('machinable');
 216:         }
 217:         $r->setMachinable($machinable);
 218: 
 219:         if ($request->getOrigPostcode()) {
 220:             $r->setOrigPostal($request->getOrigPostcode());
 221:         } else {
 222:             $r->setOrigPostal(Mage::getStoreConfig(
 223:                 Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP,
 224:                 $request->getStoreId()
 225:             ));
 226:         }
 227: 
 228:         if ($request->getOrigCountryId()) {
 229:             $r->setOrigCountryId($request->getOrigCountryId());
 230:         } else {
 231:             $r->setOrigCountryId(Mage::getStoreConfig(
 232:                 Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID,
 233:                 $request->getStoreId()
 234:             ));
 235:         }
 236: 
 237:         if ($request->getDestCountryId()) {
 238:             $destCountry = $request->getDestCountryId();
 239:         } else {
 240:             $destCountry = self::USA_COUNTRY_ID;
 241:         }
 242: 
 243:         $r->setDestCountryId($destCountry);
 244: 
 245:         if (!$this->_isUSCountry($destCountry)) {
 246:             $r->setDestCountryName($this->_getCountryName($destCountry));
 247:         }
 248: 
 249:         if ($request->getDestPostcode()) {
 250:             $r->setDestPostal($request->getDestPostcode());
 251:         }
 252: 
 253:         $weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
 254:         $r->setWeightPounds(floor($weight));
 255:         $r->setWeightOunces(round(($weight-floor($weight)) * self::OUNCES_POUND, 1));
 256:         if ($request->getFreeMethodWeight()!=$request->getPackageWeight()) {
 257:             $r->setFreeMethodWeight($request->getFreeMethodWeight());
 258:         }
 259: 
 260:         $r->setValue($request->getPackageValue());
 261:         $r->setValueWithDiscount($request->getPackageValueWithDiscount());
 262: 
 263:         $r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
 264: 
 265:         $this->_rawRequest = $r;
 266: 
 267:         return $this;
 268:     }
 269: 
 270:     /**
 271:      * Get result of request
 272:      *
 273:      * @return mixed
 274:      */
 275:     public function getResult()
 276:     {
 277:        return $this->_result;
 278:     }
 279: 
 280:     /**
 281:      * Get quotes
 282:      *
 283:      * @return Mage_Shipping_Model_Rate_Result
 284:      */
 285:     protected function _getQuotes()
 286:     {
 287:         return $this->_getXmlQuotes();
 288:     }
 289: 
 290:     /**
 291:      * Set free method request
 292:      *
 293:      * @param  $freeMethod
 294:      * @return void
 295:      */
 296:     protected function _setFreeMethodRequest($freeMethod)
 297:     {
 298:         $r = $this->_rawRequest;
 299: 
 300:         $weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight());
 301:         $r->setWeightPounds(floor($weight));
 302:         $r->setWeightOunces(round(($weight-floor($weight)) * self::OUNCES_POUND, 1));
 303:         $r->setService($freeMethod);
 304:     }
 305: 
 306:     /**
 307:      * Build RateV3 request, send it to USPS gateway and retrieve quotes in XML format
 308:      *
 309:      * @link http://www.usps.com/webtools/htm/Rate-Calculators-v2-3.htm
 310:      * @return Mage_Shipping_Model_Rate_Result
 311:      */
 312:     protected function _getXmlQuotes()
 313:     {
 314:         $r = $this->_rawRequest;
 315: 
 316:         // The origin address(shipper) must be only in USA
 317:         if(!$this->_isUSCountry($r->getOrigCountryId())){
 318:             $responseBody = '';
 319:             return $this->_parseXmlResponse($responseBody);
 320:         }
 321: 
 322:         if ($this->_isUSCountry($r->getDestCountryId())) {
 323:             $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><RateV4Request/>');
 324:             $xml->addAttribute('USERID', $r->getUserId());
 325:             // according to usps v4 documentation
 326:             $xml->addChild('Revision', '2');
 327: 
 328:             $package = $xml->addChild('Package');
 329:             $package->addAttribute('ID', 0);
 330:             $service = $this->getCode('service_to_code', $r->getService());
 331:             if (!$service) {
 332:                 $service = $r->getService();
 333:             }
 334:             if ($r->getContainer() == 'FLAT RATE BOX' || $r->getContainer() == 'FLAT RATE ENVELOPE') {
 335:                 $service = 'PRIORITY';
 336:             }
 337:             $package->addChild('Service', $service);
 338: 
 339:             // no matter Letter, Flat or Parcel, use Parcel
 340:             if ($r->getService() == 'FIRST CLASS' || $r->getService() == 'FIRST CLASS HFP COMMERCIAL') {
 341:                 $package->addChild('FirstClassMailType', 'PARCEL');
 342:             }
 343:             $package->addChild('ZipOrigination', $r->getOrigPostal());
 344:             //only 5 chars avaialble
 345:             $package->addChild('ZipDestination', substr($r->getDestPostal(), 0, 5));
 346:             $package->addChild('Pounds', $r->getWeightPounds());
 347:             $package->addChild('Ounces', $r->getWeightOunces());
 348:             // Because some methods don't accept VARIABLE and (NON)RECTANGULAR containers
 349:             $package->addChild('Container', $r->getContainer());
 350:             $package->addChild('Size', $r->getSize());
 351:             if ($r->getSize() == 'LARGE') {
 352:                 $package->addChild('Width', $r->getWidth());
 353:                 $package->addChild('Length', $r->getLength());
 354:                 $package->addChild('Height', $r->getHeight());
 355:                 if ($r->getContainer() == 'NONRECTANGULAR' || $r->getContainer() == 'VARIABLE') {
 356:                     $package->addChild('Girth', $r->getGirth());
 357:                 }
 358:             }
 359:             $package->addChild('Machinable', $r->getMachinable());
 360: 
 361:             $api = 'RateV4';
 362:         } else {
 363:             $xml = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><IntlRateV2Request/>');
 364:             $xml->addAttribute('USERID', $r->getUserId());
 365:             // according to usps v4 documentation
 366:             $xml->addChild('Revision', '2');
 367: 
 368:             $package = $xml->addChild('Package');
 369:             $package->addAttribute('ID', 0);
 370:             $package->addChild('Pounds', $r->getWeightPounds());
 371:             $package->addChild('Ounces', $r->getWeightOunces());
 372:             $package->addChild('MailType', 'All');
 373:             $package->addChild('ValueOfContents', $r->getValue());
 374:             $package->addChild('Country', $r->getDestCountryName());
 375:             $package->addChild('Container', $r->getContainer());
 376:             $package->addChild('Size', $r->getSize());
 377:             $width = $length = $height = $girth = '';
 378:             if ($r->getSize() == 'LARGE') {
 379:                 $width = $r->getWidth();
 380:                 $length = $r->getLength();
 381:                 $height = $r->getHeight();
 382:                 if ($r->getContainer() == 'NONRECTANGULAR') {
 383:                     $girth = $r->getGirth();
 384:                 }
 385:             }
 386:             $package->addChild('Width', $width);
 387:             $package->addChild('Length', $length);
 388:             $package->addChild('Height', $height);
 389:             $package->addChild('Girth', $girth);
 390: 
 391: 
 392:             $api = 'IntlRateV2';
 393:         }
 394:         $request = $xml->asXML();
 395: 
 396:         $responseBody = $this->_getCachedQuotes($request);
 397:         if ($responseBody === null) {
 398:             $debugData = array('request' => $request);
 399:             try {
 400:                 $url = $this->getConfigData('gateway_url');
 401:                 if (!$url) {
 402:                     $url = $this->_defaultGatewayUrl;
 403:                 }
 404:                 $client = new Zend_Http_Client();
 405:                 $client->setUri($url);
 406:                 $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
 407:                 $client->setParameterGet('API', $api);
 408:                 $client->setParameterGet('XML', $request);
 409:                 $response = $client->request();
 410:                 $responseBody = $response->getBody();
 411: 
 412:                 $debugData['result'] = $responseBody;
 413:                 $this->_setCachedQuotes($request, $responseBody);
 414:             } catch (Exception $e) {
 415:                 $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
 416:                 $responseBody = '';
 417:             }
 418:             $this->_debug($debugData);
 419:         }
 420:         return $this->_parseXmlResponse($responseBody);
 421:     }
 422: 
 423:     /**
 424:      * Parse calculated rates
 425:      *
 426:      * @link http://www.usps.com/webtools/htm/Rate-Calculators-v2-3.htm
 427:      * @param string $response
 428:      * @return Mage_Shipping_Model_Rate_Result
 429:      */
 430:     protected function _parseXmlResponse($response)
 431:     {
 432:         $costArr = array();
 433:         $priceArr = array();
 434:         if (strlen(trim($response)) > 0) {
 435:             if (strpos(trim($response), '<?xml') === 0) {
 436:                 if (strpos($response, '<?xml version="1.0"?>') !== false) {
 437:                     $response = str_replace(
 438:                         '<?xml version="1.0"?>',
 439:                         '<?xml version="1.0" encoding="ISO-8859-1"?>',
 440:                         $response
 441:                     );
 442:                 }
 443: 
 444:                 $xml = simplexml_load_string($response);
 445: 
 446:                 if (is_object($xml)) {
 447:                     if (is_object($xml->Number) && is_object($xml->Description) && (string)$xml->Description!='') {
 448:                         $errorTitle = (string)$xml->Description;
 449:                     } elseif (is_object($xml->Package)
 450:                           && is_object($xml->Package->Error)
 451:                           && is_object($xml->Package->Error->Description)
 452:                           && (string)$xml->Package->Error->Description!=''
 453:                     ) {
 454:                         $errorTitle = (string)$xml->Package->Error->Description;
 455:                     } else {
 456:                         $errorTitle = 'Unknown error';
 457:                     }
 458:                     $r = $this->_rawRequest;
 459:                     $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
 460:                     $allMethods = $this->getCode('method');
 461:                     $newMethod = false;
 462:                     if ($this->_isUSCountry($r->getDestCountryId())) {
 463:                         if (is_object($xml->Package) && is_object($xml->Package->Postage)) {
 464:                             foreach ($xml->Package->Postage as $postage) {
 465:                                 $serviceName = $this->_filterServiceName((string)$postage->MailService);
 466:                                 $postage->MailService = $serviceName;
 467:                                 if (in_array($serviceName, $allowedMethods)) {
 468:                                     $costArr[$serviceName] = (string)$postage->Rate;
 469:                                     $priceArr[$serviceName] = $this->getMethodPrice(
 470:                                         (string)$postage->Rate,
 471:                                         $serviceName
 472:                                     );
 473:                                 } elseif (!in_array($serviceName, $allMethods)) {
 474:                                     $allMethods[] = $serviceName;
 475:                                     $newMethod = true;
 476:                                 }
 477:                             }
 478:                             asort($priceArr);
 479:                         }
 480:                     } else {
 481:                         /*
 482:                          * International Rates
 483:                          */
 484:                         if (is_object($xml->Package) && is_object($xml->Package->Service)) {
 485:                             foreach ($xml->Package->Service as $service) {
 486:                                 $serviceName = $this->_filterServiceName((string)$service->SvcDescription);
 487:                                 $service->SvcDescription = $serviceName;
 488:                                 if (in_array($serviceName, $allowedMethods)) {
 489:                                     $costArr[$serviceName] = (string)$service->Postage;
 490:                                     $priceArr[$serviceName] = $this->getMethodPrice(
 491:                                         (string)$service->Postage,
 492:                                         $serviceName
 493:                                     );
 494:                                 } elseif (!in_array($serviceName, $allMethods)) {
 495:                                     $allMethods[] = $serviceName;
 496:                                     $newMethod = true;
 497:                                 }
 498:                             }
 499:                             asort($priceArr);
 500:                         }
 501:                     }
 502:                     /**
 503:                      * following if statement is obsolete
 504:                      * we don't have adminhtml/config resoure model
 505:                      */
 506:                     if (false && $newMethod) {
 507:                         sort($allMethods);
 508:                         $insert['usps']['fields']['methods']['value'] = $allMethods;
 509:                         Mage::getResourceModel('adminhtml/config')->saveSectionPost('carriers','','',$insert);
 510:                     }
 511:                 }
 512:             } else {
 513:                 $errorTitle = 'Response is in the wrong format';
 514:             }
 515:         }
 516: 
 517:         $result = Mage::getModel('shipping/rate_result');
 518:         if (empty($priceArr)) {
 519:             $error = Mage::getModel('shipping/rate_result_error');
 520:             $error->setCarrier('usps');
 521:             $error->setCarrierTitle($this->getConfigData('title'));
 522:             $error->setErrorMessage($this->getConfigData('specificerrmsg'));
 523:             $result->append($error);
 524:         } else {
 525:             foreach ($priceArr as $method=>$price) {
 526:                 $rate = Mage::getModel('shipping/rate_result_method');
 527:                 $rate->setCarrier('usps');
 528:                 $rate->setCarrierTitle($this->getConfigData('title'));
 529:                 $rate->setMethod($method);
 530:                 $rate->setMethodTitle($method);
 531:                 $rate->setCost($costArr[$method]);
 532:                 $rate->setPrice($price);
 533:                 $result->append($rate);
 534:             }
 535:         }
 536: 
 537:         return $result;
 538:     }
 539: 
 540:     /**
 541:      * Get configuration data of carrier
 542:      *
 543:      * @param string $type
 544:      * @param string $code
 545:      * @return array|bool
 546:      */
 547:     public function getCode($type, $code='')
 548:     {
 549:         $codes = array(
 550: 
 551:             'service'=>array(
 552:                 'FIRST CLASS' => Mage::helper('usa')->__('First-Class'),
 553:                 'PRIORITY'    => Mage::helper('usa')->__('Priority Mail'),
 554:                 'EXPRESS'     => Mage::helper('usa')->__('Express Mail'),
 555:                 'BPM'         => Mage::helper('usa')->__('Bound Printed Matter'),
 556:                 'PARCEL'      => Mage::helper('usa')->__('Parcel Post'),
 557:                 'MEDIA'       => Mage::helper('usa')->__('Media Mail'),
 558:                 'LIBRARY'     => Mage::helper('usa')->__('Library'),
 559:             ),
 560: 
 561:             'service_to_code'=>array(
 562:                 'First-Class'                                   => 'FIRST CLASS',
 563:                 'First-Class Mail International Large Envelope' => 'FIRST CLASS',
 564:                 'First-Class Mail International Letter'         => 'FIRST CLASS',
 565:                 'First-Class Mail International Package'        => 'FIRST CLASS',
 566:                 'First-Class Mail International Parcel'         => 'FIRST CLASS',
 567:                 'First-Class Mail'                 => 'FIRST CLASS',
 568:                 'First-Class Mail Flat'            => 'FIRST CLASS',
 569:                 'First-Class Mail Large Envelope'  => 'FIRST CLASS',
 570:                 'First-Class Mail International'   => 'FIRST CLASS',
 571:                 'First-Class Mail Letter'          => 'FIRST CLASS',
 572:                 'First-Class Mail Parcel'          => 'FIRST CLASS',
 573:                 'First-Class Mail Package'         => 'FIRST CLASS',
 574:                 'Parcel Post'                      => 'PARCEL',
 575:                 'Bound Printed Matter'             => 'BPM',
 576:                 'Media Mail'                       => 'MEDIA',
 577:                 'Library Mail'                     => 'LIBRARY',
 578:                 'Express Mail'                     => 'EXPRESS',
 579:                 'Express Mail PO to PO'            => 'EXPRESS',
 580:                 'Express Mail Flat Rate Envelope'  => 'EXPRESS',
 581:                 'Express Mail Flat-Rate Envelope Sunday/Holiday Guarantee'  => 'EXPRESS',
 582:                 'Express Mail Sunday/Holiday Guarantee'            => 'EXPRESS',
 583:                 'Express Mail Flat Rate Envelope Hold For Pickup'  => 'EXPRESS',
 584:                 'Express Mail Hold For Pickup'                     => 'EXPRESS',
 585:                 'Global Express Guaranteed (GXG)'                  => 'EXPRESS',
 586:                 'Global Express Guaranteed Non-Document Rectangular'     => 'EXPRESS',
 587:                 'Global Express Guaranteed Non-Document Non-Rectangular' => 'EXPRESS',
 588:                 'USPS GXG Envelopes'                               => 'EXPRESS',
 589:                 'Express Mail International'                       => 'EXPRESS',
 590:                 'Express Mail International Flat Rate Envelope'    => 'EXPRESS',
 591:                 'Priority Mail'                        => 'PRIORITY',
 592:                 'Priority Mail Small Flat Rate Box'    => 'PRIORITY',
 593:                 'Priority Mail Medium Flat Rate Box'   => 'PRIORITY',
 594:                 'Priority Mail Large Flat Rate Box'    => 'PRIORITY',
 595:                 'Priority Mail Flat Rate Box'          => 'PRIORITY',
 596:                 'Priority Mail Flat Rate Envelope'     => 'PRIORITY',
 597:                 'Priority Mail International'                            => 'PRIORITY',
 598:                 'Priority Mail International Flat Rate Envelope'         => 'PRIORITY',
 599:                 'Priority Mail International Small Flat Rate Box'        => 'PRIORITY',
 600:                 'Priority Mail International Medium Flat Rate Box'       => 'PRIORITY',
 601:                 'Priority Mail International Large Flat Rate Box'        => 'PRIORITY',
 602:                 'Priority Mail International Flat Rate Box'              => 'PRIORITY'
 603:             ),
 604: 
 605:             'first_class_mail_type'=>array(
 606:                 'LETTER'      => Mage::helper('usa')->__('Letter'),
 607:                 'FLAT'        => Mage::helper('usa')->__('Flat'),
 608:                 'PARCEL'      => Mage::helper('usa')->__('Parcel'),
 609:             ),
 610: 
 611:             'container'=>array(
 612:                 'VARIABLE'           => Mage::helper('usa')->__('Variable'),
 613:                 'FLAT RATE BOX'      => Mage::helper('usa')->__('Flat-Rate Box'),
 614:                 'FLAT RATE ENVELOPE' => Mage::helper('usa')->__('Flat-Rate Envelope'),
 615:                 'RECTANGULAR'        => Mage::helper('usa')->__('Rectangular'),
 616:                 'NONRECTANGULAR'     => Mage::helper('usa')->__('Non-rectangular'),
 617:             ),
 618: 
 619:             'containers_filter' => array(
 620:                 array(
 621:                     'containers' => array('VARIABLE'),
 622:                     'filters'    => array(
 623:                         'within_us' => array(
 624:                             'method' => array(
 625:                                 'Express Mail Flat Rate Envelope',
 626:                                 'Express Mail Flat Rate Envelope Hold For Pickup',
 627:                                 'Priority Mail Flat Rate Envelope',
 628:                                 'Priority Mail Large Flat Rate Box',
 629:                                 'Priority Mail Medium Flat Rate Box',
 630:                                 'Priority Mail Small Flat Rate Box',
 631:                                 'Express Mail',
 632:                                 'Priority Mail',
 633:                                 'Parcel Post',
 634:                                 'Media Mail',
 635:                                 'First-Class Mail Large Envelope',
 636:                             )
 637:                         ),
 638:                         'from_us' => array(
 639:                             'method' => array(
 640:                                 'Express Mail International Flat Rate Envelope',
 641:                                 'Priority Mail International Flat Rate Envelope',
 642:                                 'Priority Mail International Large Flat Rate Box',
 643:                                 'Priority Mail International Medium Flat Rate Box',
 644:                                 'Priority Mail International Small Flat Rate Box',
 645:                                 'Global Express Guaranteed (GXG)',
 646:                                 'USPS GXG Envelopes',
 647:                                 'Express Mail International',
 648:                                 'Priority Mail International',
 649:                                 'First-Class Mail International Package',
 650:                                 'First-Class Mail International Large Envelope',
 651:                                 'First-Class Mail International Parcel',
 652:                             )
 653:                         )
 654:                     )
 655:                 ),
 656:                 array(
 657:                     'containers' => array('FLAT RATE BOX'),
 658:                     'filters'    => array(
 659:                         'within_us' => array(
 660:                             'method' => array(
 661:                                 'Priority Mail Large Flat Rate Box',
 662:                                 'Priority Mail Medium Flat Rate Box',
 663:                                 'Priority Mail Small Flat Rate Box',
 664:                             )
 665:                         ),
 666:                         'from_us' => array(
 667:                             'method' => array(
 668:                                 'Priority Mail International Large Flat Rate Box',
 669:                                 'Priority Mail International Medium Flat Rate Box',
 670:                                 'Priority Mail International Small Flat Rate Box',
 671:                             )
 672:                         )
 673:                     )
 674:                 ),
 675:                 array(
 676:                     'containers' => array('FLAT RATE ENVELOPE'),
 677:                     'filters'    => array(
 678:                         'within_us' => array(
 679:                             'method' => array(
 680:                                 'Express Mail Flat Rate Envelope',
 681:                                 'Express Mail Flat Rate Envelope Hold For Pickup',
 682:                                 'Priority Mail Flat Rate Envelope',
 683:                             )
 684:                         ),
 685:                         'from_us' => array(
 686:                             'method' => array(
 687:                                 'Express Mail International Flat Rate Envelope',
 688:                                 'Priority Mail International Flat Rate Envelope',
 689:                             )
 690:                         )
 691:                     )
 692:                 ),
 693:                 array(
 694:                     'containers' => array('RECTANGULAR'),
 695:                     'filters'    => array(
 696:                         'within_us' => array(
 697:                             'method' => array(
 698:                                 'Express Mail',
 699:                                 'Priority Mail',
 700:                                 'Parcel Post',
 701:                                 'Media Mail',
 702:                             )
 703:                         ),
 704:                         'from_us' => array(
 705:                             'method' => array(
 706:                                 'USPS GXG Envelopes',
 707:                                 'Express Mail International',
 708:                                 'Priority Mail International',
 709:                                 'First-Class Mail International Package',
 710:                                 'First-Class Mail International Parcel',
 711:                             )
 712:                         )
 713:                     )
 714:                 ),
 715:                 array(
 716:                     'containers' => array('NONRECTANGULAR'),
 717:                     'filters'    => array(
 718:                         'within_us' => array(
 719:                             'method' => array(
 720:                                 'Express Mail',
 721:                                 'Priority Mail',
 722:                                 'Parcel Post',
 723:                                 'Media Mail',
 724:                             )
 725:                         ),
 726:                         'from_us' => array(
 727:                             'method' => array(
 728:                                 'Global Express Guaranteed (GXG)',
 729:                                 'USPS GXG Envelopes',
 730:                                 'Express Mail International',
 731:                                 'Priority Mail International',
 732:                                 'First-Class Mail International Package',
 733:                                 'First-Class Mail International Parcel',
 734:                             )
 735:                         )
 736:                     )
 737:                 ),
 738:              ),
 739: 
 740:             'size'=>array(
 741:                 'REGULAR'     => Mage::helper('usa')->__('Regular'),
 742:                 'LARGE'       => Mage::helper('usa')->__('Large'),
 743:             ),
 744: 
 745:             'machinable'=>array(
 746:                 'true'        => Mage::helper('usa')->__('Yes'),
 747:                 'false'       => Mage::helper('usa')->__('No'),
 748:             ),
 749: 
 750:             'delivery_confirmation_types' => array(
 751:                 'True' => Mage::helper('usa')->__('Not Required'),
 752:                 'False'  => Mage::helper('usa')->__('Required'),
 753:             ),
 754:         );
 755: 
 756:         $methods = $this->getConfigData('methods');
 757:         if (!empty($methods)) {
 758:             $codes['method'] = explode(",", $methods);
 759:         } else {
 760:             $codes['method'] = array();
 761:         }
 762: 
 763:         if (!isset($codes[$type])) {
 764:             return false;
 765:         } elseif (''===$code) {
 766:             return $codes[$type];
 767:         }
 768: 
 769:         if (!isset($codes[$type][$code])) {
 770:             return false;
 771:         } else {
 772:             return $codes[$type][$code];
 773:         }
 774:     }
 775: 
 776:     /**
 777:      * Get tracking
 778:      *
 779:      * @param mixed $trackings
 780:      * @return mixed
 781:      */
 782:     public function getTracking($trackings)
 783:     {
 784:         $this->setTrackingReqeust();
 785: 
 786:         if (!is_array($trackings)) {
 787:             $trackings = array($trackings);
 788:         }
 789: 
 790:         $this->_getXmlTracking($trackings);
 791: 
 792:         return $this->_result;
 793:     }
 794: 
 795:     /**
 796:      * Set tracking request
 797:      *
 798:      * @return null
 799:      */
 800:     protected function setTrackingReqeust()
 801:     {
 802:         $r = new Varien_Object();
 803: 
 804:         $userId = $this->getConfigData('userid');
 805:         $r->setUserId($userId);
 806: 
 807:         $this->_rawTrackRequest = $r;
 808:     }
 809: 
 810:     /**
 811:      * Send request for tracking
 812:      *
 813:      * @param array $tracking
 814:      * @return null
 815:      */
 816:     protected function _getXmlTracking($trackings)
 817:     {
 818:          $r = $this->_rawTrackRequest;
 819: 
 820:          foreach ($trackings as $tracking) {
 821:              $xml = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><TrackRequest/>');
 822:              $xml->addAttribute('USERID', $r->getUserId());
 823: 
 824:              $trackid = $xml->addChild('TrackID');
 825:              $trackid->addAttribute('ID',$tracking);
 826: 
 827:              $api = 'TrackV2';
 828:              $request = $xml->asXML();
 829:              $debugData = array('request' => $request);
 830: 
 831:              try {
 832:                 $url = $this->getConfigData('gateway_url');
 833:                 if (!$url) {
 834:                     $url = $this->_defaultGatewayUrl;
 835:                 }
 836:                 $client = new Zend_Http_Client();
 837:                 $client->setUri($url);
 838:                 $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
 839:                 $client->setParameterGet('API', $api);
 840:                 $client->setParameterGet('XML', $request);
 841:                 $response = $client->request();
 842:                 $responseBody = $response->getBody();
 843:                 $debugData['result'] = $responseBody;
 844:             }
 845:             catch (Exception $e) {
 846:                 $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
 847:                 $responseBody = '';
 848:             }
 849: 
 850:             $this->_debug($debugData);
 851:             $this->_parseXmlTrackingResponse($tracking, $responseBody);
 852:          }
 853:     }
 854: 
 855:     /**
 856:      * Parse xml tracking response
 857:      *
 858:      * @param array $trackingvalue
 859:      * @param string $response
 860:      * @return null
 861:      */
 862:     protected function _parseXmlTrackingResponse($trackingvalue, $response)
 863:     {
 864:         $errorTitle = Mage::helper('usa')->__('Unable to retrieve tracking');
 865:         $resultArr=array();
 866:         if (strlen(trim($response)) > 0) {
 867:             if (strpos(trim($response), '<?xml')===0) {
 868:                 $xml = simplexml_load_string($response);
 869:                 if (is_object($xml)) {
 870:                     if (isset($xml->Number) && isset($xml->Description) && (string)$xml->Description!='') {
 871:                         $errorTitle = (string)$xml->Description;
 872:                     } elseif (isset($xml->TrackInfo)
 873:                           && isset($xml->TrackInfo->Error)
 874:                           && isset($xml->TrackInfo->Error->Description)
 875:                           && (string)$xml->TrackInfo->Error->Description!=''
 876:                     ) {
 877:                         $errorTitle = (string)$xml->TrackInfo->Error->Description;
 878:                     } else {
 879:                         $errorTitle = Mage::helper('usa')->__('Unknown error');
 880:                     }
 881: 
 882:                     if(isset($xml->TrackInfo) && isset($xml->TrackInfo->TrackSummary)){
 883:                        $resultArr['tracksummary'] = (string)$xml->TrackInfo->TrackSummary;
 884: 
 885:                     }
 886:                 }
 887:             }
 888:         }
 889: 
 890:         if (!$this->_result) {
 891:             $this->_result = Mage::getModel('shipping/tracking_result');
 892:         }
 893:         $defaults = $this->getDefaults();
 894: 
 895:         if ($resultArr) {
 896:              $tracking = Mage::getModel('shipping/tracking_result_status');
 897:              $tracking->setCarrier('usps');
 898:              $tracking->setCarrierTitle($this->getConfigData('title'));
 899:              $tracking->setTracking($trackingvalue);
 900:              $tracking->setTrackSummary($resultArr['tracksummary']);
 901:              $this->_result->append($tracking);
 902:          } else {
 903:             $error = Mage::getModel('shipping/tracking_result_error');
 904:             $error->setCarrier('usps');
 905:             $error->setCarrierTitle($this->getConfigData('title'));
 906:             $error->setTracking($trackingvalue);
 907:             $error->setErrorMessage($errorTitle);
 908:             $this->_result->append($error);
 909:          }
 910:     }
 911: 
 912:     /**
 913:      * Get tracking response
 914:      *
 915:      * @return string
 916:      */
 917:     public function getResponse()
 918:     {
 919:         $statuses = '';
 920:         if ($this->_result instanceof Mage_Shipping_Model_Tracking_Result) {
 921:             if ($trackings = $this->_result->getAllTrackings()) {
 922:                 foreach ($trackings as $tracking) {
 923:                     if($data = $tracking->getAllData()) {
 924:                         if (!empty($data['track_summary'])) {
 925:                             $statuses .= Mage::helper('usa')->__($data['track_summary']);
 926:                         } else {
 927:                             $statuses .= Mage::helper('usa')->__('Empty response');
 928:                         }
 929:                     }
 930:                 }
 931:             }
 932:         }
 933:         if (empty($statuses)) {
 934:             $statuses = Mage::helper('usa')->__('Empty response');
 935:         }
 936:         return $statuses;
 937:     }
 938: 
 939:     /**
 940:      * Get allowed shipping methods
 941:      *
 942:      * @return array
 943:      */
 944:     public function getAllowedMethods()
 945:     {
 946:         $allowed = explode(',', $this->getConfigData('allowed_methods'));
 947:         $arr = array();
 948:         foreach ($allowed as $k) {
 949:             $arr[$k] = $k;
 950:         }
 951:         return $arr;
 952:     }
 953: 
 954:     /**
 955:      * Return USPS county name by country ISO 3166-1-alpha-2 code
 956:      * Return false for unknown countries
 957:      *
 958:      * @param string $countryId
 959:      * @return string|false
 960:      */
 961:     protected function _getCountryName($countryId)
 962:     {
 963:         $countries = array (
 964:           'AD' => 'Andorra',
 965:           'AE' => 'United Arab Emirates',
 966:           'AF' => 'Afghanistan',
 967:           'AG' => 'Antigua and Barbuda',
 968:           'AI' => 'Anguilla',
 969:           'AL' => 'Albania',
 970:           'AM' => 'Armenia',
 971:           'AN' => 'Netherlands Antilles',
 972:           'AO' => 'Angola',
 973:           'AR' => 'Argentina',
 974:           'AT' => 'Austria',
 975:           'AU' => 'Australia',
 976:           'AW' => 'Aruba',
 977:           'AX' => 'Aland Island (Finland)',
 978:           'AZ' => 'Azerbaijan',
 979:           'BA' => 'Bosnia-Herzegovina',
 980:           'BB' => 'Barbados',
 981:           'BD' => 'Bangladesh',
 982:           'BE' => 'Belgium',
 983:           'BF' => 'Burkina Faso',
 984:           'BG' => 'Bulgaria',
 985:           'BH' => 'Bahrain',
 986:           'BI' => 'Burundi',
 987:           'BJ' => 'Benin',
 988:           'BM' => 'Bermuda',
 989:           'BN' => 'Brunei Darussalam',
 990:           'BO' => 'Bolivia',
 991:           'BR' => 'Brazil',
 992:           'BS' => 'Bahamas',
 993:           'BT' => 'Bhutan',
 994:           'BW' => 'Botswana',
 995:           'BY' => 'Belarus',
 996:           'BZ' => 'Belize',
 997:           'CA' => 'Canada',
 998:           'CC' => 'Cocos Island (Australia)',
 999:           'CD' => 'Congo, Democratic Republic of the',
1000:           'CF' => 'Central African Republic',
1001:           'CG' => 'Congo, Republic of the',
1002:           'CH' => 'Switzerland',
1003:           'CI' => 'Cote d Ivoire (Ivory Coast)',
1004:           'CK' => 'Cook Islands (New Zealand)',
1005:           'CL' => 'Chile',
1006:           'CM' => 'Cameroon',
1007:           'CN' => 'China',
1008:           'CO' => 'Colombia',
1009:           'CR' => 'Costa Rica',
1010:           'CU' => 'Cuba',
1011:           'CV' => 'Cape Verde',
1012:           'CX' => 'Christmas Island (Australia)',
1013:           'CY' => 'Cyprus',
1014:           'CZ' => 'Czech Republic',
1015:           'DE' => 'Germany',
1016:           'DJ' => 'Djibouti',
1017:           'DK' => 'Denmark',
1018:           'DM' => 'Dominica',
1019:           'DO' => 'Dominican Republic',
1020:           'DZ' => 'Algeria',
1021:           'EC' => 'Ecuador',
1022:           'EE' => 'Estonia',
1023:           'EG' => 'Egypt',
1024:           'ER' => 'Eritrea',
1025:           'ES' => 'Spain',
1026:           'ET' => 'Ethiopia',
1027:           'FI' => 'Finland',
1028:           'FJ' => 'Fiji',
1029:           'FK' => 'Falkland Islands',
1030:           'FM' => 'Micronesia, Federated States of',
1031:           'FO' => 'Faroe Islands',
1032:           'FR' => 'France',
1033:           'GA' => 'Gabon',
1034:           'GB' => 'Great Britain and Northern Ireland',
1035:           'GD' => 'Grenada',
1036:           'GE' => 'Georgia, Republic of',
1037:           'GF' => 'French Guiana',
1038:           'GH' => 'Ghana',
1039:           'GI' => 'Gibraltar',
1040:           'GL' => 'Greenland',
1041:           'GM' => 'Gambia',
1042:           'GN' => 'Guinea',
1043:           'GP' => 'Guadeloupe',
1044:           'GQ' => 'Equatorial Guinea',
1045:           'GR' => 'Greece',
1046:           'GS' => 'South Georgia (Falkland Islands)',
1047:           'GT' => 'Guatemala',
1048:           'GW' => 'Guinea-Bissau',
1049:           'GY' => 'Guyana',
1050:           'HK' => 'Hong Kong',
1051:           'HN' => 'Honduras',
1052:           'HR' => 'Croatia',
1053:           'HT' => 'Haiti',
1054:           'HU' => 'Hungary',
1055:           'ID' => 'Indonesia',
1056:           'IE' => 'Ireland',
1057:           'IL' => 'Israel',
1058:           'IN' => 'India',
1059:           'IQ' => 'Iraq',
1060:           'IR' => 'Iran',
1061:           'IS' => 'Iceland',
1062:           'IT' => 'Italy',
1063:           'JM' => 'Jamaica',
1064:           'JO' => 'Jordan',
1065:           'JP' => 'Japan',
1066:           'KE' => 'Kenya',
1067:           'KG' => 'Kyrgyzstan',
1068:           'KH' => 'Cambodia',
1069:           'KI' => 'Kiribati',
1070:           'KM' => 'Comoros',
1071:           'KN' => 'Saint Kitts (St. Christopher and Nevis)',
1072:           'KP' => 'North Korea (Korea, Democratic People\'s Republic of)',
1073:           'KR' => 'South Korea (Korea, Republic of)',
1074:           'KW' => 'Kuwait',
1075:           'KY' => 'Cayman Islands',
1076:           'KZ' => 'Kazakhstan',
1077:           'LA' => 'Laos',
1078:           'LB' => 'Lebanon',
1079:           'LC' => 'Saint Lucia',
1080:           'LI' => 'Liechtenstein',
1081:           'LK' => 'Sri Lanka',
1082:           'LR' => 'Liberia',
1083:           'LS' => 'Lesotho',
1084:           'LT' => 'Lithuania',
1085:           'LU' => 'Luxembourg',
1086:           'LV' => 'Latvia',
1087:           'LY' => 'Libya',
1088:           'MA' => 'Morocco',
1089:           'MC' => 'Monaco (France)',
1090:           'MD' => 'Moldova',
1091:           'MG' => 'Madagascar',
1092:           'MK' => 'Macedonia, Republic of',
1093:           'ML' => 'Mali',
1094:           'MM' => 'Burma',
1095:           'MN' => 'Mongolia',
1096:           'MO' => 'Macao',
1097:           'MQ' => 'Martinique',
1098:           'MR' => 'Mauritania',
1099:           'MS' => 'Montserrat',
1100:           'MT' => 'Malta',
1101:           'MU' => 'Mauritius',
1102:           'MV' => 'Maldives',
1103:           'MW' => 'Malawi',
1104:           'MX' => 'Mexico',
1105:           'MY' => 'Malaysia',
1106:           'MZ' => 'Mozambique',
1107:           'NA' => 'Namibia',
1108:           'NC' => 'New Caledonia',
1109:           'NE' => 'Niger',
1110:           'NG' => 'Nigeria',
1111:           'NI' => 'Nicaragua',
1112:           'NL' => 'Netherlands',
1113:           'NO' => 'Norway',
1114:           'NP' => 'Nepal',
1115:           'NR' => 'Nauru',
1116:           'NZ' => 'New Zealand',
1117:           'OM' => 'Oman',
1118:           'PA' => 'Panama',
1119:           'PE' => 'Peru',
1120:           'PF' => 'French Polynesia',
1121:           'PG' => 'Papua New Guinea',
1122:           'PH' => 'Philippines',
1123:           'PK' => 'Pakistan',
1124:           'PL' => 'Poland',
1125:           'PM' => 'Saint Pierre and Miquelon',
1126:           'PN' => 'Pitcairn Island',
1127:           'PT' => 'Portugal',
1128:           'PY' => 'Paraguay',
1129:           'QA' => 'Qatar',
1130:           'RE' => 'Reunion',
1131:           'RO' => 'Romania',
1132:           'RS' => 'Serbia',
1133:           'RU' => 'Russia',
1134:           'RW' => 'Rwanda',
1135:           'SA' => 'Saudi Arabia',
1136:           'SB' => 'Solomon Islands',
1137:           'SC' => 'Seychelles',
1138:           'SD' => 'Sudan',
1139:           'SE' => 'Sweden',
1140:           'SG' => 'Singapore',
1141:           'SH' => 'Saint Helena',
1142:           'SI' => 'Slovenia',
1143:           'SK' => 'Slovak Republic',
1144:           'SL' => 'Sierra Leone',
1145:           'SM' => 'San Marino',
1146:           'SN' => 'Senegal',
1147:           'SO' => 'Somalia',
1148:           'SR' => 'Suriname',
1149:           'ST' => 'Sao Tome and Principe',
1150:           'SV' => 'El Salvador',
1151:           'SY' => 'Syrian Arab Republic',
1152:           'SZ' => 'Swaziland',
1153:           'TC' => 'Turks and Caicos Islands',
1154:           'TD' => 'Chad',
1155:           'TG' => 'Togo',
1156:           'TH' => 'Thailand',
1157:           'TJ' => 'Tajikistan',
1158:           'TK' => 'Tokelau (Union) Group (Western Samoa)',
1159:           'TL' => 'East Timor (Indonesia)',
1160:           'TM' => 'Turkmenistan',
1161:           'TN' => 'Tunisia',
1162:           'TO' => 'Tonga',
1163:           'TR' => 'Turkey',
1164:           'TT' => 'Trinidad and Tobago',
1165:           'TV' => 'Tuvalu',
1166:           'TW' => 'Taiwan',
1167:           'TZ' => 'Tanzania',
1168:           'UA' => 'Ukraine',
1169:           'UG' => 'Uganda',
1170:           'UY' => 'Uruguay',
1171:           'UZ' => 'Uzbekistan',
1172:           'VA' => 'Vatican City',
1173:           'VC' => 'Saint Vincent and the Grenadines',
1174:           'VE' => 'Venezuela',
1175:           'VG' => 'British Virgin Islands',
1176:           'VN' => 'Vietnam',
1177:           'VU' => 'Vanuatu',
1178:           'WF' => 'Wallis and Futuna Islands',
1179:           'WS' => 'Western Samoa',
1180:           'YE' => 'Yemen',
1181:           'YT' => 'Mayotte (France)',
1182:           'ZA' => 'South Africa',
1183:           'ZM' => 'Zambia',
1184:           'ZW' => 'Zimbabwe',
1185:           'US' => 'United States',
1186:         );
1187: 
1188:         if (isset($countries[$countryId])) {
1189:             return $countries[$countryId];
1190:         }
1191: 
1192:         return false;
1193:     }
1194: 
1195:     /**
1196:      * Clean service name from unsupported strings and characters
1197:      *
1198:      * @param  string $name
1199:      * @return string
1200:      */
1201:     protected function _filterServiceName($name)
1202:     {
1203:         $name = (string)preg_replace(array('~<[^/!][^>]+>.*</[^>]+>~sU', '~\<!--.*--\>~isU', '~<[^>]+>~is'), '',
1204:             html_entity_decode($name)
1205:         );
1206:         $name = str_replace('*', '', $name);
1207: 
1208:         return $name;
1209:     }
1210: 
1211:     /**
1212:      * Form XML for US shipment request
1213:      * As integration guide it is important to follow appropriate sequence for tags e.g.: <FromLastName /> must be
1214:      * after <FromFirstName />
1215:      *
1216:      * @param Varien_Object $request
1217:      * @return string
1218:      */
1219:     protected function _formUsExpressShipmentRequest(Varien_Object $request)
1220:     {
1221:         $packageParams = $request->getPackageParams();
1222: 
1223:         $packageWeight = $request->getPackageWeight();
1224:         if ($packageParams->getWeightUnits() != Zend_Measure_Weight::OUNCE) {
1225:             $packageWeight = round(Mage::helper('usa')->convertMeasureWeight(
1226:                 $request->getPackageWeight(),
1227:                 $packageParams->getWeightUnits(),
1228:                 Zend_Measure_Weight::OUNCE
1229:             ));
1230:         }
1231: 
1232:         list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1233:         list($toZip5, $toZip4) = $this->_parseZip($request->getRecipientAddressPostalCode(), true);
1234: 
1235:         $rootNode = 'ExpressMailLabelRequest';
1236:         // the wrap node needs for remove xml declaration above
1237:         $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1238:         $xml = $xmlWrap->addChild($rootNode);
1239:         $xml->addAttribute('USERID', $this->getConfigData('userid'));
1240:         $xml->addAttribute('PASSWORD', $this->getConfigData('password'));
1241:         $xml->addChild('Option');
1242:         $xml->addChild('Revision');
1243:         $xml->addChild('EMCAAccount');
1244:         $xml->addChild('EMCAPassword');
1245:         $xml->addChild('ImageParameters');
1246:         $xml->addChild('FromFirstName', $request->getShipperContactPersonFirstName());
1247:         $xml->addChild('FromLastName', $request->getShipperContactPersonLastName());
1248:         $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1249:         $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1250:         $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1251:         $xml->addChild('FromCity', $request->getShipperAddressCity());
1252:         $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1253:         $xml->addChild('FromZip5', $fromZip5);
1254:         $xml->addChild('FromZip4', $fromZip4);
1255:         $xml->addChild('FromPhone', $request->getShipperContactPhoneNumber());
1256:         $xml->addChild('ToFirstName', $request->getRecipientContactPersonFirstName());
1257:         $xml->addChild('ToLastName', $request->getRecipientContactPersonLastName());
1258:         $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1259:         $xml->addChild('ToAddress1', $request->getRecipientAddressStreet2());
1260:         $xml->addChild('ToAddress2', $request->getRecipientAddressStreet1());
1261:         $xml->addChild('ToCity', $request->getRecipientAddressCity());
1262:         $xml->addChild('ToState', $request->getRecipientAddressStateOrProvinceCode());
1263:         $xml->addChild('ToZip5', $toZip5);
1264:         $xml->addChild('ToZip4', $toZip4);
1265:         $xml->addChild('ToPhone', $request->getRecipientContactPhoneNumber());
1266:         $xml->addChild('WeightInOunces', $packageWeight);
1267:         $xml->addChild('WaiverOfSignature', $packageParams->getDeliveryConfirmation());
1268:         $xml->addChild('POZipCode');
1269:         $xml->addChild('ImageType', 'PDF');
1270: 
1271:         $xml = $xmlWrap->{$rootNode}->asXML();
1272:         return $xml;
1273:     }
1274: 
1275:     /**
1276:      * Form XML for US Signature Confirmation request
1277:      * As integration guide it is important to follow appropriate sequence for tags e.g.: <FromLastName /> must be
1278:      * after <FromFirstName />
1279:      *
1280:      * @param Varien_Object $request
1281:      * @param string $serviceType
1282:      * @return string
1283:      */
1284:     protected function _formUsSignatureConfirmationShipmentRequest(Varien_Object $request, $serviceType)
1285:     {
1286:         switch ($serviceType) {
1287:             case 'PRIORITY':
1288:                 $serviceType = 'Priority';
1289:                 break;
1290:             case 'FIRST CLASS':
1291:                 $serviceType = 'First Class';
1292:                 break;
1293:             case 'PARCEL':
1294:                 $serviceType = 'Parcel Post';
1295:                 break;
1296:             case 'MEDIA':
1297:                 $serviceType = 'Media Mail';
1298:                 break;
1299:             case 'LIBRARY':
1300:                 $serviceType = 'Library Mail';
1301:                 break;
1302:             default:
1303:                 throw new Exception(Mage::helper('usa')->__('Service type does not match'));
1304:         }
1305:         $packageParams = $request->getPackageParams();
1306:         $packageWeight = $request->getPackageWeight();
1307:         if ($packageParams->getWeightUnits() != Zend_Measure_Weight::OUNCE) {
1308:             $packageWeight = round(Mage::helper('usa')->convertMeasureWeight(
1309:                 $request->getPackageWeight(),
1310:                 $packageParams->getWeightUnits(),
1311:                 Zend_Measure_Weight::OUNCE
1312:             ));
1313:         }
1314: 
1315:         list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1316:         list($toZip5, $toZip4) = $this->_parseZip($request->getRecipientAddressPostalCode(), true);
1317: 
1318:         if ($this->getConfigData('mode')) {
1319:             $rootNode = 'SignatureConfirmationV3.0Request';
1320:         } else {
1321:             $rootNode = 'SigConfirmCertifyV3.0Request';
1322:         }
1323:         // the wrap node needs for remove xml declaration above
1324:         $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1325:         $xml = $xmlWrap->addChild($rootNode);
1326:         $xml->addAttribute('USERID', $this->getConfigData('userid'));
1327:         $xml->addChild('Option', 1);
1328:         $xml->addChild('ImageParameters');
1329:         $xml->addChild('FromName', $request->getShipperContactPersonName());
1330:         $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1331:         $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1332:         $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1333:         $xml->addChild('FromCity', $request->getShipperAddressCity());
1334:         $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1335:         $xml->addChild('FromZip5', $fromZip5);
1336:         $xml->addChild('FromZip4', $fromZip4);
1337:         $xml->addChild('ToName', $request->getRecipientContactPersonName());
1338:         $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1339:         $xml->addChild('ToAddress1', $request->getRecipientAddressStreet2());
1340:         $xml->addChild('ToAddress2', $request->getRecipientAddressStreet1());
1341:         $xml->addChild('ToCity', $request->getRecipientAddressCity());
1342:         $xml->addChild('ToState', $request->getRecipientAddressStateOrProvinceCode());
1343:         $xml->addChild('ToZip5', $toZip5);
1344:         $xml->addChild('ToZip4', $toZip4);
1345:         $xml->addChild('WeightInOunces', $packageWeight);
1346:         $xml->addChild('ServiceType', $serviceType);
1347:         $xml->addChild('WaiverOfSignature', $packageParams->getDeliveryConfirmation());
1348:         $xml->addChild('ImageType', 'PDF');
1349: 
1350:         $xml = $xmlWrap->{$rootNode}->asXML();
1351:         return $xml;
1352:     }
1353: 
1354:     /**
1355:      * Convert decimal weight into pound-ounces format
1356:      *
1357:      * @param float $weightInPounds
1358:      * @return array
1359:      */
1360:     protected function _convertPoundOunces($weightInPounds)
1361:     {
1362:         $weightInOunces = ceil($weightInPounds * self::OUNCES_POUND);
1363:         $pounds = floor($weightInOunces / self::OUNCES_POUND);
1364:         $ounces = $weightInOunces % self::OUNCES_POUND;
1365:         return array($pounds, $ounces);
1366:     }
1367: 
1368:     /**
1369:      * Form XML for international shipment request
1370:      * As integration guide it is important to follow appropriate sequence for tags e.g.: <FromLastName /> must be
1371:      * after <FromFirstName />
1372:      *
1373:      * @param Varien_Object $request
1374:      * @return string
1375:      */
1376:     protected function _formIntlShipmentRequest(Varien_Object $request)
1377:     {
1378:         $packageParams = $request->getPackageParams();
1379:         $height = $packageParams->getHeight();
1380:         $width = $packageParams->getWidth();
1381:         $length = $packageParams->getLength();
1382:         $girth = $packageParams->getGirth();
1383:         $packageWeight = $request->getPackageWeight();
1384:         if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
1385:             $packageWeight = Mage::helper('usa')->convertMeasureWeight(
1386:                 $request->getPackageWeight(),
1387:                 $packageParams->getWeightUnits(),
1388:                 Zend_Measure_Weight::POUND
1389:             );
1390:         }
1391:         if ($packageParams->getDimensionUnits() != Zend_Measure_Length::INCH) {
1392:             $length = round(Mage::helper('usa')->convertMeasureDimension(
1393:                 $packageParams->getLength(),
1394:                 $packageParams->getDimensionUnits(),
1395:                 Zend_Measure_Length::INCH
1396:             ));
1397:             $width = round(Mage::helper('usa')->convertMeasureDimension(
1398:                 $packageParams->getWidth(),
1399:                 $packageParams->getDimensionUnits(),
1400:                 Zend_Measure_Length::INCH
1401:             ));
1402:             $height = round(Mage::helper('usa')->convertMeasureDimension(
1403:                 $packageParams->getHeight(),
1404:                 $packageParams->getDimensionUnits(),
1405:                 Zend_Measure_Length::INCH
1406:             ));
1407:         }
1408:         if ($packageParams->getGirthDimensionUnits() != Zend_Measure_Length::INCH) {
1409:             $girth = round(Mage::helper('usa')->convertMeasureDimension(
1410:                 $packageParams->getGirth(),
1411:                 $packageParams->getGirthDimensionUnits(),
1412:                 Zend_Measure_Length::INCH
1413:             ));
1414:         }
1415: 
1416:         $container = $request->getPackagingType();
1417:         switch ($container) {
1418:             case 'VARIABLE':
1419:                 $container = 'VARIABLE';
1420:                 break;
1421:             case 'FLAT RATE ENVELOPE':
1422:                 $container = 'FLATRATEENV';
1423:                 break;
1424:             case 'FLAT RATE BOX':
1425:                 $container = 'FLATRATEBOX';
1426:                 break;
1427:             case 'RECTANGULAR':
1428:                 $container = 'RECTANGULAR';
1429:                 break;
1430:             case 'NONRECTANGULAR':
1431:                 $container = 'NONRECTANGULAR';
1432:                 break;
1433:             default:
1434:                 $container = 'VARIABLE';
1435:         }
1436:         $shippingMethod = $request->getShippingMethod();
1437:         list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1438: 
1439:         // the wrap node needs for remove xml declaration above
1440:         $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1441:         $method = '';
1442:         if (stripos($shippingMethod, 'Priority') !== false) {
1443:             $method = 'Priority';
1444:             $rootNode = 'PriorityMailIntlRequest';
1445:             $xml = $xmlWrap->addChild($rootNode);
1446:         } else if (stripos($shippingMethod, 'First-Class') !== false) {
1447:             $method = 'FirstClass';
1448:             $rootNode = 'FirstClassMailIntlRequest';
1449:             $xml = $xmlWrap->addChild($rootNode);
1450:         } else {
1451:             $method = 'Express';
1452:             $rootNode = 'ExpressMailIntlRequest';
1453:             $xml = $xmlWrap->addChild($rootNode);
1454:         }
1455: 
1456:         $xml->addAttribute('USERID', $this->getConfigData('userid'));
1457:         $xml->addAttribute('PASSWORD', $this->getConfigData('password'));
1458:         $xml->addChild('Option');
1459:         $xml->addChild('Revision', self::DEFAULT_REVISION);
1460:         $xml->addChild('ImageParameters');
1461:         $xml->addChild('FromFirstName', $request->getShipperContactPersonFirstName());
1462:         $xml->addChild('FromLastName', $request->getShipperContactPersonLastName());
1463:         $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1464:         $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1465:         $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1466:         $xml->addChild('FromCity', $request->getShipperAddressCity());
1467:         $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1468:         $xml->addChild('FromZip5', $fromZip5);
1469:         $xml->addChild('FromZip4', $fromZip4);
1470:         $xml->addChild('FromPhone', $request->getShipperContactPhoneNumber());
1471:         if ($method != 'FirstClass') {
1472:             if ($request->getReferenceData()) {
1473:                 $referenceData = $request->getReferenceData() . ' P' . $request->getPackageId();
1474:             } else {
1475:                 $referenceData = $request->getOrderShipment()->getOrder()->getIncrementId()
1476:                                  . ' P'
1477:                                  . $request->getPackageId();
1478:             }
1479:             $xml->addChild('FromCustomsReference', 'Order #' . $referenceData);
1480:         }
1481:         $xml->addChild('ToName', $request->getRecipientContactPersonName());
1482:         $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1483:         $xml->addChild('ToAddress1', $request->getRecipientAddressStreet1());
1484:         $xml->addChild('ToAddress2', $request->getRecipientAddressStreet2());
1485:         $xml->addChild('ToCity', $request->getRecipientAddressCity());
1486:         $xml->addChild('ToProvince', $request->getRecipientAddressStateOrProvinceCode());
1487:         $xml->addChild('ToCountry', $this->_getCountryName($request->getRecipientAddressCountryCode()));
1488:         $xml->addChild('ToPostalCode', $request->getRecipientAddressPostalCode());
1489:         $xml->addChild('ToPOBoxFlag', 'N');
1490:         $xml->addChild('ToPhone', $request->getRecipientContactPhoneNumber());
1491:         $xml->addChild('ToFax');
1492:         $xml->addChild('ToEmail');
1493:         if ($method != 'FirstClass') {
1494:             $xml->addChild('NonDeliveryOption', 'Return');
1495:         }
1496:         if ($method == 'FirstClass') {
1497:             if (stripos($shippingMethod, 'Letter') !== false) {
1498:                 $xml->addChild('FirstClassMailType', 'LETTER');
1499:             } else if (stripos($shippingMethod, 'Flat') !== false) {
1500:                 $xml->addChild('FirstClassMailType', 'FLAT');
1501:             } else{
1502:                 $xml->addChild('FirstClassMailType', 'PARCEL');
1503:             }
1504:         }
1505:         if ($method != 'FirstClass') {
1506:             $xml->addChild('Container', $container);
1507:         }
1508:         $shippingContents = $xml->addChild('ShippingContents');
1509:         $packageItems = $request->getPackageItems();
1510:         // get countries of manufacture
1511:         $countriesOfManufacture = array();
1512:         $productIds = array();
1513:         foreach ($packageItems as $itemShipment) {
1514:                 $item = new Varien_Object();
1515:                 $item->setData($itemShipment);
1516: 
1517:                 $productIds[]= $item->getProductId();
1518:         }
1519:         $productCollection = Mage::getResourceModel('catalog/product_collection')
1520:             ->addStoreFilter($request->getStoreId())
1521:             ->addFieldToFilter('entity_id', array('in' => $productIds))
1522:             ->addAttributeToSelect('country_of_manufacture');
1523:         foreach ($productCollection as $product) {
1524:             $countriesOfManufacture[$product->getId()] = $product->getCountryOfManufacture();
1525:         }
1526: 
1527:         $packagePoundsWeight = $packageOuncesWeight = 0;
1528:         // for ItemDetail
1529:         foreach ($packageItems as $itemShipment) {
1530:             $item = new Varien_Object();
1531:             $item->setData($itemShipment);
1532: 
1533:             $itemWeight = $item->getWeight() * $item->getQty();
1534:             if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
1535:                 $itemWeight = Mage::helper('usa')->convertMeasureWeight(
1536:                     $itemWeight,
1537:                     $packageParams->getWeightUnits(),
1538:                     Zend_Measure_Weight::POUND
1539:                 );
1540:             }
1541:             if (!empty($countriesOfManufacture[$item->getProductId()])) {
1542:                 $countryOfManufacture = $this->_getCountryName(
1543:                     $countriesOfManufacture[$item->getProductId()]
1544:                 );
1545:             } else {
1546:                 $countryOfManufacture = '';
1547:             }
1548:             $itemDetail = $shippingContents->addChild('ItemDetail');
1549:             $itemDetail->addChild('Description', $item->getName());
1550:             $ceiledQty = ceil($item->getQty());
1551:             if ($ceiledQty < 1) {
1552:                 $ceiledQty = 1;
1553:             }
1554:             $individualItemWeight = $itemWeight / $ceiledQty;
1555:             $itemDetail->addChild('Quantity', $ceiledQty);
1556:             $itemDetail->addChild('Value', $item->getCustomsValue() * $item->getQty());
1557:             list($individualPoundsWeight, $individualOuncesWeight) = $this->_convertPoundOunces($individualItemWeight);
1558:             $itemDetail->addChild('NetPounds', $individualPoundsWeight);
1559:             $itemDetail->addChild('NetOunces', $individualOuncesWeight);
1560:             $itemDetail->addChild('HSTariffNumber', 0);
1561:             $itemDetail->addChild('CountryOfOrigin', $countryOfManufacture);
1562: 
1563:             list($itemPoundsWeight, $itemOuncesWeight) = $this->_convertPoundOunces($itemWeight);
1564:             $packagePoundsWeight += $itemPoundsWeight;
1565:             $packageOuncesWeight += $itemOuncesWeight;
1566:         }
1567:         $additionalPackagePoundsWeight = floor($packageOuncesWeight / self::OUNCES_POUND);
1568:         $packagePoundsWeight += $additionalPackagePoundsWeight;
1569:         $packageOuncesWeight -= $additionalPackagePoundsWeight * self::OUNCES_POUND;
1570:         if ($packagePoundsWeight + $packageOuncesWeight / self::OUNCES_POUND < $packageWeight) {
1571:             list($packagePoundsWeight, $packageOuncesWeight) = $this->_convertPoundOunces($packageWeight);
1572:         }
1573: 
1574:         $xml->addChild('GrossPounds', $packagePoundsWeight);
1575:         $xml->addChild('GrossOunces', $packageOuncesWeight);
1576:         if ($packageParams->getContentType() == 'OTHER' && $packageParams->getContentTypeOther() != null) {
1577:             $xml->addChild('ContentType', $packageParams->getContentType());
1578:             $xml->addChild('ContentTypeOther ', $packageParams->getContentTypeOther());
1579:         } else {
1580:             $xml->addChild('ContentType', $packageParams->getContentType());
1581:         }
1582: 
1583:         $xml->addChild('Agreement', 'y');
1584:         $xml->addChild('ImageType', 'PDF');
1585:         $xml->addChild('ImageLayout', 'ALLINONEFILE');
1586:         if ($method == 'FirstClass') {
1587:             $xml->addChild('Container', $container);
1588:         }
1589:         // set size
1590:         if ($packageParams->getSize()) {
1591:             $xml->addChild('Size', $packageParams->getSize());
1592:         }
1593:         // set dimensions
1594:         $xml->addChild('Length', $length);
1595:         $xml->addChild('Width', $width);
1596:         $xml->addChild('Height', $height);
1597:         if ($girth) {
1598:             $xml->addChild('Girth', $girth);
1599:         }
1600: 
1601:         $xml = $xmlWrap->{$rootNode}->asXML();
1602:         return $xml;
1603:     }
1604: 
1605:     /**
1606:      * Do shipment request to carrier web service, obtain Print Shipping Labels and process errors in response
1607:      *
1608:      * @param Varien_Object $request
1609:      * @return Varien_Object
1610:      */
1611:     protected function _doShipmentRequest(Varien_Object $request)
1612:     {
1613:         $this->_prepareShipmentRequest($request);
1614:         $result = new Varien_Object();
1615:         $service = $this->getCode('service_to_code', $request->getShippingMethod());
1616:         $recipientUSCountry = $this->_isUSCountry($request->getRecipientAddressCountryCode());
1617: 
1618:         if ($recipientUSCountry && $service == 'EXPRESS') {
1619:             $requestXml = $this->_formUsExpressShipmentRequest($request);
1620:             $api = 'ExpressMailLabel';
1621:         } else if ($recipientUSCountry) {
1622:             $requestXml = $this->_formUsSignatureConfirmationShipmentRequest($request, $service);
1623:             if ($this->getConfigData('mode')) {
1624:                 $api = 'SignatureConfirmationV3';
1625:             } else {
1626:                 $api = 'SignatureConfirmationCertifyV3';
1627:             }
1628:         } else if ($service == 'FIRST CLASS') {
1629:             $requestXml = $this->_formIntlShipmentRequest($request);
1630:             $api = 'FirstClassMailIntl';
1631:         } else if ($service == 'PRIORITY') {
1632:             $requestXml = $this->_formIntlShipmentRequest($request);
1633:             $api = 'PriorityMailIntl';
1634:         } else {
1635:             $requestXml = $this->_formIntlShipmentRequest($request);
1636:             $api = 'ExpressMailIntl';
1637:         }
1638: 
1639:         $debugData = array('request' => $requestXml);
1640:         $url = $this->getConfigData('gateway_secure_url');
1641:         if (!$url) {
1642:             $url = $this->_defaultGatewayUrl;
1643:         }
1644:         $client = new Zend_Http_Client();
1645:         $client->setUri($url);
1646:         $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
1647:         $client->setParameterGet('API', $api);
1648:         $client->setParameterGet('XML', $requestXml);
1649:         $response = $client->request()->getBody();
1650: 
1651:         $response = simplexml_load_string($response);
1652:         if ($response === false || $response->getName() == 'Error') {
1653:             $debugData['result'] = array(
1654:                 'error' => $response->Description,
1655:                 'code' => $response->Number,
1656:                 'xml' => $response->asXML()
1657:             );
1658:             $this->_debug($debugData);
1659:             $result->setErrors($debugData['result']['error']);
1660:         } else {
1661:             if ($recipientUSCountry && $service == 'EXPRESS') {
1662:                 $labelContent = base64_decode((string) $response->EMLabel);
1663:                 $trackingNumber = (string) $response->EMConfirmationNumber;
1664:             } else if ($recipientUSCountry) {
1665:                 $labelContent = base64_decode((string) $response->SignatureConfirmationLabel);
1666:                 $trackingNumber = (string) $response->SignatureConfirmationNumber;
1667:             } else  {
1668:                 $labelContent = base64_decode((string) $response->LabelImage);
1669:                 $trackingNumber = (string) $response->BarcodeNumber;
1670:             }
1671:             $result->setShippingLabelContent($labelContent);
1672:             $result->setTrackingNumber($trackingNumber);
1673:         }
1674: 
1675:         $result->setGatewayResponse($response);
1676:         $debugData['result'] = $response;
1677:         $this->_debug($debugData);
1678:         return $result;
1679:     }
1680: 
1681:     /**
1682:      * Return container types of carrier
1683:      *
1684:      * @param Varien_Object|null $params
1685:      * @return array|bool
1686:      */
1687:     public function getContainerTypes(Varien_Object $params = null)
1688:     {
1689:         if (is_null($params)) {
1690:             return $this->_getAllowedContainers();
1691:         }
1692:         return $this->_isUSCountry($params->getCountryRecipient()) ? array() : $this->_getAllowedContainers($params);
1693:     }
1694: 
1695:     /**
1696:      * Return all container types of carrier
1697:      *
1698:      * @return array|bool
1699:      */
1700:     public function getContainerTypesAll()
1701:     {
1702:         return $this->getCode('container');
1703:     }
1704: 
1705:     /**
1706:      * Return structured data of containers witch related with shipping methods
1707:      *
1708:      * @return array|bool
1709:      */
1710:     public function getContainerTypesFilter()
1711:     {
1712:         return $this->getCode('containers_filter');
1713:     }
1714: 
1715:     /**
1716:      * Return delivery confirmation types of carrier
1717:      *
1718:      * @param Varien_Object|null $params
1719:      * @return array
1720:      */
1721:     public function getDeliveryConfirmationTypes(Varien_Object $params = null)
1722:     {
1723:         if ($params == null) {
1724:             return array();
1725:         }
1726:         $countryRecipient = $params->getCountryRecipient();
1727:         if ($this->_isUSCountry($countryRecipient)) {
1728:             return $this->getCode('delivery_confirmation_types');
1729:         } else {
1730:             return array();
1731:         }
1732:     }
1733: 
1734:     /**
1735:      * Check whether girth is allowed for the USPS
1736:      *
1737:      * @param null|string $countyDest
1738:      * @return bool
1739:      */
1740:     public function isGirthAllowed($countyDest = null)
1741:     {
1742:         return $this->_isUSCountry($countyDest) ? false : true;
1743:     }
1744: 
1745:     /**
1746:      * Return content types of package
1747:      *
1748:      * @param Varien_Object $params
1749:      * @return array
1750:      */
1751:     public function getContentTypes(Varien_Object $params)
1752:     {
1753:         $countryShipper     = $params->getCountryShipper();
1754:         $countryRecipient   = $params->getCountryRecipient();
1755: 
1756:         if ($countryShipper == self::USA_COUNTRY_ID
1757:             && $countryRecipient != self::USA_COUNTRY_ID
1758:         ) {
1759:             return array(
1760:                 'MERCHANDISE' => Mage::helper('usa')->__('Merchandise'),
1761:                 'SAMPLE' => Mage::helper('usa')->__('Sample'),
1762:                 'GIFT' => Mage::helper('usa')->__('Gift'),
1763:                 'DOCUMENTS' => Mage::helper('usa')->__('Documents'),
1764:                 'RETURN' => Mage::helper('usa')->__('Return'),
1765:                 'OTHER' => Mage::helper('usa')->__('Other'),
1766:             );
1767:         }
1768:         return array();
1769:     }
1770: 
1771:     /**
1772:      * Parse zip from string to zip5-zip4
1773:      *
1774:      * @param string $zipString
1775:      * @param bool $returnFull
1776:      * @return array
1777:      */
1778:     protected function _parseZip($zipString, $returnFull = false)
1779:     {
1780:         $zip4 = '';
1781:         $zip5 = '';
1782:         $zip = array($zipString);
1783:         if (preg_match('/[\\d\\w]{5}\\-[\\d\\w]{4}/', $zipString) != 0) {
1784:             $zip = explode('-', $zipString);
1785:         }
1786:         for ($i = 0; $i < count($zip); ++$i) {
1787:             if (strlen($zip[$i]) == 5) {
1788:                 $zip5 = $zip[$i];
1789:             } elseif (strlen($zip[$i]) == 4) {
1790:                 $zip4 = $zip[$i];
1791:             }
1792:         }
1793:         if (empty($zip5) && empty($zip4) && $returnFull) {
1794:             $zip5 = $zipString;
1795:         }
1796: 
1797:         return array($zip5, $zip4);
1798:     }
1799: }
1800: 
Magento 1.7.0.2 API documentation generated by ApiGen 2.8.0