Completed
Pull Request — master (#80)
by
unknown
03:12
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 5
Bugs 0 Features 3
Metric Value
c 5
b 0
f 3
dl 7
loc 13
ccs 4
cts 6
cp 0.6667
rs 9.4285
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
class AddressValidation extends Ups
17
{
18
    const ENDPOINT = '/XAV';
19
20
    /**
21
     * @var RequestInterface
22
     */
23
    private $request;
24
25
    /**
26
     * @var ResponseInterface
27
     *
28
     * @todo make private
29
     */
30
    public $response;
31
32
    /**
33
     * @var int
34
     */
35
    private $requestOption;
36
37
    /**
38
     * @var Address
39
     */
40
    private $address;
41
42
    /**
43
     * @var int
44
     */
45
    private $maxSuggestion;
46
    /**
47
     * @var bool
48
     */
49
    private $useAVResponseObject = false;
50
51
    /**
52
     * Request Options.
53
     */
54
    const REQUEST_OPTION_ADDRESS_VALIDATION = 1;
55
    const REQUEST_OPTION_ADDRESS_CLASSIFICATION = 2;
56
    const REQUEST_OPTION_ADDRESS_VALIDATION_AND_CLASSIFICATION = 3;
57
58
    /**
59
     * @param string|null $accessKey UPS License Access Key
60
     * @param string|null $userId UPS User ID
61
     * @param string|null $password UPS User Password
62
     * @param bool $useIntegration Determine if we should use production or CIE URLs.
63
     * @param RequestInterface $request
64
     * @param LoggerInterface PSR3 compatible logger (optional)
65
     */
66 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...
67
        $accessKey = null,
68
        $userId = null,
69
        $password = null,
70
        $useIntegration = false,
71
        RequestInterface $request = null,
72
        LoggerInterface $logger = null
73
    ) {
74 15
        if (null !== $request) {
75
            $this->setRequest($request);
76
        }
77 15
        parent::__construct($accessKey, $userId, $password, $useIntegration, $logger);
78 15
    }
79
80
    /**
81
     * Turn on returning of the AddressValidationResponse object
82
     */
83 14
    public function activateReturnObjectOnValidate()
84
    {
85 14
        $this->useAVResponseObject = true;
86 14
    }
87
88
    /**
89
     * Turn off returning of the AddressValidationResponse object
90
     */
91
    public function deActivateReturnObjectOnValidate()
92
    {
93
        $this->useAVResponseObject = false;
94
    }
95
    /**
96
     * Get address suggestions from UPS.
97
     *
98
     * @param $address
99
     * @param int $requestOption
100
     * @param int $maxSuggestion
101
     *
102
     * @throws Exception
103
     *
104
     * @return stdClass|AddressValidationResponse
105
     */
106 15
    public function validate($address, $requestOption = self::REQUEST_OPTION_ADDRESS_VALIDATION, $maxSuggestion = 15)
107
    {
108 15
        if ($maxSuggestion > 50) {
109
            throw new \Exception('Maximum of 50 suggestions allowed');
110
        }
111
112 15
        if (!in_array($requestOption, range(1, 3))) {
113
            throw new \Exception('Invalid request option supplied');
114
        }
115
116 15
        $this->address = $address;
117 15
        $this->requestOption = $requestOption;
118 15
        $this->maxSuggestion = $maxSuggestion;
119
120 15
        $access = $this->createAccess();
121 15
        $request = $this->createRequest();
122
123 15
        $this->response = $this->getRequest()->request($access, $request, $this->compileEndpointUrl(self::ENDPOINT));
124 15
        $response = $this->response->getResponse();
125
126 15
        if (null === $response) {
127 1
            throw new Exception('Failure (0): Unknown error', 0);
128
        }
129
130 14
        if ($response instanceof SimpleXMLElement && $response->Response->ResponseStatusCode == 0) {
131
            throw new Exception(
132
                "Failure ({$response->Response->Error->ErrorSeverity}): {$response->Response->Error->ErrorDescription}",
133
                (int)$response->Response->Error->ErrorCode
134
            );
135
        }
136 14
        if ($this->useAVResponseObject) {
137 14
            unset($response->Response);
138 14
            $avResponse = new AddressValidationResponse($response, $requestOption);
139 14
            return $avResponse;
140
        }
141
        return $this->formatResponse($response);
142
    }
143
144
    /**
145
     * Create the XAV request.
146
     *
147
     * @return string
148
     */
149 15
    private function createRequest()
150
    {
151 15
        $xml = new DOMDocument();
152 15
        $xml->formatOutput = true;
153
154 15
        $avRequest = $xml->appendChild($xml->createElement('AddressValidationRequest'));
155 15
        $avRequest->setAttribute('xml:lang', 'en-US');
156
157 15
        $request = $avRequest->appendChild($xml->createElement('Request'));
158
159 15
        $node = $xml->importNode($this->createTransactionNode(), true);
160 15
        $request->appendChild($node);
161
162 15
        $request->appendChild($xml->createElement('RequestAction', 'XAV'));
163
164 15
        if (null !== $this->requestOption) {
165 15
            $request->appendChild($xml->createElement('RequestOption', $this->requestOption));
166 15
        }
167
168 15
        if (null !== $this->maxSuggestion) {
169 15
            $avRequest->appendChild($xml->createElement('MaximumListSize', $this->maxSuggestion));
170 15
        }
171
172 15
        if (null !== $this->address) {
173 15
            $addressNode = $avRequest->appendChild($xml->createElement('AddressKeyFormat'));
174
175 15
            if ($this->address->getAttentionName()) {
176 15
                $addressNode->appendChild($xml->createElement('ConsigneeName', $this->address->getAttentionName()));
177 15
            }
178 15
            if ($this->address->getBuildingName()) {
179 15
                $addressNode->appendChild($xml->createElement('BuildingName', $this->address->getBuildingName()));
180 15
            }
181 15
            if ($this->address->getAddressLine1()) {
182 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine1()));
183 15
            }
184 15
            if ($this->address->getAddressLine2()) {
185 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine2()));
186 15
            }
187 15
            if ($this->address->getAddressLine3()) {
188 15
                $addressNode->appendChild($xml->createElement('AddressLine', $this->address->getAddressLine3()));
189 15
            }
190 15
            if ($this->address->getStateProvinceCode()) {
191 15
                $addressNode->appendChild($xml->createElement('PoliticalDivision2',
192 15
                    $this->address->getStateProvinceCode()));
193 15
            }
194 15
            if ($this->address->getCity()) {
195 15
                $addressNode->appendChild($xml->createElement('PoliticalDivision1', $this->address->getCity()));
196 15
            }
197 15
            if ($this->address->getCountryCode()) {
198 15
                $addressNode->appendChild($xml->createElement('CountryCode', $this->address->getCountryCode()));
199 15
            }
200 15
            if ($this->address->getPostalCode()) {
201 15
                $addressNode->appendChild($xml->createElement('PostcodePrimaryLow', $this->address->getPostalCode()));
202 15
            }
203 15
        }
204
205 15
        return $xml->saveXML();
206
    }
207
208
    /**
209
     * Format the response.
210
     *
211
     * @param SimpleXMLElement $response
212
     *
213
     * @return stdClass
214
     */
215
    private function formatResponse(SimpleXMLElement $response)
216
    {
217
        return $this->convertXmlObject($response->AddressKeyFormat);
218
    }
219
220
    /**
221
     * @return RequestInterface
222
     */
223 15
    public function getRequest()
224
    {
225 15
        if (null === $this->request) {
226
            $this->request = new Request();
227
        }
228
229 15
        return $this->request;
230
    }
231
232
    /**
233
     * @param RequestInterface $request
234
     *
235
     * @return $this
236
     */
237 15
    public function setRequest(RequestInterface $request)
238
    {
239 15
        $this->request = $request;
240
241 15
        return $this;
242
    }
243
244
    /**
245
     * @return ResponseInterface
246
     */
247
    public function getResponse()
248
    {
249
        return $this->response;
250
    }
251
252
    /**
253
     * @param ResponseInterface $response
254
     *
255
     * @return $this
256
     */
257
    public function setResponse(ResponseInterface $response)
258
    {
259
        $this->response = $response;
260
261
        return $this;
262
    }
263
}
264