13
13
use Geocoder \Exception \InvalidCredentialsException ;
14
14
use Geocoder \Exception \NoResultException ;
15
15
use Geocoder \Exception \UnsupportedException ;
16
+ use Geocoder \Exception \InvalidArgumentException ;
17
+ use Geocoder \Exception \QuotaExceededException ;
16
18
use Geocoder \HttpAdapter \HttpAdapterInterface ;
17
19
18
20
/**
19
21
* @author Andrea Cristaudo <[email protected] >
22
+ * @author Arthur Bodera <[email protected] >
23
+ *
24
+ * @link http://www.geoips.com/en/developer/api-guide
20
25
*/
21
26
class GeoIPsProvider extends AbstractProvider implements ProviderInterface
22
27
{
@@ -25,6 +30,14 @@ class GeoIPsProvider extends AbstractProvider implements ProviderInterface
25
30
*/
26
31
const GEOCODE_ENDPOINT_URL = 'http://api.geoips.com/ip/%s/key/%s/output/json/timezone/true/ ' ;
27
32
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
+
28
41
/**
29
42
* @var string
30
43
*/
@@ -85,48 +98,85 @@ public function getName()
85
98
}
86
99
87
100
/**
88
- * @param string $query
89
- *
101
+ * @param string $query
90
102
* @return array
91
103
*/
92
104
protected function executeQuery ($ query )
93
105
{
94
106
$ content = $ this ->getAdapter ()->getContent ($ query );
95
107
96
108
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 ));
98
110
}
99
111
100
112
$ json = json_decode ($ content , true );
101
113
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
+ }
103
137
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 ));
106
140
}
107
141
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
+ ));
110
157
}
111
158
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
+ }
116
163
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
+ ));
118
178
}
119
179
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 ;
131
181
}
132
182
}
0 commit comments