/mvc/components/shipping
[return to app]1
<?php
2 /**
3 * Shipping related tools
4 */
5 class shippingComponent {
6 /**
7 * Convenience array containing an index of shipping company common appreviations
8 * @var array
9 */
10 public $shippingCompanies = array('ups' => 'United Parcel Service (UPS)', 'usps' => 'US Postal Service',
11 'fedex' => 'Federal Express', 'dhl' => 'DHL');
12 /**
13 * Tracking URLs for the most common US shipping companies - just append your tracking number to the end
14 * @var array
15 */
16 public $trackingLinks = array(
17 'ups' => 'http://wwwapps.ups.com/WebTracking/track?track.y=10&showMultipiece=N&trackNums=',
18 'usps' => 'http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=',
19 'fedex' => 'http://www.fedex.com/Tracking?tracknumbers=',
20 'dhl' => 'http://track.dhl-usa.com/atrknav.asp?ShipmentNumber=',
21 'ceva' => 'http://cevalogistics.com/en/toolsresources/Pages/CEVATrak.aspx?sv=');
22
23 /**
24 * Get the URL to track a package
25 *
26 * @param string $trackingNumber
27 * @param string $service Optional, will select automatically if omitted, must be a key in
$this->trackingLinks
28 * @return string
29 */
30 public function getTrackingUrl($trackingNumber, $service = null) {
31 $trackingNumber = str_replace(array(' ', '-'), '', $trackingNumber);
32 if (!$service) {
33 $len = strlen($trackingNumber);
34 if ($trackingNumber[0] . strtoupper($trackingNumber[1]) == '1Z'
35 || ($trackingNumber[0] == 'T' && $len == 11)) {
36 $service = 'ups';
37 } else if ($len > 20) {
38 $service = 'usps';
39 } else if ($len == 10 || $len == 11) {
40 $service = 'dhl';
41 } else {
42 $service = 'fedex';
43 }
44 }
45 return $this->trackingLinks[$service] . $trackingNumber;
46 }
47
48 /**
49 * Index of UPS shipping method service codes
50 * @var array
51 */
52 public $upsShipMethods = array(
53 1 => 'Next Day Air/Express Mail', 2 => '2nd Day Air/Priority Mail', 3 => 'Ground/Parcel Post',
54 7 => 'Worldwide Express/Airmail Express Mail Service (EMS)', 8 => 'Worldwide Expedited', 11 =>
'Standard',
55 12 => '3-Day Select', 13 => 'Next Day Air Saver', 14 => 'Next Day Air Early AM', 54 => 'Worldwide Express
Plus',
56 59 => '2nd Day Air AM', 65 => 'Express Saver'
57 );
58
59 /**
60 * Flag for getUpsRates() to also get the raw-data returned by UPS as an extra 'raw' key within each shipping
option
61 * @var Boolean default false
62 */
63 public $getUpsRaw = false;
64
65 /**
66 * Gets shipping rates from UPS
67 * You must set your UPS account credentials in the .config for this method to work
68 *
69 * @param array $args Keys are all optional, but basic info needs to be supplied to get a meaningful response
70 * from UPS. Options are: originZip, destinationZip, originCountry, destinationCountry, weight, pickupType,
71 * serviceCode, packagingType, packagingDescription
72 * @return array UPS rate data or error message; an empty array means that there are no UPS rates for your
criteria
73 */
74 public function getUpsRates(array $args) {
75 $originZip = $destinationZip = '';
76 $originCountry = $destinationCountry = 'US';
77 $weight = 0;
78 $pickupType = '01';
79 $serviceCode = 11;
80 $packagingType = '02';
81 $packagingDescription = 'Package';
82 extract($args);
83
84 $xml='<?xml version="1.0"?>
85 <AccessRequest xml:lang="en-US">
86 <AccessLicenseNumber>' . get::$config->UPS['xmlAccessKey'] . '</AccessLicenseNumber>
87 <UserId>' . get::$config->UPS['userid'] . '</UserId>
88 <Password>' . get::$config->UPS['password'] . '</Password>
89 </AccessRequest>
90 <?xml version="1.0"?>
91 <RatingServiceSelectionRequest xml:lang="en-US">
92 <Request>
93 <TransactionReference>
94 <CustomerContext>Rating and Service</CustomerContext>
95 <XpciVersion>1.0001</XpciVersion>
96 </TransactionReference>
97 <RequestAction>Rate</RequestAction>
98 <RequestOption>shop</RequestOption>
99 </Request>
100 <PickupType>
101 <Code>' . $pickupType . '</Code>
102 </PickupType>
103 <Shipment>
104 <Shipper>
105 <Address>
106 <PostalCode>' . $originZip . '</PostalCode>
107 <CountryCode>' . $originCountry . '</CountryCode>
108 </Address>
109 </Shipper>
110 <ShipTo>
111 <Address>
112 <PostalCode>' . $destinationZip . '</PostalCode>
113 <CountryCode>' . $destinationCountry . '</CountryCode>
114 </Address>
115 </ShipTo>
116 <Service>
117 <Code>' . $serviceCode . '</Code>
118 </Service>
119 <Package>
120 <PackagingType>
121 <Code>' . $packagingType . '</Code>
122 <Description>' . $packagingDescription . '</Description>
123 </PackagingType>
124 <Description>Rate Shopping</Description>
125 <PackageWeight>
126 <Weight>' . ($weight < 0.1 ? 0.1 : $weight) . '</Weight>
127 </PackageWeight>
128 </Package>
129 <ShipmentServiceOptions/>
130 </Shipment>
131 </RatingServiceSelectionRequest>';
132
133 $sockheader = 'POST /ups.app/xml/Rate HTTP/1.0' . PHP_EOL
134 . 'Host: www.ups.com' . PHP_EOL
135 . 'Content-type: application/x-www-form-urlencoded' . PHP_EOL
136 . 'Content-length: ' . strlen($xml) . PHP_EOL
137 . 'Accept: */*';
138
139 $fp = stream_socket_client('ssl://www.ups.com:443', $errno, $errstr, 30);
140 fwrite($fp, $sockheader . PHP_EOL . PHP_EOL . $xml . PHP_EOL . PHP_EOL);
141 while (trim(fgets($fp, 128))); //skip over the response headers
142 while (!feof($fp)) {
143 $upsResponse[] = fgets($fp, 4096);
144 }
145 fclose($fp);
146
147 $return = array();
148 $upsResponseString = implode($upsResponse);
149 $sxml = simplexml_load_string($upsResponseString);
150 if (!(boolean) $sxml->Response->ResponseStatusCode) {
151 $return['error'] = (string) $sxml->Response->Error->ErrorDescription;
152 }
153
154 foreach($sxml as $item) {
155 $serviceCode = (Int) $item->Service->Code;
156 if ($serviceCode) {
157 $options = array('price' => (string) $item->TotalCharges->MonetaryValue,
158 'guaranteedDaysToDelivery' => (string) $item->GuaranteedDaysToDelivery,
159 'scheduledDeliveryTime' => (string) $item->ScheduledDeliveryTime);
160 if ($this->getUpsRaw) {
161 $options['raw'] = $item;
162 }
163 $options['shipMethod'] = (isset($this->upsShipMethods[$serviceCode])
164 ? $this->upsShipMethods[$serviceCode]
165 : 'UPS Service ' . $serviceCode);
166 $return['optionsArray'][$serviceCode] = $options;
167
168 $return['options'][$serviceCode] = $options['price'] . ' - ' . $options['shipMethod'];
169 if ($options['guaranteedDaysToDelivery']) {
170 $return['options'][$serviceCode] .= ' guaranteed delivery in '
171 . $options['guaranteedDaysToDelivery'] . ' days';
172 if ($options['scheduledDeliveryTime']) {
173 $return['options'][$serviceCode] .= ' by ' . $options['scheduledDeliveryTime'];
174 }
175 }
176 }
177 }
178 return $return;
179 }
180 }