From ac7a69a27e4f443d383077b53fc1f109dc702226 Mon Sep 17 00:00:00 2001 From: Stefan Giehl <stefan@piwik.org> Date: Fri, 23 Sep 2016 06:22:34 +0200 Subject: [PATCH] Improves handling of Geolocation providers (3.x) (#10523) * refactor code for including available location providers * fix test --- plugins/UserCountry/LocationProvider.php | 43 +++++++++++-------- .../UserCountry/LocationProvider/GeoIp.php | 18 +------- .../Integration/VisitorGeolocatorTest.php | 5 +++ .../PHPUnit/Fixtures/ManyVisitsWithGeoIP.php | 3 +- .../ManyVisitsWithMockLocationProvider.php | 2 + tests/PHPUnit/System/TrackerTest.php | 2 + 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/plugins/UserCountry/LocationProvider.php b/plugins/UserCountry/LocationProvider.php index 50fd52b987..771984dbd4 100755 --- a/plugins/UserCountry/LocationProvider.php +++ b/plugins/UserCountry/LocationProvider.php @@ -13,25 +13,16 @@ use Piwik\Common; use Piwik\IP; use Piwik\Option; use Piwik\Piwik; +use Piwik\Plugin; use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider; +use Piwik\Plugin\Manager as PluginManager; use Piwik\Tracker\Cache; -use ReflectionClass; /** * @see plugins/UserCountry/functions.php */ require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/functions.php'; -/** - * @see plugins/UserCountry/LocationProvider/DefaultProvider.php - */ -require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/DefaultProvider.php'; - -/** - * @see plugins/UserCountry/LocationProvider/GeoIp.php - */ -require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp.php'; - /** * The base class of all LocationProviders. * @@ -148,14 +139,10 @@ abstract class LocationProvider { if (is_null(self::$providers)) { self::$providers = array(); - foreach (get_declared_classes() as $klass) { - if (is_subclass_of($klass, 'Piwik\Plugins\UserCountry\LocationProvider')) { - $klassInfo = new ReflectionClass($klass); - if ($klassInfo->isAbstract()) { - continue; - } - - self::$providers[] = new $klass; + $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated(); + foreach ($plugins as $plugin) { + foreach (self::getLocationProviders($plugin) as $instance) { + self::$providers[] = $instance; } } } @@ -163,6 +150,24 @@ abstract class LocationProvider return self::$providers; } + /** + * Get all lo that are defined by the given plugin. + * + * @param Plugin $plugin + * @return LocationProvider[] + */ + protected static function getLocationProviders(Plugin $plugin) + { + $locationProviders = $plugin->findMultipleComponents('LocationProvider', 'Piwik\\Plugins\\UserCountry\\LocationProvider'); + $instances = []; + + foreach ($locationProviders as $locationProvider) { + $instances[] = new $locationProvider(); + } + + return $instances; + } + /** * Returns all provider instances that are 'available'. An 'available' provider * is one that is available for use. They may not necessarily be working. diff --git a/plugins/UserCountry/LocationProvider/GeoIp.php b/plugins/UserCountry/LocationProvider/GeoIp.php index b8e090ea74..b37c3df3c8 100755 --- a/plugins/UserCountry/LocationProvider/GeoIp.php +++ b/plugins/UserCountry/LocationProvider/GeoIp.php @@ -255,20 +255,4 @@ abstract class GeoIp extends LocationProvider } return false; } -} - -/** - * @see plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php - */ -require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php'; - -/** - * @see plugins/UserCountry/LocationProvider/GeoIp/Php.php - */ -require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp/Php.php'; - -/** - * @see plugins/UserCountry/LocationProvider/GeoIp/Pecl.php - */ -require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php'; - +} \ No newline at end of file diff --git a/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php b/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php index ef1be64b1a..c9e6891f54 100644 --- a/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php +++ b/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php @@ -39,6 +39,11 @@ class VisitorGeolocatorTest extends IntegrationTestCase parent::setUp(); $this->logInserter = new LogHelper(); + + // ensure all providers are loaded and add mock provider + LocationProvider::$providers = null; + $providers = LocationProvider::getAllProviders(); + LocationProvider::$providers[] = new MockLocationProvider(); } public function test_getLocation_shouldReturnLocationForProvider_IfLocationIsSetForCurrentProvider() diff --git a/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php b/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php index 8fb67f261a..7faeaee97a 100644 --- a/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php +++ b/tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php @@ -245,7 +245,8 @@ class ManyVisitsWithGeoIP extends Fixture private function setMockLocationProvider() { - LocationProvider::$providers = null; + LocationProvider::$providers = array(); + LocationProvider::$providers[] = new MockLocationProvider(); LocationProvider::setCurrentProvider('mock_provider'); MockLocationProvider::$locations = array( self::makeLocation('Stratford-upon-Avon', 'P3', 'gb', 123.456, 21.321), // template location diff --git a/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php b/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php index 9fbd6f986d..ae5b1ae4dd 100644 --- a/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php +++ b/tests/PHPUnit/Fixtures/ManyVisitsWithMockLocationProvider.php @@ -212,6 +212,8 @@ class ManyVisitsWithMockLocationProvider extends Fixture private function setMockLocationProvider() { + LocationProvider::$providers = array(); + LocationProvider::$providers[] = new MockLocationProvider(); LocationProvider::setCurrentProvider('mock_provider'); MockLocationProvider::$locations = array( self::makeLocation('Toronto', 'ON', 'CA', $lat = null, $long = null, $isp = 'comcast.net'), diff --git a/tests/PHPUnit/System/TrackerTest.php b/tests/PHPUnit/System/TrackerTest.php index 417b40f72a..65ab91cc08 100644 --- a/tests/PHPUnit/System/TrackerTest.php +++ b/tests/PHPUnit/System/TrackerTest.php @@ -150,6 +150,8 @@ class TrackerTest extends IntegrationTestCase public function test_trackingWithLangParameter_ForwardsLangParameter_ToDefaultLocationProvider() { + LocationProvider::$providers = null; + LocationProvider::getAllProviders(); LocationProvider::setCurrentProvider(LocationProvider\DefaultProvider::ID); $urlToTest = "?idsite=1&rec=1&action_name=test&lang=fr-be"; -- GitLab