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 — place-services ( fedba7 )
by Eric
03:31
created

DirectionService   D

Complexity

Total Complexity 49

Size/Duplication

Total Lines 433
Duplicated Lines 4.39 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 3
Bugs 0 Features 2
Metric Value
wmc 49
c 3
b 0
f 2
lcom 1
cbo 20
dl 19
loc 433
rs 4.2904

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 26 5
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->setName($data['name']);
313
        $transitLine->setShortName($data['short_name']);
314
        $transitLine->setVehicle($this->buildTransitVehicle($data['vehicle']));
315
        $transitLine->setAgencies($this->buildTransitAgencies($data['agencies']));
316
317
        if (isset($data['color'])) {
318
            $transitLine->setColor($data['color']);
319
        }
320
321
        if (isset($data['url'])) {
322
            $transitLine->setUrl($data['url']);
323
        }
324
325
        if (isset($data['icon'])) {
326
            $transitLine->setIcon($data['icon']);
327
        }
328
329
        if (isset($data['text_color'])) {
330
            $transitLine->setTextColor($data['text_color']);
331
        }
332
333
        return $transitLine;
334
    }
335
336
    /**
337
     * @param mixed[] $data
338
     *
339
     * @return DirectionTransitAgency[]
340
     */
341
    private function buildTransitAgencies(array $data)
342
    {
343
        $agencies = [];
344
345
        foreach ($data as $agency) {
346
            $agencies[] = $this->buildTransitAgency($agency);
347
        }
348
349
        return $agencies;
350
    }
351
352
    /**
353
     * @param mixed[] $data
354
     *
355
     * @return DirectionTransitAgency
356
     */
357
    private function buildTransitAgency(array $data)
358
    {
359
        $transitAgency = new DirectionTransitAgency();
360
        $transitAgency->setName($data['name']);
361
        $transitAgency->setPhone($data['phone']);
362
        $transitAgency->setUrl($data['url']);
363
364
        return $transitAgency;
365
    }
366
367
    /**
368
     * @param mixed[] $data
369
     *
370
     * @return DirectionTransitStop
371
     */
372
    private function buildTransitStop(array $data)
373
    {
374
        $transitStop = new DirectionTransitStop();
375
        $transitStop->setName($data['name']);
376
        $transitStop->setLocation($this->buildCoordinate($data['location']));
377
378
        return $transitStop;
379
    }
380
381
    /**
382
     * @param mixed[] $data
383
     *
384
     * @return DirectionTransitVehicle
385
     */
386
    private function buildTransitVehicle(array $data)
387
    {
388
        $transitVehicle = new DirectionTransitVehicle();
389
        $transitVehicle->setName($data['name']);
390
        $transitVehicle->setIcon($data['icon']);
391
        $transitVehicle->setType($data['type']);
392
393
        return $transitVehicle;
394
    }
395
396
    /**
397
     * @param mixed[] $data
398
     *
399
     * @return Bound
400
     */
401
    private function buildBound(array $data)
402
    {
403
        return new Bound(
404
            $this->buildCoordinate($data['southwest']),
405
            $this->buildCoordinate($data['northeast'])
406
        );
407
    }
408
409
    /**
410
     * @param mixed[] $data
411
     *
412
     * @return Coordinate
413
     */
414
    private function buildCoordinate(array $data)
415
    {
416
        return new Coordinate($data['lat'], $data['lng']);
417
    }
418
419
    /**
420
     * @param mixed[] $data
421
     *
422
     * @return Distance
423
     */
424
    private function buildDistance(array $data)
425
    {
426
        return new Distance($data['value'], $data['text']);
427
    }
428
429
    /**
430
     * @param mixed[] $data
431
     *
432
     * @return Duration
433
     */
434
    private function buildDuration(array $data)
435
    {
436
        return new Duration($data['value'], $data['text']);
437
    }
438
439
    /**
440
     * @param string[] $data
441
     *
442
     * @return EncodedPolyline
443
     */
444
    private function buildEncodedPolyline(array $data)
445
    {
446
        return new EncodedPolyline($data['points']);
447
    }
448
449
    /**
450
     * @param mixed[] $data
451
     *
452
     * @return Fare
453
     */
454
    private function buildFare(array $data)
455
    {
456
        return new Fare($data['value'], $data['currency'], $data['text']);
457
    }
458
459
    /**
460
     * @param mixed[] $data
461
     *
462
     * @return Time
463
     */
464
    private function buildTime(array $data)
465
    {
466
        return new Time(
467
            new \DateTime('@'.$data['value'], new \DateTimeZone($data['time_zone'])),
468
            $data['time_zone'],
469
            $data['text']
470
        );
471
    }
472
}
473