Passed
Push — master ( 4b5c0b...5361e0 )
by Damien
02:17
created

AbstractDistanceMatrixQuery::getLanguage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace DH\NavigationBundle\Contract\DistanceMatrix;
4
5
use DH\NavigationBundle\Exception\DestinationException;
6
use DH\NavigationBundle\Exception\OriginException;
7
use DH\NavigationBundle\Exception\ResponseException;
8
use DH\NavigationBundle\Provider\ProviderInterface;
9
use Psr\Http\Message\ResponseInterface;
10
11
abstract class AbstractDistanceMatrixQuery implements DistanceMatrixQueryInterface
12
{
13
    /**
14
     * @var ProviderInterface
15
     */
16
    private $provider;
17
18
    /**
19
     * @var array
20
     */
21
    protected $origins;
22
23
    /**
24
     * @var array
25
     */
26
    protected $destinations;
27
28
    /**
29
     * @var \DateTime
30
     */
31
    private $departure_time;
32
33
    /**
34
     * @var string
35
     */
36
    private $language;
37
38
    /**
39
     * DistanceMatrixQuery constructor.
40
     *
41
     * @param ProviderInterface $provider
42
     */
43
    public function __construct(ProviderInterface $provider)
44
    {
45
        $this->provider = $provider;
46
    }
47
48
    public function getProvider(): ProviderInterface
49
    {
50
        return $this->provider;
51
    }
52
53
    /**
54
     * @return ?\DateTime
55
     */
56
    public function getDepartureTime(): ?\DateTime
57
    {
58
        return $this->departure_time;
59
    }
60
61
    /**
62
     * @param \DateTime $departureTime
63
     *
64
     * @return DistanceMatrixQueryInterface
65
     */
66
    public function setDepartureTime(\DateTime $departureTime): DistanceMatrixQueryInterface
67
    {
68
        $this->departure_time = $departureTime;
69
70
        return $this;
71
    }
72
73
    /**
74
     * @param string $origin
75
     *
76
     * @return DistanceMatrixQueryInterface
77
     */
78
    public function addOrigin($origin): DistanceMatrixQueryInterface
79
    {
80
        $this->origins[] = $origin;
81
82
        return $this;
83
    }
84
85
    /**
86
     * @return ?array
87
     */
88
    public function getOrigins(): ?array
89
    {
90
        return $this->origins;
91
    }
92
93
    /**
94
     * @param string $destination
95
     *
96
     * @return DistanceMatrixQueryInterface
97
     */
98
    public function addDestination($destination): DistanceMatrixQueryInterface
99
    {
100
        $this->destinations[] = $destination;
101
102
        return $this;
103
    }
104
105
    /**
106
     * @return ?array
107
     */
108
    public function getDestinations(): ?array
109
    {
110
        return $this->destinations;
111
    }
112
113
    /**
114
     * @param string $language
115
     *
116
     * @return DistanceMatrixQueryInterface
117
     */
118
    public function setLanguage(string $language): DistanceMatrixQueryInterface
119
    {
120
        $this->language = $language;
121
122
        return $this;
123
    }
124
125
    /**
126
     * @return string
127
     */
128
    public function getLanguage(): string
129
    {
130
        return $this->language ?? 'en-US';
131
    }
132
133
    /**
134
     * @throws DestinationException
135
     * @throws OriginException
136
     * @throws ResponseException
137
     * @throws \GuzzleHttp\Exception\GuzzleException
138
     *
139
     * @return DistanceMatrixResponseInterface
140
     */
141
    public function execute(): DistanceMatrixResponseInterface
142
    {
143
        $this->validateRequest();
144
        $request = $this->buildRequest();
145
        $rawResponse = $this->request('GET', $request);
146
        $response = $this->buildResponse($rawResponse);
147
        $this->validateResponse($response);
148
149
        return $response;
150
    }
151
152
    /**
153
     * @return string
154
     */
155
    abstract protected function buildRequest(): string;
156
157
    /**
158
     * @param ResponseInterface $response
159
     *
160
     * @return DistanceMatrixResponseInterface
161
     */
162
    abstract protected function buildResponse(ResponseInterface $response): DistanceMatrixResponseInterface;
163
164
    /**
165
     * @param string $method
166
     * @param string $url
167
     *
168
     * @throws \GuzzleHttp\Exception\GuzzleException
169
     *
170
     * @return ResponseInterface
171
     */
172
    private function request(string $method, string $url): ResponseInterface
173
    {
174
        $client = $this->getProvider()->getClient();
175
        $response = $client->request($method, $url);
176
177
        if (200 !== $response->getStatusCode()) {
178
            throw new \Exception('Response with status code '.$response->getStatusCode());
179
        }
180
181
        return $response;
182
    }
183
184
    /**
185
     * @param DistanceMatrixResponseInterface $response
186
     *
187
     * @throws ResponseException
188
     */
189
    private function validateResponse(DistanceMatrixResponseInterface $response): void
190
    {
191
        switch ($response->getStatus()) {
192
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_OK:
193
                break;
194
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_INVALID_REQUEST:
195
                throw new ResponseException('Invalid request.', 1);
196
197
                break;
198
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_MAX_ELEMENTS_EXCEEDED:
199
                throw new ResponseException('The product of the origin and destination exceeds the limit per request.', 2);
200
201
                break;
202
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_OVER_QUERY_LIMIT:
203
                throw new ResponseException('The service has received too many requests from your application in the allowed time range.', 3);
204
205
                break;
206
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_REQUEST_DENIED:
207
                throw new ResponseException('The service denied the use of the Distance Matrix API service by your application.', 4);
208
209
                break;
210
            case DistanceMatrixResponseInterface::RESPONSE_STATUS_UNKNOWN_ERROR:
211
                throw new ResponseException('Unknown error.', 5);
212
213
                break;
214
            default:
215
                throw new ResponseException(sprintf('Unknown status code: %s', $response->getStatus()), 6);
216
217
                break;
218
        }
219
    }
220
221
    /**
222
     * @throws DestinationException
223
     * @throws OriginException
224
     */
225
    private function validateRequest(): void
226
    {
227
        if (empty($this->getOrigins())) {
228
            throw new OriginException('Origin must be set.');
229
        }
230
        if (empty($this->getDestinations())) {
231
            throw new DestinationException('Destination must be set.');
232
        }
233
    }
234
}
235