Skip to content

Add 'simple' Address Validation option #119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,32 @@ Tracking API, Shipping API, Rating API and Time in Transit API. Feel free to con
3. [Address Validation Class](#addressvalidation-class)
* [Example](#addressvalidation-class-example)
* [Parameters](#addressvalidation-class-parameters)
4. [QuantumView Class](#quantumview-class)
4. [Simple Address Validation Class](#simple-addressvalidation-class)
* [Example](#simple-addressvalidation-class-example)
* [Parameters](#simple-addressvalidation-class-parameters)
5. [QuantumView Class](#quantumview-class)
* [Example](#quantumview-class-example)
* [Parameters](#quantumview-class-parameters)
5. [Tracking Class](#tracking-class)
6. [Tracking Class](#tracking-class)
* [Example](#tracking-class-example)
* [Parameters](#tracking-class-parameters)
6. [Rate Class](#rate-class)
7. [Rate Class](#rate-class)
* [Example](#rate-class-example)
* [Parameters](#rate-class-parameters)
7. [TimeInTransit Class](#timeintransit-class)
8. [TimeInTransit Class](#timeintransit-class)
* [Example](#timeintransit-class-example)
* [Parameters](#timeintransit-class-parameters)
8. [Locator Class](#locator-class)
9. [Locator Class](#locator-class)
* [Example](#locator-class-example)
* [Parameters](#locator-class-parameters)
9. [Tradeability Class](#tradeability-class)
10. [Tradeability Class](#tradeability-class)
* [Example](#tradeability-class-example)
* [Parameters](#tradeability-class-parameters)
10. [Shipping Class](#shipping-class)
11. [Shipping Class](#shipping-class)
* [Example](#shipping-class-example)
* [Parameters](#shipping-class-parameters)
11. [Logging](#logging)
12. [License](#license-section)
12. [Logging](#logging)
13. [License](#license-section)

<a name="requirements"></a>
## Requirements
Expand Down Expand Up @@ -133,6 +136,41 @@ Address Validation parameters are:
* `address` Address object as constructed in example
* `requestOption` One of the three request options. See documentation. Default = Address Validation.
* `maxSuggestion` Maximum number of suggestions to be returned. Max = 50

<a name="simple-addressvalidation-class"></a>
## Simple Address Validation Class

The Address Validation Class allow you to validate less extensive as the previous class, but it's supported in more countries. It returns a quality score of the supplied address and provides alternatives.

Note: UPS has two Address Validations. This is supported in more countries, but offers less functionality.

Not all countries are supported, see UPS documentation.

<a name="simple-addressvalidation-class-example"></a>
### Example

```php
$address = new \Ups\Entity\Address();
$address->setStateProvinceCode('NY');
$address->setCity('New York');
$address->setCountryCode('US');
$address->setPostalCode('10000');

$av = new \Ups\SimpleAddressValidation($accessKey, $userId, $password);
try {
$response = $av->validate($address);
var_dump($response);
} catch (Exception $e) {
var_dump($e);
}
```

<a name="simpleaddressvalidation-class-parameters"></a>
### Parameters

Simple Address Validation parameters are:

* `address` Address object as constructed in example

<a name="quantumview-class"></a>
## QuantumView Class
Expand Down
12 changes: 8 additions & 4 deletions src/AddressValidation.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

/**
* Address Validation API Wrapper.
*
* This functionality is only available in USA, Puerto Rico & Canada.
*/
class AddressValidation extends Ups
{
Expand Down Expand Up @@ -43,6 +45,7 @@ class AddressValidation extends Ups
* @var int
*/
private $maxSuggestion;

/**
* @var bool
*/
Expand Down Expand Up @@ -92,18 +95,19 @@ public function deActivateReturnObjectOnValidate()
{
$this->useAVResponseObject = false;
}

/**
* Get address suggestions from UPS.
* Get address suggestions from UPS using the 'Street Level' Address Validation API (/XAV)
*
* @param $address
* @param Address $address
* @param int $requestOption
* @param int $maxSuggestion
*
* @throws Exception
*
* @return stdClass|AddressValidationResponse
*/
public function validate($address, $requestOption = self::REQUEST_OPTION_ADDRESS_VALIDATION, $maxSuggestion = 15)
public function validate(Address $address, $requestOption = self::REQUEST_OPTION_ADDRESS_VALIDATION, $maxSuggestion = 15)
{
if ($maxSuggestion > 50) {
throw new \Exception('Maximum of 50 suggestions allowed');
Expand Down Expand Up @@ -223,7 +227,7 @@ private function formatResponse(SimpleXMLElement $response)
public function getRequest()
{
if (null === $this->request) {
$this->request = new Request();
$this->request = new Request($this->logger);
}

return $this->request;
Expand Down
195 changes: 195 additions & 0 deletions src/SimpleAddressValidation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php

namespace Ups;

use DOMDocument;
use Exception;
use Psr\Log\LoggerInterface;
use SimpleXMLElement;
use stdClass;
use Ups\Entity\Address;
use Ups\Entity\AddressValidationResponse;

/**
* Address Validation API Wrapper to use the basic Address Validation endpoints.
*
* This functionality is more basic, but available in more countries than the 'extended' Address Validation methods.
*/
class SimpleAddressValidation extends Ups
{
const ENDPOINT = '/AV';

/**
* @var RequestInterface
*/
private $request;

/**
* @var ResponseInterface
*
* @todo make private
*/
public $response;

/**
* @var Address
*/
private $address;

/**
* @param string|null $accessKey UPS License Access Key
* @param string|null $userId UPS User ID
* @param string|null $password UPS User Password
* @param bool $useIntegration Determine if we should use production or CIE URLs.
* @param RequestInterface|null $request
* @param LoggerInterface|null $logger PSR3 compatible logger (optional)
*/
public function __construct(
$accessKey = null,
$userId = null,
$password = null,
$useIntegration = false,
RequestInterface $request = null,
LoggerInterface $logger = null
) {
if (null !== $request) {
$this->setRequest($request);
}
parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
}

/**
* Get address suggestions from UPS using the default Address Validation API (/AV)
*
* @param Address $address
*
* @throws Exception
*
* @return array
*/
public function validate(Address $address)
{
$this->address = $address;

$access = $this->createAccess();
$request = $this->createRequest();

$this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
$response = $this->response->getResponse();

if (null === $response) {
throw new Exception('Failure (0): Unknown error', 0);
}

if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
throw new Exception(
"Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
(int)$response->Response->Error->ErrorCode
);
}

return $this->formatResponse($response);
}

/**
* Create the AV request.
*
* @return string
*/
private function createRequest()
{
$xml = new DOMDocument();
$xml->formatOutput = true;

$avRequest = $xml->appendChild($xml->createElement('AddressValidationRequest'));
$avRequest->setAttribute('xml:lang', 'en-US');

$request = $avRequest->appendChild($xml->createElement('Request'));

$node = $xml->importNode($this->createTransactionNode(), true);
$request->appendChild($node);

$request->appendChild($xml->createElement('RequestAction', 'AV'));

if (null !== $this->address) {
$addressNode = $avRequest->appendChild($xml->createElement('Address'));

if ($this->address->getStateProvinceCode()) {
$addressNode->appendChild($xml->createElement('StateProvinceCode', $this->address->getStateProvinceCode()));
}
if ($this->address->getCity()) {
$addressNode->appendChild($xml->createElement('City', $this->address->getCity()));
}
if ($this->address->getCountryCode()) {
$addressNode->appendChild($xml->createElement('CountryCode', $this->address->getCountryCode()));
}
if ($this->address->getPostalCode()) {
$addressNode->appendChild($xml->createElement('PostalCode', $this->address->getPostalCode()));
}
}

return $xml->saveXML();
}

/**
* Format the response.
*
* @param SimpleXMLElement $response
*
* @return array
*/
private function formatResponse(SimpleXMLElement $response)
{
$result = $this->convertXmlObject($response);

if (!is_array($result->AddressValidationResult)) {
return [$result->AddressValidationResult];
}

return $result->AddressValidationResult;
}

/**
* @return RequestInterface
*/
public function getRequest()
{
if (null === $this->request) {
$this->request = new Request($this->logger);
}

return $this->request;
}

/**
* @param RequestInterface $request
*
* @return $this
*/
public function setRequest(RequestInterface $request)
{
$this->request = $request;

return $this;
}

/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}

/**
* @param ResponseInterface $response
*
* @return $this
*/
public function setResponse(ResponseInterface $response)
{
$this->response = $response;

return $this;
}
}
Loading