Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattab <matthieu.aubry@gmail.com>2013-03-28 03:42:39 +0400
committermattab <matthieu.aubry@gmail.com>2013-03-28 03:42:40 +0400
commitae4b03163792f0b6e933933e5d37df87dc3fd566 (patch)
treed1d7510a9728f587d3d63ebd03e4ecf3d904838b /plugins/UserCountry/LocationProvider
parent158c2150f5f2e13ece459b8d131244c11b763997 (diff)
Mass conversion of all files to the newly agreed coding standard: PSR 1/2
Converting Piwik core source files, PHP, JS, TPL, CSS More info: http://piwik.org/participate/coding-standards/
Diffstat (limited to 'plugins/UserCountry/LocationProvider')
-rwxr-xr-xplugins/UserCountry/LocationProvider/Default.php182
-rwxr-xr-xplugins/UserCountry/LocationProvider/GeoIp.php495
-rwxr-xr-xplugins/UserCountry/LocationProvider/GeoIp/Pecl.php641
-rwxr-xr-xplugins/UserCountry/LocationProvider/GeoIp/Php.php651
-rwxr-xr-xplugins/UserCountry/LocationProvider/GeoIp/ServerBased.php547
5 files changed, 1208 insertions, 1308 deletions
diff --git a/plugins/UserCountry/LocationProvider/Default.php b/plugins/UserCountry/LocationProvider/Default.php
index a24c3a7cd9..f19fc47641 100755
--- a/plugins/UserCountry/LocationProvider/Default.php
+++ b/plugins/UserCountry/LocationProvider/Default.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
*/
@@ -12,99 +12,99 @@
/**
* The default LocationProvider, this LocationProvider guesses a visitor's country
* using the language they use. This provider is not very accurate.
- *
+ *
* @package Piwik_UserCountry
*/
class Piwik_UserCountry_LocationProvider_Default extends Piwik_UserCountry_LocationProvider
{
- const ID = 'default';
- const TITLE = 'General_Default';
-
- /**
- * Guesses a visitor's location using a visitor's browser language.
- *
- * @param array $info Contains 'ip' & 'lang' keys.
- * @return array Contains the guessed country code mapped to LocationProvider::COUNTRY_CODE_KEY.
- */
- public function getLocation( $info )
- {
- $enableLanguageToCountryGuess = Piwik_Config::getInstance()->Tracker['enable_language_to_country_guess'];
+ const ID = 'default';
+ const TITLE = 'General_Default';
- if(empty($info['lang'])) {
- $info['lang'] = Piwik_Common::getBrowserLanguage();
- }
- $country = Piwik_Common::getCountry($info['lang'], $enableLanguageToCountryGuess, $info['ip']);
-
- $location = array(parent::COUNTRY_CODE_KEY => $country);
- $this->completeLocationResult($location);
-
- return $location;
- }
-
- /**
- * Returns whether this location provider is available.
- *
- * This implementation is always available.
- *
- * @return true
- */
- public function isAvailable()
- {
- return true;
- }
-
- /**
- * Returns whether this location provider is working correctly.
- *
- * This implementation is always working correctly.
- *
- * @return true
- */
- public function isWorking()
- {
- return true;
- }
-
- /**
- * Returns an array describing the types of location information this provider will
- * return.
- *
- * This provider supports the following types of location info:
- * - continent code
- * - continent name
- * - country code
- * - country name
- *
- * @return array
- */
- public function getSupportedLocationInfo()
- {
- return array(self::CONTINENT_CODE_KEY => true,
- self::CONTINENT_NAME_KEY => true,
- self::COUNTRY_CODE_KEY => true,
- self::COUNTRY_NAME_KEY => true);
- }
-
- /**
- * Returns information about this location provider. Contains an id, title & description:
- *
- * array(
- * 'id' => 'default',
- * 'title' => '...',
- * 'description' => '...'
- * );
- *
- * @return array
- */
- public function getInfo()
- {
- $desc = Piwik_Translate('UserCountry_DefaultLocationProviderDesc1') . ' '
- . Piwik_Translate('UserCountry_DefaultLocationProviderDesc2',
- array('<strong>', '<em>', '</em>', '</strong>'))
- . '<p><em><a href="http://piwik.org/faq/how-to/#faq_163" target="_blank">'
- . Piwik_Translate('UserCountry_HowToInstallGeoIPDatabases')
- . '</em></a></p>';
- return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1);
- }
+ /**
+ * Guesses a visitor's location using a visitor's browser language.
+ *
+ * @param array $info Contains 'ip' & 'lang' keys.
+ * @return array Contains the guessed country code mapped to LocationProvider::COUNTRY_CODE_KEY.
+ */
+ public function getLocation($info)
+ {
+ $enableLanguageToCountryGuess = Piwik_Config::getInstance()->Tracker['enable_language_to_country_guess'];
+
+ if (empty($info['lang'])) {
+ $info['lang'] = Piwik_Common::getBrowserLanguage();
+ }
+ $country = Piwik_Common::getCountry($info['lang'], $enableLanguageToCountryGuess, $info['ip']);
+
+ $location = array(parent::COUNTRY_CODE_KEY => $country);
+ $this->completeLocationResult($location);
+
+ return $location;
+ }
+
+ /**
+ * Returns whether this location provider is available.
+ *
+ * This implementation is always available.
+ *
+ * @return true
+ */
+ public function isAvailable()
+ {
+ return true;
+ }
+
+ /**
+ * Returns whether this location provider is working correctly.
+ *
+ * This implementation is always working correctly.
+ *
+ * @return true
+ */
+ public function isWorking()
+ {
+ return true;
+ }
+
+ /**
+ * Returns an array describing the types of location information this provider will
+ * return.
+ *
+ * This provider supports the following types of location info:
+ * - continent code
+ * - continent name
+ * - country code
+ * - country name
+ *
+ * @return array
+ */
+ public function getSupportedLocationInfo()
+ {
+ return array(self::CONTINENT_CODE_KEY => true,
+ self::CONTINENT_NAME_KEY => true,
+ self::COUNTRY_CODE_KEY => true,
+ self::COUNTRY_NAME_KEY => true);
+ }
+
+ /**
+ * Returns information about this location provider. Contains an id, title & description:
+ *
+ * array(
+ * 'id' => 'default',
+ * 'title' => '...',
+ * 'description' => '...'
+ * );
+ *
+ * @return array
+ */
+ public function getInfo()
+ {
+ $desc = Piwik_Translate('UserCountry_DefaultLocationProviderDesc1') . ' '
+ . Piwik_Translate('UserCountry_DefaultLocationProviderDesc2',
+ array('<strong>', '<em>', '</em>', '</strong>'))
+ . '<p><em><a href="http://piwik.org/faq/how-to/#faq_163" target="_blank">'
+ . Piwik_Translate('UserCountry_HowToInstallGeoIPDatabases')
+ . '</em></a></p>';
+ return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1);
+ }
}
diff --git a/plugins/UserCountry/LocationProvider/GeoIp.php b/plugins/UserCountry/LocationProvider/GeoIp.php
index 4af024ae96..f7a9029797 100755
--- a/plugins/UserCountry/LocationProvider/GeoIp.php
+++ b/plugins/UserCountry/LocationProvider/GeoIp.php
@@ -1,274 +1,257 @@
<?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
*/
/**
* Base type for all GeoIP LocationProviders.
- *
+ *
* @package Piwik_UserCountry
*/
abstract class Piwik_UserCountry_LocationProvider_GeoIp extends Piwik_UserCountry_LocationProvider
{
- /* For testing, use: 'http://piwik-team.s3.amazonaws.com/GeoLiteCity.dat.gz' */
- const GEO_LITE_URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz';
- const TEST_IP = '194.57.91.215';
-
- public static $geoIPDatabaseDir = 'misc';
-
- /**
- * Stores possible database file names categorized by the type of information
- * GeoIP databases hold.
- *
- * @var array
- */
- public static $dbNames = array(
- 'loc' => array('GeoIPCity.dat', 'GeoLiteCity.dat', 'GeoIP.dat'),
- 'isp' => array('GeoIPISP.dat'),
- 'org' => array('GeoIPOrg.dat'),
- );
-
- /**
- * Cached region name array. Data is from geoipregionvars.php.
- *
- * @var array
- */
- private static $regionNames = null;
-
- /**
- * Attempts to fill in some missing information in a GeoIP location.
- *
- * This method will call LocationProvider::completeLocationResult and then
- * try to set the region name of the location if the country code & region
- * code are set.
- *
- * @param array $location The location information to modify.
- */
- public function completeLocationResult( &$location )
- {
- $this->fixupLocation($location);
- parent::completeLocationResult($location);
-
- // set region name if region code is set
- if (empty($location[self::REGION_NAME_KEY])
- && !empty($location[self::REGION_CODE_KEY])
- && !empty($location[self::COUNTRY_CODE_KEY]))
- {
- $countryCode = $location[self::COUNTRY_CODE_KEY];
- $regionCode = (string)$location[self::REGION_CODE_KEY];
- $location[self::REGION_NAME_KEY] = self::getRegionNameFromCodes($countryCode, $regionCode);
- }
- }
-
- /**
- * Fix up data to work with our SVG maps which include 'Tib' boundaries
- */
- protected function fixupLocation( &$location )
- {
- if(!empty($location[self::REGION_CODE_KEY])
- && $location[self::REGION_CODE_KEY] == '14'
- && !empty($location[self::COUNTRY_CODE_KEY])
- && strtoupper($location[self::COUNTRY_CODE_KEY]) == 'CN')
- {
- $location[self::COUNTRY_CODE_KEY] = 'ti';
- $location[self::REGION_CODE_KEY] = '1';
- }
- }
-
- /**
- * Returns true if this provider has been setup correctly, the error message if
- * otherwise.
- *
- * @return bool|string
- */
- public function isWorking()
- {
- // test with an example IP to make sure the provider is working
- // NOTE: At the moment only country, region & city info is tested.
- try
- {
- $supportedInfo = $this->getSupportedLocationInfo();
-
- list($testIp, $expectedResult) = self::getTestIpAndResult();
-
- // get location using test IP
- $location = $this->getLocation(array('ip' => $testIp));
-
- // check that result is the same as expected
- $isResultCorrect = true;
- foreach ($expectedResult as $key => $value)
- {
- // if this provider is not configured to support this information type, skip it
- if (empty($supportedInfo[$key]))
- {
- continue;
- }
-
- if (empty($location[$key])
- || $location[$key] != $value)
- {
- $isResultCorrect = false;
- }
- }
-
- if (!$isResultCorrect)
- {
- $unknown = Piwik_Translate('General_Unknown');
-
- $location = "'"
- . (empty($location[self::CITY_NAME_KEY]) ? $unknown : $location[self::CITY_NAME_KEY])
- . ", "
- . (empty($location[self::REGION_CODE_KEY]) ? $unknown : $location[self::REGION_CODE_KEY])
- . ", "
- . (empty($location[self::COUNTRY_CODE_KEY]) ? $unknown : $location[self::COUNTRY_CODE_KEY])
- . "'"
- ;
-
- $expectedLocation = "'".$expectedResult[self::CITY_NAME_KEY].", "
- . $expectedResult[self::REGION_CODE_KEY].", "
- . $expectedResult[self::COUNTRY_CODE_KEY]."'";
-
- $bind = array($testIp, $location, $expectedLocation);
- return Piwik_Translate('UserCountry_TestIPLocatorFailed', $bind);
- }
-
- return true;
- }
- catch (Exception $ex)
- {
- return $ex->getMessage();
- }
- }
-
- /**
- * Returns a region name for a country code + region code.
- *
- * @param string $countryCode
- * @param string $regionCode
- * @return string The region name or 'Unknown' (translated).
- */
- public static function getRegionNameFromCodes( $countryCode, $regionCode )
- {
- $regionNames = self::getRegionNames();
-
- $countryCode = strtoupper($countryCode);
- $regionCode = strtoupper($regionCode);
-
- if (isset($regionNames[$countryCode][$regionCode]))
- {
- return $regionNames[$countryCode][$regionCode];
- }
- else
- {
- return Piwik_Translate('General_Unknown');
- }
- }
-
- /**
- * Returns an array of region names mapped by country code & region code.
- *
- * @return array
- */
- public static function getRegionNames()
- {
- if (is_null(self::$regionNames))
- {
- require_once PIWIK_INCLUDE_PATH . '/libs/MaxMindGeoIP/geoipregionvars.php';
- self::$regionNames = $GEOIP_REGION_NAME;
- }
-
- return self::$regionNames;
- }
-
- /**
- * Returns the path of an existing GeoIP database or false if none can be found.
- *
- * @param array $possibleFileNames The list of possible file names for the GeoIP database.
- * @return string|false
- */
- public static function getPathToGeoIpDatabase( $possibleFileNames )
- {
- foreach ($possibleFileNames as $filename)
- {
- $path = self::getPathForGeoIpDatabase($filename);
- if (file_exists($path))
- {
- return $path;
- }
- }
- return false;
- }
-
- /**
- * Returns full path for a GeoIP database managed by Piwik.
- *
- * @param string $filename Name of the .dat file.
- * @return string
- */
- public static function getPathForGeoIpDatabase( $filename )
- {
- return PIWIK_INCLUDE_PATH.'/'.self::$geoIPDatabaseDir.'/'.$filename;
- }
-
- /**
- * Returns test IP used by isWorking and expected result.
- *
- * @return array eg. array('1.2.3.4', array(self::COUNTRY_CODE_KEY => ...))
- */
- private static function getTestIpAndResult()
- {
- static $result = null;
- if (is_null($result))
- {
- // TODO: what happens when IP changes? should we get this information from piwik.org?
- $expected = array(self::COUNTRY_CODE_KEY => 'FR',
- self::REGION_CODE_KEY => 'A6',
- self::CITY_NAME_KEY => 'Besançon');
- $result = array(self::TEST_IP, $expected);
- }
- return $result;
- }
-
- /**
- * Returns true if there is a GeoIP database in the 'misc' directory.
- *
- * @return bool
- */
- public static function isDatabaseInstalled()
- {
- return self::getPathToGeoIpDatabase(self::$dbNames['loc'])
- || self::getPathToGeoIpDatabase(self::$dbNames['isp'])
- || self::getPathToGeoIpDatabase(self::$dbNames['org']);
- }
-
- /**
- * Returns the type of GeoIP database ('loc', 'isp' or 'org') based on the
- * filename (eg, 'GeoLiteCity.dat', 'GeoIPISP.dat', etc).
- *
- * @param string $filename
- * @return string|false 'loc', 'isp', 'org', or false if cannot find a database
- * type.
- */
- public static function getGeoIPDatabaseTypeFromFilename( $filename )
- {
- foreach (self::$dbNames as $key => $names)
- {
- foreach ($names as $name)
- {
- if ($name === $filename)
- {
- return $key;
- }
- }
- }
- return false;
- }
+ /* For testing, use: 'http://piwik-team.s3.amazonaws.com/GeoLiteCity.dat.gz' */
+ const GEO_LITE_URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz';
+ const TEST_IP = '194.57.91.215';
+
+ public static $geoIPDatabaseDir = 'misc';
+
+ /**
+ * Stores possible database file names categorized by the type of information
+ * GeoIP databases hold.
+ *
+ * @var array
+ */
+ public static $dbNames = array(
+ 'loc' => array('GeoIPCity.dat', 'GeoLiteCity.dat', 'GeoIP.dat'),
+ 'isp' => array('GeoIPISP.dat'),
+ 'org' => array('GeoIPOrg.dat'),
+ );
+
+ /**
+ * Cached region name array. Data is from geoipregionvars.php.
+ *
+ * @var array
+ */
+ private static $regionNames = null;
+
+ /**
+ * Attempts to fill in some missing information in a GeoIP location.
+ *
+ * This method will call LocationProvider::completeLocationResult and then
+ * try to set the region name of the location if the country code & region
+ * code are set.
+ *
+ * @param array $location The location information to modify.
+ */
+ public function completeLocationResult(&$location)
+ {
+ $this->fixupLocation($location);
+ parent::completeLocationResult($location);
+
+ // set region name if region code is set
+ if (empty($location[self::REGION_NAME_KEY])
+ && !empty($location[self::REGION_CODE_KEY])
+ && !empty($location[self::COUNTRY_CODE_KEY])
+ ) {
+ $countryCode = $location[self::COUNTRY_CODE_KEY];
+ $regionCode = (string)$location[self::REGION_CODE_KEY];
+ $location[self::REGION_NAME_KEY] = self::getRegionNameFromCodes($countryCode, $regionCode);
+ }
+ }
+
+ /**
+ * Fix up data to work with our SVG maps which include 'Tib' boundaries
+ */
+ protected function fixupLocation(&$location)
+ {
+ if (!empty($location[self::REGION_CODE_KEY])
+ && $location[self::REGION_CODE_KEY] == '14'
+ && !empty($location[self::COUNTRY_CODE_KEY])
+ && strtoupper($location[self::COUNTRY_CODE_KEY]) == 'CN'
+ ) {
+ $location[self::COUNTRY_CODE_KEY] = 'ti';
+ $location[self::REGION_CODE_KEY] = '1';
+ }
+ }
+
+ /**
+ * Returns true if this provider has been setup correctly, the error message if
+ * otherwise.
+ *
+ * @return bool|string
+ */
+ public function isWorking()
+ {
+ // test with an example IP to make sure the provider is working
+ // NOTE: At the moment only country, region & city info is tested.
+ try {
+ $supportedInfo = $this->getSupportedLocationInfo();
+
+ list($testIp, $expectedResult) = self::getTestIpAndResult();
+
+ // get location using test IP
+ $location = $this->getLocation(array('ip' => $testIp));
+
+ // check that result is the same as expected
+ $isResultCorrect = true;
+ foreach ($expectedResult as $key => $value) {
+ // if this provider is not configured to support this information type, skip it
+ if (empty($supportedInfo[$key])) {
+ continue;
+ }
+
+ if (empty($location[$key])
+ || $location[$key] != $value
+ ) {
+ $isResultCorrect = false;
+ }
+ }
+
+ if (!$isResultCorrect) {
+ $unknown = Piwik_Translate('General_Unknown');
+
+ $location = "'"
+ . (empty($location[self::CITY_NAME_KEY]) ? $unknown : $location[self::CITY_NAME_KEY])
+ . ", "
+ . (empty($location[self::REGION_CODE_KEY]) ? $unknown : $location[self::REGION_CODE_KEY])
+ . ", "
+ . (empty($location[self::COUNTRY_CODE_KEY]) ? $unknown : $location[self::COUNTRY_CODE_KEY])
+ . "'";
+
+ $expectedLocation = "'" . $expectedResult[self::CITY_NAME_KEY] . ", "
+ . $expectedResult[self::REGION_CODE_KEY] . ", "
+ . $expectedResult[self::COUNTRY_CODE_KEY] . "'";
+
+ $bind = array($testIp, $location, $expectedLocation);
+ return Piwik_Translate('UserCountry_TestIPLocatorFailed', $bind);
+ }
+
+ return true;
+ } catch (Exception $ex) {
+ return $ex->getMessage();
+ }
+ }
+
+ /**
+ * Returns a region name for a country code + region code.
+ *
+ * @param string $countryCode
+ * @param string $regionCode
+ * @return string The region name or 'Unknown' (translated).
+ */
+ public static function getRegionNameFromCodes($countryCode, $regionCode)
+ {
+ $regionNames = self::getRegionNames();
+
+ $countryCode = strtoupper($countryCode);
+ $regionCode = strtoupper($regionCode);
+
+ if (isset($regionNames[$countryCode][$regionCode])) {
+ return $regionNames[$countryCode][$regionCode];
+ } else {
+ return Piwik_Translate('General_Unknown');
+ }
+ }
+
+ /**
+ * Returns an array of region names mapped by country code & region code.
+ *
+ * @return array
+ */
+ public static function getRegionNames()
+ {
+ if (is_null(self::$regionNames)) {
+ require_once PIWIK_INCLUDE_PATH . '/libs/MaxMindGeoIP/geoipregionvars.php';
+ self::$regionNames = $GEOIP_REGION_NAME;
+ }
+
+ return self::$regionNames;
+ }
+
+ /**
+ * Returns the path of an existing GeoIP database or false if none can be found.
+ *
+ * @param array $possibleFileNames The list of possible file names for the GeoIP database.
+ * @return string|false
+ */
+ public static function getPathToGeoIpDatabase($possibleFileNames)
+ {
+ foreach ($possibleFileNames as $filename) {
+ $path = self::getPathForGeoIpDatabase($filename);
+ if (file_exists($path)) {
+ return $path;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns full path for a GeoIP database managed by Piwik.
+ *
+ * @param string $filename Name of the .dat file.
+ * @return string
+ */
+ public static function getPathForGeoIpDatabase($filename)
+ {
+ return PIWIK_INCLUDE_PATH . '/' . self::$geoIPDatabaseDir . '/' . $filename;
+ }
+
+ /**
+ * Returns test IP used by isWorking and expected result.
+ *
+ * @return array eg. array('1.2.3.4', array(self::COUNTRY_CODE_KEY => ...))
+ */
+ private static function getTestIpAndResult()
+ {
+ static $result = null;
+ if (is_null($result)) {
+ // TODO: what happens when IP changes? should we get this information from piwik.org?
+ $expected = array(self::COUNTRY_CODE_KEY => 'FR',
+ self::REGION_CODE_KEY => 'A6',
+ self::CITY_NAME_KEY => 'Besançon');
+ $result = array(self::TEST_IP, $expected);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns true if there is a GeoIP database in the 'misc' directory.
+ *
+ * @return bool
+ */
+ public static function isDatabaseInstalled()
+ {
+ return self::getPathToGeoIpDatabase(self::$dbNames['loc'])
+ || self::getPathToGeoIpDatabase(self::$dbNames['isp'])
+ || self::getPathToGeoIpDatabase(self::$dbNames['org']);
+ }
+
+ /**
+ * Returns the type of GeoIP database ('loc', 'isp' or 'org') based on the
+ * filename (eg, 'GeoLiteCity.dat', 'GeoIPISP.dat', etc).
+ *
+ * @param string $filename
+ * @return string|false 'loc', 'isp', 'org', or false if cannot find a database
+ * type.
+ */
+ public static function getGeoIPDatabaseTypeFromFilename($filename)
+ {
+ foreach (self::$dbNames as $key => $names) {
+ foreach ($names as $name) {
+ if ($name === $filename) {
+ return $key;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php b/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php
index b484cbf6b5..9ffc4ffa0a 100755
--- a/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php
+++ b/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php
@@ -1,353 +1,324 @@
<?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
*/
/**
* A LocationProvider that uses the PECL implementation of GeoIP.
- *
+ *
* FIXME: For some reason, if the PECL module is loaded & an organization DB is available, the PHP
* module won't return organization info. If the PECL module is not loaded, organization info is returned.
- *
+ *
* @package Piwik_UserCountry
*/
class Piwik_UserCountry_LocationProvider_GeoIp_Pecl extends Piwik_UserCountry_LocationProvider_GeoIp
{
- const ID = 'geoip_pecl';
- const TITLE = 'GeoIP (PECL)';
-
- /**
- * Uses the GeoIP PECL module to get a visitor's location based on their IP address.
- *
- * This function will return different results based on the data available. If a city
- * database can be detected by the PECL module, it may return the country code,
- * region code, city name, area code, latitude, longitude and postal code of the visitor.
- *
- * Alternatively, if only the country database can be detected, only the country code
- * will be returned.
- *
- * The GeoIP PECL module will detect the following filenames:
- * - GeoIP.dat
- * - GeoIPCity.dat
- * - GeoIPISP.dat
- * - GeoIPOrg.dat
- *
- * Note how GeoLiteCity.dat, the name for the GeoLite city database, is not detected
- * by the PECL module.
- *
- * @param array $info Must have an 'ip' field.
- * @return array
- */
- public function getLocation( $info )
- {
- $ip = $this->getIpFromInfo($info);
-
- $result = array();
-
- // get location data
- if (self::isCityDatabaseAvailable())
- {
- // Must hide errors because missing IPV6:
- $location = @geoip_record_by_name($ip);
- if (!empty($location))
- {
- $result[self::COUNTRY_CODE_KEY] = $location['country_code'];
- $result[self::REGION_CODE_KEY] = $location['region'];
- $result[self::CITY_NAME_KEY] = utf8_encode($location['city']);
- $result[self::AREA_CODE_KEY] = $location['area_code'];
- $result[self::LATITUDE_KEY] = $location['latitude'];
- $result[self::LONGITUDE_KEY] = $location['longitude'];
- $result[self::POSTAL_CODE_KEY] = $location['postal_code'];
- }
- }
- else if (self::isRegionDatabaseAvailable())
- {
- $location = @geoip_region_by_name($ip);
- if (!empty($location))
- {
- $result[self::REGION_CODE_KEY] = $location['region'];
- $result[self::COUNTRY_CODE_KEY] = $location['country_code'];
- }
- }
- else
- {
- $result[self::COUNTRY_CODE_KEY] = @geoip_country_code_by_name($ip);
- }
-
- // get organization data if the org database is available
- if (self::isOrgDatabaseAvailable())
- {
- $org = @geoip_org_by_name($ip);
- if ($org !== false)
- {
- $result[self::ORG_KEY] = utf8_encode($org);
- }
- }
-
- // get isp data if the isp database is available
- if (self::isISPDatabaseAvailable())
- {
- $isp = @geoip_isp_by_name($ip);
- if ($ip !== false)
- {
- $result[self::ISP_KEY] = utf8_encode($isp);
- }
- }
-
- if (empty($result))
- {
- return false;
- }
-
- $this->completeLocationResult($result);
- return $result;
- }
-
- /**
- * Returns true if the PECL module is installed and loaded, false if otherwise.
- *
- * @return bool
- */
- public function isAvailable()
- {
- return function_exists('geoip_db_avail');
- }
-
- /**
- * Returns true if the PECL module that is installed can be successfully used
- * to get the location of an IP address.
- *
- * @return bool
- */
- public function isWorking()
- {
- // if no no location database is available, this implementation is not setup correctly
- if (!self::isLocationDatabaseAvailable())
- {
- $dbDir = dirname(geoip_db_filename(GEOIP_COUNTRY_EDITION)).'/';
- $quotedDir = "'$dbDir'";
-
- // check if the directory the PECL module is looking for exists
- if (!is_dir($dbDir))
- {
- return Piwik_Translate('UserCountry_PeclGeoIPNoDBDir', array($quotedDir, "'geoip.custom_directory'"));
- }
-
- // check if the user named the city database GeoLiteCity.dat
- if (file_exists($dbDir.'GeoLiteCity.dat'))
- {
- return Piwik_Translate('UserCountry_PeclGeoLiteError',
- array($quotedDir, "'GeoLiteCity.dat'", "'GeoIPCity.dat'"));
- }
-
- return Piwik_Translate('UserCountry_CannotFindPeclGeoIPDb',
- array($quotedDir, "'GeoIP.dat'", "'GeoIPCity.dat'"));
- }
-
- return parent::isWorking();
- }
-
- /**
- * Returns an array describing the types of location information this provider will
- * return.
- *
- * The location info this provider supports depends on what GeoIP databases it can
- * find.
- *
- * This provider will always support country & continent information.
- *
- * If a region database is found, then region code & name information will be
- * supported.
- *
- * If a city database is found, then region code, region name, city name,
- * area code, latitude, longitude & postal code are all supported.
- *
- * If an organization database is found, organization information is
- * supported.
- *
- * If an ISP database is found, ISP information is supported.
- *
- * @return array
- */
- public function getSupportedLocationInfo()
- {
- $result = array();
-
- // country & continent info always available
- $result[self::CONTINENT_CODE_KEY] = true;
- $result[self::CONTINENT_NAME_KEY] = true;
- $result[self::COUNTRY_CODE_KEY] = true;
- $result[self::COUNTRY_NAME_KEY] = true;
-
- if (self::isCityDatabaseAvailable())
- {
- $result[self::REGION_CODE_KEY] = true;
- $result[self::REGION_NAME_KEY] = true;
- $result[self::CITY_NAME_KEY] = true;
- $result[self::AREA_CODE_KEY] = true;
- $result[self::LATITUDE_KEY] = true;
- $result[self::LONGITUDE_KEY] = true;
- $result[self::POSTAL_CODE_KEY] = true;
- }
- else if (self::isRegionDatabaseAvailable())
- {
- $result[self::REGION_CODE_KEY] = true;
- $result[self::REGION_NAME_KEY] = true;
- }
-
- // check if organization info is available
- if (self::isOrgDatabaseAvailable())
- {
- $result[self::ORG_KEY] = true;
- }
-
- // check if ISP info is available
- if (self::isISPDatabaseAvailable())
- {
- $result[self::ISP_KEY] = true;
- }
-
- return $result;
- }
-
- /**
- * Returns information about this location provider. Contains an id, title & description:
- *
- * array(
- * 'id' => 'geoip_pecl',
- * 'title' => '...',
- * 'description' => '...'
- * );
- *
- * @return array
- */
- public function getInfo()
- {
- $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Pecl1') . '<br/><br/>'
- . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Pecl2');
- $installDocs = '<em>'
- . '<a target="_blank" href="http://piwik.org/faq/how-to/#faq_164">'
- . Piwik_Translate('UserCountry_HowToInstallGeoIpPecl')
- . '</a>'
- . '</em>';
-
- $extraMessage = false;
- if ($this->isAvailable())
- {
- $peclDir = ini_get('geoip.custom_directory');
- if ($peclDir === false)
- {
- $extraMessage = Piwik_Translate('UserCountry_GeoIPPeclCustomDirNotSet', "'geoip.custom_directory'");
- }
- else
- {
- $extraMessage = 'The \'geoip.custom_directory\' PHP ini option is set to \''.$peclDir.'\'.';
- }
-
- $availableDatabaseTypes = array();
- if (self::isCityDatabaseAvailable())
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_City');
- }
- if (self::isRegionDatabaseAvailable())
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Region');
- }
- if (self::isCountryDatabaseAvailable())
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Country');
- }
- if (self::isISPDatabaseAvailable())
- {
- $availableDatabaseTypes[] = 'ISP';
- }
- if (self::isOrgDatabaseAvailable())
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Organization');
- }
-
- $extraMessage .= '<br/><br/>'.Piwik_Translate('UserCountry_GeoIPImplHasAccessTo').':&nbsp;<strong><em>'
- . implode(', ', $availableDatabaseTypes).'</em></strong>.';
-
- $extraMessage = '<strong><em>'.Piwik_Translate('General_Note').':&nbsp;</em></strong>'.$extraMessage;
- }
-
- return array('id' => self::ID,
- 'title' => self::TITLE,
- 'description' => $desc,
- 'install_docs' => $installDocs,
- 'extra_message' => $extraMessage,
- 'order' => 3);
- }
-
- /**
- * Returns true if the PECL module can detect a location database (either a country,
- * region or city will do).
- *
- * @return bool
- */
- public static function isLocationDatabaseAvailable()
- {
- return self::isCityDatabaseAvailable()
- || self::isRegionDatabaseAvailable()
- || self::isCountryDatabaseAvailable();
- }
-
- /**
- * Returns true if the PECL module can detect a city database.
- *
- * @return bool
- */
- public static function isCityDatabaseAvailable()
- {
- return geoip_db_avail(GEOIP_CITY_EDITION_REV0)
- || geoip_db_avail(GEOIP_CITY_EDITION_REV1);
- }
-
- /**
- * Returns true if the PECL module can detect a region database.
- *
- * @return bool
- */
- public static function isRegionDatabaseAvailable()
- {
- return geoip_db_avail(GEOIP_REGION_EDITION_REV0)
- || geoip_db_avail(GEOIP_REGION_EDITION_REV1);
- }
-
- /**
- * Returns true if the PECL module can detect a country database.
- *
- * @return bool
- */
- public static function isCountryDatabaseAvailable()
- {
- return geoip_db_avail(GEOIP_COUNTRY_EDITION);
- }
-
- /**
- * Returns true if the PECL module can detect an organization database.
- *
- * @return bool
- */
- public static function isOrgDatabaseAvailable()
- {
- return geoip_db_avail(GEOIP_ORG_EDITION);
- }
-
- /**
- * Returns true if the PECL module can detect an ISP database.
- *
- * @return bool
- */
- public static function isISPDatabaseAvailable()
- {
- return geoip_db_avail(GEOIP_ISP_EDITION);
- }
+ const ID = 'geoip_pecl';
+ const TITLE = 'GeoIP (PECL)';
+
+ /**
+ * Uses the GeoIP PECL module to get a visitor's location based on their IP address.
+ *
+ * This function will return different results based on the data available. If a city
+ * database can be detected by the PECL module, it may return the country code,
+ * region code, city name, area code, latitude, longitude and postal code of the visitor.
+ *
+ * Alternatively, if only the country database can be detected, only the country code
+ * will be returned.
+ *
+ * The GeoIP PECL module will detect the following filenames:
+ * - GeoIP.dat
+ * - GeoIPCity.dat
+ * - GeoIPISP.dat
+ * - GeoIPOrg.dat
+ *
+ * Note how GeoLiteCity.dat, the name for the GeoLite city database, is not detected
+ * by the PECL module.
+ *
+ * @param array $info Must have an 'ip' field.
+ * @return array
+ */
+ public function getLocation($info)
+ {
+ $ip = $this->getIpFromInfo($info);
+
+ $result = array();
+
+ // get location data
+ if (self::isCityDatabaseAvailable()) {
+ // Must hide errors because missing IPV6:
+ $location = @geoip_record_by_name($ip);
+ if (!empty($location)) {
+ $result[self::COUNTRY_CODE_KEY] = $location['country_code'];
+ $result[self::REGION_CODE_KEY] = $location['region'];
+ $result[self::CITY_NAME_KEY] = utf8_encode($location['city']);
+ $result[self::AREA_CODE_KEY] = $location['area_code'];
+ $result[self::LATITUDE_KEY] = $location['latitude'];
+ $result[self::LONGITUDE_KEY] = $location['longitude'];
+ $result[self::POSTAL_CODE_KEY] = $location['postal_code'];
+ }
+ } else if (self::isRegionDatabaseAvailable()) {
+ $location = @geoip_region_by_name($ip);
+ if (!empty($location)) {
+ $result[self::REGION_CODE_KEY] = $location['region'];
+ $result[self::COUNTRY_CODE_KEY] = $location['country_code'];
+ }
+ } else {
+ $result[self::COUNTRY_CODE_KEY] = @geoip_country_code_by_name($ip);
+ }
+
+ // get organization data if the org database is available
+ if (self::isOrgDatabaseAvailable()) {
+ $org = @geoip_org_by_name($ip);
+ if ($org !== false) {
+ $result[self::ORG_KEY] = utf8_encode($org);
+ }
+ }
+
+ // get isp data if the isp database is available
+ if (self::isISPDatabaseAvailable()) {
+ $isp = @geoip_isp_by_name($ip);
+ if ($ip !== false) {
+ $result[self::ISP_KEY] = utf8_encode($isp);
+ }
+ }
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->completeLocationResult($result);
+ return $result;
+ }
+
+ /**
+ * Returns true if the PECL module is installed and loaded, false if otherwise.
+ *
+ * @return bool
+ */
+ public function isAvailable()
+ {
+ return function_exists('geoip_db_avail');
+ }
+
+ /**
+ * Returns true if the PECL module that is installed can be successfully used
+ * to get the location of an IP address.
+ *
+ * @return bool
+ */
+ public function isWorking()
+ {
+ // if no no location database is available, this implementation is not setup correctly
+ if (!self::isLocationDatabaseAvailable()) {
+ $dbDir = dirname(geoip_db_filename(GEOIP_COUNTRY_EDITION)) . '/';
+ $quotedDir = "'$dbDir'";
+
+ // check if the directory the PECL module is looking for exists
+ if (!is_dir($dbDir)) {
+ return Piwik_Translate('UserCountry_PeclGeoIPNoDBDir', array($quotedDir, "'geoip.custom_directory'"));
+ }
+
+ // check if the user named the city database GeoLiteCity.dat
+ if (file_exists($dbDir . 'GeoLiteCity.dat')) {
+ return Piwik_Translate('UserCountry_PeclGeoLiteError',
+ array($quotedDir, "'GeoLiteCity.dat'", "'GeoIPCity.dat'"));
+ }
+
+ return Piwik_Translate('UserCountry_CannotFindPeclGeoIPDb',
+ array($quotedDir, "'GeoIP.dat'", "'GeoIPCity.dat'"));
+ }
+
+ return parent::isWorking();
+ }
+
+ /**
+ * Returns an array describing the types of location information this provider will
+ * return.
+ *
+ * The location info this provider supports depends on what GeoIP databases it can
+ * find.
+ *
+ * This provider will always support country & continent information.
+ *
+ * If a region database is found, then region code & name information will be
+ * supported.
+ *
+ * If a city database is found, then region code, region name, city name,
+ * area code, latitude, longitude & postal code are all supported.
+ *
+ * If an organization database is found, organization information is
+ * supported.
+ *
+ * If an ISP database is found, ISP information is supported.
+ *
+ * @return array
+ */
+ public function getSupportedLocationInfo()
+ {
+ $result = array();
+
+ // country & continent info always available
+ $result[self::CONTINENT_CODE_KEY] = true;
+ $result[self::CONTINENT_NAME_KEY] = true;
+ $result[self::COUNTRY_CODE_KEY] = true;
+ $result[self::COUNTRY_NAME_KEY] = true;
+
+ if (self::isCityDatabaseAvailable()) {
+ $result[self::REGION_CODE_KEY] = true;
+ $result[self::REGION_NAME_KEY] = true;
+ $result[self::CITY_NAME_KEY] = true;
+ $result[self::AREA_CODE_KEY] = true;
+ $result[self::LATITUDE_KEY] = true;
+ $result[self::LONGITUDE_KEY] = true;
+ $result[self::POSTAL_CODE_KEY] = true;
+ } else if (self::isRegionDatabaseAvailable()) {
+ $result[self::REGION_CODE_KEY] = true;
+ $result[self::REGION_NAME_KEY] = true;
+ }
+
+ // check if organization info is available
+ if (self::isOrgDatabaseAvailable()) {
+ $result[self::ORG_KEY] = true;
+ }
+
+ // check if ISP info is available
+ if (self::isISPDatabaseAvailable()) {
+ $result[self::ISP_KEY] = true;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns information about this location provider. Contains an id, title & description:
+ *
+ * array(
+ * 'id' => 'geoip_pecl',
+ * 'title' => '...',
+ * 'description' => '...'
+ * );
+ *
+ * @return array
+ */
+ public function getInfo()
+ {
+ $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Pecl1') . '<br/><br/>'
+ . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Pecl2');
+ $installDocs = '<em>'
+ . '<a target="_blank" href="http://piwik.org/faq/how-to/#faq_164">'
+ . Piwik_Translate('UserCountry_HowToInstallGeoIpPecl')
+ . '</a>'
+ . '</em>';
+
+ $extraMessage = false;
+ if ($this->isAvailable()) {
+ $peclDir = ini_get('geoip.custom_directory');
+ if ($peclDir === false) {
+ $extraMessage = Piwik_Translate('UserCountry_GeoIPPeclCustomDirNotSet', "'geoip.custom_directory'");
+ } else {
+ $extraMessage = 'The \'geoip.custom_directory\' PHP ini option is set to \'' . $peclDir . '\'.';
+ }
+
+ $availableDatabaseTypes = array();
+ if (self::isCityDatabaseAvailable()) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_City');
+ }
+ if (self::isRegionDatabaseAvailable()) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Region');
+ }
+ if (self::isCountryDatabaseAvailable()) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Country');
+ }
+ if (self::isISPDatabaseAvailable()) {
+ $availableDatabaseTypes[] = 'ISP';
+ }
+ if (self::isOrgDatabaseAvailable()) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Organization');
+ }
+
+ $extraMessage .= '<br/><br/>' . Piwik_Translate('UserCountry_GeoIPImplHasAccessTo') . ':&nbsp;<strong><em>'
+ . implode(', ', $availableDatabaseTypes) . '</em></strong>.';
+
+ $extraMessage = '<strong><em>' . Piwik_Translate('General_Note') . ':&nbsp;</em></strong>' . $extraMessage;
+ }
+
+ return array('id' => self::ID,
+ 'title' => self::TITLE,
+ 'description' => $desc,
+ 'install_docs' => $installDocs,
+ 'extra_message' => $extraMessage,
+ 'order' => 3);
+ }
+
+ /**
+ * Returns true if the PECL module can detect a location database (either a country,
+ * region or city will do).
+ *
+ * @return bool
+ */
+ public static function isLocationDatabaseAvailable()
+ {
+ return self::isCityDatabaseAvailable()
+ || self::isRegionDatabaseAvailable()
+ || self::isCountryDatabaseAvailable();
+ }
+
+ /**
+ * Returns true if the PECL module can detect a city database.
+ *
+ * @return bool
+ */
+ public static function isCityDatabaseAvailable()
+ {
+ return geoip_db_avail(GEOIP_CITY_EDITION_REV0)
+ || geoip_db_avail(GEOIP_CITY_EDITION_REV1);
+ }
+
+ /**
+ * Returns true if the PECL module can detect a region database.
+ *
+ * @return bool
+ */
+ public static function isRegionDatabaseAvailable()
+ {
+ return geoip_db_avail(GEOIP_REGION_EDITION_REV0)
+ || geoip_db_avail(GEOIP_REGION_EDITION_REV1);
+ }
+
+ /**
+ * Returns true if the PECL module can detect a country database.
+ *
+ * @return bool
+ */
+ public static function isCountryDatabaseAvailable()
+ {
+ return geoip_db_avail(GEOIP_COUNTRY_EDITION);
+ }
+
+ /**
+ * Returns true if the PECL module can detect an organization database.
+ *
+ * @return bool
+ */
+ public static function isOrgDatabaseAvailable()
+ {
+ return geoip_db_avail(GEOIP_ORG_EDITION);
+ }
+
+ /**
+ * Returns true if the PECL module can detect an ISP database.
+ *
+ * @return bool
+ */
+ public static function isISPDatabaseAvailable()
+ {
+ return geoip_db_avail(GEOIP_ISP_EDITION);
+ }
}
diff --git a/plugins/UserCountry/LocationProvider/GeoIp/Php.php b/plugins/UserCountry/LocationProvider/GeoIp/Php.php
index c2443822fd..7e60ac520a 100755
--- a/plugins/UserCountry/LocationProvider/GeoIp/Php.php
+++ b/plugins/UserCountry/LocationProvider/GeoIp/Php.php
@@ -1,355 +1,330 @@
<?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
*/
/**
* A LocationProvider that uses the PHP implementation of GeoIP.
- *
+ *
* @package Piwik_UserCountry
*/
class Piwik_UserCountry_LocationProvider_GeoIp_Php extends Piwik_UserCountry_LocationProvider_GeoIp
{
- const ID = 'geoip_php';
- const TITLE = 'GeoIP (Php)';
-
- /**
- * The GeoIP database instances used. This array will contain at most three
- * of them: one for location info, one for ISP info and another for organization
- * info.
- *
- * Each instance is mapped w/ one of the following keys: 'loc', 'isp', 'org'
- *
- * @var array of GeoIP instances
- */
- private $geoIpCache = array();
-
- /**
- * Possible filenames for each type of GeoIP database. When looking for a database
- * file in the 'misc' subdirectory, files with these names will be looked for.
- *
- * This variable is an array mapping either the 'loc', 'isp' or 'org' strings with
- * an array of filenames.
- *
- * By default, this will be set to Piwik_UserCountry_LocationProvider_GeoIp_Php::$dbNames.
- *
- * @var array
- */
- private $customDbNames;
-
- /**
- * Constructor.
- *
- * @param array|false $customDbNames The possible filenames for each type of GeoIP database.
- * eg array(
- * 'loc' => array('GeoLiteCity.dat'),
- * 'isp' => array('GeoIP.dat', 'GeoIPISP.dat')
- * 'org' => array('GeoIPOrg.dat')
- * )
- * If a key is missing (or the parameter not supplied), then the
- * default database names are used.
- */
- public function __construct( $customDbNames = false )
- {
- $this->customDbNames = parent::$dbNames;
- if ($customDbNames !== false)
- {
- foreach ($this->customDbNames as $key => $names)
- {
- if (isset($customDbNames[$key]))
- {
- $this->customDbNames[$key] = $customDbNames[$key];
- }
- }
- }
- }
-
- /**
- * Closes all open geoip instances.
- */
- public function __destruct()
- {
- foreach ($this->geoIpCache as $instance)
- {
- geoip_close($instance);
- }
- }
-
- /**
- * 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. If a city
- * database is used, it may return the country code, region code, city name, area
- * code, latitude, longitude and postal code of the visitor.
- *
- * Alternatively, if used with a country database, only the country code will be
- * returned.
- *
- * @param array $info Must have an 'ip' field.
- * @return array
- */
- public function getLocation( $info )
- {
- $ip = $this->getIpFromInfo($info);
-
- $result = array();
-
- $locationGeoIp = $this->getGeoIpInstance($key = 'loc');
- if ($locationGeoIp)
- {
- switch ($locationGeoIp->databaseType)
- {
- case GEOIP_CITY_EDITION_REV0: // city database type
- case GEOIP_CITY_EDITION_REV1:
- case GEOIP_CITYCOMBINED_EDITION:
- $location = geoip_record_by_addr($locationGeoIp, $ip);
- if (!empty($location))
- {
- $result[self::COUNTRY_CODE_KEY] = $location->country_code;
- $result[self::REGION_CODE_KEY] = $location->region;
- $result[self::CITY_NAME_KEY] = utf8_encode($location->city);
- $result[self::AREA_CODE_KEY] = $location->area_code;
- $result[self::LATITUDE_KEY] = $location->latitude;
- $result[self::LONGITUDE_KEY] = $location->longitude;
- $result[self::POSTAL_CODE_KEY] = $location->postal_code;
- }
- break;
- case GEOIP_REGION_EDITION_REV0: // region database type
- case GEOIP_REGION_EDITION_REV1:
- $location = geoip_region_by_addr($locationGeoIp, $ip);
- if (!empty($location))
- {
- $result[self::COUNTRY_CODE_KEY] = $location[0];
- $result[self::REGION_CODE_KEY] = $location[1];
- }
- break;
- case GEOIP_COUNTRY_EDITION: // country database type
- $result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
- break;
- default: // unknown database type, log warning and fallback to country edition
- Piwik::log(sprintf("Found unrecognized database type: %s", $locationGeoIp->databaseType));
-
- $result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
- break;
- }
- }
-
- // NOTE: ISP & ORG require commercial dbs to test. this code has been tested manually,
- // but not by integration tests.
- $ispGeoIp = $this->getGeoIpInstance($key = 'isp');
- if ($ispGeoIp)
- {
- $isp = geoip_org_by_addr($ispGeoIp, $ip);
- if (!empty($isp))
- {
- $result[self::ISP_KEY] = utf8_encode($isp);
- }
- }
-
- $orgGeoIp = $this->getGeoIpInstance($key = 'org');
- if ($orgGeoIp)
- {
- $org = geoip_org_by_addr($orgGeoIp, $ip);
- if (!empty($org))
- {
- $result[self::ORG_KEY] = utf8_encode($org);
- }
- }
-
- if (empty($result))
- {
- return false;
- }
-
- $this->completeLocationResult($result);
- return $result;
- }
-
- /**
- * Returns true if this location provider is available. Piwik ships w/ the MaxMind
- * PHP library, so this provider is available if a location GeoIP database can be found.
- *
- * @return bool
- */
- public function isAvailable()
- {
- $path = self::getPathToGeoIpDatabase($this->customDbNames['loc']);
- return $path !== false;
- }
-
- /**
- * Returns true if this provider has been setup correctly, the error message if
- * otherwise.
- *
- * @return bool|string
- */
- public function isWorking()
- {
- if (!function_exists('mb_internal_encoding'))
- {
- return Piwik_Translate('UserCountry_GeoIPCannotFindMbstringExtension',
- array('mb_internal_encoding', 'mbstring'));
- }
-
- return parent::isWorking();
- }
-
- /**
- * Returns an array describing the types of location information this provider will
- * return.
- *
- * The location info this provider supports depends on what GeoIP databases it can
- * find.
- *
- * This provider will always support country & continent information.
- *
- * If a region database is found, then region code & name information will be
- * supported.
- *
- * If a city database is found, then region code, region name, city name,
- * area code, latitude, longitude & postal code are all supported.
- *
- * If an organization database is found, organization information is
- * supported.
- *
- * If an ISP database is found, ISP information is supported.
- *
- * @return array
- */
- public function getSupportedLocationInfo()
- {
- $result = array();
-
- // country & continent info always available
- $result[self::CONTINENT_CODE_KEY] = true;
- $result[self::CONTINENT_NAME_KEY] = true;
- $result[self::COUNTRY_CODE_KEY] = true;
- $result[self::COUNTRY_NAME_KEY] = true;
-
- $locationGeoIp = $this->getGeoIpInstance($key = 'loc');
- if ($locationGeoIp)
- {
- switch ($locationGeoIp->databaseType)
- {
- case GEOIP_CITY_EDITION_REV0: // city database type
- case GEOIP_CITY_EDITION_REV1:
- case GEOIP_CITYCOMBINED_EDITION:
- $result[self::REGION_CODE_KEY] = true;
- $result[self::REGION_NAME_KEY] = true;
- $result[self::CITY_NAME_KEY] = true;
- $result[self::AREA_CODE_KEY] = true;
- $result[self::LATITUDE_KEY] = true;
- $result[self::LONGITUDE_KEY] = true;
- $result[self::POSTAL_CODE_KEY] = true;
- break;
- case GEOIP_REGION_EDITION_REV0: // region database type
- case GEOIP_REGION_EDITION_REV1:
- $result[self::REGION_CODE_KEY] = true;
- $result[self::REGION_NAME_KEY] = true;
- break;
- default: // country or unknown database type
- break;
- }
- }
-
- // check if isp info is available
- if ($this->getGeoIpInstance($key = 'isp'))
- {
- $result[self::ISP_KEY] = true;
- }
-
- // check of org info is available
- if ($this->getGeoIpInstance($key = 'org'))
- {
- $result[self::ORG_KEY] = true;
- }
-
- return $result;
- }
-
- /**
- * Returns information about this location provider. Contains an id, title & description:
- *
- * array(
- * 'id' => 'geoip_php',
- * 'title' => '...',
- * 'description' => '...'
- * );
- *
- * @return array
- */
- public function getInfo()
- {
- $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Php1') . '<br/><br/>'
- . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Php2',
- array('<strong><em>', '</em></strong>', '<strong><em>', '</em></strong>'));
- $installDocs = '<em><a target="_blank" href="http://piwik.org/faq/how-to/#faq_163">'
- . Piwik_Translate('UserCountry_HowToInstallGeoIPDatabases')
- . '</em></a>';
-
- $availableDatabaseTypes = array();
- if (self::getPathToGeoIpDatabase(array('GeoIPCity.dat', 'GeoLiteCity.dat')) !== false)
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_City');
- }
- if (self::getPathToGeoIpDatabase(array('GeoIPRegion.dat')) !== false)
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Region');
- }
- if (self::getPathToGeoIpDatabase(array('GeoIPCountry.dat')) !== false)
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Country');
- }
- if (self::getPathToGeoIpDatabase(array('GeoIPISP.dat')) !== false)
- {
- $availableDatabaseTypes[] = 'ISP';
- }
- if (self::getPathToGeoIpDatabase(array('GeoIPOrg.dat')) !== false)
- {
- $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Organization');
- }
-
- $extraMessage = '<strong><em>'.Piwik_Translate('General_Note').'</em></strong>:&nbsp;'
- . Piwik_Translate('UserCountry_GeoIPImplHasAccessTo').':&nbsp;<strong><em>'
- . implode(', ', $availableDatabaseTypes).'</em></strong>.';
-
- return array('id' => self::ID,
- 'title' => self::TITLE,
- 'description' => $desc,
- 'install_docs' => $installDocs,
- 'extra_message' => $extraMessage,
- 'order' => 2);
- }
-
- /**
- * Returns a GeoIP instance. Creates it if necessary.
- *
- * @param string $key 'loc', 'isp' or 'org'. Determines the type of GeoIP database
- * to load.
- * @return object|false
- */
- private function getGeoIpInstance( $key )
- {
- if (empty($this->geoIpCache[$key]))
- {
- // make sure region names are loaded & saved first
- parent::getRegionNames();
- require_once PIWIK_INCLUDE_PATH . '/libs/MaxMindGeoIP/geoipcity.inc';
-
- $pathToDb = self::getPathToGeoIpDatabase($this->customDbNames[$key]);
- if ($pathToDb !== false)
- {
- $this->geoIpCache[$key] = geoip_open($pathToDb, GEOIP_STANDARD); // TODO support shared memory
- }
- }
-
- return empty($this->geoIpCache[$key]) ? false : $this->geoIpCache[$key];
- }
+ const ID = 'geoip_php';
+ const TITLE = 'GeoIP (Php)';
+
+ /**
+ * The GeoIP database instances used. This array will contain at most three
+ * of them: one for location info, one for ISP info and another for organization
+ * info.
+ *
+ * Each instance is mapped w/ one of the following keys: 'loc', 'isp', 'org'
+ *
+ * @var array of GeoIP instances
+ */
+ private $geoIpCache = array();
+
+ /**
+ * Possible filenames for each type of GeoIP database. When looking for a database
+ * file in the 'misc' subdirectory, files with these names will be looked for.
+ *
+ * This variable is an array mapping either the 'loc', 'isp' or 'org' strings with
+ * an array of filenames.
+ *
+ * By default, this will be set to Piwik_UserCountry_LocationProvider_GeoIp_Php::$dbNames.
+ *
+ * @var array
+ */
+ private $customDbNames;
+
+ /**
+ * Constructor.
+ *
+ * @param array|false $customDbNames The possible filenames for each type of GeoIP database.
+ * eg array(
+ * 'loc' => array('GeoLiteCity.dat'),
+ * 'isp' => array('GeoIP.dat', 'GeoIPISP.dat')
+ * 'org' => array('GeoIPOrg.dat')
+ * )
+ * If a key is missing (or the parameter not supplied), then the
+ * default database names are used.
+ */
+ public function __construct($customDbNames = false)
+ {
+ $this->customDbNames = parent::$dbNames;
+ if ($customDbNames !== false) {
+ foreach ($this->customDbNames as $key => $names) {
+ if (isset($customDbNames[$key])) {
+ $this->customDbNames[$key] = $customDbNames[$key];
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes all open geoip instances.
+ */
+ public function __destruct()
+ {
+ foreach ($this->geoIpCache as $instance) {
+ geoip_close($instance);
+ }
+ }
+
+ /**
+ * 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. If a city
+ * database is used, it may return the country code, region code, city name, area
+ * code, latitude, longitude and postal code of the visitor.
+ *
+ * Alternatively, if used with a country database, only the country code will be
+ * returned.
+ *
+ * @param array $info Must have an 'ip' field.
+ * @return array
+ */
+ public function getLocation($info)
+ {
+ $ip = $this->getIpFromInfo($info);
+
+ $result = array();
+
+ $locationGeoIp = $this->getGeoIpInstance($key = 'loc');
+ if ($locationGeoIp) {
+ switch ($locationGeoIp->databaseType) {
+ case GEOIP_CITY_EDITION_REV0: // city database type
+ case GEOIP_CITY_EDITION_REV1:
+ case GEOIP_CITYCOMBINED_EDITION:
+ $location = geoip_record_by_addr($locationGeoIp, $ip);
+ if (!empty($location)) {
+ $result[self::COUNTRY_CODE_KEY] = $location->country_code;
+ $result[self::REGION_CODE_KEY] = $location->region;
+ $result[self::CITY_NAME_KEY] = utf8_encode($location->city);
+ $result[self::AREA_CODE_KEY] = $location->area_code;
+ $result[self::LATITUDE_KEY] = $location->latitude;
+ $result[self::LONGITUDE_KEY] = $location->longitude;
+ $result[self::POSTAL_CODE_KEY] = $location->postal_code;
+ }
+ break;
+ case GEOIP_REGION_EDITION_REV0: // region database type
+ case GEOIP_REGION_EDITION_REV1:
+ $location = geoip_region_by_addr($locationGeoIp, $ip);
+ if (!empty($location)) {
+ $result[self::COUNTRY_CODE_KEY] = $location[0];
+ $result[self::REGION_CODE_KEY] = $location[1];
+ }
+ break;
+ case GEOIP_COUNTRY_EDITION: // country database type
+ $result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
+ break;
+ default: // unknown database type, log warning and fallback to country edition
+ Piwik::log(sprintf("Found unrecognized database type: %s", $locationGeoIp->databaseType));
+
+ $result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
+ break;
+ }
+ }
+
+ // NOTE: ISP & ORG require commercial dbs to test. this code has been tested manually,
+ // but not by integration tests.
+ $ispGeoIp = $this->getGeoIpInstance($key = 'isp');
+ if ($ispGeoIp) {
+ $isp = geoip_org_by_addr($ispGeoIp, $ip);
+ if (!empty($isp)) {
+ $result[self::ISP_KEY] = utf8_encode($isp);
+ }
+ }
+
+ $orgGeoIp = $this->getGeoIpInstance($key = 'org');
+ if ($orgGeoIp) {
+ $org = geoip_org_by_addr($orgGeoIp, $ip);
+ if (!empty($org)) {
+ $result[self::ORG_KEY] = utf8_encode($org);
+ }
+ }
+
+ if (empty($result)) {
+ return false;
+ }
+
+ $this->completeLocationResult($result);
+ return $result;
+ }
+
+ /**
+ * Returns true if this location provider is available. Piwik ships w/ the MaxMind
+ * PHP library, so this provider is available if a location GeoIP database can be found.
+ *
+ * @return bool
+ */
+ public function isAvailable()
+ {
+ $path = self::getPathToGeoIpDatabase($this->customDbNames['loc']);
+ return $path !== false;
+ }
+
+ /**
+ * Returns true if this provider has been setup correctly, the error message if
+ * otherwise.
+ *
+ * @return bool|string
+ */
+ public function isWorking()
+ {
+ if (!function_exists('mb_internal_encoding')) {
+ return Piwik_Translate('UserCountry_GeoIPCannotFindMbstringExtension',
+ array('mb_internal_encoding', 'mbstring'));
+ }
+
+ return parent::isWorking();
+ }
+
+ /**
+ * Returns an array describing the types of location information this provider will
+ * return.
+ *
+ * The location info this provider supports depends on what GeoIP databases it can
+ * find.
+ *
+ * This provider will always support country & continent information.
+ *
+ * If a region database is found, then region code & name information will be
+ * supported.
+ *
+ * If a city database is found, then region code, region name, city name,
+ * area code, latitude, longitude & postal code are all supported.
+ *
+ * If an organization database is found, organization information is
+ * supported.
+ *
+ * If an ISP database is found, ISP information is supported.
+ *
+ * @return array
+ */
+ public function getSupportedLocationInfo()
+ {
+ $result = array();
+
+ // country & continent info always available
+ $result[self::CONTINENT_CODE_KEY] = true;
+ $result[self::CONTINENT_NAME_KEY] = true;
+ $result[self::COUNTRY_CODE_KEY] = true;
+ $result[self::COUNTRY_NAME_KEY] = true;
+
+ $locationGeoIp = $this->getGeoIpInstance($key = 'loc');
+ if ($locationGeoIp) {
+ switch ($locationGeoIp->databaseType) {
+ case GEOIP_CITY_EDITION_REV0: // city database type
+ case GEOIP_CITY_EDITION_REV1:
+ case GEOIP_CITYCOMBINED_EDITION:
+ $result[self::REGION_CODE_KEY] = true;
+ $result[self::REGION_NAME_KEY] = true;
+ $result[self::CITY_NAME_KEY] = true;
+ $result[self::AREA_CODE_KEY] = true;
+ $result[self::LATITUDE_KEY] = true;
+ $result[self::LONGITUDE_KEY] = true;
+ $result[self::POSTAL_CODE_KEY] = true;
+ break;
+ case GEOIP_REGION_EDITION_REV0: // region database type
+ case GEOIP_REGION_EDITION_REV1:
+ $result[self::REGION_CODE_KEY] = true;
+ $result[self::REGION_NAME_KEY] = true;
+ break;
+ default: // country or unknown database type
+ break;
+ }
+ }
+
+ // check if isp info is available
+ if ($this->getGeoIpInstance($key = 'isp')) {
+ $result[self::ISP_KEY] = true;
+ }
+
+ // check of org info is available
+ if ($this->getGeoIpInstance($key = 'org')) {
+ $result[self::ORG_KEY] = true;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns information about this location provider. Contains an id, title & description:
+ *
+ * array(
+ * 'id' => 'geoip_php',
+ * 'title' => '...',
+ * 'description' => '...'
+ * );
+ *
+ * @return array
+ */
+ public function getInfo()
+ {
+ $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Php1') . '<br/><br/>'
+ . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_Php2',
+ array('<strong><em>', '</em></strong>', '<strong><em>', '</em></strong>'));
+ $installDocs = '<em><a target="_blank" href="http://piwik.org/faq/how-to/#faq_163">'
+ . Piwik_Translate('UserCountry_HowToInstallGeoIPDatabases')
+ . '</em></a>';
+
+ $availableDatabaseTypes = array();
+ if (self::getPathToGeoIpDatabase(array('GeoIPCity.dat', 'GeoLiteCity.dat')) !== false) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_City');
+ }
+ if (self::getPathToGeoIpDatabase(array('GeoIPRegion.dat')) !== false) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Region');
+ }
+ if (self::getPathToGeoIpDatabase(array('GeoIPCountry.dat')) !== false) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Country');
+ }
+ if (self::getPathToGeoIpDatabase(array('GeoIPISP.dat')) !== false) {
+ $availableDatabaseTypes[] = 'ISP';
+ }
+ if (self::getPathToGeoIpDatabase(array('GeoIPOrg.dat')) !== false) {
+ $availableDatabaseTypes[] = Piwik_Translate('UserCountry_Organization');
+ }
+
+ $extraMessage = '<strong><em>' . Piwik_Translate('General_Note') . '</em></strong>:&nbsp;'
+ . Piwik_Translate('UserCountry_GeoIPImplHasAccessTo') . ':&nbsp;<strong><em>'
+ . implode(', ', $availableDatabaseTypes) . '</em></strong>.';
+
+ return array('id' => self::ID,
+ 'title' => self::TITLE,
+ 'description' => $desc,
+ 'install_docs' => $installDocs,
+ 'extra_message' => $extraMessage,
+ 'order' => 2);
+ }
+
+ /**
+ * Returns a GeoIP instance. Creates it if necessary.
+ *
+ * @param string $key 'loc', 'isp' or 'org'. Determines the type of GeoIP database
+ * to load.
+ * @return object|false
+ */
+ private function getGeoIpInstance($key)
+ {
+ if (empty($this->geoIpCache[$key])) {
+ // make sure region names are loaded & saved first
+ parent::getRegionNames();
+ require_once PIWIK_INCLUDE_PATH . '/libs/MaxMindGeoIP/geoipcity.inc';
+
+ $pathToDb = self::getPathToGeoIpDatabase($this->customDbNames[$key]);
+ if ($pathToDb !== false) {
+ $this->geoIpCache[$key] = geoip_open($pathToDb, GEOIP_STANDARD); // TODO support shared memory
+ }
+ }
+
+ return empty($this->geoIpCache[$key]) ? false : $this->geoIpCache[$key];
+ }
}
diff --git a/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php b/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php
index 7be7324744..cdafeefa6a 100755
--- a/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php
+++ b/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php
@@ -1,306 +1,277 @@
<?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
*/
/**
* A LocationProvider that uses an GeoIP module installed in an HTTP Server.
- *
+ *
* To make this provider available, make sure the GEOIP_ADDR server
* variable is set.
- *
+ *
* @package Piwik_UserCountry
*/
class Piwik_UserCountry_LocationProvider_GeoIp_ServerBased extends Piwik_UserCountry_LocationProvider_GeoIp
{
- const ID = 'geoip_serverbased';
- const TITLE = 'GeoIP (%s)';
- const TEST_SERVER_VAR = 'GEOIP_ADDR';
- const TEST_SERVER_VAR_ALT = 'GEOIP_COUNTRY_CODE';
-
- private static $geoIpServerVars = array(
- parent::COUNTRY_CODE_KEY => 'GEOIP_COUNTRY_CODE',
- parent::COUNTRY_NAME_KEY => 'GEOIP_COUNTRY_NAME',
- parent::REGION_CODE_KEY => 'GEOIP_REGION',
- parent::REGION_NAME_KEY => 'GEOIP_REGION_NAME',
- parent::AREA_CODE_KEY => 'GEOIP_AREA_CODE',
- parent::LATITUDE_KEY => 'GEOIP_LATITUDE',
- parent::LONGITUDE_KEY => 'GEOIP_LONGITUDE',
- parent::POSTAL_CODE_KEY => 'GEOIP_POSTAL_CODE',
- );
-
- private static $geoIpUtfServerVars = array(
- parent::CITY_NAME_KEY => 'GEOIP_CITY',
- parent::ISP_KEY => 'GEOIP_ISP',
- parent::ORG_KEY => 'GEOIP_ORGANIZATION',
- );
-
- /**
- * 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;
- }
-
- /**
- * Returns an array describing the types of location information this provider will
- * return.
- *
- * There's no way to tell exactly what database the HTTP server is using, so we just
- * assume country and continent information is available. This can make diagnostics
- * a bit more difficult, unfortunately.
- *
- * @return array
- */
- public function getSupportedLocationInfo()
- {
- $result = array();
-
- // assume country info is always available. it's an error if it's not.
- $result[self::COUNTRY_CODE_KEY] = true;
- $result[self::COUNTRY_NAME_KEY] = true;
- $result[self::CONTINENT_CODE_KEY] = true;
- $result[self::CONTINENT_NAME_KEY] = true;
-
- return $result;
- }
-
- /**
- * Checks if an HTTP server module has been installed. It checks by looking for
- * the GEOIP_ADDR server variable.
- *
- * There's a special check for the Apache module, but we can't check specifically
- * for anything else.
- *
- * @return bool|string
- */
- public function isAvailable()
- {
- // check if apache module is installed
- if (function_exists('apache_get_modules'))
- {
- foreach (apache_get_modules() as $name)
- {
- if (strpos($name, 'geoip') !== false)
- {
- return true;
- }
- }
- }
-
- $available = !empty($_SERVER[self::TEST_SERVER_VAR])
- || !empty($_SERVER[self::TEST_SERVER_VAR_ALT]);
-
- if ($available)
- {
- return true;
- }
- else // if not available return message w/ extra info
- {
- if (!function_exists('apache_get_modules'))
- {
- return Piwik_Translate('General_Note').':&nbsp;'.Piwik_Translate('UserCountry_AssumingNonApache');
- }
-
- $message = "<strong><em>".Piwik_Translate('General_Note').':&nbsp;'
- . Piwik_Translate('UserCountry_FoundApacheModules')
- . "</em></strong>:<br/><br/>\n<ul style=\"list-style:disc;margin-left:24px\">\n";
- foreach (apache_get_modules() as $name)
- {
- $message .= "<li>$name</li>\n";
- }
- $message .= "</ul>";
- return $message;
- }
- }
-
- /**
- * Returns true if the GEOIP_ADDR server variable is defined.
- *
- * @return bool
- */
- public function isWorking()
- {
- if (empty($_SERVER[self::TEST_SERVER_VAR])
- && empty($_SERVER[self::TEST_SERVER_VAR_ALT]))
- {
- return Piwik_Translate("UserCountry_CannotFindGeoIPServerVar", self::TEST_SERVER_VAR.' $_SERVER');
- }
-
- return true; // can't check for another IP
- }
-
- /**
- * Returns information about this location provider. Contains an id, title & description:
- *
- * array(
- * 'id' => 'geoip_serverbased',
- * 'title' => '...',
- * 'description' => '...'
- * );
- *
- * @return array
- */
- public function getInfo()
- {
- if (function_exists('apache_note'))
- {
- $serverDesc = 'Apache';
- }
- else
- {
- $serverDesc = Piwik_Translate('UserCountry_HttpServerModule');
- }
-
- $title = sprintf(self::TITLE, $serverDesc);
- $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBased1', array('<strong>', '</strong>'))
- . '<br/><br/>'
- . '<em>'.Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBasedAnonWarn').'</em>'
- . '<br/><br/>'
- . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBased2',
- array('<strong><em>', '</em></strong>', '<strong><em>', '</em></strong>'));
- $installDocs =
- '<em><a target="_blank" href="http://piwik.org/faq/how-to/#faq_165">'
- . Piwik_Translate('UserCountry_HowToInstallApacheModule')
- . '</a></em><br/><em>'
- . '<a target="_blank" href="http://piwik.org/faq/how-to/#faq_166">'
- . Piwik_Translate('UserCountry_HowToInstallNginxModule')
- . '</a></em>';
-
- $geoipServerVars = array();
- foreach ($_SERVER as $key => $value)
- {
- if (strpos($key, 'GEOIP') === 0)
- {
- $geoipServerVars[] = $key;
- }
- }
-
- if (empty($geoipServerVars))
- {
- $extraMessage = '<strong><em>'.Piwik_Translate('UserCountry_GeoIPNoServerVars', '$_SERVER').'</em></strong>';
- }
- else
- {
- $extraMessage = '<strong><em>'.Piwik_Translate('UserCountry_GeoIPServerVarsFound', '$_SERVER')
- .":</em></strong><br/><br/>\n<ul style=\"list-style:disc;margin-left:24px\">\n";
- foreach ($geoipServerVars as $key)
- {
- $extraMessage .= '<li>'.$key."</li>\n";
- }
- $extraMessage .= '</ul>';
- }
-
- return array('id' => self::ID,
- 'title' => $title,
- 'description' => $desc,
- 'order' => 4,
- 'install_docs' => $installDocs,
- 'extra_message' => $extraMessage);
- }
-
- /**
- * Checks if two IP addresses are the same or if the first is the anonymized
- * version of the other.
- *
- * @param string $ip
- * @param string $currentIp This IP should not be anonymized.
- * @return bool
- */
- public static function isSameOrAnonymizedIp( $ip, $currentIp )
- {
- $ip = array_reverse(explode('.', $ip));
- $currentIp = array_reverse(explode('.', $currentIp));
-
- if (count($ip) != count($currentIp))
- {
- return false;
- }
-
- foreach ($ip as $i => $byte)
- {
- if ($byte == 0)
- {
- $currentIp[$i] = 0;
- }
- else
- {
- break;
- }
- }
-
- foreach ($ip as $i => $byte)
- {
- if ($byte != $currentIp[$i])
- {
- return false;
- }
- }
- return true;
- }
+ const ID = 'geoip_serverbased';
+ const TITLE = 'GeoIP (%s)';
+ const TEST_SERVER_VAR = 'GEOIP_ADDR';
+ const TEST_SERVER_VAR_ALT = 'GEOIP_COUNTRY_CODE';
+
+ private static $geoIpServerVars = array(
+ parent::COUNTRY_CODE_KEY => 'GEOIP_COUNTRY_CODE',
+ parent::COUNTRY_NAME_KEY => 'GEOIP_COUNTRY_NAME',
+ parent::REGION_CODE_KEY => 'GEOIP_REGION',
+ parent::REGION_NAME_KEY => 'GEOIP_REGION_NAME',
+ parent::AREA_CODE_KEY => 'GEOIP_AREA_CODE',
+ parent::LATITUDE_KEY => 'GEOIP_LATITUDE',
+ parent::LONGITUDE_KEY => 'GEOIP_LONGITUDE',
+ parent::POSTAL_CODE_KEY => 'GEOIP_POSTAL_CODE',
+ );
+
+ private static $geoIpUtfServerVars = array(
+ parent::CITY_NAME_KEY => 'GEOIP_CITY',
+ parent::ISP_KEY => 'GEOIP_ISP',
+ parent::ORG_KEY => 'GEOIP_ORGANIZATION',
+ );
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns an array describing the types of location information this provider will
+ * return.
+ *
+ * There's no way to tell exactly what database the HTTP server is using, so we just
+ * assume country and continent information is available. This can make diagnostics
+ * a bit more difficult, unfortunately.
+ *
+ * @return array
+ */
+ public function getSupportedLocationInfo()
+ {
+ $result = array();
+
+ // assume country info is always available. it's an error if it's not.
+ $result[self::COUNTRY_CODE_KEY] = true;
+ $result[self::COUNTRY_NAME_KEY] = true;
+ $result[self::CONTINENT_CODE_KEY] = true;
+ $result[self::CONTINENT_NAME_KEY] = true;
+
+ return $result;
+ }
+
+ /**
+ * Checks if an HTTP server module has been installed. It checks by looking for
+ * the GEOIP_ADDR server variable.
+ *
+ * There's a special check for the Apache module, but we can't check specifically
+ * for anything else.
+ *
+ * @return bool|string
+ */
+ public function isAvailable()
+ {
+ // check if apache module is installed
+ if (function_exists('apache_get_modules')) {
+ foreach (apache_get_modules() as $name) {
+ if (strpos($name, 'geoip') !== false) {
+ return true;
+ }
+ }
+ }
+
+ $available = !empty($_SERVER[self::TEST_SERVER_VAR])
+ || !empty($_SERVER[self::TEST_SERVER_VAR_ALT]);
+
+ if ($available) {
+ return true;
+ } else // if not available return message w/ extra info
+ {
+ if (!function_exists('apache_get_modules')) {
+ return Piwik_Translate('General_Note') . ':&nbsp;' . Piwik_Translate('UserCountry_AssumingNonApache');
+ }
+
+ $message = "<strong><em>" . Piwik_Translate('General_Note') . ':&nbsp;'
+ . Piwik_Translate('UserCountry_FoundApacheModules')
+ . "</em></strong>:<br/><br/>\n<ul style=\"list-style:disc;margin-left:24px\">\n";
+ foreach (apache_get_modules() as $name) {
+ $message .= "<li>$name</li>\n";
+ }
+ $message .= "</ul>";
+ return $message;
+ }
+ }
+
+ /**
+ * Returns true if the GEOIP_ADDR server variable is defined.
+ *
+ * @return bool
+ */
+ public function isWorking()
+ {
+ if (empty($_SERVER[self::TEST_SERVER_VAR])
+ && empty($_SERVER[self::TEST_SERVER_VAR_ALT])
+ ) {
+ return Piwik_Translate("UserCountry_CannotFindGeoIPServerVar", self::TEST_SERVER_VAR . ' $_SERVER');
+ }
+
+ return true; // can't check for another IP
+ }
+
+ /**
+ * Returns information about this location provider. Contains an id, title & description:
+ *
+ * array(
+ * 'id' => 'geoip_serverbased',
+ * 'title' => '...',
+ * 'description' => '...'
+ * );
+ *
+ * @return array
+ */
+ public function getInfo()
+ {
+ if (function_exists('apache_note')) {
+ $serverDesc = 'Apache';
+ } else {
+ $serverDesc = Piwik_Translate('UserCountry_HttpServerModule');
+ }
+
+ $title = sprintf(self::TITLE, $serverDesc);
+ $desc = Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBased1', array('<strong>', '</strong>'))
+ . '<br/><br/>'
+ . '<em>' . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBasedAnonWarn') . '</em>'
+ . '<br/><br/>'
+ . Piwik_Translate('UserCountry_GeoIpLocationProviderDesc_ServerBased2',
+ array('<strong><em>', '</em></strong>', '<strong><em>', '</em></strong>'));
+ $installDocs =
+ '<em><a target="_blank" href="http://piwik.org/faq/how-to/#faq_165">'
+ . Piwik_Translate('UserCountry_HowToInstallApacheModule')
+ . '</a></em><br/><em>'
+ . '<a target="_blank" href="http://piwik.org/faq/how-to/#faq_166">'
+ . Piwik_Translate('UserCountry_HowToInstallNginxModule')
+ . '</a></em>';
+
+ $geoipServerVars = array();
+ foreach ($_SERVER as $key => $value) {
+ if (strpos($key, 'GEOIP') === 0) {
+ $geoipServerVars[] = $key;
+ }
+ }
+
+ if (empty($geoipServerVars)) {
+ $extraMessage = '<strong><em>' . Piwik_Translate('UserCountry_GeoIPNoServerVars', '$_SERVER') . '</em></strong>';
+ } else {
+ $extraMessage = '<strong><em>' . Piwik_Translate('UserCountry_GeoIPServerVarsFound', '$_SERVER')
+ . ":</em></strong><br/><br/>\n<ul style=\"list-style:disc;margin-left:24px\">\n";
+ foreach ($geoipServerVars as $key) {
+ $extraMessage .= '<li>' . $key . "</li>\n";
+ }
+ $extraMessage .= '</ul>';
+ }
+
+ return array('id' => self::ID,
+ 'title' => $title,
+ 'description' => $desc,
+ 'order' => 4,
+ 'install_docs' => $installDocs,
+ 'extra_message' => $extraMessage);
+ }
+
+ /**
+ * Checks if two IP addresses are the same or if the first is the anonymized
+ * version of the other.
+ *
+ * @param string $ip
+ * @param string $currentIp This IP should not be anonymized.
+ * @return bool
+ */
+ public static function isSameOrAnonymizedIp($ip, $currentIp)
+ {
+ $ip = array_reverse(explode('.', $ip));
+ $currentIp = array_reverse(explode('.', $currentIp));
+
+ if (count($ip) != count($currentIp)) {
+ return false;
+ }
+
+ foreach ($ip as $i => $byte) {
+ if ($byte == 0) {
+ $currentIp[$i] = 0;
+ } else {
+ break;
+ }
+ }
+
+ foreach ($ip as $i => $byte) {
+ if ($byte != $currentIp[$i]) {
+ return false;
+ }
+ }
+ return true;
+ }
}