Skip to content

Commit 3428ffb

Browse files
committed
Fix geocoder-php#267 - Geoips not working (api change)
1 parent 8b8f7b3 commit 3428ffb

File tree

3 files changed

+241
-63
lines changed

3 files changed

+241
-63
lines changed

src/Geocoder/Provider/GeoIPsProvider.php

+74-24
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@
1313
use Geocoder\Exception\InvalidCredentialsException;
1414
use Geocoder\Exception\NoResultException;
1515
use Geocoder\Exception\UnsupportedException;
16+
use Geocoder\Exception\InvalidArgumentException;
17+
use Geocoder\Exception\QuotaExceededException;
1618
use Geocoder\HttpAdapter\HttpAdapterInterface;
1719

1820
/**
1921
* @author Andrea Cristaudo <[email protected]>
22+
* @author Arthur Bodera <[email protected]>
23+
*
24+
* @link http://www.geoips.com/en/developer/api-guide
2025
*/
2126
class GeoIPsProvider extends AbstractProvider implements ProviderInterface
2227
{
@@ -25,6 +30,14 @@ class GeoIPsProvider extends AbstractProvider implements ProviderInterface
2530
*/
2631
const GEOCODE_ENDPOINT_URL = 'http://api.geoips.com/ip/%s/key/%s/output/json/timezone/true/';
2732

33+
const CODE_SUCCESS = '200_1'; // The following results has been returned.
34+
const CODE_NOT_FOUND = '200_2'; // No result set has been returned.
35+
const CODE_BAD_KEY = '400_1'; // Error in the URI - The API call should include a API key parameter.
36+
const CODE_BAD_IP = '400_2'; // Error in the URI - The API call should include a valid IP address.
37+
const CODE_NOT_AUTHORIZED = '403_1'; // The API key associated with your request was not recognized.
38+
const CODE_ACCOUNT_INACTIVE = '403_2'; // The API key has not been approved or has been disabled.
39+
const CODE_LIMIT_EXCEEDED = '403_3'; // The service you have requested is over capacity.
40+
2841
/**
2942
* @var string
3043
*/
@@ -85,48 +98,85 @@ public function getName()
8598
}
8699

87100
/**
88-
* @param string $query
89-
*
101+
* @param string $query
90102
* @return array
91103
*/
92104
protected function executeQuery($query)
93105
{
94106
$content = $this->getAdapter()->getContent($query);
95107

96108
if (null === $content || '' === $content) {
97-
throw new NoResultException(sprintf('Could not execute query %s', $query));
109+
throw new NoResultException(sprintf('Invalid response from GeoIPs server for query %s', $query));
98110
}
99111

100112
$json = json_decode($content, true);
101113

102-
$response = array_key_exists('response', $json) ? $json['response'] : $json;
114+
if (isset($json['error'])) {
115+
switch ($json['error']['code']) {
116+
case static::CODE_BAD_IP:
117+
throw new InvalidArgumentException('The API call should include a valid IP address.');
118+
case static::CODE_BAD_KEY:
119+
throw new InvalidCredentialsException('The API call should include a API key parameter.');
120+
case static::CODE_NOT_AUTHORIZED:
121+
throw new InvalidCredentialsException('The API key associated with your request was not recognized.');
122+
case static::CODE_ACCOUNT_INACTIVE:
123+
throw new InvalidCredentialsException('The API key has not been approved or has been disabled.');
124+
case static::CODE_LIMIT_EXCEEDED:
125+
throw new QuotaExceededException('The service you have requested is over capacity.');
126+
default:
127+
throw new NoResultException(sprintf(
128+
'GeoIPs error %s%s%s%s - query: %s',
129+
$json['error']['code'],
130+
isset($json['error']['status']) ? ', ' . $json['error']['status'] : '',
131+
isset($json['error']['message']) ? ', ' . $json['error']['message'] : '',
132+
isset($json['error']['notes']) ? ', ' . $json['error']['notes'] : '',
133+
$query
134+
));
135+
}
136+
}
103137

104-
if (!is_array($response) || !count($response)) {
105-
throw new NoResultException(sprintf('Could not execute query %s', $query));
138+
if (!is_array($json) || empty($json) || empty($json['response']) || empty($json['response']['code'])) {
139+
throw new NoResultException(sprintf('Invalid response from GeoIPs server for query %s', $query));
106140
}
107141

108-
if (!isset($response['status']) || 'Bad Request' == $response['status']) {
109-
throw new NoResultException(sprintf('Could not execute query %s', $query));
142+
$response = $json['response'];
143+
144+
// Check response code
145+
switch ($response['code']) {
146+
case static::CODE_NOT_FOUND:
147+
throw new NoResultException();
148+
case static::CODE_SUCCESS;
149+
// everything is ok
150+
break;
151+
default:
152+
throw new NoResultException(sprintf(
153+
'GeoIPs returned unknown result code %s for query: %s',
154+
$response['code'],
155+
$query
156+
));
110157
}
111158

112-
if ('Forbidden' === $response['status']) {
113-
if ('Limit Exceeded' === $response['message']) {
114-
throw new NoResultException(sprintf('Could not execute query %s', $query));
115-
}
159+
// Make sure that we do have proper result array
160+
if (empty($response['locations']) || !is_array($response['locations']) || empty($response['locations'][0])) {
161+
throw new NoResultException(sprintf('Invalid response from GeoIPs server for query %s', $query));
162+
}
116163

117-
throw new InvalidCredentialsException('API Key provided is not valid.');
164+
// Pick the first location from the response
165+
$locations = array();
166+
foreach ($response['locations'] as $location) {
167+
$locations[] = array_merge($this->getDefaults(), array(
168+
'country' => '' === $location['country_name'] ? null : $location['country_name'],
169+
'countryCode' => '' === $location['country_code'] ? null : $location['country_code'],
170+
'region' => '' === $location['region_name'] ? null : $location['region_name'],
171+
'regionCode' => '' === $location['region_code'] ? null : $location['region_code'],
172+
'county' => '' === $location['county_name'] ? null : $location['county_name'],
173+
'city' => '' === $location['city_name'] ? null : $location['city_name'],
174+
'latitude' => '' === $location['latitude'] ? null : $location['latitude'],
175+
'longitude' => '' === $location['longitude'] ? null : $location['longitude'],
176+
'timezone' => '' === $location['timezone'] ? null : $location['timezone'],
177+
));
118178
}
119179

120-
return array(array_merge($this->getDefaults(), array(
121-
'country' => '' === $response['country_name'] ? null : $response['country_name'],
122-
'countryCode' => '' === $response['country_code'] ? null : $response['country_code'],
123-
'region' => '' === $response['region_name'] ? null : $response['region_name'],
124-
'regionCode' => '' === $response['region_code'] ? null : $response['region_code'],
125-
'county' => '' === $response['county_name'] ? null : $response['county_name'],
126-
'city' => '' === $response['city_name'] ? null : $response['city_name'],
127-
'latitude' => '' === $response['latitude'] ? null : $response['latitude'],
128-
'longitude' => '' === $response['longitude'] ? null : $response['longitude'],
129-
'timezone' => '' === $response['timezone'] ? null : $response['timezone'],
130-
)));
180+
return $locations;
131181
}
132182
}

0 commit comments

Comments
 (0)