Passed
Push — master ( d31a50...87284d )
by Damien
02:11
created

AbstractRoutingQuery::validateResponse()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 21
nc 7
nop 1
dl 0
loc 29
rs 8.6506
c 1
b 0
f 0
1
<?php
2
3
namespace DH\NavigationBundle\Contract\Routing;
4
5
use DH\NavigationBundle\Exception\ResponseException;
6
use DH\NavigationBundle\Exception\WaypointException;
7
use DH\NavigationBundle\Provider\ProviderInterface;
8
use Psr\Http\Message\ResponseInterface;
9
10
abstract class AbstractRoutingQuery implements RoutingQueryInterface
11
{
12
    /**
13
     * @var ProviderInterface
14
     */
15
    private $provider;
16
17
    /**
18
     * @var array
19
     */
20
    protected $waypoints;
21
22
    /**
23
     * @var \DateTime
24
     */
25
    private $departure_time;
26
27
    /**
28
     * @var \DateTime
29
     */
30
    private $arrival_time;
31
32
    /**
33
     * RoutingQuery constructor.
34
     *
35
     * @param ProviderInterface $provider
36
     */
37
    public function __construct(ProviderInterface $provider)
38
    {
39
        $this->provider = $provider;
40
    }
41
42
    public function getProvider(): ProviderInterface
43
    {
44
        return $this->provider;
45
    }
46
47
    /**
48
     * @return ?\DateTime
49
     */
50
    public function getDepartureTime(): ?\DateTime
51
    {
52
        return $this->departure_time;
53
    }
54
55
    /**
56
     * @param \DateTime $departureTime
57
     *
58
     * @return RoutingQueryInterface
59
     */
60
    public function setDepartureTime(\DateTime $departureTime): RoutingQueryInterface
61
    {
62
        $this->departure_time = $departureTime;
63
64
        return $this;
65
    }
66
67
    /**
68
     * @return ?\DateTime
69
     */
70
    public function getArrivalTime(): ?\DateTime
71
    {
72
        return $this->arrival_time;
73
    }
74
75
    /**
76
     * @param \DateTime $arrivalTime
77
     *
78
     * @return RoutingQueryInterface
79
     */
80
    public function setArrivalTime(\DateTime $arrivalTime): RoutingQueryInterface
81
    {
82
        $this->arrival_time = $arrivalTime;
83
84
        return $this;
85
    }
86
87
    /**
88
     * @param string $waypoint
89
     *
90
     * @return RoutingQueryInterface
91
     */
92
    public function addWaypoint($waypoint): RoutingQueryInterface
93
    {
94
        $this->waypoints[] = $waypoint;
95
96
        return $this;
97
    }
98
99
    /**
100
     * @return ?array
101
     */
102
    public function getWaypoints(): ?array
103
    {
104
        return $this->waypoints;
105
    }
106
107
    /**
108
     * @return RoutingResponseInterface
109
     * @throws OriginException
110
     * @throws ResponseException
111
     * @throws WaypointException
112
     * @throws \GuzzleHttp\Exception\GuzzleException
113
     */
114
    public function execute(): RoutingResponseInterface
115
    {
116
        $this->validateRequest();
117
        $request = $this->buildRequest();
118
        $rawResponse = $this->request('GET', $request);
119
        $response = $this->buildResponse($rawResponse);
120
        $this->validateResponse($response);
121
122
        return $response;
123
    }
124
125
    /**
126
     * @return string
127
     */
128
    abstract protected function buildRequest(): string;
129
130
    /**
131
     * @param ResponseInterface $response
132
     *
133
     * @return RoutingResponseInterface
134
     */
135
    abstract protected function buildResponse(ResponseInterface $response): RoutingResponseInterface;
136
137
    /**
138
     * @param string $method
139
     * @param string $url
140
     *
141
     * @throws \GuzzleHttp\Exception\GuzzleException
142
     *
143
     * @return ResponseInterface
144
     */
145
    private function request(string $method, string $url): ResponseInterface
146
    {
147
        $client = $this->getProvider()->getClient();
148
        $response = $client->request($method, $url);
149
150
        if (200 !== $response->getStatusCode()) {
151
            throw new \Exception('Response with status code '.$response->getStatusCode());
152
        }
153
154
        return $response;
155
    }
156
157
    /**
158
     * @param DistanceMatrixResponseInterface $response
0 ignored issues
show
Bug introduced by
The type DH\NavigationBundle\Cont...MatrixResponseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
159
     *
160
     * @throws ResponseException
161
     */
162
    private function validateResponse(RoutingResponseInterface $response): void
163
    {
164
        switch ($response->getStatus()) {
165
            case RoutingResponseInterface::RESPONSE_STATUS_OK:
166
                break;
167
            case RoutingResponseInterface::RESPONSE_STATUS_INVALID_REQUEST:
168
                throw new ResponseException('Invalid request.', 1);
169
170
                break;
171
            case RoutingResponseInterface::RESPONSE_STATUS_MAX_ELEMENTS_EXCEEDED:
172
                throw new ResponseException('The product of the origin and destination exceeds the limit per request.', 2);
173
174
                break;
175
            case RoutingResponseInterface::RESPONSE_STATUS_OVER_QUERY_LIMIT:
176
                throw new ResponseException('The service has received too many requests from your application in the allowed time range.', 3);
177
178
                break;
179
            case RoutingResponseInterface::RESPONSE_STATUS_REQUEST_DENIED:
180
                throw new ResponseException('The service denied the use of the Distance Matrix API service by your application.', 4);
181
182
                break;
183
            case RoutingResponseInterface::RESPONSE_STATUS_UNKNOWN_ERROR:
184
                throw new ResponseException('Unknown error.', 5);
185
186
                break;
187
            default:
188
                throw new ResponseException(sprintf('Unknown status code: %s', $response->getStatus()), 6);
189
190
                break;
191
        }
192
    }
193
194
    /**
195
     * @throws WaypointException
196
     */
197
    private function validateRequest(): void
198
    {
199
        if (empty($this->getWaypoints()) || count($this->getWaypoints()) < 2) {
200
            throw new WaypointException('At least two waypoints must be set.');
201
        }
202
203
        if (null !== $this->getDepartureTime() && null !== $this->getArrivalTime()) {
204
            throw new WaypointException('departure_time and arrival_time cannot be both specified at the same time.');
205
        }
206
    }
207
}
208