diff options
Diffstat (limited to 'plugins/UserCountry/LocationProvider.php')
-rwxr-xr-x | plugins/UserCountry/LocationProvider.php | 883 |
1 files changed, 422 insertions, 461 deletions
diff --git a/plugins/UserCountry/LocationProvider.php b/plugins/UserCountry/LocationProvider.php index 3f6b8821ed..34dfac6dfc 100755 --- a/plugins/UserCountry/LocationProvider.php +++ b/plugins/UserCountry/LocationProvider.php @@ -1,10 +1,10 @@ <?php /** * Piwik - Open source web analytics - * + * * @link http://piwik.org * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * + * * @category Piwik_Plugins * @package Piwik_UserCountry */ @@ -21,470 +21,431 @@ require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp.p /** * The base class of all LocationProviders. - * + * * LocationProviders attempt to determine a visitor's location using other * visitor info. All LocationProviders require a visitor's IP address, some * require more, such as the browser language. */ abstract class Piwik_UserCountry_LocationProvider { - const NOT_INSTALLED = 0; - const INSTALLED = 1; - const BROKEN = 2; - - const CURRENT_PROVIDER_OPTION_NAME = 'usercountry.location_provider'; - - const GEOGRAPHIC_COORD_PRECISION = 3; - - const CONTINENT_CODE_KEY = 'continent_code'; - const CONTINENT_NAME_KEY = 'continent_name'; - const COUNTRY_CODE_KEY = 'country_code'; - const COUNTRY_NAME_KEY = 'country_name'; - const REGION_CODE_KEY = 'region_code'; - const REGION_NAME_KEY = 'region_name'; - const CITY_NAME_KEY = 'city_name'; - const AREA_CODE_KEY = 'area_code'; - const LATITUDE_KEY = 'lat'; - const LONGITUDE_KEY = 'long'; - const POSTAL_CODE_KEY = 'postal_code'; - const ISP_KEY = 'isp'; - const ORG_KEY = 'org'; - - /** - * An array of all provider instances. Access it through static methods. - * - * @var array - */ - public static $providers = null; - - /** - * Returns location information based on visitor information. - * - * The result of this function will be an array. The array can store some or all of - * the following information: - * - * - Continent Code: The code of the visitor's continent. - * (array key is self::CONTINENT_CODE_KEY) - * - Continent Name: The name of the visitor's continent. - * (array key is self::CONTINENT_NAME_KEY) - * - Country Code: The code of the visitor's country. - * (array key is self::COUNTRY_CODE_KEY) - * - Country Name: The name of the visitor's country. - * (array key is self::COUNTRY_NAME_KEY) - * - Region Code: The code of the visitor's region. - * (array key is self::REGION_CODE_KEY) - * - Region Name: The name of the visitor's region. - * (array key is self::REGION_NAME_KEY) - * - City Name: The name of the visitor's city. - * (array key is self::CITY_NAME_KEY) - * - Area Code: The visitor's area code. - * (array key is self::AREA_CODE_KEY) - * - Latitude: The visitor's latitude. - * (array key is self::LATITUDE_KEY) - * - Longitude: The visitor's longitude. - * (array key is self::LONGITUDE_KEY) - * - Postal Code: The visitor's postal code. - * (array key is self::POSTAL_CODE_KEY) - * - ISP: The visitor's ISP. - * (array key is self::ISP_KEY) - * - Org: The company/organization of the visitor's IP. - * (array key is self::ORG_KEY) - * - * All LocationProviders will attempt to return the country of the visitor. - * - * @param array $info What this must contain depends on the specific provider - * implementation. All providers require an 'ip' key mapped - * to the visitor's IP address. - * @return array|false - */ - abstract public function getLocation( $info ); - - /** - * Returns true if this provider is available for use, false if otherwise. - * - * @return bool - */ - abstract public function isAvailable(); - - /** - * Returns true if this provider is working, false if otherwise. - * - * @return bool - */ - abstract public function isWorking(); - - /** - * Returns an array mapping location result keys w/ bool values indicating whether - * that information is supported by this provider. If it is not supported, that means - * this provider either cannot get this information, or is not configured to get it. - * - * @return array eg. array(self::CONTINENT_CODE_KEY => true, - * self::CONTINENT_NAME_KEY => true, - * self::ORG_KEY => false) - * The result is not guaranteed to have keys for every type of location - * info. - */ - abstract public function getSupportedLocationInfo(); - - /** - * Returns every available provider instance. - * - * @return array - */ - public static function getAllProviders() - { - if (is_null(self::$providers)) - { - self::$providers = array(); - foreach (get_declared_classes() as $klass) - { - if (is_subclass_of($klass, 'Piwik_UserCountry_LocationProvider')) - { - $klassInfo = new ReflectionClass($klass); - if ($klassInfo->isAbstract()) - { - continue; - } - - self::$providers[] = new $klass; - } - } - } - - return self::$providers; - } - - /** - * Returns all provider instances that are 'available'. An 'available' provider - * is one that is available for use. They may not necessarily be working. - * - * @return array - */ - public static function getAvailableProviders() - { - $result = array(); - foreach (self::getAllProviders() as $provider) - { - if ($provider->isAvailable()) - { - $result[] = $provider; - } - } - return $result; - } - - /** - * Returns an array mapping provider IDs w/ information about the provider, - * for each location provider. - * - * The following information is provided for each provider: - * 'id' - The provider's unique string ID. - * 'title' - The provider's title. - * 'description' - A description of how the location provider works. - * 'status' - Either self::NOT_INSTALLED, self::INSTALLED or self::BROKEN. - * 'statusMessage' - If the status is self::BROKEN, then the message describes why. - * 'location' - A pretty formatted location of the current IP address - * (Piwik_IP::getIpFromHeader()). - * - * An example result: - * array( - * 'geoip_php' => array('id' => 'geoip_php', - * 'title' => '...', - * 'desc' => '...', - * 'status' => Piwik_UserCountry_LocationProvider_GeoIp::BROKEN, - * 'statusMessage' => '...', - * 'location' => '...') - * 'geoip_serverbased' => array(...) - * ) - * - * @param string $newline What to separate lines with in the pretty locations. - * @param bool $includeExtra Whether to include ISP/Org info in formatted location. - * @return array - */ - public static function getAllProviderInfo( $newline = "\n", $includeExtra = false ) - { - $allInfo = array(); - foreach (self::getAllProviders() as $provider) - { - $info = $provider->getInfo(); - - $status = self::INSTALLED; - $location = false; - $statusMessage = false; - - $availableOrMessage = $provider->isAvailable(); - if ($availableOrMessage !== true) - { - $status = self::NOT_INSTALLED; - if (is_string($availableOrMessage)) - { - $statusMessage = $availableOrMessage; - } - } - else - { - $workingOrError = $provider->isWorking(); - if ($workingOrError === true) // if the implementation is configured correctly, get the location - { - $locInfo = array('ip' => Piwik_IP::getIpFromHeader(), - 'lang' => Piwik_Common::getBrowserLanguage(), - 'disable_fallbacks' => true); - - $location = $provider->getLocation($locInfo); - $location = self::prettyFormatLocation($location, $newline, $includeExtra); - } - else // otherwise set an error message describing why - { - $status = self::BROKEN; - $statusMessage = $workingOrError; - } - } - - $info['status'] = $status; - $info['statusMessage'] = $statusMessage; - $info['location'] = $location; - - $allInfo[$info['order']] = $info; - } - - ksort($allInfo); - - $result = array(); - foreach ($allInfo as $info) - { - $result[$info['id']] = $info; - } - return $result; - } - - /** - * Returns the ID of the currently used location provider. - * - * The used provider is stored in the 'usercountry.location_provider' option. - * - * This function should not be called by the Tracker. - * - * @return string - */ - public static function getCurrentProviderId() - { - $optionValue = Piwik_GetOption(self::CURRENT_PROVIDER_OPTION_NAME); - return $optionValue === false ? Piwik_UserCountry_LocationProvider_Default::ID : $optionValue; - } - - /** - * Returns the provider instance of the current location provider. - * - * This function should not be called by the Tracker. - * - * @return Piwik_UserCountry_LocationProvider - */ - public static function getCurrentProvider() - { - return self::getProviderById(self::getCurrentProviderId()); - } - - /** - * Sets the provider to use when tracking. - * - * @param string $providerId The ID of the provider to use. - * @return Piwik_UserCountry_LocationProvider The new current provider. - * @throws Exception If the provider ID is invalid. - */ - public static function setCurrentProvider( $providerId ) - { - $provider = self::getProviderById($providerId); - if ($provider === false) - { - throw new Exception( - "Invalid provider ID '$providerId'. The provider either does not exist or is not available"); - } - Piwik_SetOption(self::CURRENT_PROVIDER_OPTION_NAME, $providerId); - Piwik_Tracker_Cache::clearCacheGeneral(); - return $provider; - } - - /** - * Returns a provider instance by ID or false if the ID is invalid or unavailable. - * - * @param string $providerId - * @return Piwik_UserCountry_LocationProvider|false - */ - public static function getProviderById( $providerId ) - { - foreach (self::getAvailableProviders() as $provider) - { - $info = $provider->getInfo(); - if ($info['id'] == $providerId) - { - return $provider; - } - } - return false; - } - - /** - * Tries to fill in any missing information in a location result. - * - * This method will try to set the continent code, continent name and country code - * using other information. - * - * Note: This function must always be called by location providers in getLocation. - * - * @param array $location The location information to modify. - */ - public function completeLocationResult( &$location ) - { - // fill in continent code if country code is present - if (empty($location[self::CONTINENT_CODE_KEY]) - && !empty($location[self::COUNTRY_CODE_KEY])) - { - $countryCode = strtolower($location[self::COUNTRY_CODE_KEY]); - $location[self::CONTINENT_CODE_KEY] = Piwik_Common::getContinent($countryCode); - } - - // fill in continent name if continent code is present - if (empty($location[self::CONTINENT_NAME_KEY]) - && !empty($location[self::CONTINENT_CODE_KEY])) - { - $continentCode = strtolower($location[self::CONTINENT_CODE_KEY]); - $location[self::CONTINENT_NAME_KEY] = Piwik_Translate('UserCountry_continent_'.$continentCode); - } - - // fill in country name if country code is present - if (empty($location[self::COUNTRY_NAME_KEY]) - && !empty($location[self::COUNTRY_CODE_KEY])) - { - $countryCode = strtolower($location[self::COUNTRY_CODE_KEY]); - $location[self::COUNTRY_NAME_KEY] = Piwik_Translate('UserCountry_country_'.$countryCode); - } - - // deal w/ improper latitude/longitude & round proper values - if (!empty($location[self::LATITUDE_KEY])) - { - if (is_numeric($location[self::LATITUDE_KEY])) - { - $location[self::LATITUDE_KEY] = round($location[self::LATITUDE_KEY], self::GEOGRAPHIC_COORD_PRECISION); - } - else - { - unset($location[self::LATITUDE_KEY]); - } - } - - if (!empty($location[self::LONGITUDE_KEY])) - { - if (is_numeric($location[self::LONGITUDE_KEY])) - { - $location[self::LONGITUDE_KEY] = round($location[self::LONGITUDE_KEY], self::GEOGRAPHIC_COORD_PRECISION); - } - else - { - unset($location[self::LONGITUDE_KEY]); - } - } - } - - /** - * Returns a prettified location result. - * - * @param array|false $locationInfo - * @param string $newline The line separator (ie, \n or <br/>). - * @param bool $includeExtra Whether to include ISP/Organization info. - * @return string - */ - public static function prettyFormatLocation( $locationInfo, $newline = "\n", $includeExtra = false ) - { - if ($locationInfo === false) - { - return Piwik_Translate('General_Unknown'); - } - - // add latitude/longitude line - $lines = array(); - if (!empty($locationInfo[self::LATITUDE_KEY]) - && !empty($locationInfo[self::LONGITUDE_KEY])) - { - $lines[] = '('.$locationInfo[self::LATITUDE_KEY].', '.$locationInfo[self::LONGITUDE_KEY].')'; - } - - // add city/state line - $cityState = array(); - if (!empty($locationInfo[self::CITY_NAME_KEY])) - { - $cityState[] = $locationInfo[self::CITY_NAME_KEY]; - } - - if (!empty($locationInfo[self::REGION_CODE_KEY])) - { - $cityState[] = $locationInfo[self::REGION_CODE_KEY]; - } - else if (!empty($locationInfo[self::REGION_NAME_KEY])) - { - $cityState[] = $locationInfo[self::REGION_NAME_KEY]; - } - - if (!empty($cityState)) - { - $lines[] = implode(', ', $cityState); - } - - // add postal code line - if (!empty($locationInfo[self::POSTAL_CODE_KEY])) - { - $lines[] = $locationInfo[self::POSTAL_CODE_KEY]; - } - - // add country line - if (!empty($locationInfo[self::COUNTRY_NAME_KEY])) - { - $lines[] = $locationInfo[self::COUNTRY_NAME_KEY]; - } - else if (!empty($locationInfo[self::COUNTRY_CODE_KEY])) - { - $lines[] = $locationInfo[self::COUNTRY_CODE_KEY]; - } - - // add extra information (ISP/Organization) - if ($includeExtra) - { - $lines[] = ''; - - $unknown = Piwik_Translate('General_Unknown'); - - $org = !empty($locationInfo[self::ORG_KEY]) ? $locationInfo[self::ORG_KEY] : $unknown; - $lines[] = "Org: $org"; - - $isp = !empty($locationInfo[self::ISP_KEY]) ? $locationInfo[self::ISP_KEY] : $unknown; - $lines[] = "ISP: $isp"; - } - - return implode($newline, $lines); - } - - /** - * Returns an IP address from an array that was passed into getLocation. This - * will return an IPv4 address or false if the address is IPv6 (IPv6 is not - * supported yet). - * - * @param array $ip Must have 'ip' key. - * @return string|bool - */ - protected function getIpFromInfo( $info ) - { - $ip = $info['ip']; - if (Piwik_IP::isMappedIPv4($ip)) - { - return Piwik_IP::getIPv4FromMappedIPv6($ip); - } - else if (Piwik_IP::isIPv6($ip)) // IPv6 is not supported (yet) - { - return false; - } - else - { - return $ip; - } - } + const NOT_INSTALLED = 0; + const INSTALLED = 1; + const BROKEN = 2; + + const CURRENT_PROVIDER_OPTION_NAME = 'usercountry.location_provider'; + + const GEOGRAPHIC_COORD_PRECISION = 3; + + const CONTINENT_CODE_KEY = 'continent_code'; + const CONTINENT_NAME_KEY = 'continent_name'; + const COUNTRY_CODE_KEY = 'country_code'; + const COUNTRY_NAME_KEY = 'country_name'; + const REGION_CODE_KEY = 'region_code'; + const REGION_NAME_KEY = 'region_name'; + const CITY_NAME_KEY = 'city_name'; + const AREA_CODE_KEY = 'area_code'; + const LATITUDE_KEY = 'lat'; + const LONGITUDE_KEY = 'long'; + const POSTAL_CODE_KEY = 'postal_code'; + const ISP_KEY = 'isp'; + const ORG_KEY = 'org'; + + /** + * An array of all provider instances. Access it through static methods. + * + * @var array + */ + public static $providers = null; + + /** + * Returns location information based on visitor information. + * + * The result of this function will be an array. The array can store some or all of + * the following information: + * + * - Continent Code: The code of the visitor's continent. + * (array key is self::CONTINENT_CODE_KEY) + * - Continent Name: The name of the visitor's continent. + * (array key is self::CONTINENT_NAME_KEY) + * - Country Code: The code of the visitor's country. + * (array key is self::COUNTRY_CODE_KEY) + * - Country Name: The name of the visitor's country. + * (array key is self::COUNTRY_NAME_KEY) + * - Region Code: The code of the visitor's region. + * (array key is self::REGION_CODE_KEY) + * - Region Name: The name of the visitor's region. + * (array key is self::REGION_NAME_KEY) + * - City Name: The name of the visitor's city. + * (array key is self::CITY_NAME_KEY) + * - Area Code: The visitor's area code. + * (array key is self::AREA_CODE_KEY) + * - Latitude: The visitor's latitude. + * (array key is self::LATITUDE_KEY) + * - Longitude: The visitor's longitude. + * (array key is self::LONGITUDE_KEY) + * - Postal Code: The visitor's postal code. + * (array key is self::POSTAL_CODE_KEY) + * - ISP: The visitor's ISP. + * (array key is self::ISP_KEY) + * - Org: The company/organization of the visitor's IP. + * (array key is self::ORG_KEY) + * + * All LocationProviders will attempt to return the country of the visitor. + * + * @param array $info What this must contain depends on the specific provider + * implementation. All providers require an 'ip' key mapped + * to the visitor's IP address. + * @return array|false + */ + abstract public function getLocation($info); + + /** + * Returns true if this provider is available for use, false if otherwise. + * + * @return bool + */ + abstract public function isAvailable(); + + /** + * Returns true if this provider is working, false if otherwise. + * + * @return bool + */ + abstract public function isWorking(); + + /** + * Returns an array mapping location result keys w/ bool values indicating whether + * that information is supported by this provider. If it is not supported, that means + * this provider either cannot get this information, or is not configured to get it. + * + * @return array eg. array(self::CONTINENT_CODE_KEY => true, + * self::CONTINENT_NAME_KEY => true, + * self::ORG_KEY => false) + * The result is not guaranteed to have keys for every type of location + * info. + */ + abstract public function getSupportedLocationInfo(); + + /** + * Returns every available provider instance. + * + * @return array + */ + public static function getAllProviders() + { + if (is_null(self::$providers)) { + self::$providers = array(); + foreach (get_declared_classes() as $klass) { + if (is_subclass_of($klass, 'Piwik_UserCountry_LocationProvider')) { + $klassInfo = new ReflectionClass($klass); + if ($klassInfo->isAbstract()) { + continue; + } + + self::$providers[] = new $klass; + } + } + } + + return self::$providers; + } + + /** + * Returns all provider instances that are 'available'. An 'available' provider + * is one that is available for use. They may not necessarily be working. + * + * @return array + */ + public static function getAvailableProviders() + { + $result = array(); + foreach (self::getAllProviders() as $provider) { + if ($provider->isAvailable()) { + $result[] = $provider; + } + } + return $result; + } + + /** + * Returns an array mapping provider IDs w/ information about the provider, + * for each location provider. + * + * The following information is provided for each provider: + * 'id' - The provider's unique string ID. + * 'title' - The provider's title. + * 'description' - A description of how the location provider works. + * 'status' - Either self::NOT_INSTALLED, self::INSTALLED or self::BROKEN. + * 'statusMessage' - If the status is self::BROKEN, then the message describes why. + * 'location' - A pretty formatted location of the current IP address + * (Piwik_IP::getIpFromHeader()). + * + * An example result: + * array( + * 'geoip_php' => array('id' => 'geoip_php', + * 'title' => '...', + * 'desc' => '...', + * 'status' => Piwik_UserCountry_LocationProvider_GeoIp::BROKEN, + * 'statusMessage' => '...', + * 'location' => '...') + * 'geoip_serverbased' => array(...) + * ) + * + * @param string $newline What to separate lines with in the pretty locations. + * @param bool $includeExtra Whether to include ISP/Org info in formatted location. + * @return array + */ + public static function getAllProviderInfo($newline = "\n", $includeExtra = false) + { + $allInfo = array(); + foreach (self::getAllProviders() as $provider) { + $info = $provider->getInfo(); + + $status = self::INSTALLED; + $location = false; + $statusMessage = false; + + $availableOrMessage = $provider->isAvailable(); + if ($availableOrMessage !== true) { + $status = self::NOT_INSTALLED; + if (is_string($availableOrMessage)) { + $statusMessage = $availableOrMessage; + } + } else { + $workingOrError = $provider->isWorking(); + if ($workingOrError === true) // if the implementation is configured correctly, get the location + { + $locInfo = array('ip' => Piwik_IP::getIpFromHeader(), + 'lang' => Piwik_Common::getBrowserLanguage(), + 'disable_fallbacks' => true); + + $location = $provider->getLocation($locInfo); + $location = self::prettyFormatLocation($location, $newline, $includeExtra); + } else // otherwise set an error message describing why + { + $status = self::BROKEN; + $statusMessage = $workingOrError; + } + } + + $info['status'] = $status; + $info['statusMessage'] = $statusMessage; + $info['location'] = $location; + + $allInfo[$info['order']] = $info; + } + + ksort($allInfo); + + $result = array(); + foreach ($allInfo as $info) { + $result[$info['id']] = $info; + } + return $result; + } + + /** + * Returns the ID of the currently used location provider. + * + * The used provider is stored in the 'usercountry.location_provider' option. + * + * This function should not be called by the Tracker. + * + * @return string + */ + public static function getCurrentProviderId() + { + $optionValue = Piwik_GetOption(self::CURRENT_PROVIDER_OPTION_NAME); + return $optionValue === false ? Piwik_UserCountry_LocationProvider_Default::ID : $optionValue; + } + + /** + * Returns the provider instance of the current location provider. + * + * This function should not be called by the Tracker. + * + * @return Piwik_UserCountry_LocationProvider + */ + public static function getCurrentProvider() + { + return self::getProviderById(self::getCurrentProviderId()); + } + + /** + * Sets the provider to use when tracking. + * + * @param string $providerId The ID of the provider to use. + * @return Piwik_UserCountry_LocationProvider The new current provider. + * @throws Exception If the provider ID is invalid. + */ + public static function setCurrentProvider($providerId) + { + $provider = self::getProviderById($providerId); + if ($provider === false) { + throw new Exception( + "Invalid provider ID '$providerId'. The provider either does not exist or is not available"); + } + Piwik_SetOption(self::CURRENT_PROVIDER_OPTION_NAME, $providerId); + Piwik_Tracker_Cache::clearCacheGeneral(); + return $provider; + } + + /** + * Returns a provider instance by ID or false if the ID is invalid or unavailable. + * + * @param string $providerId + * @return Piwik_UserCountry_LocationProvider|false + */ + public static function getProviderById($providerId) + { + foreach (self::getAvailableProviders() as $provider) { + $info = $provider->getInfo(); + if ($info['id'] == $providerId) { + return $provider; + } + } + return false; + } + + /** + * Tries to fill in any missing information in a location result. + * + * This method will try to set the continent code, continent name and country code + * using other information. + * + * Note: This function must always be called by location providers in getLocation. + * + * @param array $location The location information to modify. + */ + public function completeLocationResult(&$location) + { + // fill in continent code if country code is present + if (empty($location[self::CONTINENT_CODE_KEY]) + && !empty($location[self::COUNTRY_CODE_KEY]) + ) { + $countryCode = strtolower($location[self::COUNTRY_CODE_KEY]); + $location[self::CONTINENT_CODE_KEY] = Piwik_Common::getContinent($countryCode); + } + + // fill in continent name if continent code is present + if (empty($location[self::CONTINENT_NAME_KEY]) + && !empty($location[self::CONTINENT_CODE_KEY]) + ) { + $continentCode = strtolower($location[self::CONTINENT_CODE_KEY]); + $location[self::CONTINENT_NAME_KEY] = Piwik_Translate('UserCountry_continent_' . $continentCode); + } + + // fill in country name if country code is present + if (empty($location[self::COUNTRY_NAME_KEY]) + && !empty($location[self::COUNTRY_CODE_KEY]) + ) { + $countryCode = strtolower($location[self::COUNTRY_CODE_KEY]); + $location[self::COUNTRY_NAME_KEY] = Piwik_Translate('UserCountry_country_' . $countryCode); + } + + // deal w/ improper latitude/longitude & round proper values + if (!empty($location[self::LATITUDE_KEY])) { + if (is_numeric($location[self::LATITUDE_KEY])) { + $location[self::LATITUDE_KEY] = round($location[self::LATITUDE_KEY], self::GEOGRAPHIC_COORD_PRECISION); + } else { + unset($location[self::LATITUDE_KEY]); + } + } + + if (!empty($location[self::LONGITUDE_KEY])) { + if (is_numeric($location[self::LONGITUDE_KEY])) { + $location[self::LONGITUDE_KEY] = round($location[self::LONGITUDE_KEY], self::GEOGRAPHIC_COORD_PRECISION); + } else { + unset($location[self::LONGITUDE_KEY]); + } + } + } + + /** + * Returns a prettified location result. + * + * @param array|false $locationInfo + * @param string $newline The line separator (ie, \n or <br/>). + * @param bool $includeExtra Whether to include ISP/Organization info. + * @return string + */ + public static function prettyFormatLocation($locationInfo, $newline = "\n", $includeExtra = false) + { + if ($locationInfo === false) { + return Piwik_Translate('General_Unknown'); + } + + // add latitude/longitude line + $lines = array(); + if (!empty($locationInfo[self::LATITUDE_KEY]) + && !empty($locationInfo[self::LONGITUDE_KEY]) + ) { + $lines[] = '(' . $locationInfo[self::LATITUDE_KEY] . ', ' . $locationInfo[self::LONGITUDE_KEY] . ')'; + } + + // add city/state line + $cityState = array(); + if (!empty($locationInfo[self::CITY_NAME_KEY])) { + $cityState[] = $locationInfo[self::CITY_NAME_KEY]; + } + + if (!empty($locationInfo[self::REGION_CODE_KEY])) { + $cityState[] = $locationInfo[self::REGION_CODE_KEY]; + } else if (!empty($locationInfo[self::REGION_NAME_KEY])) { + $cityState[] = $locationInfo[self::REGION_NAME_KEY]; + } + + if (!empty($cityState)) { + $lines[] = implode(', ', $cityState); + } + + // add postal code line + if (!empty($locationInfo[self::POSTAL_CODE_KEY])) { + $lines[] = $locationInfo[self::POSTAL_CODE_KEY]; + } + + // add country line + if (!empty($locationInfo[self::COUNTRY_NAME_KEY])) { + $lines[] = $locationInfo[self::COUNTRY_NAME_KEY]; + } else if (!empty($locationInfo[self::COUNTRY_CODE_KEY])) { + $lines[] = $locationInfo[self::COUNTRY_CODE_KEY]; + } + + // add extra information (ISP/Organization) + if ($includeExtra) { + $lines[] = ''; + + $unknown = Piwik_Translate('General_Unknown'); + + $org = !empty($locationInfo[self::ORG_KEY]) ? $locationInfo[self::ORG_KEY] : $unknown; + $lines[] = "Org: $org"; + + $isp = !empty($locationInfo[self::ISP_KEY]) ? $locationInfo[self::ISP_KEY] : $unknown; + $lines[] = "ISP: $isp"; + } + + return implode($newline, $lines); + } + + /** + * Returns an IP address from an array that was passed into getLocation. This + * will return an IPv4 address or false if the address is IPv6 (IPv6 is not + * supported yet). + * + * @param array $ip Must have 'ip' key. + * @return string|bool + */ + protected function getIpFromInfo($info) + { + $ip = $info['ip']; + if (Piwik_IP::isMappedIPv4($ip)) { + return Piwik_IP::getIPv4FromMappedIPv6($ip); + } else if (Piwik_IP::isIPv6($ip)) // IPv6 is not supported (yet) + { + return false; + } else { + return $ip; + } + } } |