array('GeoIP2-City.mmdb', 'DBIP-City.mmdb', 'DBIP-City-Lite.mmdb', 'DBIP-Country-Lite.mmdb', 'DBIP-Country.mmdb', 'dbip-city-lite-\d{4}-\d{2}.mmdb', 'GeoIP2-City-Africa.mmdb', 'GeoIP2-City-Asia-Pacific.mmdb', 'GeoIP2-City-Europe.mmdb', 'GeoIP2-City-North-America.mmdb', 'GeoIP2-City-South-America.mmdb', 'GeoIP2-Enterprise.mmdb', 'GeoIP2-Country.mmdb', 'dbip-country-lite-\d{4}-\d{2}.mmdb', 'GeoLite2-City.mmdb', 'GeoLite2-Country.mmdb', 'DBIP-Enterprise.mmdb'), 'isp' => array('GeoIP2-ISP.mmdb', 'GeoLite2-ASN.mmdb', 'DBIP-ISP.mmdb', 'GeoIP2-Enterprise.mmdb', 'DBIP-Enterprise.mmdb', 'DBIP-ASN.mmdb', 'dbip-asn-lite-\d{4}-\d{2}.mmdb'), ); public static function getDbIpLiteUrl($type = 'city') { $today = Date::today(); return "https://download.db-ip.com/free/dbip-{$type}-lite-{$today->toString('Y-m')}.mmdb.gz"; } /** * Returns true if this provider has been setup correctly, the error message if not. * * @return bool|string */ public function isWorking() { // test with an example IP to make sure the provider is working try { $testIp = self::TEST_IP; // get location using test IP and check that some information was returned $location = $this->getLocation(array('ip' => $testIp)); $location = $location ? array_filter($location) : $location; $isResultCorrect = !empty($location); if (!$isResultCorrect) { $bind = array($testIp); return Piwik::translate('UserCountry_TestIPLocatorFailed', $bind); } return true; } catch (Exception $ex) { return $ex->getMessage(); } } /** * Returns the path of an existing GeoIP 2 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 2 database managed by Piwik. * * @param string $filename Name of the .dat file. * @return string */ public static function getPathForGeoIpDatabase($filename) { if (strpos($filename, '/') !== false && file_exists($filename)) { return $filename; } return StaticContainer::get('path.geoip2') . $filename; } public function activate() { $option = Option::get(self::SWITCH_TO_ISO_REGIONS_OPTION_NAME); if (empty($option)) { Option::set(self::SWITCH_TO_ISO_REGIONS_OPTION_NAME, time()); } } /** * Returns true if there is a GeoIP 2 database in the 'misc' directory. * * @return bool */ public static function isDatabaseInstalled() { return self::getPathToGeoIpDatabase(self::$dbNames['loc']) || self::getPathToGeoIpDatabase(self::$dbNames['isp']); } /** * Returns the type of GeoIP 2 database ('loc' or 'isp') based on the * filename (eg, 'GeoLite2-City.mmdb', 'GeoIP2-ISP.mmdb', etc). * * @param string $filename * @return string|false 'loc', 'isp' 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 || preg_match('/'.$name.'/', $filename)) { return $key; } } } return false; } /** * 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)) { self::$regionNames = require_once __DIR__ . '/../data/isoRegionNames.php'; } return self::$regionNames; } /** * Converts an old FIPS region code to ISO * * @param string $countryCode * @param string $fipsRegionCode * @param bool $returnOriginalIfNotFound return given region code if no mapping was found * @return array */ public static function convertRegionCodeToIso($countryCode, $fipsRegionCode, $returnOriginalIfNotFound = false) { static $mapping; if(empty($mapping)) { $mapping = include __DIR__ . '/../data/regionMapping.php'; } $countryCode = strtoupper($countryCode); if (empty($countryCode) || in_array($countryCode, ['EU', 'AP', 'A1', 'A2'])) { return ['', '']; } if (in_array($countryCode, ['US', 'CA'])) { // US and CA always haven been iso codes return [$countryCode, $fipsRegionCode]; } if ($countryCode == 'TI') { $countryCode = 'CN'; $fipsRegionCode = '14'; } $isoRegionCode = $returnOriginalIfNotFound ? $fipsRegionCode : ''; if (!empty($fipsRegionCode) && !empty($mapping[$countryCode][$fipsRegionCode])) { $isoRegionCode = $mapping[$countryCode][$fipsRegionCode]; } return [$countryCode, $isoRegionCode]; } /** * Returns an IP address from an array that was passed into getLocation. This * will return an IPv4 address or IPv6 address. * * @param array $info Must have 'ip' key. * @return string|null */ protected function getIpFromInfo($info) { $ip = \Matomo\Network\IP::fromStringIP($info['ip']); return $ip->toString(); } }