update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit 47263617c5
88 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -11,7 +11,6 @@ namespace Piwik\Plugins\UserCountry;
use Exception;
use Piwik\Archive;
use Piwik\DataTable;
use Piwik\Metrics;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
@ -33,6 +32,7 @@ class API extends \Piwik\Plugin\API
$dataTable = $this->getDataTable(Archiver::COUNTRY_RECORD_NAME, $idSite, $period, $date, $segment);
// apply filter on the whole datatable in order the inline search to work (searches are done on "beautiful" label)
$dataTable->filter('AddSegmentValue');
$dataTable->filter('ColumnCallbackAddMetadata', array('label', 'code'));
$dataTable->filter('ColumnCallbackAddMetadata', array('label', 'logo', __NAMESPACE__ . '\getFlagFromCode'));
$dataTable->filter('ColumnCallbackReplace', array('label', __NAMESPACE__ . '\countryTranslate'));
@ -69,6 +69,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;
@ -111,6 +114,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;
@ -174,12 +180,12 @@ class API extends \Piwik\Plugin\API
{
Piwik::checkUserHasSomeViewAccess();
if ($provider === false) {
if (empty($provider)) {
$provider = LocationProvider::getCurrentProviderId();
}
$oProvider = LocationProvider::getProviderById($provider);
if ($oProvider === false) {
if (empty($oProvider)) {
throw new Exception("Cannot find the '$provider' provider. It is either an invalid provider "
. "ID or the ID of a provider that is not working.");
}
@ -197,7 +203,6 @@ class API extends \Piwik\Plugin\API
Piwik::checkUserHasViewAccess($idSite);
$archive = Archive::build($idSite, $period, $date, $segment);
$dataTable = $archive->getDataTable($name);
$dataTable->filter('Sort', array(Metrics::INDEX_NB_VISITS));
$dataTable->queueFilter('ReplaceColumnNames');
return $dataTable;
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -61,8 +61,17 @@ class Archiver extends \Piwik\Plugin\Archiver
self::REGION_RECORD_NAME,
self::CITY_RECORD_NAME,
);
$columnsAggregationOperation = null;
$nameToCount = $this->getProcessor()->aggregateDataTableRecords($dataTableToSum);
$nameToCount = $this->getProcessor()->aggregateDataTableRecords(
$dataTableToSum,
$maximumRowsInDataTableLevelZero = null,
$maximumRowsInSubDataTable = null,
$columnToSortByBeforeTruncation = null,
$columnsAggregationOperation,
$columnsToRenameAfterAggregation = null,
$countRowsRecursive = array()
);
$this->getProcessor()->insertNumericRecord(self::DISTINCT_COUNTRIES_METRIC,
$nameToCount[self::COUNTRY_RECORD_NAME]['level0']);
}

View file

@ -0,0 +1,92 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Common;
use Piwik\Network\IPUtils;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\UserCountry\VisitorGeolocator;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Request;
abstract class Base extends VisitDimension
{
/**
* @var VisitorGeolocator
*/
private $visitorGeolocator;
protected function getUrlOverrideValueIfAllowed($urlParamToOverride, Request $request)
{
if (!$request->isAuthenticated()) {
return false;
}
$value = Common::getRequestVar($urlParamToOverride, false, 'string', $request->getParams());
if (!empty($value)) {
return $value;
}
return false;
}
public function getRequiredVisitFields()
{
return array('location_ip', 'location_browser_lang');
}
protected function getLocationDetail($userInfo, $locationKey)
{
$useLocationCache = empty($GLOBALS['PIWIK_TRACKER_LOCAL_TRACKING']);
$location = $this->getVisitorGeolocator()->getLocation($userInfo, $useLocationCache);
if (!isset($location[$locationKey])) {
return false;
}
return $location[$locationKey];
}
protected function getVisitorGeolocator()
{
if ($this->visitorGeolocator === null) {
$this->visitorGeolocator = new VisitorGeolocator();
}
return $this->visitorGeolocator;
}
protected function getUserInfo(Request $request, Visitor $visitor)
{
$ipAddress = $this->getIpAddress($visitor->getVisitorColumn('location_ip'), $request);
$language = $request->getBrowserLanguage();
$userInfo = array('lang' => $language, 'ip' => $ipAddress);
return $userInfo;
}
private function getIpAddress($anonymizedIp, \Piwik\Tracker\Request $request)
{
$privacyConfig = new PrivacyManagerConfig();
$ip = $request->getIp();
if ($privacyConfig->useAnonymizedIpForVisitEnrichment) {
$ip = $anonymizedIp;
}
$ipAddress = IPUtils::binaryToStringIP($ip);
return $ipAddress;
}
}

View file

@ -0,0 +1,77 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
use Piwik\Plugins\UserCountry\Segment;
class City extends Base
{
protected $columnName = 'location_city';
protected $columnType = 'varchar(255) DEFAULT NULL';
protected function configureSegments()
{
$segment = new Segment();
$segment->setSegment('city');
$segment->setName('UserCountry_City');
$segment->setAcceptedValues('Sydney, Sao Paolo, Rome, etc.');
$this->addSegment($segment);
}
public function getName()
{
return Piwik::translate('UserCountry_City');
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
$value = $this->getUrlOverrideValueIfAllowed('city', $request);
if ($value !== false) {
return $value;
}
$userInfo = $this->getUserInfo($request, $visitor);
return $this->getLocationDetail($userInfo, LocationProvider::CITY_NAME_KEY);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return int
*/
public function onExistingVisit(Request $request, Visitor $visitor, $action)
{
return $this->getUrlOverrideValueIfAllowed('city', $request);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
{
return $visitor->getVisitorColumn($this->columnName);
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Columns\Dimension;
use Piwik\Piwik;
class Continent extends Dimension
{
public function getName()
{
return Piwik::translate('UserCountry_Continent');
}
}

View file

@ -0,0 +1,155 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Intl\Data\Provider\RegionDataProvider;
use Piwik\Network\IP;
use Piwik\Piwik;
use Piwik\Plugin\Manager;
use Piwik\Plugins\Provider\Provider as ProviderProvider;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\Segment;
use Piwik\Tracker\Visit;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
use Piwik\Tracker\Request;
class Country extends Base
{
protected $columnName = 'location_country';
protected $columnType = 'CHAR(3) NOT NULL';
protected function configureSegments()
{
$segment = new Segment();
$segment->setSegment('countryCode');
$segment->setName('UserCountry_Country');
$segment->setAcceptedValues('de, us, fr, in, es, etc.');
$this->addSegment($segment);
$segment = new Segment();
$segment->setSegment('continentCode');
$segment->setName('UserCountry_Continent');
$segment->setSqlFilter('Piwik\Plugins\UserCountry\UserCountry::getCountriesForContinent');
$segment->setAcceptedValues('eur, asi, amc, amn, ams, afr, ant, oce');
$this->addSegment($segment);
}
public function getName()
{
return Piwik::translate('UserCountry_Country');
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
$value = $this->getUrlOverrideValueIfAllowed('country', $request);
if ($value !== false) {
return $value;
}
$userInfo = $this->getUserInfo($request, $visitor);
$country = $this->getLocationDetail($userInfo, LocationProvider::COUNTRY_CODE_KEY);
if (!empty($country) && $country != Visit::UNKNOWN_CODE) {
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
* @param Action|null $action
* @return int
*/
public function onExistingVisit(Request $request, Visitor $visitor, $action)
{
return $this->getUrlOverrideValueIfAllowed('country', $request);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
{
$country = $visitor->getVisitorColumn($this->columnName);
if (isset($country) && false !== $country) {
return $country;
}
$browserLanguage = $request->getBrowserLanguage();
$enableLanguageToCountryGuess = Config::getInstance()->Tracker['enable_language_to_country_guess'];
$locationIp = $visitor->getVisitorColumn('location_ip');
$country = Common::getCountry($browserLanguage, $enableLanguageToCountryGuess, $locationIp);
return $country;
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\Segment;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
class Latitude extends Base
{
protected $columnName = 'location_latitude';
protected $columnType = 'float(10, 6) DEFAULT NULL';
protected function configureSegments()
{
$segment = new Segment();
$segment->setSegment('latitude');
$segment->setName('UserCountry_Latitude');
$segment->setAcceptedValues('-33.578, 40.830, etc.<br/>You can select visitors within a lat/long range using &segment=lat&gt;X;lat&lt;Y;long&gt;M;long&lt;N.');
$this->addSegment($segment);
}
public function getName()
{
return Piwik::translate('UserCountry_Latitude');
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
$value = $this->getUrlOverrideValueIfAllowed('lat', $request);
if ($value !== false) {
return $value;
}
$userInfo = $this->getUserInfo($request, $visitor);
$latitude = $this->getLocationDetail($userInfo, LocationProvider::LATITUDE_KEY);
return $latitude;
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return int
*/
public function onExistingVisit(Request $request, Visitor $visitor, $action)
{
return $this->getUrlOverrideValueIfAllowed('lat', $request);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
{
return $visitor->getVisitorColumn($this->columnName);
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\Segment;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
class Longitude extends Base
{
protected $columnName = 'location_longitude';
protected $columnType = 'float(10, 6) DEFAULT NULL';
protected function configureSegments()
{
$segment = new Segment();
$segment->setSegment('longitude');
$segment->setName('UserCountry_Longitude');
$segment->setAcceptedValues('-70.664, 14.326, etc.');
$this->addSegment($segment);
}
public function getName()
{
return Piwik::translate('UserCountry_Longitude');
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
$value = $this->getUrlOverrideValueIfAllowed('long', $request);
if ($value !== false) {
return $value;
}
$userInfo = $this->getUserInfo($request, $visitor);
$longitude = $this->getLocationDetail($userInfo, LocationProvider::LONGITUDE_KEY);
return $longitude;
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return int
*/
public function onExistingVisit(Request $request, Visitor $visitor, $action)
{
return $this->getUrlOverrideValueIfAllowed('long', $request);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
{
return $visitor->getVisitorColumn($this->columnName);
}
}

View file

@ -0,0 +1,56 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Plugin\Manager;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
use Piwik\Tracker\Request;
class Provider extends Base
{
protected $columnName = 'location_provider';
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
if (!Manager::getInstance()->isPluginInstalled('Provider')) {
return false;
}
$userInfo = $this->getUserInfo($request, $visitor);
$isp = $this->getLocationDetail($userInfo, LocationProvider::ISP_KEY);
$org = $this->getLocationDetail($userInfo, LocationProvider::ORG_KEY);
// if the location has provider/organization info, set it
if (!empty($isp)) {
$providerValue = $isp;
// if the org is set and not the same as the isp, add it to the provider value
if (!empty($org) && $org != $providerValue) {
$providerValue .= ' - ' . $org;
}
return $providerValue;
}
if (!empty($org)) {
return $org;
}
return false;
}
}

View file

@ -0,0 +1,77 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Columns;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\Segment;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
class Region extends Base
{
protected $columnName = 'location_region';
protected $columnType = 'char(2) DEFAULT NULL';
protected function configureSegments()
{
$segment = new Segment();
$segment->setSegment('regionCode');
$segment->setName('UserCountry_Region');
$segment->setAcceptedValues('01 02, OR, P8, etc.<br/>eg. region=A1;country=fr');
$this->addSegment($segment);
}
public function getName()
{
return Piwik::translate('UserCountry_Region');
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onNewVisit(Request $request, Visitor $visitor, $action)
{
$value = $this->getUrlOverrideValueIfAllowed('region', $request);
if ($value !== false) {
return $value;
}
$userInfo = $this->getUserInfo($request, $visitor);
return $this->getLocationDetail($userInfo, LocationProvider::REGION_CODE_KEY);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return int
*/
public function onExistingVisit(Request $request, Visitor $visitor, $action)
{
return $this->getUrlOverrideValueIfAllowed('region', $request);
}
/**
* @param Request $request
* @param Visitor $visitor
* @param Action|null $action
* @return mixed
*/
public function onAnyGoalConversion(Request $request, Visitor $visitor, $action)
{
return $visitor->getVisitorColumn($this->columnName);
}
}

View file

@ -0,0 +1,202 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\UserCountry\VisitorGeolocator;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\DataAccess\RawLogDao;
use Piwik\Timer;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class AttributeHistoricalDataWithLocations extends ConsoleCommand
{
const DATES_RANGE_ARGUMENT = 'dates-range';
const PERCENT_STEP_ARGUMENT = 'percent-step';
const PERCENT_STEP_ARGUMENT_DEFAULT = 5;
const PROVIDER_ARGUMENT = 'provider';
const SEGMENT_LIMIT_OPTION = 'segment-limit';
const SEGMENT_LIMIT_OPTION_DEFAULT = 1000;
const FORCE_OPTION = 'force';
/**
* @var RawLogDao
*/
protected $dao;
/**
* @var VisitorGeolocator
*/
protected $visitorGeolocator;
/**
* @var int
*/
private $processed = 0;
/**
* @var int
*/
private $amountOfVisits;
/**
* @var Timer
*/
private $timer;
/**
* @var int
*/
private $percentStep;
/**
* @var int
*/
private $processedPercent = 0;
public function __construct(RawLogDao $dao = null)
{
parent::__construct();
$this->dao = $dao ?: new RawLogDao();
}
protected function configure()
{
$this->setName('usercountry:attribute');
$this->setDescription("Re-attribute existing log data (visits & conversions) with geolocated location data, using the specified or configured location provider.");
$this->addArgument(self::DATES_RANGE_ARGUMENT, InputArgument::REQUIRED, 'Attribute visits in this date range. Eg, 2012-01-01,2013-01-01');
$this->addOption(self::PERCENT_STEP_ARGUMENT, null, InputArgument::OPTIONAL,
'How often to display the command progress. A status update will be printed after N percent of visits are processed, '
. 'where N is the value of this option.', self::PERCENT_STEP_ARGUMENT_DEFAULT);
$this->addOption(self::PROVIDER_ARGUMENT, null, InputOption::VALUE_REQUIRED, 'Provider id which should be used to attribute visits. If empty then'
. ' Piwik will use the currently configured provider. If no provider is configured, the default provider is used.');
$this->addOption(self::SEGMENT_LIMIT_OPTION, null, InputOption::VALUE_OPTIONAL, 'Number of visits to process at a time.', self::SEGMENT_LIMIT_OPTION_DEFAULT);
$this->addOption(self::FORCE_OPTION, null, InputOption::VALUE_NONE, "Force geolocation, even if the requested provider does not appear to work. It is not "
. "recommended to use this option.");
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return void|int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
list($from, $to) = $this->getDateRangeToAttribute($input);
$this->visitorGeolocator = $this->createGeolocator($output, $input);
$this->percentStep = $this->getPercentStep($input);
$this->amountOfVisits = $this->dao->countVisitsWithDatesLimit($from, $to);
$output->writeln(
sprintf('Re-attribution for date range: %s to %s. %d visits to process with provider "%s".',
$from, $to, $this->amountOfVisits, $this->visitorGeolocator->getProvider()->getId())
);
$this->timer = new Timer();
$this->processSpecifiedLogsInChunks($output, $from, $to, $input->getOption(self::SEGMENT_LIMIT_OPTION));
$output->writeln("Completed. <comment>" . $this->timer->__toString() . "</comment>");
return 0;
}
protected function processSpecifiedLogsInChunks(OutputInterface $output, $from, $to, $segmentLimit)
{
$self = $this;
$this->visitorGeolocator->reattributeVisitLogs($from, $to, $idSite = null, $segmentLimit, function () use ($output, $self) {
$self->onVisitProcessed($output);
});
}
/**
* @param InputInterface $input
* @return int
*/
protected function getPercentStep(InputInterface $input)
{
$percentStep = $input->getOption(self::PERCENT_STEP_ARGUMENT);
if (!is_numeric($percentStep)) {
return self::PERCENT_STEP_ARGUMENT_DEFAULT;
}
// Percent step should be between maximum percent value and minimum percent value (1-100)
if ($percentStep > 99 || $percentStep < 1) {
return 100;
}
return $percentStep;
}
/**
* Print information about progress.
* @param OutputInterface $output
*/
protected function onVisitProcessed(OutputInterface $output)
{
++$this->processed;
$percent = ceil($this->processed / $this->amountOfVisits * 100);
if ($percent > $this->processedPercent
&& $percent % $this->percentStep === 0
) {
$output->writeln(sprintf('%d%% processed. <comment>%s</comment>', $percent, $this->timer->__toString()));
$this->processedPercent = $percent;
}
}
private function getDateRangeToAttribute(InputInterface $input)
{
$dateRangeString = $input->getArgument(self::DATES_RANGE_ARGUMENT);
$dates = explode(',', $dateRangeString);
$dates = array_map(array('Piwik\Date', 'factory'), $dates);
if (count($dates) != 2) {
throw new \InvalidArgumentException('Invalid date range supplied: ' . $dateRangeString);
}
return $dates;
}
private function createGeolocator(OutputInterface $output, InputInterface $input)
{
$providerId = $input->getOption(self::PROVIDER_ARGUMENT);
$geolocator = new VisitorGeolocator(LocationProvider::getProviderById($providerId) ?: null);
$usedProvider = $geolocator->getProvider();
if (!$usedProvider->isAvailable()) {
throw new \InvalidArgumentException("The provider '$providerId' is not currently available, please make sure it is configured correctly.");
}
$isWorkingOrErrorMessage = $usedProvider->isWorking();
if ($isWorkingOrErrorMessage !== true) {
$errorMessage = "The provider '$providerId' does not appear to be working correctly. Details: $isWorkingOrErrorMessage";
$forceGeolocation = $input->getOption(self::FORCE_OPTION);
if ($forceGeolocation) {
$output->writeln("<error>$errorMessage</error>");
$output->writeln("<comment>Ignoring location provider issue, geolocating anyway due to --force option.</comment>");
} else {
throw new \InvalidArgumentException($errorMessage);
}
}
return $geolocator;
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -14,13 +14,12 @@ use Piwik\DataTable\Renderer\Json;
use Piwik\Http;
use Piwik\IP;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\ServerBased;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\Pecl;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\ServerBased;
use Piwik\View;
use Piwik\ViewDataTable\Factory;
/**
*
@ -34,10 +33,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$view->urlSparklineCountries = $this->getUrlSparkline('getLastDistinctCountriesGraph');
$view->numberDistinctCountries = $this->getNumberOfDistinctCountries(true);
$view->dataTableCountry = $this->getCountry(true);
$view->dataTableContinent = $this->getContinent(true);
$view->dataTableRegion = $this->getRegion(true);
$view->dataTableCity = $this->getCity(true);
$view->dataTableCountry = $this->renderReport('getCountry');
$view->dataTableContinent = $this->renderReport('getContinent');
$view->dataTableRegion = $this->renderReport('getRegion');
$view->dataTableCity = $this->renderReport('getCity');
return $view->render();
}
@ -132,9 +131,9 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$result['next_screen'] = $this->getGeoIpUpdaterManageScreen();
}
return Common::json_encode($result);
return json_encode($result);
} catch (Exception $ex) {
return Common::json_encode(array('error' => $ex->getMessage()));
return json_encode(array('error' => $ex->getMessage()));
}
}
}
@ -204,15 +203,15 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
// the browser so it can download it next
$info = $this->getNextMissingDbUrlInfo();
if ($info !== false) {
return Common::json_encode($info);
return json_encode($info);
} else {
$view = new View("@UserCountry/_updaterNextRunTime");
$view->nextRunTime = GeoIPAutoUpdater::getNextRunTime();
$nextRunTimeHtml = $view->render();
return Common::json_encode(array('nextRunTime' => $nextRunTimeHtml));
return json_encode(array('nextRunTime' => $nextRunTimeHtml));
}
} catch (Exception $ex) {
return Common::json_encode(array('error' => $ex->getMessage()));
return json_encode(array('error' => $ex->getMessage()));
}
}
}
@ -267,13 +266,13 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$info = $this->getNextMissingDbUrlInfo();
if ($info !== false) {
return Common::json_encode($info);
return json_encode($info);
}
}
return Common::json_encode($result);
return json_encode($result);
} catch (Exception $ex) {
return Common::json_encode(array('error' => $ex->getMessage()));
return json_encode(array('error' => $ex->getMessage()));
}
}
}
@ -315,8 +314,8 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
public function getLocationUsingProvider()
{
$providerId = Common::getRequestVar('id');
$provider = $provider = LocationProvider::getProviderById($providerId);
if ($provider === false) {
$provider = LocationProvider::getProviderById($providerId);
if (empty($provider)) {
throw new Exception("Invalid provider ID: '$providerId'.");
}
@ -329,36 +328,6 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
return $location;
}
public function getCountry()
{
return $this->renderReport(__FUNCTION__);
}
public function getContinent()
{
return $this->renderReport(__FUNCTION__);
}
/**
* Echo's or returns an HTML view of the visits by region report.
*
* @return string
*/
public function getRegion()
{
return $this->renderReport(__FUNCTION__);
}
/**
* Echo's or returns an HTML view of the visits by city report.
*
* @return string
*/
public function getCity()
{
return $this->renderReport(__FUNCTION__);
}
public function getNumberOfDistinctCountries()
{
return $this->getNumericValue('UserCountry.getNumberOfDistinctCountries');
@ -396,7 +365,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
private function dieIfGeolocationAdminIsDisabled()
{
if(!UserCountry::isGeoLocationAdminEnabled()) {
if (!UserCountry::isGeoLocationAdminEnabled()) {
throw new \Exception('Geo location setting page has been disabled.');
}
}

View file

@ -0,0 +1,64 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\UserCountry\Diagnostic;
use Piwik\Config;
use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic;
use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Translation\Translator;
/**
* Check the geolocation setup.
*/
class GeolocationDiagnostic implements Diagnostic
{
/**
* @var Translator
*/
private $translator;
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function execute()
{
$isPiwikInstalling = !Config::getInstance()->existsLocalConfig();
if ($isPiwikInstalling) {
// Skip the diagnostic if Piwik is being installed
return array();
}
$label = $this->translator->translate('UserCountry_Geolocation');
$currentProviderId = LocationProvider::getCurrentProviderId();
$allProviders = LocationProvider::getAllProviderInfo();
$isRecommendedProvider = in_array($currentProviderId, array(LocationProvider\GeoIp\Php::ID, $currentProviderId == LocationProvider\GeoIp\Pecl::ID));
$isProviderInstalled = ($allProviders[$currentProviderId]['status'] == LocationProvider::INSTALLED);
if ($isRecommendedProvider && $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(
'<a href="http://piwik.org/docs/geo-locate/" rel="noreferrer" target="_blank">', '', '', '</a>'
));
} else {
$comment = $this->translator->translate('UserCountry_DefaultLocationProviderDesc1') . ' ';
$comment .= $this->translator->translate('UserCountry_DefaultLocationProviderDesc2', array(
'<a href="http://piwik.org/docs/geo-locate/" rel="noreferrer" target="_blank">', '', '', '</a>'
));
}
return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -12,26 +12,27 @@ require_once PIWIK_INCLUDE_PATH . "/core/ScheduledTask.php"; // for the tracker
use Exception;
use Piwik\Common;
use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Http;
use Piwik\Log;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\Php;
use Piwik\ScheduledTask;
use Piwik\ScheduledTaskTimetable;
use Piwik\ScheduledTime\Monthly;
use Piwik\ScheduledTime\Weekly;
use Piwik\TaskScheduler;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Scheduler\Scheduler;
use Piwik\Scheduler\Task;
use Piwik\Scheduler\Timetable;
use Piwik\Scheduler\Schedule\Monthly;
use Piwik\Scheduler\Schedule\Weekly;
use Piwik\Unzip;
/**
* Used to automatically update installed GeoIP databases, and manages the updater's
* scheduled task.
*/
class GeoIPAutoUpdater extends ScheduledTask
class GeoIPAutoUpdater extends Task
{
const SCHEDULE_PERIOD_MONTHLY = 'month';
const SCHEDULE_PERIOD_WEEKLY = 'week';
@ -78,7 +79,7 @@ class GeoIPAutoUpdater extends ScheduledTask
break;
}
parent::__construct($this, 'update', null, $schedulePeriod, ScheduledTask::LOWEST_PRIORITY);
parent::__construct($this, 'update', null, $schedulePeriod, Task::LOWEST_PRIORITY);
}
/**
@ -128,6 +129,8 @@ class GeoIPAutoUpdater extends ScheduledTask
*/
protected function downloadFile($dbType, $url)
{
$url = trim($url);
$ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url);
// NOTE: using the first item in $dbNames[$dbType] makes sure GeoLiteCity will be renamed to GeoIPCity
@ -265,7 +268,7 @@ class GeoIPAutoUpdater extends ScheduledTask
}
$tempFile = GeoIp::getPathForGeoIpDatabase($tempFilename);
rename($existing = $tempFile, $newName = $oldDbFile);
rename($tempFile, $oldDbFile);
// delete original archive
if ($unlink) {
@ -332,7 +335,7 @@ class GeoIPAutoUpdater extends ScheduledTask
// set period option
if (!empty($options['period'])) {
$period = $options['period'];
if ($period != self::SCHEDULE_PERIOD_MONTHLY
&& $period != self::SCHEDULE_PERIOD_WEEKLY
) {
@ -344,7 +347,10 @@ class GeoIPAutoUpdater extends ScheduledTask
Option::set(self::SCHEDULE_PERIOD_OPTION_NAME, $period);
TaskScheduler::rescheduleTask(new GeoIPAutoUpdater());
/** @var Scheduler $scheduler */
$scheduler = StaticContainer::getContainer()->get('Piwik\Scheduler\Scheduler');
$scheduler->rescheduleTask(new GeoIPAutoUpdater());
}
}
@ -516,8 +522,10 @@ class GeoIPAutoUpdater extends ScheduledTask
* Databases are renamed to ${original}.broken .
*
* Note: method is protected for testability.
*
* @param $logErrors - only used to hide error logs during tests
*/
protected function performRedundantDbChecks()
protected function performRedundantDbChecks($logErrors = true)
{
$databaseTypes = array_keys(GeoIp::$dbNames);
@ -536,8 +544,11 @@ class GeoIPAutoUpdater extends ScheduledTask
self::getTestLocationCatchPhpErrors($provider);
if (self::$unzipPhpError !== null) {
list($errno, $errstr, $errfile, $errline) = self::$unzipPhpError;
Log::warning("GeoIPAutoUpdater: Encountered PHP error when performing redundant tests on GeoIP "
. "%s database: %s: %s on line %s of %s.", $type, $errno, $errstr, $errline, $errfile);
if($logErrors) {
Log::error("GeoIPAutoUpdater: Encountered PHP error when performing redundant tests on GeoIP "
. "%s database: %s: %s on line %s of %s.", $type, $errno, $errstr, $errline, $errfile);
}
// get the current filename for the DB and an available new one to rename it to
list($oldPath, $newPath) = $this->getOldAndNewPathsForBrokenDb($customNames[$type]);
@ -622,19 +633,19 @@ class GeoIPAutoUpdater extends ScheduledTask
/**
* Returns the next scheduled time for the auto updater.
*
*
* @return Date|false
*/
public static function getNextRunTime()
{
$task = new GeoIPAutoUpdater();
$timetable = new ScheduledTaskTimetable();
$timetable = new Timetable();
return $timetable->getScheduledTaskTime($task->getName());
}
/**
* See {@link Piwik\ScheduledTime::getRescheduledTime()}.
* See {@link Piwik\Scheduler\Schedule\Schedule::getRescheduledTime()}.
*/
public function getRescheduledTime()
{

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -18,9 +18,14 @@ use Piwik\Tracker\Cache;
use ReflectionClass;
/**
* @see plugins/UserCountry/LocationProvider/Default.php
* @see plugins/UserCountry/functions.php
*/
require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/Default.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
@ -30,8 +35,8 @@ require_once PIWIK_INCLUDE_PATH . '/plugins/UserCountry/LocationProvider/GeoIp.p
/**
* The base class of all LocationProviders.
*
* LocationProviders attempt to determine a visitor's location using other
* visitor info. All LocationProviders require a visitor's IP address, some
* LocationProviders attempt to determine a visitor's location using
* visit information. All LocationProviders require a visitor's IP address, some
* require more, such as the browser language.
*/
abstract class LocationProvider
@ -272,7 +277,7 @@ abstract class LocationProvider
*
* This function should not be called by the Tracker.
*
* @return \Piwik\Plugins\UserCountry\LocationProvider
* @return \Piwik\Plugins\UserCountry\LocationProvider|null
*/
public static function getCurrentProvider()
{
@ -289,7 +294,7 @@ abstract class LocationProvider
public static function setCurrentProvider($providerId)
{
$provider = self::getProviderById($providerId);
if ($provider === false) {
if (empty($provider)) {
throw new Exception(
"Invalid provider ID '$providerId'. The provider either does not exist or is not available");
}
@ -302,17 +307,24 @@ abstract class LocationProvider
* Returns a provider instance by ID or false if the ID is invalid or unavailable.
*
* @param string $providerId
* @return \Piwik\Plugins\UserCountry\LocationProvider|false
* @return \Piwik\Plugins\UserCountry\LocationProvider|null
*/
public static function getProviderById($providerId)
{
foreach (self::getAvailableProviders() as $provider) {
$info = $provider->getInfo();
if ($info['id'] == $providerId) {
if ($provider->getId() == $providerId) {
return $provider;
}
}
return false;
return null;
}
public function getId()
{
$info = $this->getInfo();
return $info['id'];
}
/**
@ -340,7 +352,7 @@ abstract class LocationProvider
&& !empty($location[self::CONTINENT_CODE_KEY])
) {
$continentCode = strtolower($location[self::CONTINENT_CODE_KEY]);
$location[self::CONTINENT_NAME_KEY] = Piwik::translate('UserCountry_continent_' . $continentCode);
$location[self::CONTINENT_NAME_KEY] = continentTranslate($continentCode);
}
// fill in country name if country code is present
@ -348,7 +360,7 @@ abstract class LocationProvider
&& !empty($location[self::COUNTRY_CODE_KEY])
) {
$countryCode = strtolower($location[self::COUNTRY_CODE_KEY]);
$location[self::COUNTRY_NAME_KEY] = Piwik::translate('UserCountry_country_' . $countryCode);
$location[self::COUNTRY_NAME_KEY] = countryTranslate($countryCode);
}
// deal w/ improper latitude/longitude & round proper values
@ -437,22 +449,19 @@ abstract class LocationProvider
/**
* Returns an IP address from an array that was passed into getLocation. This
* will return an IPv4 address or false if the address is IPv6 (IPv6 is not
* supported yet).
* will return an IPv4 address or IPv6 address.
*
* @param array $info Must have 'ip' key.
* @return string|bool
* @return string|null
*/
protected function getIpFromInfo($info)
{
$ip = $info['ip'];
if (IP::isMappedIPv4($ip)) {
return IP::getIPv4FromMappedIPv6($ip);
} else if (IP::isIPv6($ip)) // IPv6 is not supported (yet)
{
return false;
$ip = \Piwik\Network\IP::fromStringIP($info['ip']);
if ($ip instanceof \Piwik\Network\IPv6 && $ip->isMappedIPv4()) {
return $ip->toIPv4String();
} else {
return $ip;
return $ip->toString();
}
}
}

View file

@ -0,0 +1,113 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Common;
use Piwik\Config;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
/**
* The default LocationProvider, this LocationProvider guesses a visitor's country
* using the language they use. This provider is not very accurate.
*
*/
class DefaultProvider extends 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 = Config::getInstance()->Tracker['enable_language_to_country_guess'];
if (empty($info['lang'])) {
$info['lang'] = Common::getBrowserLanguage();
}
$country = 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 bool always true
*/
public function isAvailable()
{
return true;
}
/**
* Returns whether this location provider is working correctly.
*
* This implementation is always working correctly.
*
* @return bool always 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" rel="noreferrer" target="_blank">'
. Piwik::translate('UserCountry_HowToInstallGeoIPDatabases')
. '</em></a></p>';
return array('id' => self::ID, 'title' => self::TITLE, 'description' => $desc, 'order' => 1);
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -90,7 +90,7 @@ class Pecl extends GeoIp
// get isp data if the isp database is available
if (self::isISPDatabaseAvailable()) {
$isp = @geoip_isp_by_name($ip);
if ($ip !== false) {
if ($isp !== false) {
$result[self::ISP_KEY] = utf8_encode($isp);
}
}
@ -218,7 +218,7 @@ class Pecl extends GeoIp
$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">'
. '<a rel="noreferrer" target="_blank" href="http://piwik.org/faq/how-to/#faq_164">'
. Piwik::translate('UserCountry_HowToInstallGeoIpPecl')
. '</a>'
. '</em>';

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -8,7 +8,6 @@
*/
namespace Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Log;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
@ -96,6 +95,7 @@ class Php extends GeoIp
public function getLocation($info)
{
$ip = $this->getIpFromInfo($info);
$isIPv6 = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
$result = array();
@ -105,7 +105,11 @@ class Php extends GeoIp
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 ($isIPv6) {
$location = geoip_record_by_addr_v6($locationGeoIp, $ip);
} else {
$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;
@ -118,28 +122,46 @@ class Php extends GeoIp
break;
case GEOIP_REGION_EDITION_REV0: // region database type
case GEOIP_REGION_EDITION_REV1:
$location = geoip_region_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
// NOTE: geoip_region_by_addr_v6 does not exist (yet?), so we
// return the country code and an empty region code
$location = array(geoip_country_code_by_addr_v6($locationGeoIp, $ip), '');
} else {
$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);
if ($isIPv6) {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr_v6($locationGeoIp, $ip);
} else {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
}
break;
default: // unknown database type, log warning and fallback to country edition
Log::warning("Found unrecognized database type: %s", $locationGeoIp->databaseType);
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr_v6($locationGeoIp, $ip);
} else {
$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.
// NOTE: ISP & ORG require commercial dbs to test. The code has been tested manually,
// but not by system tests.
$ispGeoIp = $this->getGeoIpInstance($key = 'isp');
if ($ispGeoIp) {
$isp = geoip_org_by_addr($ispGeoIp, $ip);
if ($isIPv6) {
$isp = geoip_name_by_addr_v6($ispGeoIp, $ip);
} else {
$isp = geoip_org_by_addr($ispGeoIp, $ip);
}
if (!empty($isp)) {
$result[self::ISP_KEY] = utf8_encode($isp);
}
@ -147,7 +169,11 @@ class Php extends GeoIp
$orgGeoIp = $this->getGeoIpInstance($key = 'org');
if ($orgGeoIp) {
$org = geoip_org_by_addr($orgGeoIp, $ip);
if ($isIPv6) {
$org = geoip_name_by_addr_v6($orgGeoIp, $ip);
} else {
$org = geoip_org_by_addr($orgGeoIp, $ip);
}
if (!empty($org)) {
$result[self::ORG_KEY] = utf8_encode($org);
}
@ -298,7 +324,7 @@ class Php extends GeoIp
$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">'
$installDocs = '<em><a rel="noreferrer" target="_blank" href="http://piwik.org/faq/how-to/#faq_163">'
. Piwik::translate('UserCountry_HowToInstallGeoIPDatabases')
. '</em></a>';

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -12,8 +12,8 @@ namespace Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Common;
use Piwik\IP;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
/**
* A LocationProvider that uses an GeoIP module installed in an HTTP Server.
@ -28,6 +28,7 @@ class ServerBased extends GeoIp
const TITLE = 'GeoIP (%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';
private static $geoIpServerVars = array(
parent::COUNTRY_CODE_KEY => 'GEOIP_COUNTRY_CODE',
@ -96,6 +97,11 @@ class ServerBased extends GeoIp
if (!empty($_SERVER[$geoipVarName])) {
$result[$resultKey] = $_SERVER[$geoipVarName];
}
$geoipVarNameV6 = $geoipVarName . '_V6';
if (!empty($_SERVER[$geoipVarNameV6])) {
$result[$resultKey] = $_SERVER[$geoipVarNameV6];
}
}
foreach (self::$geoIpUtfServerVars as $resultKey => $geoipVarName) {
if (!empty($_SERVER[$geoipVarName])) {
@ -150,25 +156,27 @@ class ServerBased extends GeoIp
}
$available = !empty($_SERVER[self::TEST_SERVER_VAR])
|| !empty($_SERVER[self::TEST_SERVER_VAR_ALT]);
|| !empty($_SERVER[self::TEST_SERVER_VAR_ALT])
|| !empty($_SERVER[self::TEST_SERVER_VAR_ALT_IPV6])
;
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;
}
// 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;
}
/**
@ -180,6 +188,7 @@ class ServerBased extends GeoIp
{
if (empty($_SERVER[self::TEST_SERVER_VAR])
&& empty($_SERVER[self::TEST_SERVER_VAR_ALT])
&& empty($_SERVER[self::TEST_SERVER_VAR_ALT_IPV6])
) {
return Piwik::translate("UserCountry_CannotFindGeoIPServerVar", self::TEST_SERVER_VAR . ' $_SERVER');
}
@ -214,10 +223,10 @@ class ServerBased extends GeoIp
. 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">'
'<em><a rel="noreferrer" 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">'
. '<a rel="noreferrer" target="_blank" href="http://piwik.org/faq/how-to/#faq_166">'
. Piwik::translate('UserCountry_HowToInstallNginxModule')
. '</a></em>';

Some files were not shown because too many files have changed in this diff Show more