Completed
Push — master ( 5ec83a...077a27 )
by Stefan
04:10
created

AddressValidation::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 7
Ratio 53.85 %

Code Coverage

Tests 4
CRAP Score 2.1481

Importance

Changes 0
Metric Value
dl 7
loc 13
ccs 4
cts 6
cp 0.6667
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 10
nc 2
nop 6
crap 2.1481
1
<?php
2
3
namespace Ups;
4
5
use DOMDocument;
6
use Exception;
7
use Psr\Log\LoggerInterface;
8
use SimpleXMLElement;
9
use stdClass;
10
use Ups\Entity\Address;
11
use Ups\Entity\AddressValidationResponse;
12
13
/**
14
 * Address Validation API Wrapper.
15
 *
16
 * This functionality is only available in USA, Puerto Rico & Canada.
17
 */
18
class AddressValidation extends Ups
19
{
20
    const ENDPOINT = '/XAV';
21
22
    /**
23
     * @var RequestInterface
24
     */
25
    private $request;
26
27
    /**
28
     * @var ResponseInterface
29
     *
30
     * @todo make private
31
     */
32
    public $response;
33
34
    /**
35
     * @var int
36
     */
37
    private $requestOption;
38
39
    /**
40
     * @var Address
41
     */
42
    private $address;
43
44
    /**
45
     * @var int
46
     */
47
    private $maxSuggestion;
48
49
    /**
50
     * @var bool
51
     */
52
    private $useAVResponseObject = false;
53
54
    /**
55
     * Request Options.
56
     */
57
    const REQUEST_OPTION_ADDRESS_VALIDATION = 1;
58
    const REQUEST_OPTION_ADDRESS_CLASSIFICATION = 2;
59
    const REQUEST_OPTION_ADDRESS_VALIDATION_AND_CLASSIFICATION = 3;
60
61
    /**
62
     * @param string|null $accessKey UPS License Access Key
63
     * @param string|null $userId UPS User ID
64
     * @param string|null $password UPS User Password
65
     * @param bool $useIntegration Determine if we should use production or CIE URLs.
66
     * @param RequestInterface|null $request
67
     * @param LoggerInterface|null $logger PSR3 compatible logger (optional)
68
     */
69 15 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
        $accessKey = null,
71
        $userId = null,
72
        $password = null,
73
        $useIntegration = false,
74
        RequestInterface $request = null,
75
        LoggerInterface $logger = null
76
    ) {
77 15
        if (null !== $request) {
78
            $this->setRequest($request);
79
        }
80 15
        parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
81 15
    }
82
83
    /**
84
     * Turn on returning of the AddressValidationResponse object
85
     */
86 14
    public function activateReturnObjectOnValidate()
87
    {
88 14
        $this->useAVResponseObject = true;
89 14
    }
90
91
    /**
92
     * Turn off returning of the AddressValidationResponse object
93
     */
94
    public function deActivateReturnObjectOnValidate()
95
    {
96
        $this->useAVResponseObject = false;
97
    }
98
99
    /**
100
     * Get address suggestions from UPS using the 'Street Level' Address Validation API (/XAV)
101
     *
102
     * @param Address $address
103
     * @param int $requestOption
104
     * @param int $maxSuggestion
105
     *
106
     * @throws Exception
107
     *
108
     * @return stdClass|AddressValidationResponse
109
     */
110 15
    public function validate(Address $address, $requestOption = self::REQUEST_OPTION_ADDRESS_VALIDATION, $maxSuggestion = 15)
111
    {
112 15
        if ($maxSuggestion > 50) {
113
            throw new \Exception('Maximum of 50 suggestions allowed');
114
        }
115
116 15
        if (!in_array($requestOption, range(1, 3))) {
117 1
            throw new \Exception('Invalid request option supplied');
118
        }
119
120 15
        $this->address = $address;
121 15
        $this->requestOption = $requestOption;
122 15
        $this->maxSuggestion = $maxSuggestion;
123
124 15
        $access = $this->createAccess();
125 15
        $request = $this->createRequest();
126
127 15
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
128 15
        $response = $this->response->getResponse();
129
130 15
        if (null === $response) {
131 1
            throw new Exception('Failure (0): Unknown error', 0);
132
        }
133
134 14
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
135
            throw new Exception(
136
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
137
                (int)$response->Response->Error->ErrorCode
138
            );
139
        }
140 14
        if ($this->useAVResponseObject) {
141 14
            unset($response->Response);
142 14
            $avResponse = new AddressValidationResponse($response, $requestOption);
143 14
            return $avResponse;
144
        }
145
        return $this->formatResponse($response);
146
    }
147
148
    /**
149
     * Create the XAV request.
150
     *
151
     * @return string
152
     */
153 15
    private function createRequest()
154
    {
155 15
        $xml = new DOMDocument();
156 15
        $xml->formatOutput = true;
157
158 15
        $avRequest = $xml->appendChild($xml->createElement('AddressValidationRequest'));
159 15
        $avRequest->setAttribute('xml:lang', 'en-US');
160
161 15
        $request = $avRequest->appendChild($xml->createElement('Request'));
162
163 15
        $node = $xml->importNode($this->createTransactionNode(), true);
164 15
        $request->appendChild($node);
165
166 15
        $request->appendChild($xml->createElement('RequestAction', 'XAV'));
167
168 15
        if (null !== $this->requestOption) {
169 15
            $request->appendChild($xml->createElement('RequestOption', $this->requestOption));
170 15
        }
171
172 15
        if (null !== $this->maxSuggestion) {
173 15
            $avRequest->appendChild($xml->createElement('MaximumListSize', $this->maxSuggestion));
174 15
        }
175
176 15
        if (null !== $this->address) {
177 15
            $addressNode = $avRequest->appendChild($xml->createElement('AddressKeyFormat'));
178
179 15
            if ($this->address->getAttentionName()) {
180 15
                $addressNode->appendChild($xml->createElement('ConsigneeName', $this->address->getAttentionName()));
181 15
            }
182 15
            if ($this->address->getBuildingName()) {
183 15
                $addressNode->appendChild($xml->createElement('BuildingName', $this->address->getBuildingName()));
184 15
            }
185 15
            if ($this->address->getAddressLine1()) {
186 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine1()));
187 15
            }
188 15
            if ($this->address->getAddressLine2()) {
189 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine2()));
190 15
            }
191 15
            if ($this->address->getAddressLine3()) {
192 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine3()));
193 15
            }
194 15
            if ($this->address->getStateProvinceCode()) {
195 15
                $addressNode->appendChild($xml->createElement('PoliticalDivision1',
196 15
                    $this->address->getStateProvinceCode()));
197 15
            }
198 15
            if ($this->address->getCity()) {
199 15
                $addressNode->appendChild($xml->createElement('PoliticalDivision2', $this->address->getCity()));
200 15
            }
201 15
            if ($this->address->getCountryCode()) {
202 15
                $addressNode->appendChild($xml->createElement('CountryCode', $this->address->getCountryCode()));
203 15
            }
204 15
            if ($this->address->getPostalCode()) {
205 15
                $addressNode->appendChild($xml->createElement('PostcodePrimaryLow', $this->address->getPostalCode()));
206 15
            }
207 15
        }
208
209 15
        return $xml->saveXML();
210
    }
211
212
    /**
213
     * Format the response.
214
     *
215
     * @param SimpleXMLElement $response
216
     *
217
     * @return stdClass
218
     */
219
    private function formatResponse(SimpleXMLElement $response)
220
    {
221
        return $this->convertXmlObject($response->AddressKeyFormat);
222
    }
223
224
    /**
225
     * @return RequestInterface
226
     */
227 15
    public function getRequest()
228
    {
229 15
        if (null === $this->request) {
230
            $this->request = new Request($this->logger);
231
        }
232
233 15
        return $this->request;
234
    }
235
236
    /**
237
     * @param RequestInterface $request
238
     *
239
     * @return $this
240
     */
241 15
    public function setRequest(RequestInterface $request)
242
    {
243 15
        $this->request = $request;
244
245 15
        return $this;
246
    }
247
248
    /**
249
     * @return ResponseInterface
250
     */
251
    public function getResponse()
252
    {
253
        return $this->response;
254
    }
255
256
    /**
257
     * @param ResponseInterface $response
258
     *
259
     * @return $this
260
     */
261
    public function setResponse(ResponseInterface $response)
262
    {
263
        $this->response = $response;
264
265
        return $this;
266
    }
267
}
268