diff options
author | Stefan Giehl <stefan@matomo.org> | 2022-04-14 15:13:58 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-14 15:13:58 +0300 |
commit | c9baad5f9502fe9ee4c70d94a21a1b3942398c62 (patch) | |
tree | 4157f9f085b4c6a9d2294bf2d6812b980aee14d2 /plugins | |
parent | aab84d6b6d7a86e432d108c8156b8346cb3bcb5a (diff) |
Move guessing location country by provider to default location provider (#19085)
* Move guessing ocation country by provider to default location provider
* Adds test
* fix tests
Diffstat (limited to 'plugins')
3 files changed, 140 insertions, 69 deletions
diff --git a/plugins/UserCountry/Columns/Country.php b/plugins/UserCountry/Columns/Country.php index 9a13f68790..038b7c8d31 100644 --- a/plugins/UserCountry/Columns/Country.php +++ b/plugins/UserCountry/Columns/Country.php @@ -1,4 +1,5 @@ <?php + /** * Matomo - free/libre analytics platform * @@ -6,19 +7,16 @@ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later * */ + namespace Piwik\Plugins\UserCountry\Columns; use Piwik\Columns\DimensionSegmentFactory; use Piwik\Common; use Piwik\Config; use Piwik\Container\StaticContainer; -use Piwik\Intl\Data\Provider\RegionDataProvider; use Piwik\Metrics\Formatter; -use Matomo\Network\IP; use Piwik\Piwik; -use Piwik\Plugin\Manager; use Piwik\Plugin\Segment; -use Piwik\Plugins\Provider\Provider as ProviderProvider; use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Segment\SegmentsList; use Piwik\Tracker\Visit; @@ -53,8 +51,8 @@ class Country extends Base $segment->setNeedsMostFrequentValues(false); $regionDataProvider = StaticContainer::get('Piwik\Intl\Data\Provider\RegionDataProvider'); $countryList = $regionDataProvider->getCountryList(); - array_walk($countryList, function(&$item, $key) { - $item = Piwik::translate('Intl_Country_'.strtoupper($key), [], 'en'); + array_walk($countryList, function (&$item, $key) { + $item = Piwik::translate('Intl_Country_' . strtoupper($key), [], 'en'); }); $segment->setSqlFilterValue(function ($val) use ($countryList) { @@ -97,55 +95,9 @@ class Country extends Base return strtolower($country); } - $country = $this->getCountryUsingProviderExtensionIfValid($userInfo['ip']); - - if (!empty($country)) { - return $country; - } - return Visit::UNKNOWN_CODE; } - private function getCountryUsingProviderExtensionIfValid($ipAddress) - { - if (!Manager::getInstance()->isPluginInstalled('Provider')) { - return false; - } - - $hostname = $this->getHost($ipAddress); - $hostnameExtension = ProviderProvider::getCleanHostname($hostname); - - $hostnameDomain = substr($hostnameExtension, 1 + strrpos($hostnameExtension, '.')); - if ($hostnameDomain == 'uk') { - $hostnameDomain = 'gb'; - } - - /** @var RegionDataProvider $regionDataProvider */ - $regionDataProvider = StaticContainer::get('Piwik\Intl\Data\Provider\RegionDataProvider'); - - if (array_key_exists($hostnameDomain, $regionDataProvider->getCountryList())) { - return $hostnameDomain; - } - - return false; - } - - /** - * Returns the hostname given the IP address string - * - * @param string $ipStr IP Address - * @return string hostname (or human-readable IP address) - */ - private function getHost($ipStr) - { - $ip = IP::fromStringIP($ipStr); - - $host = $ip->getHostname(); - $host = ($host === null ? $ipStr : $host); - - return trim(strtolower($host)); - } - /** * @param Request $request * @param Visitor $visitor @@ -175,8 +127,6 @@ class Country extends Base $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess']; $locationIp = $visitor->getVisitorColumn('location_ip'); - $country = Common::getCountry($browserLanguage, $enableLanguageToCountryGuess, $locationIp); - - return $country; + return Common::getCountry($browserLanguage, $enableLanguageToCountryGuess, $locationIp); } -}
\ No newline at end of file +} diff --git a/plugins/UserCountry/LocationProvider/DefaultProvider.php b/plugins/UserCountry/LocationProvider/DefaultProvider.php index 4c426eef6b..c5483122a7 100644 --- a/plugins/UserCountry/LocationProvider/DefaultProvider.php +++ b/plugins/UserCountry/LocationProvider/DefaultProvider.php @@ -1,4 +1,5 @@ <?php + /** * Matomo - free/libre analytics platform * @@ -6,11 +7,18 @@ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later * */ + namespace Piwik\Plugins\UserCountry\LocationProvider; +use Matomo\Network\IP; use Piwik\Common; use Piwik\Config; +use Piwik\Container\StaticContainer; +use Piwik\Intl\Data\Provider\RegionDataProvider; use Piwik\Piwik; +use Piwik\Plugin\Manager; +use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig; +use Piwik\Plugins\Provider\Provider as ProviderProvider; use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Tracker\TrackerConfig; @@ -32,19 +40,74 @@ class DefaultProvider extends LocationProvider */ public function getLocation($info) { - $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess']; + $country = $this->getCountryUsingProviderExtensionIfAvailable($info['ip']); - if (empty($info['lang'])) { - $info['lang'] = Common::getBrowserLanguage(); + if (empty($country)) { + $enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess']; + + if (empty($info['lang'])) { + $info['lang'] = Common::getBrowserLanguage(); + } + $country = Common::getCountry($info['lang'], $enableLanguageToCountryGuess, $info['ip']); } - $country = Common::getCountry($info['lang'], $enableLanguageToCountryGuess, $info['ip']); - $location = array(parent::COUNTRY_CODE_KEY => $country); + $location = [parent::COUNTRY_CODE_KEY => $country]; $this->completeLocationResult($location); return $location; } + + private function getCountryUsingProviderExtensionIfAvailable($ipAddress) + { + if ( + !Manager::getInstance()->isPluginInstalled('Provider') + || Common::getRequestVar('dp', 0, 'int') === 1 + ) { + return false; + } + + $privacyConfig = new PrivacyManagerConfig(); + + // when using anonymized ip for enrichment we skip this check + if ($privacyConfig->useAnonymizedIpForVisitEnrichment) { + return false; + } + + $hostname = $this->getHost($ipAddress); + $hostnameExtension = ProviderProvider::getCleanHostname($hostname); + + $hostnameDomain = substr($hostnameExtension, 1 + strrpos($hostnameExtension, '.')); + if ($hostnameDomain == 'uk') { + $hostnameDomain = 'gb'; + } + + /** @var RegionDataProvider $regionDataProvider */ + $regionDataProvider = StaticContainer::get('Piwik\Intl\Data\Provider\RegionDataProvider'); + + if (array_key_exists($hostnameDomain, $regionDataProvider->getCountryList())) { + return $hostnameDomain; + } + + return false; + } + + /** + * Returns the hostname given the IP address string + * + * @param string $ipStr IP Address + * @return string hostname (or human-readable IP address) + */ + protected function getHost($ipStr) + { + $ip = IP::fromStringIP($ipStr); + + $host = $ip->getHostname(); + $host = ($host === null ? $ipStr : $host); + + return trim(strtolower($host)); + } + /** * Returns whether this location provider is available. * @@ -92,10 +155,10 @@ class DefaultProvider extends LocationProvider */ public function getSupportedLocationInfo() { - return array(self::CONTINENT_CODE_KEY => true, + return [self::CONTINENT_CODE_KEY => true, self::CONTINENT_NAME_KEY => true, self::COUNTRY_CODE_KEY => true, - self::COUNTRY_NAME_KEY => true); + self::COUNTRY_NAME_KEY => true]; } /** @@ -112,22 +175,23 @@ class DefaultProvider extends LocationProvider public function getInfo() { $desc = '<p>' . Piwik::translate('UserCountry_DefaultLocationProviderDesc1') . ' ' - . Piwik::translate('UserCountry_DefaultLocationProviderDesc2', - array('<strong>', '', '', '</strong>')) + . Piwik::translate( + 'UserCountry_DefaultLocationProviderDesc2', + ['<strong>', '', '', '</strong>'] + ) . '</p><p><a href="https://matomo.org/faq/how-to/#faq_163" rel="noreferrer noopener" target="_blank">' . Piwik::translate('UserCountry_HowToInstallGeoIPDatabases') . '</a></p>'; - return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1); + return ['id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1]; } public function getUsageWarning(): ?string { $comment = Piwik::translate('UserCountry_DefaultLocationProviderDesc1') . ' '; - $comment .= Piwik::translate('UserCountry_DefaultLocationProviderDesc2', array( + $comment .= Piwik::translate('UserCountry_DefaultLocationProviderDesc2', [ '<a href="https://matomo.org/docs/geo-locate/" rel="noreferrer noopener" target="_blank">', '', '', '</a>' - )); + ]); return $comment; } } - diff --git a/plugins/UserCountry/tests/Integration/DefaultLocationProviderTest.php b/plugins/UserCountry/tests/Integration/DefaultLocationProviderTest.php new file mode 100644 index 0000000000..0c3c1cb74e --- /dev/null +++ b/plugins/UserCountry/tests/Integration/DefaultLocationProviderTest.php @@ -0,0 +1,57 @@ +<?php + +/** + * Matomo - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\UserCountry\tests\Integration; + +use Piwik\Plugin\Manager; +use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; + +/** + * @group bla + */ +class DefaultLocationProviderTest extends IntegrationTestCase +{ + public function setUp(): void + { + parent::setUp(); + + Manager::getInstance()->activatePlugin('Provider'); + } + + public function testGetCountryFromProvider() + { + $locationProvider = $this->getMockBuilder(DefaultProvider::class)->onlyMethods(['getHost'])->getMock(); + $locationProvider->expects($this->once())->method('getHost')->willReturn('p573a336f.dip0.t-ipconnect.de'); + + $result = $locationProvider->getLocation( + [ + 'ip' => '123.123.123.123', + 'lang' => 'fr', + ] + ); + + self::assertEquals('de', $result[DefaultProvider::COUNTRY_CODE_KEY]); + } + + public function testGetCountryFromLanguageIfProviderNotAvailable() + { + $locationProvider = $this->getMockBuilder(DefaultProvider::class)->onlyMethods(['getHost'])->getMock(); + $locationProvider->expects($this->once())->method('getHost')->willReturn('123.123.123.123'); + + $result = $locationProvider->getLocation( + [ + 'ip' => '123.123.123.123', + 'lang' => 'fr', + ] + ); + + self::assertEquals('fr', $result[DefaultProvider::COUNTRY_CODE_KEY]); + } +} |