[ Index ] |
PHP Cross Reference of osCMax 2.0.4 |
[Summary view] [Print] [Text view]
1 <?php 2 3 $server = 'test'; // which fedex server to use: test or production 4 $request_referer = 'localhost'; // base url for site, e.g.: 'yoursite.com' 5 6 /* 7 $Id: fedexdc.php 3 2006-05-27 04:59:07Z user $ 8 Copyright 2006 osCMax2003 Vermonster LLC 9 All rights reserved. 10 11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Lesser General Public 13 License as published by the Free Software Foundation; either 14 version 2.1 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Lesser General Public License for more details. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this library; if not, write to the Free Software 23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 25 26 -------------------------------------------------------------------- 27 FedEx-DirectConnect - PHP interface to FedEx Direct Connect API 28 29 This class has been developed to send transactions to FedEx's 30 Ship Manager Direct API. It can be used for all transactions 31 the API can support. For more detailed information please 32 referer to FedEx's documentation located at their website. 33 http://www.fedex.com/us/solutions/wis/. Here you will be able 34 to download "TagTransGuide.pdf" which outlines all the FedEx 35 codes needed to send calls to their API. 36 37 This class requires you have PHP CURL support. 38 39 To submit a transaction to FedEx's Gateway server you must have a valid 40 FedEx Account Number and a FedEx Meter Number. To gain access 41 and receive a Meter Number you must send a Subscribe () request to 42 FedEx containing your FedEx account number and contact information. 43 44 Questions, Comments 45 46 Jay Powers 47 [email protected] 48 49 Vermonster LLC 50 312 Stuart St. 51 Boston, MA 02116 52 53 */ 54 55 // check for test or production gateway 56 if ($server == 'test') { 57 define('FEDEX_URI', 'https://gatewaybeta.fedex.com/GatewayDC', true); 58 define('FEDEX_HOST', 'gatewaybeta.fedex.com', true); 59 } 60 elseif ($server == 'production') { 61 define('FEDEX_URI', 'https://gateway.fedex.com/GatewayDC', true); 62 define('FEDEX_HOST', 'gateway.fedex.com', true); 63 } 64 65 define('REQUEST_REFERER', $request_referer, true); 66 define('REQUEST_TIMEOUT', 10, true); 67 define('REQUEST_TYPE', 'CURL', true); 68 69 class FedExDC { 70 71 var $VERSION = '0.3'; 72 var $NAME = 'FedExDC'; 73 var $ERROR_STR = false; 74 75 //this will be the field returned by FedEx 76 //containing the binary image data 77 var $image_key; 78 79 // FedEx API URI 80 var $fedex_uri; 81 82 // referer host 83 var $referer; 84 85 // set the timeout 86 var $timeout; 87 88 /** 89 * load FedEx UTIs => Transaction Types, Applicable Carrier 90 * 91 * @var FE_TT 92 * @access public 93 */ 94 var $FE_TT = array ( 95 '1002' => array ('007','FDXG'), 96 '1005' => array ('023','FDXE'), 97 '2016' => array ('021','FDXE'), 98 '2017' => array ('022','FDXE'), 99 '2018' => array ('019','FDXE'), 100 '2024' => array ('025',''), 101 '2025' => array ('410',''), 102 '3000' => array ('021','FDXG'), 103 '3001' => array ('023','FDXG'), 104 '3003' => array ('211',''), 105 '3004' => array ('022','FDXG'), 106 '5000' => array ('402',''), 107 '5001' => array ('405',''), 108 '5002' => array ('403','') 109 ); 110 111 /** 112 * constructor: loads account# and meter# 113 * 114 * @param int $account FedEx Account number 115 * @param int $meter FedEx meter number 116 * @param array $params Associative array of parameters listed: 117 * fedex_uri: FedEx API URI 118 fedex_host: Host for FedEx 119 referer: Referering Host 120 timeout: Connection timeout in seconds. 121 * 122 * @access public 123 */ 124 function FedExDC ($account='', $meter='', $params = array()) { 125 $this->account = $account; 126 $this->meter = $meter; 127 $this->time_start = $this->getmicrotime(); 128 129 130 // param defaults 131 $this->fedex_uri = FEDEX_URI; 132 $this->fedex_host = FEDEX_HOST; 133 $this->referer = REQUEST_REFERER; 134 $this->timeout = REQUEST_TIMEOUT; 135 $this->image_key = 188; 136 foreach ($params as $key => $value) { 137 $this->{$key} = $value; 138 } 139 140 } 141 142 /** 143 * Sets debug information 144 * 145 * @param string $string debug data 146 * @access private 147 */ 148 function debug($string){ 149 $this->debug_str .= get_class($this).": $string\n"; 150 } 151 152 /** 153 * returns error string if present 154 * 155 * @return boolean string 156 * @access public 157 */ 158 function getError(){ 159 if($this->ERROR_STR != ""){ 160 return $this->ERROR_STR; 161 } 162 return false; 163 } 164 165 /** 166 * sets error string 167 * 168 * @param string $str 169 * @access private 170 */ 171 function setError($str){ 172 $this->ERROR_STR .= $str; 173 } 174 175 /** 176 * microtime 177 * 178 * @return float 179 * @access private 180 */ 181 function getmicrotime(){ 182 list($usec, $sec) = explode(" ",microtime()); 183 return ((float)$usec + (float)$sec); 184 } 185 186 /** 187 * creates FedEx buffer string 188 * 189 * @param int $uti FedEx transaction UTI 190 * @param array $vals values to send to FedEx 191 * @return string 192 * @access public 193 */ 194 function setData($uti, $vals) { 195 $this->sBuf = ''; 196 if (empty($vals[0])) $vals[0] = $this->FE_TT[$uti][0]; 197 if (empty($vals[3025])) $vals[3025] = $this->FE_TT[$uti][1]; 198 if (isset($this->account) and !array_key_exists(10, $vals)) $this->sBuf .= '10,"' . $this->account . '"'; 199 if (isset($this->meter) and !array_key_exists(498, $vals)) $this->sBuf .= '498,"' .$this->meter. '"'; 200 foreach ($vals as $key => $val) { 201 if (preg_match('/^([0-9]+)\-?[0-9]?$/', $key)) { //let users use the hyphenated number fields 202 $this->sBuf .= "$key,\"$val\""; 203 } else { continue; } 204 } 205 $time = $this->getmicrotime() - $this->time_start; 206 $this->debug('setData: build FedEx string ('. $time.')'); 207 return $this->sBuf .= '99,""'; 208 } 209 210 /** 211 * parses FedEx return string into assoc array 212 * 213 * @return array FedEx return values 214 * @access public 215 */ 216 function _splitData(){ 217 $this->rHash = array(); 218 $count=0; 219 $st_key = 0; // start the first key at 0 220 $aFedRet = preg_split('/,"/s', $this->httpBody); 221 foreach ($aFedRet as $chunk) { 222 preg_match('/(.*)"([\d+\-?]+)/s', $chunk, $match); 223 if (empty($match[1])) continue; 224 if ($st_key == 99) continue; 225 $this->rHash[$st_key] = $match[1]; 226 $st_key = $match[2]; //this will be the next key 227 } 228 $time = $this->getmicrotime() - $this->time_start; 229 $this->debug('_splitData: Parse FedEx response ('. $time.')'); 230 if ($this->rHash[2]) { 231 $this->setError("FedEx Return Error ". $this->rHash[2]." : ".$this->rHash[3]); 232 } 233 return $this->rHash; 234 } 235 236 /** 237 * decode binary label data 238 * 239 * @param string $label_file file to save label on disk 240 * @return mixed 241 * @access public 242 */ 243 function label($label_file=false) { 244 $this->httpLabel = $this->rHash[$this->image_key]; 245 if ($this->httpLabel = preg_replace('/%([0-9][0-9])/e', "chr(hexdec($1))", $this->httpLabel)) { 246 $this->debug('separate binary image data'); 247 $this->debug('decoded binary label data'); 248 } 249 if ($label_file) { 250 $this->debug('label: trying to write out label to '. $label_file); 251 $FH = fopen ($label_file, "w+b"); 252 if (!fwrite($FH, $this->httpLabel)) { 253 $this->setError("Can't write to file $label_file"); 254 return false; 255 } 256 fclose($FH); 257 } else { 258 return $this->httpLabel; 259 } 260 261 } 262 /** 263 * prepares and sends request to FedEx API 264 * 265 * @param string $buf pre-formatted FedEx buffer 266 * @return mixed 267 * @access public 268 */ 269 function transaction($buf=false) { 270 if ($buf) $this->sBuf = $buf; 271 272 // Future design to allow different types of requests 273 if (REQUEST_TYPE == 'CURL') { 274 $meth = '_sendCurl'; 275 } 276 if ($this->$meth()) { 277 $this->_splitData(); 278 return $this->rHash; 279 } else { 280 return false; 281 } 282 } 283 284 /** 285 * sends a request to FedEx using cUrl 286 * 287 * @return string 288 * @access private 289 */ 290 function _sendCurl() { 291 $ch = curl_init(); 292 curl_setopt($ch, CURLOPT_URL, $this->fedex_uri); 293 curl_setopt($ch, CURLOPT_HEADER, 1); 294 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 295 curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); 296 curl_setopt($ch, CURLOPT_POST, 1); 297 curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 298 curl_setopt($ch, CURLOPT_HTTPHEADER, array( 299 'Referer: '. $this->referer 300 ,'Host: ' . $this->fedex_host 301 ,'User-Agent: '. $this->NAME .'-'. $this->VERSION . ' class ( http://vermonster.com/ )' 302 ,'Accept: image/gif, image/jpeg, image/pjpeg, text/plain, text/html, */*' 303 ,'Content-Type: image/gif' 304 ,'Content-Length: '. strlen($this->sBuf) 305 )); 306 curl_setopt( $ch, CURLOPT_POSTFIELDS, $this->sBuf ); 307 $this->debug('Sending to FedEx with data length: '.strlen($this->sBuf)); 308 // write to file for testing 309 $fp = fopen('images/fedex/post.txt', 'w'); 310 fwrite($fp, ($this->sBuf)); 311 312 $this->httpData = curl_exec($ch); 313 if (curl_errno($ch) != 0){ 314 $err = "cURL ERROR: ".curl_errno($ch).": ".curl_error($ch)."<br>"; 315 $this->setError($err); 316 curl_close($ch); 317 return false; 318 } 319 curl_close($ch); 320 321 // separate content from HTTP headers 322 if(ereg("^(.*)\r?\n\r?\n", $this->httpData)) { 323 $this->debug("found proper headers and document"); 324 $this->httpBody = ereg_replace("^[^<]*\r\n\r\n","", $this->httpData); 325 $this->debug("remove headers, body length: ".strlen($this->httpBody)); 326 } else { 327 $this->debug("headers and body are not properly separated"); 328 $this->setError('headers and body are not properly separated'); 329 return false; 330 } 331 332 if(strlen($this->httpBody) == 0){ 333 $this->debug("body contains no data"); 334 $this->setError("body contains no data"); 335 return false; 336 } 337 $time = $this->getmicrotime() - $this->time_start; 338 $this->debug('Got response from FedEx ('. $time.')'); 339 return $this->httpBody; 340 } 341 342 343 /* Below are methods for each of FedEx's services 344 I thought this would be easier as all the 345 functions are the same except for the setData 346 UTI value. If someone knows how to create dynamic 347 functions in PHP (Perl has an AUTOLOAD method) I could 348 just use an array to create all these methods on the fly. 349 */ 350 351 352 /** 353 * close ground shipments 354 * 355 * @param $aData array values to send to FedEx 356 * @return string 357 * @access private 358 */ 359 function close_ground ($aData) { 360 $this->setData(1002, $aData); 361 if ($aRet = $this->transaction()) { 362 return $aRet; 363 } else { 364 $this->setError('unable to process close_ground'); 365 return false; 366 } 367 } 368 369 /** 370 * cancel an express shipment 371 * 372 * @param $aData array values to send to FedEx 373 * @return string 374 * @access private 375 */ 376 function cancel_express ($aData) { 377 $this->setData(1005, $aData); 378 if ($aRet = $this->transaction()) { 379 return $aRet; 380 } else { 381 $this->setError('unable to process cancel_express'); 382 return false; 383 } 384 } 385 386 /** 387 * send an express shipment 388 * 389 * @param $aData array values to send to FedEx 390 * @return string 391 * @access private 392 */ 393 function ship_express ($aData) { 394 $this->setData(2016, $aData); 395 if ($aRet = $this->transaction()) { 396 return $aRet; 397 } else { 398 $this->setError('unable to process ship_express'); 399 return false; 400 } 401 } 402 403 /** 404 * global rate available services 405 * 406 * @param $aData array values to send to FedEx 407 * @return string 408 * @access private 409 */ 410 function global_rate_express ($aData) { 411 $this->setData(2017, $aData); 412 if ($aRet = $this->transaction()) { 413 return $aRet; 414 } else { 415 $this->setError('unable to process global_rate'); 416 return false; 417 } 418 } 419 420 /** 421 * FedEx service availability 422 * 423 * @param $aData array values to send to FedEx 424 * @return string 425 * @access private 426 */ 427 function service_avail ($aData) { 428 $this->setData(2018, $aData); 429 if ($aRet = $this->transaction()) { 430 return $aRet; 431 } else { 432 $this->setError('unable to process service_avail'); 433 return false; 434 } 435 } 436 437 /** 438 * rate all available services 439 * 440 * @param $aData array values to send to FedEx 441 * @return string 442 * @access private 443 */ 444 function rate_services ($aData) { 445 $this->setData(2024, $aData); 446 if ($aRet = $this->transaction()) { 447 return $aRet; 448 } else { 449 $this->setError('unable to process rate_services'); 450 return false; 451 } 452 } 453 454 /** 455 * Locate FedEx services 456 * 457 * @param $aData array values to send to FedEx 458 * @return string 459 * @access private 460 */ 461 function fedex_locater ($aData) { 462 $this->setData(2025, $aData); 463 if ($aRet = $this->transaction()) { 464 return $aRet; 465 } else { 466 $this->setError('unable to process fedex_locater'); 467 return false; 468 } 469 } 470 471 /** 472 * send a ground shipment 473 * 474 * @param $aData array values to send to FedEx 475 * @return string 476 * @access private 477 */ 478 function ship_ground ($aData) { 479 $this->setData(3000, $aData); 480 if ($aRet = $this->transaction()) { 481 return $aRet; 482 } else { 483 $this->setError('unable to process ship_ground'); 484 return false; 485 } 486 } 487 488 /** 489 * cancel ground shipments 490 * 491 * @param $aData array values to send to FedEx 492 * @return string 493 * @access private 494 */ 495 function cancel_ground ($aData) { 496 $this->setData(3001, $aData); 497 if ($aRet = $this->transaction()) { 498 return $aRet; 499 } else { 500 $this->setError('unable to process cancel_ground'); 501 return false; 502 } 503 } 504 505 /** 506 * Subscribe to FedEx API 507 * 508 * @param $aData array values to send to FedEx 509 * @return string 510 * @access private 511 */ 512 function subscribe ($aData) { 513 $this->setData(3003, $aData); 514 if ($aRet = $this->transaction()) { 515 return $aRet; 516 } else { 517 $this->setError('unable to process subscribe'); 518 return false; 519 } 520 } 521 522 /** 523 * global rate available services 524 * 525 * @param $aData array values to send to FedEx 526 * @return string 527 * @access private 528 */ 529 function global_rate_ground ($aData) { 530 $this->setData(3004, $aData); 531 if ($aRet = $this->transaction()) { 532 return $aRet; 533 } else { 534 $this->setError('unable to process global_rate'); 535 return false; 536 } 537 } 538 539 /** 540 * Signature Proof of Delivery 541 * 542 * @param $aData array values to send to FedEx 543 * @return string 544 * @access private 545 */ 546 function sig_proof_delivery ($aData) { 547 $this->image_key = 1471; 548 $this->setData(5001, $aData); 549 if ($aRet = $this->transaction()) { 550 return $aRet; 551 } else { 552 $this->setError('unable to process sig_proof_delivery'); 553 return false; 554 } 555 } 556 557 /** 558 * Track a shipment by tracking number 559 * 560 * @param $aData array values to send to FedEx 561 * @return string 562 * @access private 563 */ 564 function track ($aData) { 565 $this->setData(5000, $aData); 566 if ($aRet = $this->transaction()) { 567 return $aRet; 568 } else { 569 $this->setError('unable to process track'); 570 return false; 571 } 572 } 573 574 /** 575 * Track By Number, Destination, Ship Date, and Reference 576 * 577 * @param $aData array values to send to FedEx 578 * @return string 579 * @access private 580 */ 581 function ref_track ($aData) { 582 $this->setData(5002, $aData); 583 if ($aRet = $this->transaction()) { 584 return $aRet; 585 } else { 586 $this->setError('unable to process ref_track'); 587 return false; 588 } 589 } 590 } 591 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Jan 1 13:43:16 2010 | Cross-referenced by PHPXref 0.7 |