-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathclass.canadapost.php
More file actions
266 lines (227 loc) · 7.36 KB
/
class.canadapost.php
File metadata and controls
266 lines (227 loc) · 7.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
<?php
/***
* This class will allow you to fetch information from Canada Post Server and show the information to you.
* Its a very basic and can be extended.
*
* @author Abdullah Rubiyath (c) July 2008.
* @version 1.0
* @license MIT
*
* Usage:
*
* At Constructor Merchant Info & Customer Info needs to be passed in associative array in this format:
*
* $merchantInfo = array (
* 'merchantCPCID' => CPC_DEMO_XML,
* 'fromPostalCode' => YOUR_POSTAL_CODE,
* 'turnAroundTime' => 24,
* 'itemsPrice' => 14
* );
*
* $customerInfo = array (
* 'city' => 'Brampton', [CUSTOMER_CITY]
* 'provOrState' => 'Ontario', [CUSTOMER_STATE_PROVINCE]
* 'country' => CA, [2 Digit Code, see Canada Post Specs for more Info]
* 'postalCode' => 'L1JK9' [CUSTOMER_POSTAL_OR_ZIP_CODE]
* );
*
* Product information needs to be passed in this following format in Associate Array:
*
* $product_info = array (
* 'quantity' => 1,
* 'weight'=> 2 (kg),
* 'length' => 3 (cm),
* 'width' => 1 (cm),
* 'height' => 8 (cm),
* 'description' => 'some Description about Product'
* );
*
* To get a better understanding of XML Please see CanadaPost's DTD:
* http://sellonline.canadapost.ca/DevelopersResources/protocolV3/eParcel.dtd
*
* Sample XML POST AND RESPONSE FROM Canada Post can be viewed here:
* http://sellonline.canadapost.ca/DevelopersResources/protocolV3/HTTPInterface.html
*/
class CanadaPost {
protected $sendXML;
protected $responseXML;
protected $merchantInfo;
protected $customerInfo;
protected $productInfo;
protected $errorMessage;
/** the constructor where all values are initialized **/
public function __construct() {
$this->merchatInfo = array (
'merchantCPCID' => 'CPC_DEMO_XML',
'fromPostalCode' => 'L6V4K9',
'turnAroundTime' => '24',
'itemsPrice' => '0'
);
$this->productInfo = array();
$this->errorMessage = array (
'code' => 0,
'message' => 'success'
);
}
/**
* This Method sets the Manufacturer information
* @return none
* @param array $mInfo Array containing Manufacturer Info in Associative format
*/
public function setManufacturer($mInfo) {
$this->merchantInfo = $mInfo;
}
/**
* This Method sets the Item Price
* @return none
* @param float $itemPrice Float containing the total price of items to be shipped
*/
public function setPrice($itemPrice) {
$this->merchantInfo['itemsPrice'] = $itemPrice;
}
/**
* This Method sets the Customer Info
* @return none
* @param array $cInfo Array containing the Customer's Info in Associative Format
*/
public function setCustomer($cInfo) {
$this->customerInfo = $cInfo;
}
/**
* This Method allows you to Add items to be shipped
* @return none
* @param array $pInfo Array containing product Info in
*/
public function addItem($pInfo) {
$this->productInfo[] = $pInfo;
}
/**
* This Method allows you to add Product
* @return none
* @param array $pInfo Array containing product Info in
*/
public function addProduct($pInfo) {
$this->productInfo[] = $pInfo;
}
/**
* This Method Returns Data by fetching from Canada Post's Server. Depending on parameter passed, it
* returns either Array in Associative format or an XML String. On failure it returns false.
*
* @return string|boolean|array Returns false for error or either XML String or in Associative array.
* @param string $return String 'xml' or 'array'
*/
public function getRates($returnString = 'xml') {
$pData = $this->prepareXML();
// $this->sendXML = $pData;
$context_options = array (
'http' => array (
'method' => 'POST',
'header'=> "Host: sellonline.canadapost.ca\n"
. "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen($pData) . "\r\n"
)
);
$context = stream_context_create($context_options);
// socket Connection to CanadaPost Server with proper context
$socket = @stream_socket_client('sellonline.canadapost.ca:30000', $errno,
$errstr, 15, STREAM_CLIENT_CONNECT, $context);
if( !$socket ) {
$this->errorMessage['code'] = $errno;
$this->errorMessage['message'] = $errstr;
return false;
}
fwrite($socket, $pData);
$responseXML = "";
while (!feof($socket) ) {
$responseXML .= fgets($socket,255);
}
fclose($socket);
if( $returnString == 'xml' ) {
return $responseXML;
} else if( $returnString == 'array') {
// make an assoc array by using xpath on Dom and the basic elements in an assoc array
$rArray = array();
$rDoc = new DomDocument();
$rDoc->loadXML($responseXML);
$xpath = new DomXPath($rDoc);
$statusCode = $xpath->query('//statusCode');
// check for Error, if there's error then return false
if( $statusCode->item(0)->nodeValue != "1" ) {
$this->errorMessage['code'] = $statusCode->item(0)->nodeValue;
$statusMessage = $xpath->query('//statusMessage');
$this->errorMessage['message'] = $statusMessage->item(0)->nodeValue;
// var_dump ( $responseXML );
return false;
}
$rates = $xpath->query('/eparcel/ratesAndServicesResponse/product');
foreach($rates as $eachRate) {
$tempArray = array();
foreach($eachRate->childNodes as $eachChild) {
if( $eachChild->tagName != "" )
$tempArray[$eachChild->tagName] = $eachChild->nodeValue;
}
$rArray['product'][] = $tempArray;
}
$packingInfo = $xpath->query('/eparcel/ratesAndServicesResponse/shippingOptions');
foreach($packingInfo as $eachPack ) {
$tempArray = array();
foreach($eachPack->childNodes as $eachChild) {
if( $eachChild->tagName != "" )
$tempArray[$eachChild->tagName] = $eachChild->nodeValue;
}
$rArray['shippingOptions'] = $tempArray;
}
return $rArray;
}
}
/**
* This Method prepares the XML to be send to Canada Posts's Server.
* @return none
*/
public function prepareXML() {
$sendXML = new DomDocument("1.0");
$eParcel = $sendXML->createElement("eparcel");
$eParcel->appendChild( $sendXML->createElement('language', 'en') );
$rSRequest = $sendXML->createElement("ratesAndServicesRequest");
foreach($this->merchatInfo as $tag=>$value) {
$rSRequest->appendChild( $sendXML->createElement($tag, $value) );
}
$lineItems = $sendXML->createElement('lineItems');
foreach($this->productInfo as $eachProduct ) {
$eachItems = $sendXML->createElement('item');
foreach($eachProduct as $eachKey=>$eachValue) {
$eachItems->appendChild( $sendXML->createElement($eachKey,$eachValue) );
}
$lineItems->appendChild($eachItems);
}
$rSRequest->appendChild( $lineItems );
foreach($this->customerInfo as $tag=>$value) {
$rSRequest->appendChild( $sendXML->createElement($tag, $value) );
}
$eParcel->appendChild( $rSRequest );
$sendXML->appendChild( $eParcel );
$sendXML->formatOutput = true;
return $sendXML->saveXML();
}
/**
*
* @return String Returns Error Message if applicable
*/
public function getErrorMessage() {
return $this->errorMessage['message'];
}
/**
*
* @return array of Error Message
*/
public function getError() {
return $this->errorMessage;
}
/*** ***/
public function getSendXML() {
return $this->sendXML;
}
public function getResponseXML() {
return $this->responseXML;
}
}