/** * Uses a GeoIP database to get a visitor's location based on their IP address. * * This function will return different results based on the data used and based * on how the GeoIP module is configured. * * If a region database is used, it may return the country code, region code, * city name, area code, latitude, longitude and postal code of the visitor. * * Alternatively, only the country code may be returned for another database. * * If your HTTP server is not configured to include all GeoIP information, some * information will not be available to Piwik. * * @param array $info Must have an 'ip' field. * @return array */ public function getLocation($info) { $ip = $this->getIpFromInfo($info); // geoip modules that are built into servers can't use a forced IP. in this case we try // to fallback to another version. $myIP = Piwik_IP::getIpFromHeader(); if (!self::isSameOrAnonymizedIp($ip, $myIP) && (!isset($info['disable_fallbacks']) || !$info['disable_fallbacks'])) { printDebug("The request is for IP address: " . $info['ip'] . " but your IP is: {$myIP}. GeoIP Server Module (apache/nginx) does not support this use case... "); $fallbacks = array(Piwik_UserCountry_LocationProvider_GeoIp_Pecl::ID, Piwik_UserCountry_LocationProvider_GeoIp_Php::ID); foreach ($fallbacks as $fallbackProviderId) { $otherProvider = Piwik_UserCountry_LocationProvider::getProviderById($fallbackProviderId); if ($otherProvider) { printDebug("Used {$fallbackProviderId} to detect this visitor IP"); return $otherProvider->getLocation($info); } } printDebug("FAILED to lookup the geo location of this IP address, as no fallback location providers is configured. We recommend to configure Geolocation PECL module to fix this error."); return false; } $result = array(); foreach (self::$geoIpServerVars as $resultKey => $geoipVarName) { if (!empty($_SERVER[$geoipVarName])) { $result[$resultKey] = $_SERVER[$geoipVarName]; } } foreach (self::$geoIpUtfServerVars as $resultKey => $geoipVarName) { if (!empty($_SERVER[$geoipVarName])) { $result[$resultKey] = utf8_encode($_SERVER[$geoipVarName]); } } $this->completeLocationResult($result); return $result; }
/** * @param Piwik_Event_Notification $notification notification object */ public function getVisitorLocation($notification) { require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php"; $location =& $notification->getNotificationObject(); $visitorInfo = $notification->getNotificationInfo(); $id = Piwik_Common::getCurrentLocationProviderId(); $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); if ($provider === false) { $id = Piwik_UserCountry_LocationProvider_Default::ID; $provider = Piwik_UserCountry_LocationProvider::getProviderById($id); printDebug("GEO: no current location provider sent, falling back to default '{$id}' one."); } $location = $provider->getLocation($visitorInfo); // if we can't find a location, use default provider if ($location === false) { $defaultId = Piwik_UserCountry_LocationProvider_Default::ID; $provider = Piwik_UserCountry_LocationProvider::getProviderById($defaultId); $location = $provider->getLocation($visitorInfo); printDebug("GEO: couldn't find a location with Geo Module '{$id}', using Default '{$defaultId}' provider as fallback..."); $id = $defaultId; } printDebug("GEO: Found IP location (provider '" . $id . "'): " . var_export($location, true)); }
/** * Echo's a pretty formatted location using a specific LocationProvider. * * Input: * The 'id' query parameter must be set to the ID of the LocationProvider to use. * * Output: * The pretty formatted location that was obtained. Will be HTML. */ public function getLocationUsingProvider() { $providerId = Piwik_Common::getRequestVar('id'); $provider = $provider = Piwik_UserCountry_LocationProvider::getProviderById($providerId); if ($provider === false) { throw new Exception("Invalid provider ID: '{$providerId}'."); } $location = $provider->getLocation(array('ip' => Piwik_IP::getIpFromHeader(), 'lang' => Piwik_Common::getBrowserLanguage(), 'disable_fallbacks' => true)); $location = Piwik_UserCountry_LocationProvider::prettyFormatLocation($location, $newline = '<br/>', $includeExtra = true); echo $location; }