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
Pull Request — master (#177)
by Eric
08:46 queued 06:24
created

DirectionService   D

Complexity

Total Complexity 50

Size/Duplication

Total Lines 436
Duplicated Lines 4.36 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 20
dl 19
loc 436
rs 4.05
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A route() 19 19 1
A buildResponse() 0 19 4
A buildRoutes() 0 10 2
B buildRoute() 0 29 6
A buildGeocodedWaypoints() 0 10 2
A buildGeocodedWaypoint() 0 16 3
A buildLegs() 0 10 2
B buildLeg() 0 29 5
A buildSteps() 0 10 2
A buildStep() 0 17 2
A buildTransitDetails() 0 17 2
B buildTransitLine() 0 29 6
A buildTransitAgencies() 0 10 2
A buildTransitAgency() 0 9 1
A buildTransitStop() 0 8 1
A buildTransitVehicle() 0 9 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
A buildFare() 0 4 1
A buildTime() 0 8 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DirectionService 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 DirectionService, 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\Direction;
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\AbstractParsableService;
20
use Ivory\GoogleMap\Service\Base\Distance;
21
use Ivory\GoogleMap\Service\Base\Duration;
22
use Ivory\GoogleMap\Service\Base\Fare;
23
use Ivory\GoogleMap\Service\Base\Time;
24
use Ivory\GoogleMap\Service\Direction\Request\DirectionRequestInterface;
25
use Ivory\GoogleMap\Service\Direction\Response\DirectionGeocoded;
26
use Ivory\GoogleMap\Service\Direction\Response\DirectionLeg;
27
use Ivory\GoogleMap\Service\Direction\Response\DirectionResponse;
28
use Ivory\GoogleMap\Service\Direction\Response\DirectionRoute;
29
use Ivory\GoogleMap\Service\Direction\Response\DirectionStep;
30
use Ivory\GoogleMap\Service\Direction\Response\Transit\DirectionTransitAgency;
31
use Ivory\GoogleMap\Service\Direction\Response\Transit\DirectionTransitDetails;
32
use Ivory\GoogleMap\Service\Direction\Response\Transit\DirectionTransitLine;
33
use Ivory\GoogleMap\Service\Direction\Response\Transit\DirectionTransitStop;
34
use Ivory\GoogleMap\Service\Direction\Response\Transit\DirectionTransitVehicle;
35
use Ivory\GoogleMap\Service\Utility\Parser;
36
37
/**
38
 * @author GeLo <[email protected]>
39
 */
40
class DirectionService extends AbstractParsableService
41
{
42
    /**
43
     * @param HttpClient     $client
44
     * @param MessageFactory $messageFactory
45
     * @param Parser|null    $parser
46
     */
47
    public function __construct(HttpClient $client, MessageFactory $messageFactory, Parser $parser = null)
48
    {
49
        parent::__construct($client, $messageFactory, 'http://maps.googleapis.com/maps/api/directions', $parser);
50
    }
51
52
    /**
53
     * @param DirectionRequestInterface $request
54
     *
55
     * @return DirectionResponse
56
     */
57 View Code Duplication
    public function route(DirectionRequestInterface $request)
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...
58
    {
59
        $httpRequest = $this->createRequest($request);
60
        $httpResponse = $this->getClient()->sendRequest($httpRequest);
61
62
        $data = $this->parse((string) $httpResponse->getBody(), [
63
            'pluralization_rules' => [
64
                'leg'            => 'legs',
65
                'route'          => 'routes',
66
                'step'           => 'steps',
67
                'waypoint_index' => 'waypoint_order',
68
            ],
69
        ]);
70
71
        $response = $this->buildResponse($data);
72
        $response->setRequest($request);
73
74
        return $response;
75
    }
76
77
    /**
78
     * @param mixed[] $data
79
     *
80
     * @return DirectionResponse
81
     */
82
    private function buildResponse(array $data)
83
    {
84
        $response = new DirectionResponse();
85
        $response->setStatus($data['status']);
86
87
        if (isset($data['routes'])) {
88
            $response->setRoutes($this->buildRoutes($data['routes']));
89
        }
90
91
        if (isset($data['geocoded_waypoints'])) {
92
            $response->setGeocodedWaypoints($this->buildGeocodedWaypoints($data['geocoded_waypoints']));
93
        }
94
95
        if (isset($data['available_travel_modes'])) {
96
            $response->setAvailableTravelModes($data['available_travel_modes']);
97
        }
98
99
        return $response;
100
    }
101
102
    /**
103
     * @param mixed[] $data
104
     *
105
     * @return DirectionRoute[]
106
     */
107
    private function buildRoutes(array $data)
108
    {
109
        $routes = [];
110
111
        foreach ($data as $route) {
112
            $routes[] = $this->buildRoute($route);
113
        }
114
115
        return $routes;
116
    }
117
118
    /**
119
     * @param mixed[] $data
120
     *
121
     * @return DirectionRoute
122
     */
123
    private function buildRoute(array $data)
124
    {
125
        $route = new DirectionRoute();
126
        $route->setBound($this->buildBound($data['bounds']));
127
        $route->setLegs($this->buildLegs($data['legs']));
128
        $route->setOverviewPolyline($this->buildEncodedPolyline($data['overview_polyline']));
129
130
        if (isset($data['copyrights'])) {
131
            $route->setCopyrights($data['copyrights']);
132
        }
133
134
        if (isset($data['summary'])) {
135
            $route->setSummary($data['summary']);
136
        }
137
138
        if (isset($data['fare'])) {
139
            $route->setFare($this->buildFare($data['fare']));
140
        }
141
142
        if (isset($data['warnings'])) {
143
            $route->setWarnings($data['warnings']);
144
        }
145
146
        if (isset($data['waypoint_order'])) {
147
            $route->setWaypointOrders($data['waypoint_order']);
148
        }
149
150
        return $route;
151
    }
152
153
    /**
154
     * @param mixed[] $data
155
     *
156
     * @return DirectionGeocoded[]
157
     */
158
    private function buildGeocodedWaypoints(array $data)
159
    {
160
        $waypoints = [];
161
162
        foreach ($data as $waypoint) {
163
            $waypoints[] = $this->buildGeocodedWaypoint($waypoint);
164
        }
165
166
        return $waypoints;
167
    }
168
169
    /**
170
     * @param mixed[] $data
171
     *
172
     * @return DirectionGeocoded
173
     */
174
    private function buildGeocodedWaypoint(array $data)
175
    {
176
        $geocodedWaypoint = new DirectionGeocoded();
177
        $geocodedWaypoint->setStatus($data['geocoder_status']);
178
        $geocodedWaypoint->setTypes($data['types']);
179
180
        if (isset($data['place_id'])) {
181
            $geocodedWaypoint->setPlaceId($data['place_id']);
182
        }
183
184
        if (isset($data['partial_match'])) {
185
            $geocodedWaypoint->setPartialMatch($data['partial_match']);
186
        }
187
188
        return $geocodedWaypoint;
189
    }
190
191
    /**
192
     * @param mixed[] $data
193
     *
194
     * @return DirectionLeg[]
195
     */
196
    private function buildLegs(array $data)
197
    {
198
        $legs = [];
199
200
        foreach ($data as $leg) {
201
            $legs[] = $this->buildLeg($leg);
202
        }
203
204
        return $legs;
205
    }
206
207
    /**
208
     * @param mixed[] $data
209
     *
210
     * @return DirectionLeg
211
     */
212
    private function buildLeg(array $data)
213
    {
214
        $leg = new DirectionLeg();
215
        $leg->setDistance($this->buildDistance($data['distance']));
216
        $leg->setDuration($this->buildDuration($data['duration']));
217
        $leg->setStartLocation($this->buildCoordinate($data['start_location']));
218
        $leg->setEndLocation($this->buildCoordinate($data['end_location']));
219
        $leg->setStartAddress($data['start_address']);
220
        $leg->setEndAddress($data['end_address']);
221
        $leg->setSteps($this->buildSteps($data['steps']));
222
223
        if (isset($data['departure_time'])) {
224
            $leg->setDepartureTime($this->buildTime($data['departure_time']));
225
        }
226
227
        if (isset($data['arrival_time'])) {
228
            $leg->setArrivalTime($this->buildTime($data['arrival_time']));
229
        }
230
231
        if (isset($data['via_waypoint'])) {
232
            $leg->setViaWaypoints($data['via_waypoint']);
233
        }
234
235
        if (isset($data['duration_in_traffic'])) {
236
            $leg->setDurationInTraffic($this->buildDuration($data['duration_in_traffic']));
237
        }
238
239
        return $leg;
240
    }
241
242
    /**
243
     * @param mixed[] $data
244
     *
245
     * @return DirectionStep[]
246
     */
247
    private function buildSteps(array $data)
248
    {
249
        $steps = [];
250
251
        foreach ($data as $step) {
252
            $steps[] = $this->buildStep($step);
253
        }
254
255
        return $steps;
256
    }
257
258
    /**
259
     * @param mixed[] $data
260
     *
261
     * @return DirectionStep
262
     */
263
    private function buildStep(array $data)
264
    {
265
        $step = new DirectionStep();
266
        $step->setDistance($this->buildDistance($data['distance']));
267
        $step->setDuration($this->buildDuration($data['duration']));
268
        $step->setEndLocation($this->buildCoordinate($data['end_location']));
269
        $step->setEncodedPolyline($this->buildEncodedPolyline($data['polyline']));
270
        $step->setStartLocation($this->buildCoordinate($data['start_location']));
271
        $step->setInstructions($data['html_instructions']);
272
        $step->setTravelMode($data['travel_mode']);
273
274
        if (isset($data['transit_details'])) {
275
            $step->setTransitDetails($this->buildTransitDetails($data['transit_details']));
276
        }
277
278
        return $step;
279
    }
280
281
    /**
282
     * @param mixed[] $data
283
     *
284
     * @return DirectionTransitDetails
285
     */
286
    private function buildTransitDetails(array $data)
287
    {
288
        $transitDetails = new DirectionTransitDetails();
289
        $transitDetails->setDepartureStop($this->buildTransitStop($data['departure_stop']));
290
        $transitDetails->setArrivalStop($this->buildTransitStop($data['arrival_stop']));
291
        $transitDetails->setDepartureTime($this->buildTime($data['departure_time']));
292
        $transitDetails->setArrivalTime($this->buildTime($data['arrival_time']));
293
        $transitDetails->setLine($this->buildTransitLine($data['line']));
294
        $transitDetails->setHeadSign($data['headsign']);
295
        $transitDetails->setNumStops($data['num_stops']);
296
297
        if (isset($data['headway'])) {
298
            $transitDetails->setHeadWay($data['headway']);
299
        }
300
301
        return $transitDetails;
302
    }
303
304
    /**
305
     * @param mixed[] $data
306
     *
307
     * @return DirectionTransitLine
308
     */
309
    private function buildTransitLine(array $data)
310
    {
311
        $transitLine = new DirectionTransitLine();
312
        $transitLine->setShortName($data['short_name']);
313
        $transitLine->setVehicle($this->buildTransitVehicle($data['vehicle']));
314
        $transitLine->setAgencies($this->buildTransitAgencies($data['agencies']));
315
316
        if (isset($data['name'])) {
317
            $transitLine->setName($data['name']);
318
        }
319
320
        if (isset($data['color'])) {
321
            $transitLine->setColor($data['color']);
322
        }
323
324
        if (isset($data['url'])) {
325
            $transitLine->setUrl($data['url']);
326
        }
327
328
        if (isset($data['icon'])) {
329
            $transitLine->setIcon($data['icon']);
330
        }
331
332
        if (isset($data['text_color'])) {
333
            $transitLine->setTextColor($data['text_color']);
334
        }
335
336
        return $transitLine;
337
    }
338
339
    /**
340
     * @param mixed[] $data
341
     *
342
     * @return DirectionTransitAgency[]
343
     */
344
    private function buildTransitAgencies(array $data)
345
    {
346
        $agencies = [];
347
348
        foreach ($data as $agency) {
349
            $agencies[] = $this->buildTransitAgency($agency);
350
        }
351
352
        return $agencies;
353
    }
354
355
    /**
356
     * @param mixed[] $data
357
     *
358
     * @return DirectionTransitAgency
359
     */
360
    private function buildTransitAgency(array $data)
361
    {
362
        $transitAgency = new DirectionTransitAgency();
363
        $transitAgency->setName($data['name']);
364
        $transitAgency->setPhone($data['phone']);
365
        $transitAgency->setUrl($data['url']);
366
367
        return $transitAgency;
368
    }
369
370
    /**
371
     * @param mixed[] $data
372
     *
373
     * @return DirectionTransitStop
374
     */
375
    private function buildTransitStop(array $data)
376
    {
377
        $transitStop = new DirectionTransitStop();
378
        $transitStop->setName($data['name']);
379
        $transitStop->setLocation($this->buildCoordinate($data['location']));
380
381
        return $transitStop;
382
    }
383
384
    /**
385
     * @param mixed[] $data
386
     *
387
     * @return DirectionTransitVehicle
388
     */
389
    private function buildTransitVehicle(array $data)
390
    {
391
        $transitVehicle = new DirectionTransitVehicle();
392
        $transitVehicle->setName($data['name']);
393
        $transitVehicle->setIcon($data['icon']);
394
        $transitVehicle->setType($data['type']);
395
396
        return $transitVehicle;
397
    }
398
399
    /**
400
     * @param mixed[] $data
401
     *
402
     * @return Bound
403
     */
404
    private function buildBound(array $data)
405
    {
406
        return new Bound(
407
            $this->buildCoordinate($data['southwest']),
408
            $this->buildCoordinate($data['northeast'])
409
        );
410
    }
411
412
    /**
413
     * @param mixed[] $data
414
     *
415
     * @return Coordinate
416
     */
417
    private function buildCoordinate(array $data)
418
    {
419
        return new Coordinate($data['lat'], $data['lng']);
420
    }
421
422
    /**
423
     * @param mixed[] $data
424
     *
425
     * @return Distance
426
     */
427
    private function buildDistance(array $data)
428
    {
429
        return new Distance($data['value'], $data['text']);
430
    }
431
432
    /**
433
     * @param mixed[] $data
434
     *
435
     * @return Duration
436
     */
437
    private function buildDuration(array $data)
438
    {
439
        return new Duration($data['value'], $data['text']);
440
    }
441
442
    /**
443
     * @param string[] $data
444
     *
445
     * @return EncodedPolyline
446
     */
447
    private function buildEncodedPolyline(array $data)
448
    {
449
        return new EncodedPolyline($data['points']);
450
    }
451
452
    /**
453
     * @param mixed[] $data
454
     *
455
     * @return Fare
456
     */
457
    private function buildFare(array $data)
458
    {
459
        return new Fare($data['value'], $data['currency'], $data['text']);
460
    }
461
462
    /**
463
     * @param mixed[] $data
464
     *
465
     * @return Time
466
     */
467
    private function buildTime(array $data)
468
    {
469
        return new Time(
470
            new \DateTime('@'.$data['value'], new \DateTimeZone($data['time_zone'])),
471
            $data['time_zone'],
472
            $data['text']
473
        );
474
    }
475
}
476