1313use Geocoder \Exception \InvalidCredentialsException ;
1414use Geocoder \Exception \NoResultException ;
1515use Geocoder \Exception \UnsupportedException ;
16+ use Geocoder \Exception \InvalidArgumentException ;
17+ use Geocoder \Exception \QuotaExceededException ;
1618use Geocoder \HttpAdapter \HttpAdapterInterface ;
1719
1820/**
1921 * @author Andrea Cristaudo <andrea.cristaudo@gmail.com>
22+ * @author Arthur Bodera <abodera@thinkscape.pro>
23+ *
24+ * @link http://www.geoips.com/en/developer/api-guide
2025 */
2126class 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