Passed
Push — master ( 9bf4b6...47f34f )
by Jonathan
04:25
created

SPW::geocodeQuery()   C

Complexity

Conditions 10
Paths 35

Size

Total Lines 64
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 64
rs 6.309
c 0
b 0
f 0
cc 10
eloc 42
nc 35
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Geocoder package.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT License
11
 */
12
13
namespace Geocoder\Provider\SPW;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\InvalidArgument;
17
use Geocoder\Exception\InvalidServerResponse;
18
use Geocoder\Exception\UnsupportedOperation;
19
use Geocoder\Http\Provider\AbstractHttpProvider;
20
use Geocoder\Model\Address;
21
use Geocoder\Model\AddressCollection;
22
use Geocoder\Provider\Provider;
23
use Geocoder\Query\GeocodeQuery;
24
use Geocoder\Query\ReverseQuery;
25
use Http\Client\HttpClient;
26
use proj4php\Point;
27
use proj4php\Proj;
28
use proj4php\Proj4php;
29
30
/**
31
 * @author Jonathan Beliën <[email protected]>
32
 */
33
final class SPW extends AbstractHttpProvider implements Provider
34
{
35
    /**
36
     * @var string
37
     */
38
    const GEOCODE_ENDPOINT_URL = 'http://geoservices.wallonie.be/geolocalisation/rest/searchPositionScored/%s/';
39
40
    /**
41
     * @var string
42
     */
43
    const REVERSE_ENDPOINT_URL = 'http://geoservices.wallonie.be/geolocalisation/rest/getNearestPosition/%F/%F/';
44
45
    /**
46
     * @param HttpClient $client an HTTP adapter
47
     */
48
    public function __construct(HttpClient $client)
49
    {
50
        parent::__construct($client);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function geocodeQuery(GeocodeQuery $query): Collection
57
    {
58
        $address = $query->getText();
59
        // This API does not support IP
60
        if (filter_var($address, FILTER_VALIDATE_IP)) {
61
            throw new UnsupportedOperation('The SPW provider does not support IP addresses, only street addresses.');
62
        }
63
64
        // Save a request if no valid address entered
65
        if (empty($address)) {
66
            throw new InvalidArgument('Address cannot be empty.');
67
        }
68
69
        $url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address));
70
        $json = $this->executeQuery($url);
71
72
        // no result
73
        if (is_null($json->x) && is_null($json->y)) {
74
            return new AddressCollection([]);
75
        }
76
77
        $results = [];
78
79
        $proj4 = new Proj4php();
80
81
        $proj31370 = new Proj('EPSG:31370', $proj4);
82
        $proj4326 = new Proj('EPSG:4326', $proj4);
83
84
        $pointSrc = new Point($json->x, $json->y, $proj31370);
85
        $coordinates = $proj4->transform($proj4326, $pointSrc);
86
87
        $streetName = !empty($json->rue->nom) ? $json->rue->nom : null;
88
        $number = !empty($json->num) ? $json->num : null;
89
        $municipality = !empty($json->rue->commune) ? $json->rue->commune : null;
90
        $postCode = !empty($json->rue->cps) ? implode(', ', $json->rue->cps) : null;
91
        $subLocality = !empty($json->rue->localites) ? implode(', ', $json->rue->localites) : null;
92
        $countryCode = 'BE';
93
94
        $lowerLeftSrc = new Point($json->rue->xMin, $json->rue->yMin, $proj31370);
95
        $lowerLeft = $proj4->transform($proj4326, $lowerLeftSrc);
96
        $upperRightSrc = new Point($json->rue->xMax, $json->rue->yMax, $proj31370);
97
        $upperRight = $proj4->transform($proj4326, $upperRightSrc);
98
99
        $bounds = [
100
          'west'  => $lowerLeft->x,
101
          'south' => $lowerLeft->y,
102
          'east'  => $upperRight->x,
103
          'north' => $upperRight->y,
104
        ];
105
106
        $results[] = Address::createFromArray([
107
            'providedBy'   => $this->getName(),
108
            'latitude'     => $coordinates->y,
109
            'longitude'    => $coordinates->x,
110
            'streetNumber' => $number,
111
            'streetName'   => $streetName,
112
            'locality'     => $municipality,
113
            'subLocality'  => $subLocality,
114
            'postalCode'   => $postCode,
115
            'countryCode'  => $countryCode,
116
            'bounds'       => $bounds,
117
        ]);
118
119
        return new AddressCollection($results);
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function reverseQuery(ReverseQuery $query): Collection
126
    {
127
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Geocoder\Collection. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function getName(): string
133
    {
134
        return 'spw';
135
    }
136
137
    /**
138
     * @param string $url
139
     *
140
     * @return \stdClass
141
     */
142
    private function executeQuery(string $url): \stdClass
143
    {
144
        $content = $this->getUrlContents($url);
145
        $json = json_decode($content);
146
        // API error
147
        if (!isset($json)) {
148
            throw InvalidServerResponse::create($url);
149
        }
150
151
        return $json;
152
    }
153
}
154