A modest collection of PHP libraries used at SparkFun.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

245 lines
6.6 KiB

<?php
namespace SparkLib\UPS;
use SparkLib\UPS\StreetAddressValidate\AddressKeyFormatType,
SparkLib\UPS\StreetAddressValidate\RequestType,
SparkLib\UPS\StreetAddressValidate\ServiceAccessToken,
SparkLib\UPS\StreetAddressValidate\StreetAddressValidateException,
SparkLib\UPS\StreetAddressValidate\UPSSecurity,
SparkLib\UPS\StreetAddressValidate\UsernameToken,
SparkLib\UPS\StreetAddressValidate\XAVRequest;
use DOMDocument,
SoapClient,
SoapHeader,
SoapFault;
class StreetAddressValidate {
const UNKNOWN = 0;
const COMMERCIAL = 1;
const RESIDENTIAL = 2;
const INVALID = 0;
const VALID = 1;
const AMBIGUOUS = 2;
const OPTION_VALIDATE = 1;
const OPTION_CLASSIFY = 2;
const OPTION_BOTH = 3;
private $_wsdl = UPS_XAV_WSDL;
private $_endpoint = UPS_XAV_SERVER;
private $_schema = UPS_SCHEMA;
private $_user = UPS_USERID;
private $_pass = UPS_USERPASS;
private $_key = UPS_APIKEY;
private $_client;
private $_response;
private $_requestOption;
private $_streetAddress;
public function __construct($countryCode = 'US') {
$this->initAddress();
$this->setCountryCode($countryCode);
}
private function initAddress() {
if (! isset($this->_streetAddress))
$this->_streetAddress = new AddressKeyFormatType();
}
public function setName($name) {
$name = $name;
$this->_streetAddress->setConsigneeName($name);
return $this;
}
public function setAddressLine($address) {
if (! is_array($address))
$address = [ $address ];
$this->_streetAddress->setAddressLine($address);
return $this;
}
public function setProvince($province) {
$province = $province;
$this->_streetAddress->setPoliticalDivision1($province);
return $this;
}
public function setState($state) {
$state = $state;
return $this->setProvince($state);
}
public function setCity($city) {
$city = $city;
$this->_streetAddress->setPoliticalDivision2($city);
return $this;
}
public function setZipcode($zip) {
$parts = [];
if (preg_match('/([a-zA-Z0-9]{5})[\-\+_\s]?(\d{4})?/', trim($zip), $parts)) {
$this->setPostcode($parts[1]);
if(isset($parts[2]))
$this->setPlusFour($parts[2]);
}
return $this;
}
public function setPostcode($postcode) {
$this->_streetAddress->setPostcodePrimaryLow($postcode);
return $this;
}
public function setPlusFour($plusFour) {
$plusFour = trim($plusFour);
$code = $this->getCountryCode();
if (! $code) {
throw new StreetAddressValidateException('Must set country code before setting plus four zip code.');
} else if ($code != 'US') {
throw new StreetAddressValidateException('Plus four can only be used for U.S. addresses.');
} else if (! preg_match('/\d{4}/', $plusFour)) {
throw new StreetAddressValidateException('Plus four must be exactly four digits.');
} else {
$this->_streetAddress->setPostcodeExtendedLow($plusFour);
}
return $this;
}
private function getCountryCode() {
if (isset($this->_streetAddress) && isset($this->_streetAddress->CountryCode))
return $this->_streetAddress->CountryCode;
}
public function setCountryCode($code = 'US') {
if ($code == 'US') {
$this->_requestOption = self::OPTION_BOTH;
} else if ($code == 'PR') {
$this->_requestOption = self::OPTION_VALIDATE;
} else if ($code == 'CA') {
$this->_requestOption = self::OPTION_CLASSIFY;
} else {
throw new StreetAddressValidateException(
'Street address validation can only be performed for addresses in ' .
'the U.S., Puerto Rico, and Canada.'
);
}
$this->_streetAddress->setCountryCode($code);
return $this;
}
public function send() {
$RequestType = new RequestType(self::OPTION_BOTH);
$request = new XAVRequest($RequestType, null, null, $this->_streetAddress);
$UsernameToken = new UsernameToken();
$ServiceAccessToken = new ServiceAccessToken();
$UPSSecurity = new UPSSecurity($UsernameToken, $ServiceAccessToken);
$UsernameToken->setUsername($this->_user);
$UsernameToken->setPassword($this->_pass);
$ServiceAccessToken->setAccessLicenseNumber($this->_key);
$header = new SoapHeader($this->_schema, 'UPSSecurity', $UPSSecurity);
$options = [
'soap_version' => 'SOAP_1_1',
'exceptions' => true,
'location' => $this->_endpoint,
'trace' => true
];
$wsdl = $this->_wsdl;
$this->_client = new SoapClient($wsdl, $options);
$this->_client->__setSoapHeaders($header);
try {
$this->_response = $this->_client->ProcessXAV($request, $options);
} catch (SoapFault $s) {
if (isset($s->detail)) {
$err = $s->detail->Errors->ErrorDetail->PrimaryErrorCode->Description;
throw new StreetAddressValidateException($err);
}
}
return $this;
}
public function getAddressClassification() {
if (! isset($this->_response))
throw new StreetAddressValidateException('No server response has been set.');
if ($this->getCountryCode() == 'PR')
throw new StreetAddressValidateException('Cannot validate Puerto Rico addresses.');
if (isset($this->_response->ValidAddressIndicator))
return intval($this->_response->AddressClassification->Code);
return static::UNKNOWN;
}
public function isResidential() {
return $this->getAddressClassification() == static::RESIDENTIAL;
}
public function isCommercial() {
return $this->getAddressClassification() == static::COMMERCIAL;
}
public function getAddressValidity() {
if (! isset($this->_response))
throw new StreetAddressValidateException('No server response has been set.');
if (isset($this->_response->ValidAddressIndicator))
return static::VALID;
else if (isset($this->_response->NoCandidates))
return static::INVALID;
else if (isset($this->_response->AmbiguousAddressIndicator))
return static::AMBIGUOUS;
}
public function valid() {
return $this->getAddressValidity() == static::VALID;
}
public function getLastRequest() {
$request = $this->_client->__getLastRequest();
if ($request) {
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->formatOutput = TRUE;
$dom->loadXML($request);
return $dom->saveXml();
}
}
public function getLastResponse() {
$request = $this->_client->__getLastResponse();
if ($request) {
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->formatOutput = TRUE;
$dom->loadXML($request);
return $dom->saveXml();
}
}
}