diff --git a/README.md b/README.md
index b6b7f541..d704e2b5 100644
--- a/README.md
+++ b/README.md
@@ -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)
## Requirements
@@ -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
+
+
+## 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.
+
+
+### 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);
+}
+```
+
+
+### Parameters
+
+Simple Address Validation parameters are:
+
+* `address` Address object as constructed in example
## QuantumView Class
diff --git a/src/AddressValidation.php b/src/AddressValidation.php
index 62f574b7..b3134996 100644
--- a/src/AddressValidation.php
+++ b/src/AddressValidation.php
@@ -12,6 +12,8 @@
/**
* Address Validation API Wrapper.
+ *
+ * This functionality is only available in USA, Puerto Rico & Canada.
*/
class AddressValidation extends Ups
{
@@ -43,6 +45,7 @@ class AddressValidation extends Ups
* @var int
*/
private $maxSuggestion;
+
/**
* @var bool
*/
@@ -92,10 +95,11 @@ 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
*
@@ -103,7 +107,7 @@ public function deActivateReturnObjectOnValidate()
*
* @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');
@@ -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;
diff --git a/src/SimpleAddressValidation.php b/src/SimpleAddressValidation.php
new file mode 100644
index 00000000..57261c8c
--- /dev/null
+++ b/src/SimpleAddressValidation.php
@@ -0,0 +1,195 @@
+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;
+ }
+}
diff --git a/tests/Ups/Tests/AddressValidationTest.php b/tests/Ups/Tests/AddressValidationTest.php
index 81cc6d5f..dc75f208 100644
--- a/tests/Ups/Tests/AddressValidationTest.php
+++ b/tests/Ups/Tests/AddressValidationTest.php
@@ -35,7 +35,7 @@ public function testCreateRequest()
public function testAddressValidationResponseReturned()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -45,7 +45,7 @@ public function testAddressValidationResponseReturned()
public function testIsValidWhenKnownAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response3.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response3.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -54,7 +54,7 @@ public function testIsValidWhenKnownAddressValidated()
public function testIsValidWhenUnKnownAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -63,7 +63,7 @@ public function testIsValidWhenUnKnownAddressValidated()
public function testNoCandidatesWhenUnknownAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response2.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response2.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -72,7 +72,7 @@ public function testNoCandidatesWhenUnknownAddressValidated()
public function testNoCandidatesWhenKnownAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -81,7 +81,7 @@ public function testNoCandidatesWhenKnownAddressValidated()
public function testIsAmbiguousWhenAmbiguousAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -90,7 +90,7 @@ public function testIsAmbiguousWhenAmbiguousAddressValidated()
public function testIsAmbiguousWhenKnownAddressValidated()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response3.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response3.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address);
@@ -100,7 +100,7 @@ public function testIsAmbiguousWhenKnownAddressValidated()
public function testNoCandidatesThrowsBadMethodExceptionOnClassificationOnlyRequests()
{
$this->setExpectedException('BadMethodCallException');
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response4.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response4.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
@@ -111,7 +111,7 @@ public function testNoCandidatesThrowsBadMethodExceptionOnClassificationOnlyRequ
public function testIsAmbiguousThrowsBadMethodExceptionOnClassificationOnlyRequests()
{
$this->setExpectedException('BadMethodCallException');
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response4.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response4.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
@@ -121,7 +121,7 @@ public function testIsAmbiguousThrowsBadMethodExceptionOnClassificationOnlyReque
public function testIsValidWhenClassificationOnlyRequestsReturnsValidClassification()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response4.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response4.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
AddressValidation::REQUEST_OPTION_ADDRESS_CLASSIFICATION);
@@ -131,7 +131,7 @@ public function testIsValidWhenClassificationOnlyRequestsReturnsValidClassificat
public function testGetAddressClassificationThrowsExceptionOnAddressOnlyRequest()
{
$this->setExpectedException('BadMethodCallException');
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response4.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response4.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address, AddressValidation::REQUEST_OPTION_ADDRESS_VALIDATION);
$response->getAddressClassification();
@@ -139,7 +139,7 @@ public function testGetAddressClassificationThrowsExceptionOnAddressOnlyRequest(
public function testGetAddressClassificationReturnsObject()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
AddressValidation::REQUEST_OPTION_ADDRESS_VALIDATION_AND_CLASSIFICATION);
@@ -149,7 +149,7 @@ public function testGetAddressClassificationReturnsObject()
public function testGetCandidateAddressList()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response1.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response1.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
AddressValidation::REQUEST_OPTION_ADDRESS_VALIDATION_AND_CLASSIFICATION);
@@ -159,7 +159,7 @@ public function testGetCandidateAddressList()
public function testGetValidatedAddressReturnsValidAddressObject()
{
- $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/response3.xml'));
+ $this->xavRequest->setRequest(new RequestMock(null, '/AddressValidation/Response3.xml'));
$this->xavRequest->activateReturnObjectOnValidate();
$response = $this->xavRequest->validate($this->address,
AddressValidation::REQUEST_OPTION_ADDRESS_VALIDATION_AND_CLASSIFICATION);
diff --git a/tests/Ups/Tests/SimpleAddressValidationTest.php b/tests/Ups/Tests/SimpleAddressValidationTest.php
new file mode 100644
index 00000000..cb7182f6
--- /dev/null
+++ b/tests/Ups/Tests/SimpleAddressValidationTest.php
@@ -0,0 +1,72 @@
+setStateProvinceCode('NY');
+ $address->setCity('NYork');
+ $address->setCountryCode('US');
+ $address->setPostalCode('10118');
+
+ $validator->setRequest($request = new RequestMock());
+
+ try {
+ $validator->validate($address);
+ } catch (Exception $e) {
+ }
+
+ $this->assertEquals(
+ $request->getRequestXml(),
+ $request->getExpectedRequestXml('/SimpleAddressValidation/Request1.xml')
+ );
+ }
+
+ public function testResponse()
+ {
+ $validator = new Ups\SimpleAddressValidation();
+ $validator->setRequest($request = new RequestMock(null, '/SimpleAddressValidation/Response1.xml'));
+
+ $address = new \Ups\Entity\Address();
+ $address->setStateProvinceCode('NY');
+ $address->setCity('NYork');
+ $address->setCountryCode('US');
+ $address->setPostalCode('10118');
+ $result = $validator->validate($address);
+
+ // Test response
+ $this->assertInternalType('array', $result);
+ $this->assertCount(6, $result);
+
+ $first = $result[0];
+ $this->assertInstanceOf('stdClass', $first);
+ $this->assertEquals(1, $first->Rank);
+ $this->assertInternalType('string', $first->Quality);
+ $this->assertEquals('0.9875', $first->Quality);
+ $this->assertInstanceOf('stdClass', $first->Address);
+ $this->assertEquals('NEW YORK', $first->Address->City);
+ $this->assertEquals('NY', $first->Address->StateProvinceCode);
+ $this->assertEquals('10118', $first->PostalCodeLowEnd);
+ $this->assertEquals('10118', $first->PostalCodeHighEnd);
+
+ $last = $result[5];
+ $this->assertInstanceOf('stdClass', $last);
+ $this->assertEquals(6, $last->Rank);
+ $this->assertInternalType('string', $last->Quality);
+ $this->assertEquals('0.9875', $last->Quality);
+ $this->assertInstanceOf('stdClass', $last->Address);
+ $this->assertEquals('NYC', $last->Address->City);
+ $this->assertEquals('NY', $last->Address->StateProvinceCode);
+ $this->assertEquals('10118', $last->PostalCodeLowEnd);
+ $this->assertEquals('10118', $last->PostalCodeHighEnd);
+ }
+}
diff --git a/tests/Ups/Tests/_files/requests/SimpleAddressValidation/Request1.xml b/tests/Ups/Tests/_files/requests/SimpleAddressValidation/Request1.xml
new file mode 100644
index 00000000..92874c13
--- /dev/null
+++ b/tests/Ups/Tests/_files/requests/SimpleAddressValidation/Request1.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ AV
+
+
+ NY
+ NYork
+ US
+ 10118
+
+
\ No newline at end of file
diff --git a/tests/Ups/Tests/_files/responses/AddressValidation/response1.xml b/tests/Ups/Tests/_files/responses/AddressValidation/Response1.xml
similarity index 100%
rename from tests/Ups/Tests/_files/responses/AddressValidation/response1.xml
rename to tests/Ups/Tests/_files/responses/AddressValidation/Response1.xml
diff --git a/tests/Ups/Tests/_files/responses/AddressValidation/response2.xml b/tests/Ups/Tests/_files/responses/AddressValidation/Response2.xml
similarity index 100%
rename from tests/Ups/Tests/_files/responses/AddressValidation/response2.xml
rename to tests/Ups/Tests/_files/responses/AddressValidation/Response2.xml
diff --git a/tests/Ups/Tests/_files/responses/AddressValidation/response3.xml b/tests/Ups/Tests/_files/responses/AddressValidation/Response3.xml
similarity index 100%
rename from tests/Ups/Tests/_files/responses/AddressValidation/response3.xml
rename to tests/Ups/Tests/_files/responses/AddressValidation/Response3.xml
diff --git a/tests/Ups/Tests/_files/responses/AddressValidation/response4.xml b/tests/Ups/Tests/_files/responses/AddressValidation/Response4.xml
similarity index 100%
rename from tests/Ups/Tests/_files/responses/AddressValidation/response4.xml
rename to tests/Ups/Tests/_files/responses/AddressValidation/Response4.xml
diff --git a/tests/Ups/Tests/_files/responses/SimpleAddressValidation/Response1.xml b/tests/Ups/Tests/_files/responses/SimpleAddressValidation/Response1.xml
new file mode 100644
index 00000000..6e4844f9
--- /dev/null
+++ b/tests/Ups/Tests/_files/responses/SimpleAddressValidation/Response1.xml
@@ -0,0 +1,68 @@
+
+
+
+
+ 1
+ Success
+
+
+ 1
+ 0.9875
+
+ NEW YORK
+ NY
+
+ 10118
+ 10118
+
+
+ 2
+ 0.9875
+
+ MANHATTAN
+ NY
+
+ 10118
+ 10118
+
+
+ 3
+ 0.9875
+
+ NEW YORK CITY
+ NY
+
+ 10118
+ 10118
+
+
+ 4
+ 0.9875
+
+ NY
+ NY
+
+ 10118
+ 10118
+
+
+ 5
+ 0.9875
+
+ NY CITY
+ NY
+
+ 10118
+ 10118
+
+
+ 6
+ 0.9875
+
+ NYC
+ NY
+
+ 10118
+ 10118
+
+