@@ -168,33 +168,96 @@ class web_analytics {
168168 private $ ubid = null ;
169169 private $ session_id = null ;
170170
171- private $ topleveltocountry = array (
172- "gov " => "US " ,
173- "edu " => "US " ,
174- "com " => "US " ,
175- "net " => "US " ,
176- "bayern " => "DE "
177- );
178-
179- function get_country_by_host ($ host , $ topleveltocountry = null ) {
171+ function get_country_by_host ($ host ) {
180172 if (isset ($ host ) && filter_var ($ host , FILTER_VALIDATE_IP ) == false ) {
181173 $ domainparts = explode (". " , $ host );
182174 $ topleveldomain = $ domainparts [count ($ domainparts ) - 1 ];
183175 if (strlen ($ topleveldomain ) == 2 ) {
184176 return strtoupper ($ topleveldomain );
185- } else if (isset ($ topleveltocountry ) && array_key_exists ($ topleveldomain , $ topleveltocountry )) {
186- return strtoupper ($ topleveltocountry [$ topleveldomain ]);
177+ }
178+ }
179+ return null ;
180+ }
181+
182+ function get_country_by_ip ($ ip ) {
183+ if (filter_var ($ ip , FILTER_VALIDATE_IP )) {
184+ $ host = gethostbyaddr ($ ip );
185+ $ country = $ this ->get_country_by_host (gethostbyaddr ($ ip ));
186+ if ($ country == null && $ ip != "127.0.0.1 " && $ ip != "::1 " ) {
187+ $ country = $ this ->get_country_by_rdap ($ ip );
188+ if ($ country == null ) {
189+ $ domainparts = explode (". " , $ host );
190+ $ topleveldomain = $ domainparts [count ($ domainparts ) - 1 ];
191+ if ($ topleveldomain == "com " || $ topleveldomain == "net " || $ topleveldomain == "edu " || $ topleveldomain == "gov " ) {
192+ return "US " ;
193+ }
194+ }
195+ }
196+ return $ country ;
197+ }
198+ return null ;
199+ }
200+
201+ function get_country_by_rdap ($ query ) {
202+ if (filter_var ($ query , FILTER_VALIDATE_IP )) {
203+ $ ip = $ query ;
204+ if (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 )) {
205+ $ iana_ipv4 = file_get_contents ("http://data.iana.org/rdap/ipv4.json " );
206+ if (is_bool ($ iana_ipv4 )) {
207+ return null ;
208+ }
209+ $ iana_ipv4 = json_decode ($ iana_ipv4 , true );
210+ $ ipparts = explode (". " , $ ip );
211+ foreach ($ iana_ipv4 ["services " ] as $ service ) {
212+ foreach ($ service [0 ] as $ iprange ) {
213+ if ($ iprange == $ ipparts [0 ].".0.0.0/8 " ) {
214+ $ service_rdap = file_get_contents (preg_replace ("/https/i " , "http " , $ service [1 ][0 ])."ip/ " .$ ip );
215+ if ($ service_rdap == FALSE ) {
216+ return null ;
217+ }
218+ $ service_rdap = json_decode ($ service_rdap , true );
219+ if (isset ($ service_rdap ["country " ])) {
220+ return strtoupper ($ service_rdap ["country " ]);
221+ } else {
222+ return null ;
223+ }
224+ }
225+ }
226+ }
227+ } else if (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 )) {
228+ $ iana_ipv6 = file_get_contents ("http://data.iana.org/rdap/ipv6.json " );
229+ if (is_bool ($ iana_ipv6 )) {
230+ return null ;
231+ }
232+ $ iana_ipv6 = json_decode ($ iana_ipv6 , true );
233+ $ ipparts = explode (": " , $ ip );
234+ foreach ($ iana_ipv6 ["services " ] as $ service ) {
235+ foreach ($ service [0 ] as $ iprange ) {
236+ if (preg_match ("/ " .$ ipparts [0 ].": " .$ ipparts [1 ]."::\/\d[\d]*/ " , $ iprange ) || preg_match ("/ " .$ ipparts [0 ]."::\/\d[\d]*/ " , $ iprange )) {
237+ $ service_rdap = file_get_contents (preg_replace ("/https/i " , "http " , $ service [1 ][0 ])."ip/ " .$ ip );
238+ if ($ service_rdap == FALSE ) {
239+ return null ;
240+ }
241+ $ service_rdap = json_decode ($ service_rdap , true );
242+ if (isset ($ service_rdap ["country " ])) {
243+ return strtoupper ($ service_rdap ["country " ]);
244+ } else {
245+ return null ;
246+ }
247+ }
248+ }
249+ }
187250 }
188251 }
189252 return null ;
190253 }
191254
192255 // Get user language and country from hostname and http header
193- function get_country_code ($ host ) {
256+ function get_country_code ($ ip ) {
194257 if (isset ($ this ->s ["HTTP_CF_IPCOUNTRY " ])) {
195258 return $ this ->s ["HTTP_CF_IPCOUNTRY " ];
196259 }
197- return $ this ->get_country_by_host ( $ host , $ this -> topleveltocountry );
260+ return $ this ->get_country_by_ip ( $ ip );
198261 }
199262
200263 // Anonymize ip address
@@ -300,7 +363,7 @@ function save_ip($ip, $anonymize = FALSE) {
300363 $ host = gethostbyaddr ($ ip );
301364 }
302365 $ isp = $ this ->get_isp ($ host );
303- $ this ->u_country_code = $ this ->get_country_code ($ host );
366+ $ this ->u_country_code = $ this ->get_country_code ($ ip );
304367 if ($ anonymize ) {
305368 $ ip = $ this ->anonymize_ip ($ ip );
306369 $ host = null ;
0 commit comments