GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 915195...1cdae9 )
by Eric
02:19
created

Directions   F

Complexity

Total Complexity 51

Size/Duplication

Total Lines 388
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 21

Importance

Changes 7
Bugs 0 Features 6
Metric Value
wmc 51
c 7
b 0
f 6
lcom 1
cbo 21
dl 0
loc 388
rs 3.4503

25 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A parse() 0 13 2
A route() 0 7 1
A buildFare() 0 9 1
A buildSteps() 0 9 2
A buildResponse() 0 16 4
A buildRoutes() 0 9 2
B buildRoute() 0 14 6
A buildGeocodedWaypoints() 0 9 2
A buildGeocodedWaypoint() 0 10 3
A buildLegs() 0 9 2
B buildLeg() 0 19 5
A buildStep() 0 16 2
A buildTransitDetails() 0 14 2
B buildTransitLine() 0 14 5
A buildTransitAgencies() 0 10 2
A buildTransitAgency() 0 9 1
A buildTransitStop() 0 8 1
A buildTransitVehicle() 0 9 1
A buildDateTime() 0 4 1
A buildBound() 0 7 1
A buildCoordinate() 0 4 1
A buildDistance() 0 4 1
A buildDuration() 0 4 1
A buildEncodedPolyline() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Directions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Directions, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the Ivory Google Map package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\GoogleMap\Service\Directions;
13
14
use Http\Client\HttpClient;
15
use Http\Message\MessageFactory;
16
use Ivory\GoogleMap\Base\Bound;
17
use Ivory\GoogleMap\Base\Coordinate;
18
use Ivory\GoogleMap\Overlay\EncodedPolyline;
19
use Ivory\GoogleMap\Service\AbstractService;
20
use Ivory\GoogleMap\Service\Base\Distance;
21
use Ivory\GoogleMap\Service\Base\Duration;
22
23
/**
24
 * @author GeLo <[email protected]>
25
 */
26
class Directions extends AbstractService
27
{
28
    /**
29
     * @param HttpClient     $client
30
     * @param MessageFactory $messageFactory
31
     */
32
    public function __construct(HttpClient $client, MessageFactory $messageFactory)
33
    {
34
        parent::__construct($client, $messageFactory, 'http://maps.googleapis.com/maps/api/directions');
35
    }
36
37
    /**
38
     * @param DirectionsRequest $request
39
     *
40
     * @return DirectionsResponse
41
     */
42
    public function route(DirectionsRequest $request)
43
    {
44
        $response = $this->getClient()->sendRequest($this->createRequest($request->buildQuery()));
45
        $data = $this->parse((string) $response->getBody());
46
47
        return $this->buildResponse($data);
48
    }
49
50
    /**
51
     * @param string $data
52
     *
53
     * @return mixed[]
54
     */
55
    private function parse($data)
56
    {
57
        if ($this->getFormat() === self::FORMAT_JSON) {
58
            return json_decode($data, true);
59
        }
60
61
        return $this->getXmlParser()->parse($data, [
62
            'leg'            => 'legs',
63
            'route'          => 'routes',
64
            'step'           => 'steps',
65
            'waypoint_index' => 'waypoint_order',
66
        ]);
67
    }
68
69
    /**
70
     * @param mixed[] $data
71
     *
72
     * @return DirectionsResponse
73
     */
74
    private function buildResponse(array $data)
75
    {
76
        $response = new DirectionsResponse();
77
        $response->setStatus($data['status']);
78
        $response->setRoutes(isset($data['routes']) ? $this->buildRoutes($data['routes']) : []);
79
80
        $response->setGeocodedWaypoints(
81
            isset($data['geocoded_waypoints']) ? $this->buildGeocodedWaypoints($data['geocoded_waypoints']) : []
82
        );
83
84
        $response->setAvailableTravelModes(
85
            isset($data['available_travel_modes']) ? $data['available_travel_modes'] : []
86
        );
87
88
        return $response;
89
    }
90
91
    /**
92
     * @param mixed[] $data
93
     *
94
     * @return DirectionsRoute[]
95
     */
96
    private function buildRoutes(array $data)
97
    {
98
        $routes = [];
99
        foreach ($data as $item) {
100
            $routes[] = $this->buildRoute($item);
101
        }
102
103
        return $routes;
104
    }
105
106
    /**
107
     * @param mixed[] $data
108
     *
109
     * @return DirectionsRoute
110
     */
111
    private function buildRoute(array $data)
112
    {
113
        $route = new DirectionsRoute();
114
        $route->setBound($this->buildBound($data['bounds']));
115
        $route->setCopyrights(isset($data['copyrights']) ? $data['copyrights'] : null);
116
        $route->setLegs($this->buildLegs($data['legs']));
117
        $route->setOverviewPolyline($this->buildEncodedPolyline($data['overview_polyline']));
118
        $route->setSummary(isset($data['summary']) ? $data['summary'] : null);
119
        $route->setFare(isset($data['fare']) ? $this->buildFare($data['fare']) : null);
120
        $route->setWarnings(isset($data['warnings']) ? $data['warnings'] : []);
121
        $route->setWaypointOrders(isset($data['waypoint_order']) ? $data['waypoint_order'] : []);
122
123
        return $route;
124
    }
125
126
    /**
127
     * @param mixed[] $data
128
     *
129
     * @return DirectionsGeocoded[]
130
     */
131
    private function buildGeocodedWaypoints(array $data)
132
    {
133
        $geocodedWaypoints = [];
134
        foreach ($data as $item) {
135
            $geocodedWaypoints[] = $this->buildGeocodedWaypoint($item);
136
        }
137
138
        return $geocodedWaypoints;
139
    }
140
141
    /**
142
     * @param mixed[] $data
143
     *
144
     * @return DirectionsGeocoded
145
     */
146
    private function buildGeocodedWaypoint(array $data)
147
    {
148
        $geocodedWaypoint = new DirectionsGeocoded();
149
        $geocodedWaypoint->setStatus($data['geocoder_status']);
150
        $geocodedWaypoint->setPartialMatch(isset($data['partial_match']) ? $data['partial_match'] : null);
151
        $geocodedWaypoint->setPlaceId(isset($data['place_id']) ? $data['place_id'] : null);
152
        $geocodedWaypoint->setTypes($data['types']);
153
154
        return $geocodedWaypoint;
155
    }
156
157
    /**
158
     * @param mixed[] $data
159
     *
160
     * @return DirectionsLeg[]
161
     */
162
    private function buildLegs(array $data)
163
    {
164
        $legs = [];
165
        foreach ($data as $item) {
166
            $legs[] = $this->buildLeg($item);
167
        }
168
169
        return $legs;
170
    }
171
172
    /**
173
     * @param mixed[] $data
174
     *
175
     * @return DirectionsLeg
176
     */
177
    private function buildLeg(array $data)
178
    {
179
        $leg = new DirectionsLeg();
180
        $leg->setDistance($this->buildDistance($data['distance']));
181
        $leg->setDuration($this->buildDuration($data['duration']));
182
        $leg->setDepartureTime(isset($data['departure_time']) ? $this->buildDateTime($data['departure_time']) : null);
183
        $leg->setArrivalTime(isset($data['arrival_time']) ? $this->buildDateTime($data['arrival_time']) : null);
184
        $leg->setEndAddress($data['end_address']);
185
        $leg->setEndLocation($this->buildCoordinate($data['end_location']));
186
        $leg->setStartAddress($data['start_address']);
187
        $leg->setStartLocation($this->buildCoordinate($data['start_location']));
188
        $leg->setSteps($this->buildSteps($data['steps']));
189
        $leg->setViaWaypoints(isset($data['via_waypoint']) ? $data['via_waypoint'] : []);
190
        $leg->setDurationInTraffic(
191
            isset($data['duration_in_traffic']) ? $this->buildDuration($data['duration_in_traffic']) : null
192
        );
193
194
        return $leg;
195
    }
196
197
    /**
198
     * @codeCoverageIgnore
199
     *
200
     * @param mixed[] $data
201
     *
202
     * @return DirectionsFare
203
     */
204
    private function buildFare(array $data)
205
    {
206
        $fare = new DirectionsFare();
207
        $fare->setCurrency($data['currency']);
208
        $fare->setValue($data['value']);
209
        $fare->setText($data['text']);
210
211
        return $fare;
212
    }
213
214
    /**
215
     * @param mixed[] $data
216
     *
217
     * @return DirectionsStep[]
218
     */
219
    private function buildSteps(array $data)
220
    {
221
        $steps = [];
222
        foreach ($data as $item) {
223
            $steps[] = $this->buildStep($item);
224
        }
225
226
        return $steps;
227
    }
228
229
    /**
230
     * @param mixed[] $data
231
     *
232
     * @return DirectionsStep
233
     */
234
    private function buildStep(array $data)
235
    {
236
        $step = new DirectionsStep();
237
        $step->setDistance($this->buildDistance($data['distance']));
238
        $step->setDuration($this->buildDuration($data['duration']));
239
        $step->setEndLocation($this->buildCoordinate($data['end_location']));
240
        $step->setInstructions($data['html_instructions']);
241
        $step->setEncodedPolyline($this->buildEncodedPolyline($data['polyline']));
242
        $step->setStartLocation($this->buildCoordinate($data['start_location']));
243
        $step->setTravelMode($data['travel_mode']);
244
        $step->setTransitDetails(
245
            isset($data['transit_details']) ? $this->buildTransitDetails($data['transit_details']) : null
246
        );
247
248
        return $step;
249
    }
250
251
    /**
252
     * @param mixed[] $data
253
     *
254
     * @return DirectionsTransitDetails
255
     */
256
    private function buildTransitDetails(array $data)
257
    {
258
        $transitDetails = new DirectionsTransitDetails();
259
        $transitDetails->setDepartureStop($this->buildTransitStop($data['departure_stop']));
260
        $transitDetails->setArrivalStop($this->buildTransitStop($data['arrival_stop']));
261
        $transitDetails->setDepartureTime($this->buildDateTime($data['departure_time']));
262
        $transitDetails->setArrivalTime($this->buildDateTime($data['arrival_time']));
263
        $transitDetails->setHeadSign($data['headsign']);
264
        $transitDetails->setHeadWay(isset($data['headway']) ? $data['headway'] : null);
265
        $transitDetails->setLine($this->buildTransitLine($data['line']));
266
        $transitDetails->setNumStops($data['num_stops']);
267
268
        return $transitDetails;
269
    }
270
271
    /**
272
     * @param mixed[] $data
273
     *
274
     * @return DirectionsTransitLine
275
     */
276
    private function buildTransitLine(array $data)
277
    {
278
        $transitLine = new DirectionsTransitLine();
279
        $transitLine->setName($data['name']);
280
        $transitLine->setShortName($data['short_name']);
281
        $transitLine->setColor(isset($data['color']) ? $data['color'] : null);
282
        $transitLine->setUrl(isset($data['url']) ? $data['url'] : null);
283
        $transitLine->setIcon(isset($data['icon']) ? $data['icon'] : null);
284
        $transitLine->setTextColor(isset($data['text_color']) ? $data['text_color'] : null);
285
        $transitLine->setVehicle($this->buildTransitVehicle($data['vehicle']));
286
        $transitLine->setAgencies($this->buildTransitAgencies($data['agencies']));
287
288
        return $transitLine;
289
    }
290
291
    /**
292
     * @param mixed[] $data
293
     *
294
     * @return DirectionsTransitAgency[]
295
     */
296
    private function buildTransitAgencies(array $data)
297
    {
298
        $transitAgencies = [];
299
300
        foreach ($data as $item) {
301
            $transitAgencies[] = $this->buildTransitAgency($item);
302
        }
303
304
        return $transitAgencies;
305
    }
306
307
    /**
308
     * @param mixed[] $data
309
     *
310
     * @return DirectionsTransitAgency
311
     */
312
    private function buildTransitAgency(array $data)
313
    {
314
        $transitAgency = new DirectionsTransitAgency();
315
        $transitAgency->setName($data['name']);
316
        $transitAgency->setPhone($data['phone']);
317
        $transitAgency->setUrl($data['url']);
318
319
        return $transitAgency;
320
    }
321
322
    /**
323
     * @param mixed[] $data
324
     *
325
     * @return DirectionsTransitStop
326
     */
327
    private function buildTransitStop(array $data)
328
    {
329
        $transitStop = new DirectionsTransitStop();
330
        $transitStop->setName($data['name']);
331
        $transitStop->setLocation($this->buildCoordinate($data['location']));
332
333
        return $transitStop;
334
    }
335
336
    /**
337
     * @param mixed[] $data
338
     *
339
     * @return DirectionsTransitVehicle
340
     */
341
    private function buildTransitVehicle(array $data)
342
    {
343
        $transitVehicle = new DirectionsTransitVehicle();
344
        $transitVehicle->setName($data['name']);
345
        $transitVehicle->setIcon($data['icon']);
346
        $transitVehicle->setType($data['type']);
347
348
        return $transitVehicle;
349
    }
350
351
    /**
352
     * @param mixed[] $data
353
     *
354
     * @return \DateTime
355
     */
356
    private function buildDateTime(array $data)
357
    {
358
        return new \DateTime('@'.$data['value'], new \DateTimeZone($data['time_zone']));
359
    }
360
361
    /**
362
     * @param mixed[] $data
363
     *
364
     * @return Bound
365
     */
366
    private function buildBound(array $data)
367
    {
368
        return new Bound(
369
            $this->buildCoordinate($data['southwest']),
370
            $this->buildCoordinate($data['northeast'])
371
        );
372
    }
373
374
    /**
375
     * @param mixed[] $data
376
     *
377
     * @return Coordinate
378
     */
379
    private function buildCoordinate(array $data)
380
    {
381
        return new Coordinate($data['lat'], $data['lng']);
382
    }
383
384
    /**
385
     * @param mixed[] $data
386
     *
387
     * @return Distance
388
     */
389
    private function buildDistance(array $data)
390
    {
391
        return new Distance($data['text'], $data['value']);
392
    }
393
394
    /**
395
     * @param mixed[] $data
396
     *
397
     * @return Duration
398
     */
399
    private function buildDuration(array $data)
400
    {
401
        return new Duration($data['text'], $data['value']);
402
    }
403
404
    /**
405
     * @param string[] $data
406
     *
407
     * @return EncodedPolyline
408
     */
409
    private function buildEncodedPolyline(array $data)
410
    {
411
        return new EncodedPolyline($data['points']);
412
    }
413
}
414