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 ( 7b9099...de9632 )
by Tobias
02:38
created

Geonames   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 11
dl 0
loc 200
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A geocodeQuery() 0 13 2
A reverseQuery() 0 10 1
B getCountryInfo() 0 50 6
A getName() 0 4 1
C executeQuery() 0 59 10
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\Geonames;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\InvalidCredentials;
17
use Geocoder\Exception\InvalidServerResponse;
18
use Geocoder\Exception\UnsupportedOperation;
19
use Geocoder\Model\AddressBuilder;
20
use Geocoder\Model\AddressCollection;
21
use Geocoder\Model\AdminLevelCollection;
22
use Geocoder\Provider\Geonames\Model\CountryInfo;
23
use Geocoder\Provider\Geonames\Model\GeonamesAddress;
24
use Geocoder\Query\GeocodeQuery;
25
use Geocoder\Query\ReverseQuery;
26
use Geocoder\Http\Provider\AbstractHttpProvider;
27
use Geocoder\Provider\Provider;
28
use Http\Client\HttpClient;
29
30
/**
31
 * @author Giovanni Pirrotta <[email protected]>
32
 */
33
final class Geonames extends AbstractHttpProvider implements Provider
34
{
35
    /**
36
     * @var string
37
     */
38
    const GEOCODE_ENDPOINT_URL = 'http://api.geonames.org/searchJSON?q=%s&maxRows=%d&style=full&username=%s';
39
40
    /**
41
     * @var string
42
     */
43
    const REVERSE_ENDPOINT_URL = 'http://api.geonames.org/findNearbyPlaceNameJSON?lat=%F&lng=%F&style=full&maxRows=%d&username=%s';
44
45
    /**
46
     * @var string
47
     */
48
    const BASE_ENDPOINT_URL = 'http://api.geonames.org/%s?username=%s';
49
50
    /**
51
     * @var string
52
     */
53
    private $username;
54
55
    /**
56
     * @param HttpClient $client   An HTTP adapter
57
     * @param string     $username Username login (Free registration at http://www.geonames.org/login)
58
     */
59
    public function __construct(HttpClient $client, string $username)
60
    {
61
        if (empty($username)) {
62
            throw new InvalidCredentials('No username provided.');
63
        }
64
65
        $this->username = $username;
66
        parent::__construct($client);
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function geocodeQuery(GeocodeQuery $query): Collection
73
    {
74
        $address = $query->getText();
75
76
        // This API doesn't handle IPs
77
        if (filter_var($address, FILTER_VALIDATE_IP)) {
78
            throw new UnsupportedOperation('The Geonames provider does not support IP addresses.');
79
        }
80
81
        $url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address), $query->getLimit(), $this->username);
82
83
        return $this->executeQuery($url, $query->getLocale());
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function reverseQuery(ReverseQuery $query): Collection
90
    {
91
        $coordinates = $query->getCoordinates();
92
        $longitude = $coordinates->getLongitude();
93
        $latitude = $coordinates->getLatitude();
94
95
        $url = sprintf(self::REVERSE_ENDPOINT_URL, $latitude, $longitude, $query->getLimit(), $this->username);
96
97
        return $this->executeQuery($url, $query->getLocale());
98
    }
99
100
    /**
101
     * @param string|null $country
102
     * @param string|null $locale
103
     *
104
     * @return array
105
     *
106
     * @throws \Geocoder\Exception\Exception
107
     */
108
    public function getCountryInfo(string $country = null, string $locale = null): array
109
    {
110
        $url = sprintf(self::BASE_ENDPOINT_URL, 'countryInfoJSON', $this->username);
111
112
        if (isset($country)) {
113
            $url = sprintf('%s&country=%s', $url, $country);
114
        }
115
116
        $url = sprintf('%s&style=FULL', $url);
117
118
        if (null !== $locale) {
119
            // Locale code transformation: for example from it_IT to it
120
            $url = sprintf('%s&lang=%s', $url, substr($locale, 0, 2));
121
        }
122
123
        $content = $this->getUrlContents($url);
124
        if (null === $json = json_decode($content)) {
125
            throw InvalidServerResponse::create($url);
126
        }
127
128
        $data = $json->geonames;
129
130
        if (empty($data)) {
131
            return [];
132
        }
133
134
        $results = [];
135
136
        foreach ($data as $item) {
137
            $countryInfo = new CountryInfo();
138
139
            $results[] = $countryInfo
140
                ->setBounds($item->south, $item->west, $item->north, $item->east)
141
                ->withContinent($item->continent ?? null)
142
                ->withCapital($item->capital ?? null)
143
                ->withLanguages($item->langesuages ?? '')
144
                ->withGeonameId($item->geonameId ?? null)
145
                ->withIsoAlpha3($item->isoAlpha3 ?? null)
146
                ->withFipsCode($item->fipsCode ?? null)
147
                ->withPopulation($item->population ?? null)
148
                ->withIsoNumeric($item->isoNumeric ?? null)
149
                ->withAreaInSqKm($item->areaInSqKm ?? null)
150
                ->withCountryCode($item->countryCode ?? null)
151
                ->withCountryName($item->countryName ?? null)
152
                ->withContinentName($item->continentName ?? null)
153
                ->withCurrencyCode($item->currencyCode ?? null);
154
        }
155
156
        return $results;
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162
    public function getName(): string
163
    {
164
        return 'geonames';
165
    }
166
167
    /**
168
     * @param string      $url
169
     * @param string|null $locale
170
     *
171
     * @return AddressCollection
172
     */
173
    private function executeQuery(string $url, string $locale = null): AddressCollection
174
    {
175
        if (null !== $locale) {
176
            // Locale code transformation: for example from it_IT to it
177
            $url = sprintf('%s&lang=%s', $url, substr($locale, 0, 2));
178
        }
179
180
        $content = $this->getUrlContents($url);
181
        if (null === $json = json_decode($content)) {
182
            throw InvalidServerResponse::create($url);
183
        }
184
185
        if (isset($json->totalResultsCount) && empty($json->totalResultsCount)) {
186
            return new AddressCollection([]);
187
        }
188
189
        $data = $json->geonames;
190
191
        if (empty($data)) {
192
            return new AddressCollection([]);
193
        }
194
195
        $results = [];
196
        foreach ($data as $item) {
197
            $builder = new AddressBuilder($this->getName());
198
199
            if (isset($item->bbox)) {
200
                $builder->setBounds($item->bbox->south, $item->bbox->west, $item->bbox->north, $item->bbox->east);
201
            }
202
203
            for ($level = 1; $level <= AdminLevelCollection::MAX_LEVEL_DEPTH; ++$level) {
204
                $adminNameProp = 'adminName'.$level;
205
                $adminCodeProp = 'adminCode'.$level;
206
                if (!empty($item->$adminNameProp)) {
207
                    $builder->addAdminLevel($level, $item->$adminNameProp, $item->$adminCodeProp ?? null);
208
                }
209
            }
210
211
            $builder->setCoordinates($item->lat ?? null, $item->lng ?? null);
212
            $builder->setLocality($item->name ?? null);
213
            $builder->setCountry($item->countryName ?? null);
214
            $builder->setCountryCode($item->countryCode ?? null);
215
            $builder->setTimezone($item->timezone->timeZoneId ?? null);
216
217
            /** @var GeonamesAddress $address */
218
            $address = $builder->build(GeonamesAddress::class);
219
            $address = $address->withName($item->name ?? null);
220
            $address = $address->withAsciiName($item->asciiName ?? null);
221
            $address = $address->withFclName($item->fclName ?? null);
222
            $address = $address->withAlternateNames($item->alternateNames ?? []);
223
            $address = $address->withPopulation($item->population ?? null);
224
            $address = $address->withGeonameId($item->geonameId ?? null);
225
            $address = $address->withFcode($item->fcode ?? null);
226
227
            $results[] = $address;
228
        }
229
230
        return new AddressCollection($results);
231
    }
232
}
233