/** * Returns the GeoIp Location for the given IP address. * * @param null|string $ip Address for which to return the location data. * Note, if you leave it empty, the location will be determined using the current client IP. * * @return Location * @throws GeoIpException * @throws \Exception */ public function getGeoIpLocation($ip = null) { if (empty($ip)) { $ip = $this->getCurrentIp(); } // check if we have it in session $sessionKey = $this->getSessionKey($ip); $geoData = $this->httpSession()->get($sessionKey, false); if ($geoData) { $location = new Location(); $location->populate($geoData); return $location; } $protocol = $this->getIpProtocol($ip); try { if ($protocol == 4) { $location = $this->provider->getLocationFromIPv4($ip); } else { $location = $this->provider->getLocationFromIPv6($ip); } // save it into session $this->httpSession()->save($sessionKey, $location->exportToJson()); return $location; } catch (ProviderGeoIpNotFound $e) { return false; } catch (\Exception $e) { throw $e; } }
/** * Does the geo ip lookup. * * @param string $ip * * @return bool|Location * @throws \Webiny\GeoIp\GeoIpException */ private function getLocationInfo($ip) { $ctx = stream_context_create(['http' => ['timeout' => 3]]); $geoData = @file_get_contents('https://freegeoip.net/json/' . $ip, false, $ctx); if ($geoData == false) { return false; } $geoData = @json_decode($geoData, true); if ($geoData == false) { return false; } // Since setCountry throws an exception if country_code is missing, let's check it here before proceeding // This can happen if provider returns empty results - happened when sent a local IP address $hasCountryCode = isset($geoData['country_code']) && $geoData['country_code'] && strlen($geoData['country_code']) === 2; if (!$hasCountryCode) { return false; } $location = new Location(); $location->setCountry($geoData['country_code'], $geoData['country_name']); $location->setCityName($geoData['city']); $location->setTimeZone($geoData['time_zone']); if (isset($geoData['region_code'])) { $location->setSubdivision1($geoData['region_code'], $geoData['region_name']); } return $location; }
public function testSetGetTimeZone() { $location = new Location(); $location->setTimeZone('Europe/London'); $this->assertSame('Europe/London', $location->getTimeZone()); }
/** * Returns the Location for the provided IPv6 address. * * @param string $ip6 IPv6 address. * * @throws ProviderGeoIpNotFound * @return Location */ public function getLocationFromIPv6($ip6) { // create a cidr block $ip = $this->str($ip6)->explode(':'); do { $ip->removeLast(); } while ($ip->count() > 3); $subNet = $ip->implode(':')->val(); $ipStart = floatval(Ipv6Helper::ip2LongV6($subNet . ':8000:0:0:0:0')); $cityBlock = CityBlockIp6Entity::findOne(['rangeStart' => $ipStart]); if (!$cityBlock) { $ipStart = floatval(Ipv6Helper::ip2LongV6($subNet . ':0:0:0:0:0')); $cityBlock = CityBlockIp6Entity::findOne(['rangeStart' => $ipStart]); } // verify that end ip is within range if (!$cityBlock || !(Ipv6Helper::ip2LongV6($ip6) <= $cityBlock->rangeEnd)) { throw new ProviderGeoIpNotFound('GeoIp entry not found'); } // get location info $locationInfo = LocationEntity::findOne(['geoId' => $cityBlock->geoId]); // populate location variable $location = new Location(); $location->setContinent($locationInfo->continentCode, $locationInfo->continentName); $location->setCountry($locationInfo->countryCode, $locationInfo->countryName); $location->setCityName($locationInfo->cityName); $location->setSubdivision1($locationInfo->subdivision1Code, $locationInfo->subdivision1Name); $location->setSubdivision2($locationInfo->subdivision2Code, $locationInfo->subdivision2Name); $location->setTimeZone($locationInfo->timeZone); return $location; }