diff options
author | Stefan Giehl <stefan@piwik.org> | 2018-05-04 08:15:12 +0300 |
---|---|---|
committer | Matthieu Aubry <mattab@users.noreply.github.com> | 2018-05-04 08:15:12 +0300 |
commit | 18ad4f7f04d01b90fb9fc1d623585b5033092ed8 (patch) | |
tree | 256d6b3628c3d39b7d911f35698636d331194109 /plugins/UserCountry | |
parent | 453e3fbdabbf8c72264a3e15e2650cfad99b06b2 (diff) |
GeoIP2 implementation as a plugin (#12699)
* require geoip2/geoip2 composer package
* Determine region name based on Location Provider
* Adds empty GeoIp2 plugin
* move location_region column definition to GeoIp2 plugin
so it's get changed as soon as the plugin is activated
* Adds GeoIP2 location providers
* ignore GeoIP2 mmdb files
* Adds script to generate GeoIP2 test databases
* Adds Command to convert region codes from FIPS to ISO for old log table records
* Adds GeoIP2 AutoUpdater
* Use GeoIP2 in tests
* update test files
* code fixes
* adds tests
* rename old GeoIP providers to Legacy
* Let GeoIP autoupdater UI handle GeoIp2 as well
* convert region codes to ISO in API after switch to GeoIP2
* do not show GeoIP providers if GeoIP2 plugin is enabled an no GeoIP Legacy provider is still in use
* small fixes
* review changes
* Use correct region translations
* Show correct message if no database can be found
* if log tables have been converted, use archive date to check if region codes still need to be converted to iso
* fix tests
* Improves extracting GeoIP2 databases
* Adjust GeoLocation diagnostics
* readds old taiwan fixes
* Assume all third party location providers as 'recommended'
* Download database over HTTPS
* remove outdated comment (see https://github.com/matomo-org/matomo/issues/12411)
* Remove indication that Geoip2 may be slow, since we found it should be quite fast and this should not be an issue in theory
* skip detection if IP is empty & do not try convert IP to IPv4
* remove downloaded file if an error occurs while extracting
* command should be runnable multiple times
* use ISO codes for suggested region codes
* reload after wizard success
* Drop table if exists.
* Fix two translation keys.
* add special region handling for UK
* update system test
* update UI files
* submodule update
* update test files
Diffstat (limited to 'plugins/UserCountry')
24 files changed, 472 insertions, 128 deletions
diff --git a/plugins/UserCountry/API.php b/plugins/UserCountry/API.php index 9fe7cfdcb1..34a00a4add 100644 --- a/plugins/UserCountry/API.php +++ b/plugins/UserCountry/API.php @@ -12,9 +12,12 @@ use Exception; use Piwik\Archive; use Piwik\Container\StaticContainer; use Piwik\DataTable; -use Piwik\Metrics; +use Piwik\Date; +use Piwik\Option; +use Piwik\Period; use Piwik\Piwik; -use Piwik\Plugins\UserCountry\LocationProvider; +use Piwik\Plugins\GeoIp2\Commands\ConvertRegionCodesToIso; +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Tracker\Visit; /** @@ -89,13 +92,9 @@ class API extends \Piwik\Plugin\API { $dataTable = $this->getDataTable(Archiver::REGION_RECORD_NAME, $idSite, $period, $date, $segment); - $segments = array('regionCode', 'countryCode'); - $dataTable->filter('AddSegmentByLabel', array($segments, Archiver::LOCATION_SEPARATOR)); - $separator = Archiver::LOCATION_SEPARATOR; $unk = Visit::UNKNOWN_CODE; - // show visits tracked as Tibet as region of China $dataTables = [$dataTable]; if ($dataTable instanceof DataTable\Map) { @@ -103,7 +102,33 @@ class API extends \Piwik\Plugin\API } foreach ($dataTables as $dt) { - if ($dt->getRowFromLabel('1|ti')) { + $archiveDate = $dt->getMetadata(DataTable::ARCHIVED_DATE_METADATA_NAME); + + // convert fips region codes to iso if required + if ($this->shouldRegionCodesBeConvertedToIso($archiveDate, $date, $period)) { + $dt->filter('GroupBy', array( + 'label', + function ($label) use ($separator, $unk) { + $regionCode = getElementFromStringArray($label, $separator, 0, ''); + $countryCode = getElementFromStringArray($label, $separator, 1, ''); + + list($countryCode, $regionCode) = GeoIp2::convertRegionCodeToIso($countryCode, + $regionCode, true); + + $splitLabel = explode($separator, $label); + + if (isset($splitLabel[0])) { + $splitLabel[0] = $regionCode; + } + + if (isset($splitLabel[1])) { + $splitLabel[1] = strtolower($countryCode); + } + + return implode($separator, $splitLabel); + } + )); + } else if ($dt->getRowFromLabel('1|ti')) { $dt->filter('GroupBy', array( 'label', function ($label) { @@ -116,6 +141,9 @@ class API extends \Piwik\Plugin\API } } + $segments = array('regionCode', 'countryCode'); + $dataTable->filter('AddSegmentByLabel', array($segments, Archiver::LOCATION_SEPARATOR)); + // split the label and put the elements into the 'region' and 'country' metadata fields $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'region', __NAMESPACE__ . '\getElementFromStringArray', array($separator, 0, $unk))); @@ -155,13 +183,9 @@ class API extends \Piwik\Plugin\API { $dataTable = $this->getDataTable(Archiver::CITY_RECORD_NAME, $idSite, $period, $date, $segment); - $segments = array('city', 'regionCode', 'countryCode'); - $dataTable->filter('AddSegmentByLabel', array($segments, Archiver::LOCATION_SEPARATOR)); - $separator = Archiver::LOCATION_SEPARATOR; $unk = Visit::UNKNOWN_CODE; - - // show visits from "1|ti" cities to "14|cn" + $dataTables = [$dataTable]; if ($dataTable instanceof DataTable\Map) { @@ -169,17 +193,48 @@ class API extends \Piwik\Plugin\API } foreach ($dataTables as $dt) { - $dt->filter('GroupBy', array( - 'label', - function ($label) { - if (substr($label, -5) == '|1|ti') { - return substr($label, 0, -5) . '|14|cn'; + $archiveDate = $dt->getMetadata(DataTable::ARCHIVED_DATE_METADATA_NAME); + + // convert fips region codes to iso if required + if ($this->shouldRegionCodesBeConvertedToIso($archiveDate, $date, $period)) { + $dt->filter('GroupBy', array( + 'label', + function ($label) use ($separator, $unk) { + $regionCode = getElementFromStringArray($label, $separator, 1, ''); + $countryCode = getElementFromStringArray($label, $separator, 2, ''); + + list($countryCode, $regionCode) = GeoIp2::convertRegionCodeToIso($countryCode, + $regionCode, true); + + $splitLabel = explode($separator, $label); + + if (isset($splitLabel[1])) { + $splitLabel[1] = $regionCode; + } + + if (isset($splitLabel[2])) { + $splitLabel[2] = strtolower($countryCode); + } + + return implode($separator, $splitLabel); } - return $label; - } - )); + )); + } else { + $dt->filter('GroupBy', array( + 'label', + function ($label) { + if (substr($label, -5) == '|1|ti') { + return substr($label, 0, -5) . '|14|cn'; + } + return $label; + } + )); + } } + $segments = array('city', 'regionCode', 'countryCode'); + $dataTable->filter('AddSegmentByLabel', array($segments, Archiver::LOCATION_SEPARATOR)); + // split the label and put the elements into the 'city_name', 'region', 'country', // 'lat' & 'long' metadata fields $strUnknown = Piwik::translate('General_Unknown'); @@ -209,7 +264,7 @@ class API extends \Piwik\Plugin\API $dataTable->filter('MetadataCallbackAddMetadata', array('country', 'country_name', __NAMESPACE__ . '\countryTranslate', $applyToSummaryRow = false)); - $getRegionName = '\\Piwik\\Plugins\\UserCountry\\LocationProvider\\GeoIp::getRegionNameFromCodes'; + $getRegionName = '\\Piwik\\Plugins\\UserCountry\\getRegionNameFromCodes'; $dataTable->filter('MetadataCallbackAddMetadata', array( array('country', 'region'), 'region_name', $getRegionName, $applyToSummaryRow = false)); @@ -225,6 +280,55 @@ class API extends \Piwik\Plugin\API } /** + * if no switch to ISO was done --> no conversion as only FIPS codes are in use and handled correctly + * if there has been a switch to ISO, we need to check the date: + * - if the start date of the period is after the date we switched to ISO: no conversion needed + * - if not we need to convert the codes to ISO, if the code is mappable + * Note: as all old codes are mapped, not mappable codes need to be iso codes already, so we leave them + * @param $date + * @param $period + * @return bool + */ + private function shouldRegionCodesBeConvertedToIso($archiveDate, $date, $period) + { + $timeOfSwitch = Option::get(GeoIp2::SWITCH_TO_ISO_REGIONS_OPTION_NAME); + + if (empty($timeOfSwitch)) { + return false; // if option was not set, all codes are fips codes, so leave them + } + + try { + $dateOfSwitch = Date::factory((int)$timeOfSwitch); + $period = Period\Factory::build($period, $date); + $periodStart = $period->getDateStart(); + } catch (Exception $e) { + return false; + } + + // if all region codes in log tables have been converted, check if archiving date was after the date of switch to iso + // this check might not be fully correct in cases were only periods > day get recreated, but it should avoid some + // double conversion if all archives have been recreated after converting all region codes + $codesConverted = Option::get(ConvertRegionCodesToIso::OPTION_NAME); + + if ($codesConverted && $archiveDate) { + try { + $dateOfArchive = Date::factory($archiveDate); + + if ($dateOfArchive->isLater($dateOfSwitch)) { + return false; + } + } catch (Exception $e) { + } + } + + if ($dateOfSwitch->isEarlier($periodStart)) { + return false; + } + + return true; + } + + /** * Returns a simple mapping from country code to country name * * @return \string[] @@ -279,7 +383,7 @@ class API extends \Piwik\Plugin\API /** * Set the location provider * - * @param string $providerId The ID of the provider to use eg 'default', 'geoip_php', ... + * @param string $providerId The ID of the provider to use eg 'default', 'geoip2_php', ... * @throws Exception if ID is invalid */ public function setLocationProvider($providerId) diff --git a/plugins/UserCountry/Columns/Region.php b/plugins/UserCountry/Columns/Region.php index 1f14275e7b..0eaf73f473 100644 --- a/plugins/UserCountry/Columns/Region.php +++ b/plugins/UserCountry/Columns/Region.php @@ -16,13 +16,12 @@ use Piwik\Tracker\Action; class Region extends Base { protected $columnName = 'location_region'; - protected $columnType = 'char(2) DEFAULT NULL'; protected $type = self::TYPE_TEXT; protected $category = 'UserCountry_VisitLocation'; protected $segmentName = 'regionCode'; protected $nameSingular = 'UserCountry_Region'; protected $namePlural = 'UserCountryMap_Regions'; - protected $acceptValues = '01 02, OR, P8, etc.<br/>eg. region=A1;country=fr'; + protected $acceptValues = '01 02, OR, P8, etc.<br/>eg. region=BFC;country=fr'; /** * @param Request $request diff --git a/plugins/UserCountry/Controller.php b/plugins/UserCountry/Controller.php index a6a3bd9fbe..6097a5e0bf 100644 --- a/plugins/UserCountry/Controller.php +++ b/plugins/UserCountry/Controller.php @@ -14,11 +14,11 @@ use Piwik\DataTable\Renderer\Json; use Piwik\Http; use Piwik\IP; use Piwik\Piwik; -use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\ServerBased; +use Piwik\Plugin\Manager; +use Piwik\Plugins\GeoIp2\GeoIP2AutoUpdater; use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; -use Piwik\Plugins\UserCountry\LocationProvider; +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider; -use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\Pecl; use Piwik\View; /** @@ -31,7 +31,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin $view = new View('@UserCountry/getDistinctCountries'); $view->urlSparklineCountries = $this->getUrlSparkline('getLastDistinctCountriesGraph'); - $view->numberDistinctCountries = $this->getNumberOfDistinctCountries(true); + $view->numberDistinctCountries = $this->getNumberOfDistinctCountries(); return $view->render(); } @@ -46,7 +46,13 @@ class Controller extends \Piwik\Plugin\ControllerAdmin $view->locationProviders = $allProviderInfo; $view->currentProviderId = LocationProvider::getCurrentProviderId(); $view->thisIP = IP::getIpFromHeader(); - $geoIPDatabasesInstalled = GeoIp::isDatabaseInstalled(); + + if ($this->isGeoIp2Enabled()) { + $geoIPDatabasesInstalled = GeoIp2::isDatabaseInstalled(); + } else { + $geoIPDatabasesInstalled = GeoIp::isDatabaseInstalled(); + } + $view->geoIPDatabasesInstalled = $geoIPDatabasesInstalled; $view->updatePeriodOptions = $this->getPeriodUpdateOptions(); @@ -62,13 +68,12 @@ class Controller extends \Piwik\Plugin\ControllerAdmin } $view->isThereWorkingProvider = $isThereWorkingProvider; - // if using either the Apache or PECL module, they are working and there are no databases + // if using either the Apache, Nginx or PECL module, they are working and there are no databases // in misc, then the databases are located outside of Piwik, so we cannot update them $view->showGeoIPUpdateSection = true; $currentProviderId = LocationProvider::getCurrentProviderId(); if (!$geoIPDatabasesInstalled - && ($currentProviderId == ServerBased::ID - || $currentProviderId == Pecl::ID) + && in_array($currentProviderId, [GeoIp2\ServerModule::ID, GeoIp\ServerBased::ID, GeoIp\Pecl::ID]) && $allProviderInfo[$currentProviderId]['status'] == LocationProvider::INSTALLED ) { $view->showGeoIPUpdateSection = false; @@ -102,6 +107,11 @@ class Controller extends \Piwik\Plugin\ControllerAdmin { $this->dieIfGeolocationAdminIsDisabled(); Piwik::checkUserHasSuperUserAccess(); + + if ($this->isGeoIp2Enabled()) { + return $this->downloadFreeGeoIP2DB(); + } + if ($_SERVER["REQUEST_METHOD"] == "POST") { $this->checkTokenInUrl(); Json::sendHeaderJSON(); @@ -119,12 +129,12 @@ class Controller extends \Piwik\Plugin\ControllerAdmin // setup the auto updater GeoIPAutoUpdater::setUpdaterOptions(array( - 'loc_db' => GeoIp::GEO_LITE_URL, + 'loc' => GeoIp::GEO_LITE_URL, 'period' => GeoIPAutoUpdater::SCHEDULE_PERIOD_MONTHLY, )); // make sure to echo out the geoip updater management screen - $result['next_screen'] = $this->getGeoIpUpdaterManageScreen(); + $result['settings'] = GeoIPAutoUpdater::getConfiguredUrls(); } return json_encode($result); @@ -135,18 +145,61 @@ class Controller extends \Piwik\Plugin\ControllerAdmin } /** - * Renders and returns the HTML that manages the GeoIP auto-updater. + * Starts or continues download of GeoLite2-City.mmdb. + * + * To avoid a server/PHP timeout & to show progress of the download to the user, we + * use the HTTP Range header to download one chunk of the file at a time. After each + * chunk, it is the browser's responsibility to call the method again to continue the download. + * + * Input: + * 'continue' query param - if set to 1, will assume we are currently downloading & use + * Range: HTTP header to get another chunk of the file. * - * @return string + * Output (in JSON): + * 'current_size' - Current size of the partially downloaded file on disk. + * 'expected_file_size' - The expected finished file size as returned by the HTTP server. + * 'next_screen' - When the download finishes, this is the next screen that should be shown. + * 'error' - When an error occurs, the message is returned in this property. */ - private function getGeoIpUpdaterManageScreen() + public function downloadFreeGeoIP2DB() { - $view = new View('@UserCountry/getGeoIpUpdaterManageScreen'); + $this->dieIfGeolocationAdminIsDisabled(); + Piwik::checkUserHasSuperUserAccess(); + if ($_SERVER["REQUEST_METHOD"] == "POST") { + $this->checkTokenInUrl(); + Json::sendHeaderJSON(); + $outputPath = GeoIp2::getPathForGeoIpDatabase('GeoLite2-City.tar') . '.gz'; + try { + $result = Http::downloadChunk( + $url = GeoIp2::GEO_LITE_URL, + $outputPath, + $continue = Common::getRequestVar('continue', true, 'int') + ); - $view->updatePeriodOptions = $this->getPeriodUpdateOptions(); - $view->geoIPDatabasesInstalled = true; - $this->setUpdaterManageVars($view); - return $view->render(); + // if the file is done + if ($result['current_size'] >= $result['expected_file_size']) { + try { + GeoIP2AutoUpdater::unzipDownloadedFile($outputPath, 'loc', $unlink = true); + } catch (\Exception $e) { + // remove downloaded file on error + unlink($outputPath); + throw $e; + } + + // setup the auto updater + GeoIP2AutoUpdater::setUpdaterOptions(array( + 'loc' => GeoIp2::GEO_LITE_URL, + 'period' => GeoIP2AutoUpdater::SCHEDULE_PERIOD_MONTHLY, + )); + + $result['settings'] = GeoIP2AutoUpdater::getConfiguredUrls(); + } + + return json_encode($result); + } catch (Exception $ex) { + return json_encode(array('error' => $ex->getMessage())); + } + } } private function getPeriodUpdateOptions() @@ -164,22 +217,47 @@ class Controller extends \Piwik\Plugin\ControllerAdmin */ private function setUpdaterManageVars($view) { - $urls = GeoIPAutoUpdater::getConfiguredUrls(); + $view->isGeoIp2Available = $this->isGeoIp2Enabled(); + + if ($this->isGeoIp2Enabled()) { + // Get GeoIPLegacy Update information to show them + $urls = GeoIPAutoUpdater::getConfiguredUrls(); + + $view->geoIPLegacyLocUrl = $urls['loc']; + $view->geoIPLegacyIspUrl = $urls['isp']; + $view->geoIPLegacyOrgUrl = $urls['org']; + $view->geoIPLegacyUpdatePeriod = GeoIPAutoUpdater::getSchedulePeriod(); + + $urls = GeoIP2AutoUpdater::getConfiguredUrls(); - $view->geoIPLocUrl = $urls['loc']; - $view->geoIPIspUrl = $urls['isp']; - $view->geoIPOrgUrl = $urls['org']; - $view->geoIPUpdatePeriod = GeoIPAutoUpdater::getSchedulePeriod(); + $view->geoIPLocUrl = $urls['loc']; + $view->geoIPIspUrl = $urls['isp']; + $view->geoIPUpdatePeriod = GeoIP2AutoUpdater::getSchedulePeriod(); - $view->geoLiteUrl = GeoIp::GEO_LITE_URL; + $view->geoLiteUrl = GeoIp2::GEO_LITE_URL; + $view->geoLiteFilename = 'GeoLite2-City.mmdb'; + $view->nextRunTime = GeoIP2AutoUpdater::getNextRunTime(); + + $lastRunTime = GeoIP2AutoUpdater::getLastRunTime(); + } else { + $urls = GeoIPAutoUpdater::getConfiguredUrls(); + + $view->geoIPLocUrl = $urls['loc']; + $view->geoIPIspUrl = $urls['isp']; + $view->geoIPOrgUrl = $urls['org']; + $view->geoIPUpdatePeriod = GeoIPAutoUpdater::getSchedulePeriod(); + + $view->geoLiteUrl = GeoIp::GEO_LITE_URL; + $view->geoLiteFilename = 'GeoLiteCity.dat'; + $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime(); + + $lastRunTime = GeoIPAutoUpdater::getLastRunTime(); + } - $lastRunTime = GeoIPAutoUpdater::getLastRunTime(); if ($lastRunTime !== false) { $view->lastTimeUpdaterRun = '<strong>' . $lastRunTime->toString() . '</strong>'; } - - $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime(); - } + } /** * Sets the URLs used to download new versions of the installed GeoIP databases. @@ -203,7 +281,11 @@ class Controller extends \Piwik\Plugin\ControllerAdmin try { $this->checkTokenInUrl(); - GeoIPAutoUpdater::setUpdaterOptionsFromUrl(); + if ($this->isGeoIp2Enabled()) { + GeoIP2AutoUpdater::setUpdaterOptionsFromUrl(); + } else { + GeoIPAutoUpdater::setUpdaterOptionsFromUrl(); + } // if there is a updater URL for a database, but its missing from the misc dir, tell // the browser so it can download it next @@ -212,7 +294,11 @@ class Controller extends \Piwik\Plugin\ControllerAdmin return json_encode($info); } else { $view = new View("@UserCountry/_updaterNextRunTime"); - $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime(); + if ($this->isGeoIp2Enabled()) { + $view->nextRunTime = GeoIP2AutoUpdater::getNextRunTime(); + } else { + $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime(); + } $nextRunTimeHtml = $view->render(); return json_encode(array('nextRunTime' => $nextRunTimeHtml)); } @@ -252,15 +338,22 @@ class Controller extends \Piwik\Plugin\ControllerAdmin // based on the database type (provided by the 'key' query param) determine the // url & output file name $key = Common::getRequestVar('key', null, 'string'); - $url = GeoIPAutoUpdater::getConfiguredUrl($key); - $ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url); - $filename = GeoIp::$dbNames[$key][0] . '.' . $ext; + if ($this->isGeoIp2Enabled()) { + $url = GeoIP2AutoUpdater::getConfiguredUrl($key); + $ext = GeoIP2AutoUpdater::getGeoIPUrlExtension($url); + $filename = GeoIp2::$dbNames[$key][0] . '.' . $ext; + $outputPath = GeoIp2::getPathForGeoIpDatabase($filename); + } else { + $url = GeoIPAutoUpdater::getConfiguredUrl($key); + $ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url); + $filename = GeoIp::$dbNames[$key][0] . '.' . $ext; - if (substr($filename, 0, 15) == 'GeoLiteCity.dat') { - $filename = 'GeoIPCity.dat' . substr($filename, 15); + if (substr($filename, 0, 15) == 'GeoLiteCity.dat') { + $filename = 'GeoIPCity.dat' . substr($filename, 15); + } + $outputPath = GeoIp::getPathForGeoIpDatabase($filename); } - $outputPath = GeoIp::getPathForGeoIpDatabase($filename); // download part of the file $result = Http::downloadChunk( @@ -268,7 +361,11 @@ class Controller extends \Piwik\Plugin\ControllerAdmin // if the file is done if ($result['current_size'] >= $result['expected_file_size']) { - GeoIPAutoUpdater::unzipDownloadedFile($outputPath, $unlink = true); + if ($this->isGeoIp2Enabled()) { + GeoIP2AutoUpdater::unzipDownloadedFile($outputPath, $key, $unlink = true); + } else { + GeoIPAutoUpdater::unzipDownloadedFile($outputPath, $unlink = true); + } $info = $this->getNextMissingDbUrlInfo(); if ($info !== false) { @@ -324,10 +421,14 @@ class Controller extends \Piwik\Plugin\ControllerAdmin /** * Gets information for the first missing GeoIP database (if any). * - * @return bool + * @return array|bool */ private function getNextMissingDbUrlInfo() { + if ($this->isGeoIp2Enabled()) { + return $this->getNextMissingDbUrlInfoGeoIp2(); + } + $missingDbs = GeoIPAutoUpdater::getMissingDatabases(); if (!empty($missingDbs)) { $missingDbKey = $missingDbs[0]; @@ -344,10 +445,38 @@ class Controller extends \Piwik\Plugin\ControllerAdmin return false; } + /** + * Gets information for the first missing GeoIP2 database (if any). + * + * @return array|bool + */ + private function getNextMissingDbUrlInfoGeoIp2() + { + $missingDbs = GeoIP2AutoUpdater::getMissingDatabases(); + if (!empty($missingDbs)) { + $missingDbKey = $missingDbs[0]; + $missingDbName = GeoIp2::$dbNames[$missingDbKey][0]; + $url = GeoIP2AutoUpdater::getConfiguredUrl($missingDbKey); + + $link = '<a href="' . $url . '">' . $missingDbName . '</a>'; + + return array( + 'to_download' => $missingDbKey, + 'to_download_label' => Piwik::translate('UserCountry_DownloadingDb', $link) . '...', + ); + } + return false; + } + private function dieIfGeolocationAdminIsDisabled() { if (!UserCountry::isGeoLocationAdminEnabled()) { throw new \Exception('Geo location setting page has been disabled.'); } } + + private function isGeoIp2Enabled() + { + return Manager::getInstance()->isPluginActivated('GeoIp2'); + } } diff --git a/plugins/UserCountry/Diagnostic/GeolocationDiagnostic.php b/plugins/UserCountry/Diagnostic/GeolocationDiagnostic.php index 5a7ce0a69a..fa6497c199 100644 --- a/plugins/UserCountry/Diagnostic/GeolocationDiagnostic.php +++ b/plugins/UserCountry/Diagnostic/GeolocationDiagnostic.php @@ -8,8 +8,10 @@ namespace Piwik\Plugins\UserCountry\Diagnostic; use Piwik\Config; +use Piwik\Plugin\Manager; use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult; +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Translation\Translator; @@ -40,16 +42,20 @@ class GeolocationDiagnostic implements Diagnostic $currentProviderId = LocationProvider::getCurrentProviderId(); $allProviders = LocationProvider::getAllProviderInfo(); - $isRecommendedProvider = in_array($currentProviderId, array(LocationProvider\GeoIp\Php::ID, $currentProviderId == LocationProvider\GeoIp\Pecl::ID)); + $isNotRecommendedProvider = in_array($currentProviderId, array( + LocationProvider\DefaultProvider::ID, + LocationProvider\GeoIp\ServerBased::ID, + GeoIp2\ServerModule::ID)); $isProviderInstalled = (isset($allProviders[$currentProviderId]['status']) && $allProviders[$currentProviderId]['status'] == LocationProvider::INSTALLED); - if ($isRecommendedProvider && $isProviderInstalled) { + if (!$isNotRecommendedProvider && $isProviderInstalled) { return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK)); } if ($isProviderInstalled) { $comment = $this->translator->translate('UserCountry_GeoIpLocationProviderNotRecomnended') . ' '; - $comment .= $this->translator->translate('UserCountry_GeoIpLocationProviderDesc_ServerBased2', array( + $message = Manager::getInstance()->isPluginActivated('GeoIp2') ? 'GeoIp2_LocationProviderDesc_ServerModule2' : 'UserCountry_GeoIpLocationProviderDesc_ServerBased2'; + $comment .= $this->translator->translate($message, array( '<a href="https://matomo.org/docs/geo-locate/" rel="noreferrer" target="_blank">', '', '', '</a>' )); } else { diff --git a/plugins/UserCountry/GeoIPAutoUpdater.php b/plugins/UserCountry/GeoIPAutoUpdater.php index 2c44ebb66d..53b299a5c6 100755 --- a/plugins/UserCountry/GeoIPAutoUpdater.php +++ b/plugins/UserCountry/GeoIPAutoUpdater.php @@ -359,6 +359,17 @@ class GeoIPAutoUpdater extends Task } /** + * Removes all options to disable any configured automatic updates + */ + public static function clearOptions() + { + foreach (self::$urlOptions as $optionKey => $optionName) { + Option::delete($optionName); + } + Option::delete(self::SCHEDULE_PERIOD_OPTION_NAME); + } + + /** * Returns true if the auto-updater is setup to update at least one type of * database. False if otherwise. * diff --git a/plugins/UserCountry/LocationProvider.php b/plugins/UserCountry/LocationProvider.php index 771984dbd4..75e34fbe84 100755 --- a/plugins/UserCountry/LocationProvider.php +++ b/plugins/UserCountry/LocationProvider.php @@ -118,6 +118,19 @@ abstract class LocationProvider abstract public function isWorking(); /** + * Returns information about this location provider. Contains an id, title & description: + * + * array( + * 'id' => 'geoip2php', + * 'title' => '...', + * 'description' => '...' + * ); + * + * @return array + */ + abstract public function getInfo(); + + /** * Returns an array mapping location result keys w/ bool values indicating whether * that information is supported by this provider. If it is not supported, that means * this provider either cannot get this information, or is not configured to get it. @@ -131,6 +144,21 @@ abstract class LocationProvider abstract public function getSupportedLocationInfo(); /** + * Method called when a provider gets activated. + */ + public function activate() + { + } + + /** + * Returns if location provider should be shown. + */ + public function isVisible() + { + return true; + } + + /** * Returns every available provider instance. * * @return LocationProvider[] @@ -142,7 +170,9 @@ abstract class LocationProvider $plugins = PluginManager::getInstance()->getPluginsLoadedAndActivated(); foreach ($plugins as $plugin) { foreach (self::getLocationProviders($plugin) as $instance) { - self::$providers[] = $instance; + if ($instance->isVisible()) { + self::$providers[] = $instance; + } } } } @@ -200,10 +230,10 @@ abstract class LocationProvider * * An example result: * array( - * 'geoip_php' => array('id' => 'geoip_php', + * 'geoip2php' => array('id' => 'geoip2php', * 'title' => '...', * 'desc' => '...', - * 'status' => GeoIp::BROKEN, + * 'status' => GeoIp2::BROKEN, * 'statusMessage' => '...', * 'location' => '...') * 'geoip_serverbased' => array(...) @@ -217,6 +247,7 @@ abstract class LocationProvider { $allInfo = array(); foreach (self::getAllProviders() as $provider) { + $info = $provider->getInfo(); $status = self::INSTALLED; @@ -273,7 +304,11 @@ abstract class LocationProvider */ public static function getCurrentProviderId() { - $optionValue = Option::get(self::CURRENT_PROVIDER_OPTION_NAME); + try { + $optionValue = Option::get(self::CURRENT_PROVIDER_OPTION_NAME); + } catch (\Exception $e) { + $optionValue = false; + } return $optionValue === false ? DefaultProvider::ID : $optionValue; } @@ -303,6 +338,9 @@ abstract class LocationProvider throw new Exception( "Invalid provider ID '$providerId'. The provider either does not exist or is not available"); } + + $provider->activate(); + Option::set(self::CURRENT_PROVIDER_OPTION_NAME, $providerId); Cache::clearCacheGeneral(); return $provider; @@ -470,4 +508,3 @@ abstract class LocationProvider } } } - diff --git a/plugins/UserCountry/LocationProvider/GeoIp.php b/plugins/UserCountry/LocationProvider/GeoIp.php index 247ae6035a..a20e3f0462 100755 --- a/plugins/UserCountry/LocationProvider/GeoIp.php +++ b/plugins/UserCountry/LocationProvider/GeoIp.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\UserCountry\LocationProvider; use Exception; use Piwik\Piwik; +use Piwik\Plugin\Manager; use Piwik\Plugins\UserCountry\LocationProvider; /** @@ -67,6 +68,11 @@ abstract class GeoIp extends LocationProvider } } + public function isVisible() + { + return !Manager::getInstance()->isPluginActivated('GeoIp2') || self::getCurrentProvider() instanceof GeoIp; + } + /** * Returns true if this provider has been setup correctly, the error message if * otherwise. diff --git a/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php b/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php index ed83a69755..8171485e42 100755 --- a/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php +++ b/plugins/UserCountry/LocationProvider/GeoIp/Pecl.php @@ -21,7 +21,7 @@ use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; class Pecl extends GeoIp { const ID = 'geoip_pecl'; - const TITLE = 'GeoIP (PECL)'; + const TITLE = 'GeoIP Legacy (PECL)'; /** * For tests. @@ -258,7 +258,7 @@ class Pecl extends GeoIp 'description' => $desc, 'install_docs' => $installDocs, 'extra_message' => $extraMessage, - 'order' => 3); + 'order' => 13); } /** diff --git a/plugins/UserCountry/LocationProvider/GeoIp/Php.php b/plugins/UserCountry/LocationProvider/GeoIp/Php.php index a0bdc15ae2..db274f6bf7 100755 --- a/plugins/UserCountry/LocationProvider/GeoIp/Php.php +++ b/plugins/UserCountry/LocationProvider/GeoIp/Php.php @@ -19,7 +19,7 @@ use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; class Php extends GeoIp { const ID = 'geoip_php'; - const TITLE = 'GeoIP (Php)'; + const TITLE = 'GeoIP Legacy (Php)'; /** * The GeoIP database instances used. This array will contain at most three @@ -345,16 +345,21 @@ class Php extends GeoIp $availableDatabaseTypes[] = Piwik::translate('UserCountry_Organization'); } - $extraMessage = '<strong>' . Piwik::translate('General_Note') . '</strong>: ' - . Piwik::translate('UserCountry_GeoIPImplHasAccessTo') . ': <strong>' - . implode(', ', $availableDatabaseTypes) . '</strong>.'; + if (!empty($availableDatabaseTypes)) { + $extraMessage = '<strong>' . Piwik::translate('General_Note') . '</strong>: ' + . Piwik::translate('UserCountry_GeoIPImplHasAccessTo') . ': <strong>' + . implode(', ', $availableDatabaseTypes) . '</strong>.'; + } else { + $extraMessage = '<strong>' . Piwik::translate('General_Note') . '</strong>: ' + . Piwik::translate('UserCountry_GeoIPNoDatabaseFound') . '<strong>'; + } return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'install_docs' => $installDocs, 'extra_message' => $extraMessage, - 'order' => 2); + 'order' => 12); } /** diff --git a/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php b/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php index a30c5f0400..2a597bd030 100755 --- a/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php +++ b/plugins/UserCountry/LocationProvider/GeoIp/ServerBased.php @@ -25,7 +25,7 @@ use Piwik\Plugins\UserCountry\LocationProvider; class ServerBased extends GeoIp { const ID = 'geoip_serverbased'; - const TITLE = 'GeoIP (%s)'; + const TITLE = 'GeoIP Legacy (%s)'; const TEST_SERVER_VAR = 'GEOIP_ADDR'; const TEST_SERVER_VAR_ALT = 'GEOIP_COUNTRY_CODE'; const TEST_SERVER_VAR_ALT_IPV6 = 'GEOIP_COUNTRY_CODE_V6'; @@ -251,7 +251,7 @@ class ServerBased extends GeoIp return array('id' => self::ID, 'title' => $title, 'description' => $desc, - 'order' => 4, + 'order' => 14, 'install_docs' => $installDocs, 'extra_message' => $extraMessage); } diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php index 61e5925c37..cab362a3c6 100644 --- a/plugins/UserCountry/UserCountry.php +++ b/plugins/UserCountry/UserCountry.php @@ -57,7 +57,6 @@ class UserCountry extends \Piwik\Plugin public function getJsFiles(&$jsFiles) { - $jsFiles[] = "plugins/UserCountry/javascripts/userCountry.js"; $jsFiles[] = "plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.controller.js"; $jsFiles[] = "plugins/UserCountry/angularjs/location-provider-selection/location-provider-selection.directive.js"; $jsFiles[] = "plugins/UserCountry/angularjs/location-provider-updater/location-provider-updater.controller.js"; diff --git a/plugins/UserCountry/VisitorDetails.php b/plugins/UserCountry/VisitorDetails.php index 1458aea307..2b333d8aac 100644 --- a/plugins/UserCountry/VisitorDetails.php +++ b/plugins/UserCountry/VisitorDetails.php @@ -9,12 +9,8 @@ namespace Piwik\Plugins\UserCountry; use Piwik\Common; -use Piwik\Plugins\Live; use Piwik\Plugins\Live\VisitorDetailsAbstract; -use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; use Piwik\Tracker\Visit; -use Piwik\Url; -use Piwik\View; require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/functions.php'; @@ -73,7 +69,7 @@ class VisitorDetails extends VisitorDetailsAbstract { $region = $this->getRegionCode(); if ($region != '' && $region != Visit::UNKNOWN_CODE) { - return GeoIp::getRegionNameFromCodes( + return getRegionNameFromCodes( $this->details['location_country'], $region); } diff --git a/plugins/UserCountry/angularjs/location-provider-updater/location-provider-updater.controller.js b/plugins/UserCountry/angularjs/location-provider-updater/location-provider-updater.controller.js index 8c94467ec1..677acec8a3 100644 --- a/plugins/UserCountry/angularjs/location-provider-updater/location-provider-updater.controller.js +++ b/plugins/UserCountry/angularjs/location-provider-updater/location-provider-updater.controller.js @@ -7,9 +7,9 @@ (function () { angular.module('piwikApp').controller('LocationProviderUpdaterController', LocationProviderUpdaterController); - LocationProviderUpdaterController.$inject = ['piwikApi']; + LocationProviderUpdaterController.$inject = ['piwikApi', '$window']; - function LocationProviderUpdaterController(piwikApi) { + function LocationProviderUpdaterController(piwikApi, $window) { // remember to keep controller very simple. Create a service/factory (model) if needed var self = this; @@ -33,7 +33,7 @@ callback(response); } else { // update progress bar - var newProgressVal = Math.ceil((response.current_size / response.expected_file_size) * 100); + var newProgressVal = Math.floor((response.current_size / response.expected_file_size) * 100); self[progressBarId] = Math.min(newProgressVal, 100); // if incomplete, download next chunk, otherwise, show updater manager @@ -66,7 +66,7 @@ $('#geoipdb-update-info').html(response.error); self.geoipDatabaseInstalled = true; } else { - self.showGeoIpUpdateInfo(); + $window.location.reload(); } } ); @@ -136,7 +136,7 @@ piwikApi.post({ period: this.updatePeriod, module: 'UserCountry', - action: 'updateGeoIPLinks', + action: 'updateGeoIPLinks' }, { loc_db: this.locationDbUrl, isp_db: this.ispDbUrl, diff --git a/plugins/UserCountry/functions.php b/plugins/UserCountry/functions.php index afab257068..f02003776d 100644 --- a/plugins/UserCountry/functions.php +++ b/plugins/UserCountry/functions.php @@ -10,7 +10,10 @@ namespace Piwik\Plugins\UserCountry; use Piwik\DataTable; +use Piwik\Option; use Piwik\Piwik; +use Piwik\Plugin\Manager; +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Plugins\UserCountry\LocationProvider\GeoIp; use Piwik\Tracker\Visit; @@ -106,6 +109,31 @@ function getElementFromStringArray($label, $separator, $index, $emptyValue = fal } /** + * Returns region name for the given regionCode / countryCode combination + * using the currently set location provider + * + * @param string $countryCode + * @param string $regionCode + * @return string + */ +function getRegionNameFromCodes($countryCode, $regionCode) +{ + if (!Manager::getInstance()->isPluginActivated('GeoIp2') || + LocationProvider::getCurrentProvider() instanceof GeoIp) { + return GeoIp::getRegionNameFromCodes($countryCode, $regionCode); + } + + $name = GeoIp2::getRegionNameFromCodes($countryCode, $regionCode); + + // fallback if no translation for with GeoIP2 + if ($name == Piwik::translate('General_Unknown')) { + $name = GeoIp::getRegionNameFromCodes($countryCode, $regionCode); + } + + return $name; +} + +/** * Returns the region name using the label of a Visits by Region report. * * @param string $label A label containing a region code followed by '|' and a country code, eg, @@ -123,7 +151,7 @@ function getRegionName($label) } list($regionCode, $countryCode) = explode(Archiver::LOCATION_SEPARATOR, $label); - return GeoIp::getRegionNameFromCodes($countryCode, $regionCode); + return getRegionNameFromCodes($countryCode, $regionCode); } /** @@ -146,7 +174,7 @@ function getPrettyRegionName($label) list($regionCode, $countryCode) = explode(Archiver::LOCATION_SEPARATOR, $label); - $result = GeoIp::getRegionNameFromCodes($countryCode, $regionCode); + $result = getRegionNameFromCodes($countryCode, $regionCode); if ($countryCode != Visit::UNKNOWN_CODE && $countryCode != '') { $result .= ', ' . countryTranslate($countryCode); } @@ -185,7 +213,7 @@ function getPrettyCityName($label) $result = $cityName; if ($countryCode != Visit::UNKNOWN_CODE && $countryCode != '') { if ($regionCode != '' && $regionCode != Visit::UNKNOWN_CODE) { - $regionName = GeoIp::getRegionNameFromCodes($countryCode, $regionCode); + $regionName = getRegionNameFromCodes($countryCode, $regionCode); $result .= ', ' . $regionName; } $result .= ', ' . countryTranslate($countryCode); diff --git a/plugins/UserCountry/javascripts/userCountry.js b/plugins/UserCountry/javascripts/userCountry.js deleted file mode 100755 index bbdb5e32b9..0000000000 --- a/plugins/UserCountry/javascripts/userCountry.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Piwik - free/libre analytics platform - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - */ - -$(document).ready(function () { - -}); diff --git a/plugins/UserCountry/lang/en.json b/plugins/UserCountry/lang/en.json index 407d95fbb3..38694d78f5 100644 --- a/plugins/UserCountry/lang/en.json +++ b/plugins/UserCountry/lang/en.json @@ -31,6 +31,7 @@ "GeoIPCannotFindMbstringExtension": "Cannot find the %1$s function. Please make sure the %2$s extension is installed and loaded.", "GeoIPDatabases": "GeoIP Databases", "GeoIPDocumentationSuffix": "In order to see data for this report, you must setup GeoIP in the Geolocation admin tab. The commercial %1$sMaxmind%2$s GeoIP databases are more accurate than the free ones. To see how accurate they are, click %3$shere%4$s.", + "GeoIPNoDatabaseFound": "This GeoIP implementation was not able to find any database.", "GeoIPImplHasAccessTo": "This GeoIP implementation has access to the following types of databases", "GeoIPIncorrectDatabaseFormat": "Your GeoIP database does not seem to have the correct format. It may be corrupt. Make sure you are using the binary version and try replacing it with another copy.", "GeoIpLocationProviderDesc_Pecl1": "This location provider uses a GeoIP database and a PECL module to accurately and efficiently determine the location of your visitors.", diff --git a/plugins/UserCountry/templates/_updaterManage.twig b/plugins/UserCountry/templates/_updaterManage.twig index edb8258de2..571b3ce170 100755 --- a/plugins/UserCountry/templates/_updaterManage.twig +++ b/plugins/UserCountry/templates/_updaterManage.twig @@ -25,12 +25,14 @@ value="{{ geoIPIspUrl }}"> </div> + {% if geoIPOrgUrl is defined %} <div piwik-field uicontrol="text" name="geoip-org-db" ng-model="locationUpdater.orgDbUrl" introduction="{{ 'UserCountry_OrgDatabase'|translate|e('html_attr') }}" title="{{ 'Actions_ColumnDownloadURL'|translate|e('html_attr') }}" value="{{ geoIPOrgUrl }}"> </div> + {% endif %} <div id="locationProviderUpdatePeriodInlineHelp" class="inline-help-node"> {% if lastTimeUpdaterRun is defined and lastTimeUpdaterRun is not empty %} diff --git a/plugins/UserCountry/templates/adminIndex.twig b/plugins/UserCountry/templates/adminIndex.twig index 2cca082a8a..653e2b1561 100755 --- a/plugins/UserCountry/templates/adminIndex.twig +++ b/plugins/UserCountry/templates/adminIndex.twig @@ -18,8 +18,8 @@ <h3 style="margin-top:0;">{{ 'UserCountry_HowToSetupGeoIP'|translate }}</h3> <p>{{ 'UserCountry_HowToSetupGeoIPIntro'|translate }}</p> <ul style="list-style:disc !important;margin-left:2em;"> - <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step1'|translate('<a href="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz">','</a>','<a rel="noreferrer" target="_blank" href="http://www.maxmind.com/?rId=piwik">','</a>')|raw }}</li> - <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step2'|translate("'GeoLiteCity.dat'",'<strong>','</strong>')|raw }}</li> + <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step1'|translate('<a href="'~geoLiteUrl~'">','</a>','<a rel="noreferrer" target="_blank" href="http://www.maxmind.com/?rId=piwik">','</a>')|raw }}</li> + <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step2'|translate("'"~geoLiteFilename~"'",'<strong>','</strong>')|raw }}</li> <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step3'|translate('<strong>','</strong>','<span style="color:green"><strong>','</strong></span>')|raw }}</li> <li style="list-style-type: disc !important;">{{ 'UserCountry_HowToSetupGeoIP_Step4'|translate }}</li> </ul> @@ -97,6 +97,36 @@ </div> </div> + +{% if geoIPLegacyLocUrl is defined and geoIPLegacyLocUrl %} + {# The text in this part is not translatable on purpose, as it will be removed again soon #} + <div piwik-content-block content-title="Automatic Updates for GeoIP Legacy"> + + <p>Setting up automatic updates for GeoIP Legacy is no longer supported.</p> + + <div class="notification system notification-warning"> + {% if 'GeoLite' in geoIPLegacyLocUrl %} + <div>Maxmind announced to discontinue updates to the GeoLite Legacy databases as of April 1, 2018.</div> + {% endif %} + <strong>Please consider switching to GeoIP 2 soon! GeoIP Legacy Support is deprecated and will be removed in one of the next major releases.</strong> + </div> + + {% if geoIPLegacyLocUrl or geoIPLegacyIspUrl or geoIPLegacyOrgUrl %} + <h3>GeoIP Legacy Auto Update</h3> + + <p>Your previous configuration for automatic updates for GeoIP legacy databases is still up and running. It will be automatically disabled and removed after switching to GeoIP2.</p> + + <p>Below you can find the current configuration:</p> + + {% if geoIPLegacyLocUrl %}<p>{{ 'UserCountry_LocationDatabase'|translate|e('html_attr') }}: {{ geoIPLegacyLocUrl }}</p>{% endif %} + {% if geoIPLegacyIspUrl %}<p>{{ 'UserCountry_ISPDatabase'|translate|e('html_attr') }}: {{ geoIPLegacyIspUrl }}</p>{% endif %} + {% if geoIPLegacyOrgUrl %}<p>{{ 'UserCountry_OrgDatabase'|translate|e('html_attr') }}: {{ geoIPLegacyOrgUrl }}</p>{% endif %} + {% if geoIPLegacyUpdatePeriod %}<p>{{ 'UserCountry_DownloadNewDatabasesEvery'|translate|e('html_attr') }}: {{ geoIPLegacyUpdatePeriod }}</p>{% endif %} + + {% endif %} + </div> +{% endif %} + <div piwik-content-block content-title="{% if not geoIPDatabasesInstalled %}{{ 'UserCountry_GeoIPDatabases'|translate|e('html_attr') }}{% else %}{{ 'UserCountry_SetupAutomaticUpdatesOfGeoIP'|translate|e('html_attr') }}{% endif %}" id="geoip-db-mangement"> @@ -132,7 +162,7 @@ </div> <div id="geoipdb-screen2-download" ng-show="locationUpdater.showFreeDownload"> <div piwik-progressbar - label="{{ ('UserCountry_DownloadingDb'|translate('<a href="'~geoLiteUrl~'">GeoLiteCity.dat</a>') ~ '...')|json_encode }}" + label="{{ ('UserCountry_DownloadingDb'|translate('<a href="'~geoLiteUrl~'">'~geoLiteFilename~'</a>') ~ '...')|json_encode }}" progress="locationUpdater.progressFreeDownload"> </div> </div> diff --git a/plugins/UserCountry/templates/getGeoIpUpdaterManageScreen.twig b/plugins/UserCountry/templates/getGeoIpUpdaterManageScreen.twig deleted file mode 100755 index 750e395b44..0000000000 --- a/plugins/UserCountry/templates/getGeoIpUpdaterManageScreen.twig +++ /dev/null @@ -1 +0,0 @@ -{% include "@UserCountry/_updaterManage.twig" %}
\ No newline at end of file diff --git a/plugins/UserCountry/tests/Integration/APITest.php b/plugins/UserCountry/tests/Integration/APITest.php index a424048258..689f1e0867 100644 --- a/plugins/UserCountry/tests/Integration/APITest.php +++ b/plugins/UserCountry/tests/Integration/APITest.php @@ -12,6 +12,7 @@ use Piwik\Access; use Piwik\Common; use Piwik\Config; use Piwik\Plugins\UserCountry\API; +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use Piwik\Plugins\UserCountry\LocationProvider; use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -41,7 +42,8 @@ class APITest extends IntegrationTestCase public function test_setLocationProvider() { - $locationProvider = LocationProvider\GeoIp\Php::ID; + GeoIp2::$geoIPDatabaseDir = 'tests/lib/geoip-files'; + $locationProvider = GeoIp2\Php::ID; $this->api->setLocationProvider($locationProvider); $this->assertEquals($locationProvider, Common::getCurrentLocationProviderId()); diff --git a/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php b/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php index c9e6891f54..8e2a4c0d64 100644 --- a/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php +++ b/plugins/UserCountry/tests/Integration/VisitorGeolocatorTest.php @@ -364,7 +364,7 @@ class VisitorGeolocatorTest extends IntegrationTestCase protected function getProviderMock() { return $this->getMockBuilder('\Piwik\Plugins\UserCountry\LocationProvider') - ->setMethods(array('getId', 'getLocation', 'isAvailable', 'isWorking', 'getSupportedLocationInfo')) + ->setMethods(array('getId', 'getInfo', 'getLocation', 'isAvailable', 'isWorking', 'getSupportedLocationInfo')) ->disableOriginalConstructor() ->getMock(); } diff --git a/plugins/UserCountry/tests/System/AttributeHistoricalDataWithLocationsTest.php b/plugins/UserCountry/tests/System/AttributeHistoricalDataWithLocationsTest.php index 7265f6bce9..23c62d7058 100644 --- a/plugins/UserCountry/tests/System/AttributeHistoricalDataWithLocationsTest.php +++ b/plugins/UserCountry/tests/System/AttributeHistoricalDataWithLocationsTest.php @@ -58,7 +58,7 @@ class AttributeHistoricalDataWithLocationsTest extends IntegrationTestCase Db::query($sql); } - self::$fixture->setLocationProvider('GeoIPCity.dat'); + self::$fixture->setLocationProvider('GeoIP2-City.mmdb'); } /** @@ -82,7 +82,7 @@ class AttributeHistoricalDataWithLocationsTest extends IntegrationTestCase public function testExecute_ShouldReturnEmptyWorkingProcessLogs_IfThereIsNoData() { $this->assertRegExp( - '/Re-attribution for date range: 2014-06-01 to 2014-06-06. 0 visits to process with provider "geoip_php"./', + '/Re-attribution for date range: 2014-06-01 to 2014-06-06. 0 visits to process with provider "geoip2php"./', $this->executeCommand('2014-06-01,2014-06-06') ); } @@ -92,7 +92,7 @@ class AttributeHistoricalDataWithLocationsTest extends IntegrationTestCase $result = $this->executeCommand('2010-01-03,2010-06-03'); $this->assertContains( - 'Re-attribution for date range: 2010-01-03 to 2010-06-03. 35 visits to process with provider "geoip_php".', + 'Re-attribution for date range: 2010-01-03 to 2010-06-03. 35 visits to process with provider "geoip2php".', $result ); diff --git a/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getCity_month.xml b/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getCity_month.xml index 1ef9b96f0c..c2c4b948e5 100644 --- a/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getCity_month.xml +++ b/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getCity_month.xml @@ -63,7 +63,7 @@ <logo>plugins/Morpheus/icons/dist/flags/ca.png</logo> </row> <row> - <label>Besançon, Franche-Comte, France</label> + <label>Besançon, Doubs, France</label> <nb_visits>3</nb_visits> <nb_actions>7</nb_actions> <max_actions>5</max_actions> @@ -86,12 +86,12 @@ <sum_daily_nb_users>1</sum_daily_nb_users> <lat>47.249</lat> <long>6.018</long> - <segment>city==Besan%C3%A7on;regionCode==A6;countryCode==fr</segment> + <segment>city==Besan%C3%A7on;regionCode==25;countryCode==fr</segment> <city_name>Besançon</city_name> - <region>A6</region> + <region>25</region> <country>fr</country> <country_name>France</country_name> - <region_name>Franche-Comte</region_name> + <region_name>Doubs</region_name> <logo>plugins/Morpheus/icons/dist/flags/fr.png</logo> </row> <row> @@ -118,9 +118,9 @@ <sum_daily_nb_users>0</sum_daily_nb_users> <lat>29.65</lat> <long>91.1</long> - <segment>city==Lhasa;regionCode==14;countryCode==cn</segment> + <segment>city==Lhasa;regionCode==XZ;countryCode==cn</segment> <city_name>Lhasa</city_name> - <region>14</region> + <region>XZ</region> <country>cn</country> <country_name>China</country_name> <region_name>Xizang</region_name> @@ -150,9 +150,9 @@ <sum_daily_nb_users>0</sum_daily_nb_users> <lat>41.9</lat> <long>12.483</long> - <segment>city==Rome;regionCode==07;countryCode==it</segment> + <segment>city==Rome;regionCode==62;countryCode==it</segment> <city_name>Rome</city_name> - <region>07</region> + <region>62</region> <country>it</country> <country_name>Italy</country_name> <region_name>Lazio</region_name> diff --git a/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getRegion_month.xml b/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getRegion_month.xml index 34fd1a7dfe..3973b41e30 100644 --- a/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getRegion_month.xml +++ b/plugins/UserCountry/tests/System/expected/test_AttributeHistoricalDataWithLocationsTest_testExecute_ShouldReturnLogAfterWorkingWithSomeData__UserCountry.getRegion_month.xml @@ -58,7 +58,7 @@ <logo>plugins/Morpheus/icons/dist/flags/ca.png</logo> </row> <row> - <label>Franche-Comte, France</label> + <label>Doubs, France</label> <nb_visits>3</nb_visits> <nb_actions>7</nb_actions> <max_actions>5</max_actions> @@ -79,11 +79,11 @@ <revenue>20</revenue> <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>1</sum_daily_nb_users> - <segment>regionCode==A6;countryCode==fr</segment> - <region>A6</region> + <segment>regionCode==25;countryCode==fr</segment> + <region>25</region> <country>fr</country> <country_name>France</country_name> - <region_name>Franche-Comte</region_name> + <region_name>Doubs</region_name> <logo>plugins/Morpheus/icons/dist/flags/fr.png</logo> </row> <row> @@ -108,8 +108,8 @@ <revenue>15</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> - <segment>regionCode==07;countryCode==it</segment> - <region>07</region> + <segment>regionCode==62;countryCode==it</segment> + <region>62</region> <country>it</country> <country_name>Italy</country_name> <region_name>Lazio</region_name> @@ -137,8 +137,8 @@ <revenue>15</revenue> <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors> <sum_daily_nb_users>0</sum_daily_nb_users> - <segment>regionCode==14;countryCode==cn</segment> - <region>14</region> + <segment>regionCode==XZ;countryCode==cn</segment> + <region>XZ</region> <country>cn</country> <country_name>China</country_name> <region_name>Xizang</region_name> |