Completed
Pull Request — master (#112)
by Stefan
06:05 queued 02:06
created

Request::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 10
loc 10
ccs 0
cts 7
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 6
1
<?php
2
3
namespace Ups;
4
5
use DateTime;
6
use Exception;
7
use GuzzleHttp\Client as Guzzle;
8
use Psr\Log\LoggerAwareInterface;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\NullLogger;
11
use SimpleXMLElement;
12
use Ups\Exception\InvalidResponseException;
13
use Ups\Exception\RequestException;
14
15
class Request implements RequestInterface, LoggerAwareInterface
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $access;
21
22
    /**
23
     * @var string
24
     */
25
    protected $request;
26
27
    /**
28
     * @var string
29
     */
30
    protected $endpointUrl;
31
32
    /**
33
     * @var LoggerInterface
34
     */
35
    protected $logger;
36
37
    /**
38
     * @var Guzzle
39
     */
40
    protected $client;
41
42
    /**
43
     * @param LoggerInterface $logger
44
     */
45 View Code Duplication
    public function __construct(LoggerInterface $logger = null)
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...
46
    {
47
        if ($logger !== null) {
48
            $this->setLogger($logger);
49
        } else {
50
            $this->setLogger(new NullLogger);
51
        }
52
53
        $this->setClient();
54
    }
55
56
    /**
57
     * Sets a logger instance on the object.
58
     *
59
     * @param LoggerInterface $logger
60
     *
61
     * @return null
62
     */
63
    public function setLogger(LoggerInterface $logger)
64
    {
65
        $this->logger = $logger;
66
    }
67
68
    /**
69
     * Creates a single instance of the Guzzle client
70
     *
71
     * @return null
72
     */
73
    public function setClient()
74
    {
75
        $this->client = new Guzzle();
76
    }
77
78
    /**
79
     * Send request to UPS.
80
     *
81
     * @param string $access The access request xml
82
     * @param string $request The request xml
83
     * @param string $endpointurl The UPS API Endpoint URL
84
     *
85
     * @throws Exception
86
     *                   todo: make access, request and endpointurl nullable to make the testable
87
     *
88
     * @return ResponseInterface
89
     */
90
    public function request($access, $request, $endpointurl)
91
    {
92
        $this->setAccess($access);
93
        $this->setRequest($request);
94
        $this->setEndpointUrl($endpointurl);
95
96
        // Log request
97
        $date = new DateTime();
98
        $id = $date->format('YmdHisu');
99
        $this->logger->info('Request To UPS API', [
100
            'id' => $id,
101
            'endpointurl' => $this->getEndpointUrl(),
102
        ]);
103
104
        $this->logger->debug('Request: ' . $this->getRequest(), [
105
            'id' => $id,
106
            'endpointurl' => $this->getEndpointUrl(),
107
        ]);
108
109
        try {
110
            $response = $this->client->post(
111
                $this->getEndpointUrl(),
112
                [
113
                    'body' => $this->getAccess() . $this->getRequest(),
114
                    'headers' => [
115
                        'Content-type' => 'application/x-www-form-urlencoded; charset=utf-8',
116
                        'Accept-Charset' => 'UTF-8',
117
                    ],
118
                    'http_errors' => true,
119
                ]
120
            );
121
122
            $body = (string)$response->getBody();
123
124
            $this->logger->info('Response from UPS API', [
125
                'id' => $id,
126
                'endpointurl' => $this->getEndpointUrl(),
127
            ]);
128
129
            $this->logger->debug('Response: ' . $body, [
130
                'id' => $id,
131
                'endpointurl' => $this->getEndpointUrl(),
132
            ]);
133
134
            if ($response->getStatusCode() === 200) {
135
                $body = $this->convertEncoding($body);
136
137
                $xml = new SimpleXMLElement($body);
138
                if (isset($xml->Response) && isset($xml->Response->ResponseStatusCode)) {
139
                    if ($xml->Response->ResponseStatusCode == 1) {
140
                        $responseInstance = new Response();
141
142
                        return $responseInstance->setText($body)->setResponse($xml);
143
                    } elseif ($xml->Response->ResponseStatusCode == 0) {
144
                        throw new InvalidResponseException('Failure: ' . $xml->Response->Error->ErrorDescription . ' (' . $xml->Response->Error->ErrorCode . ')');
145
                    }
146
                } else {
147
                    throw new InvalidResponseException('Failure: response is in an unexpected format.');
148
                }
149
            }
150
        } catch (\GuzzleHttp\Exception\TransferException $e) { // Guzzle: All of the exceptions extend from GuzzleHttp\Exception\TransferException
151
            $this->logger->alert($e->getMessage(), [
152
                'id' => $id,
153
                'endpointurl' => $this->getEndpointUrl(),
154
            ]);
155
156
            throw new RequestException('Failure: ' . $e->getMessage());
157
        }
158
    }
159
160
    /**
161
     * @param $access
162
     *
163
     * @return $this
164
     */
165
    public function setAccess($access)
166
    {
167
        $this->access = $access;
168
169
        return $this;
170
    }
171
172
    /**
173
     * @return string
174
     */
175
    public function getAccess()
176
    {
177
        return $this->access;
178
    }
179
180
    /**
181
     * @param $request
182
     *
183
     * @return $this
184
     */
185
    public function setRequest($request)
186
    {
187
        $this->request = $request;
188
189
        return $this;
190
    }
191
192
    /**
193
     * @return string
194
     */
195
    public function getRequest()
196
    {
197
        return $this->request;
198
    }
199
200
    /**
201
     * @param $endpointUrl
202
     *
203
     * @return $this
204
     */
205
    public function setEndpointUrl($endpointUrl)
206
    {
207
        $this->endpointUrl = $endpointUrl;
208
209
        return $this;
210
    }
211
212
    /**
213
     * @return string
214
     */
215
    public function getEndpointUrl()
216
    {
217
        return $this->endpointUrl;
218
    }
219
220
    /**
221
     * @param $body
222
     * @return string
223
     */
224
    protected function convertEncoding($body)
225
    {
226
        if (!function_exists('mb_convert_encoding')) {
227
            return $body;
228
        }
229
230
        $encoding = mb_detect_encoding($body);
231
        if ($encoding) {
232
            return mb_convert_encoding($body, 'UTF-8', $encoding);
233
        }
234
235
        return utf8_encode($body);
236
    }
237
}
238