Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Czołnowski <marcin@czolnowski.net>2014-10-17 18:39:07 +0400
committerMarcin Czołnowski <marcin@czolnowski.net>2014-12-03 16:12:23 +0300
commit8b913e015101e03510a5da675a98a36d8af0aba2 (patch)
tree3ad104f532712af76c3ce98e0e38aa5c67ad11e1 /plugins/UserCountry/Commands
parent79ea4ecafcc595f7f5776c05c81ed277b86d051e (diff)
User country attribution command.
Diffstat (limited to 'plugins/UserCountry/Commands')
-rw-r--r--plugins/UserCountry/Commands/AttributeHistoricalDataWithLocations.php243
1 files changed, 243 insertions, 0 deletions
diff --git a/plugins/UserCountry/Commands/AttributeHistoricalDataWithLocations.php b/plugins/UserCountry/Commands/AttributeHistoricalDataWithLocations.php
new file mode 100644
index 0000000000..224f3f24de
--- /dev/null
+++ b/plugins/UserCountry/Commands/AttributeHistoricalDataWithLocations.php
@@ -0,0 +1,243 @@
+<?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 PDORow;
+use Piwik\IP;
+use Piwik\Plugin\ConsoleCommand;
+use Piwik\Plugins\UserCountry\LocationFetcher;
+use Piwik\Plugins\UserCountry\LocationFetcherProvider;
+use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Plugins\UserCountry\Repository\Mysql\LogsRepository;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Piwik\Plugins\UserCountry\Repository\LogsRepository as LogsRepositoryInterface;
+
+class AttributeHistoricalDataWithLocations extends ConsoleCommand
+{
+ const DATES_RANGE_ARGUMENT = 'dates-range';
+
+ const PERCENT_STEP_ARGUMENT = 'percent-step';
+
+ const PROVIDER_ARGUMENT = 'provider';
+
+ /**
+ * @var LogsRepositoryInterface
+ */
+ protected $repository;
+
+ /**
+ * @var LocationFetcher
+ */
+ protected $locationFetcher;
+
+ /**
+ * @var array
+ */
+ protected $logVisitFieldsToUpdate = array(
+ 'location_country' => LocationProvider::COUNTRY_CODE_KEY,
+ 'location_region' => LocationProvider::REGION_CODE_KEY,
+ 'location_city' => LocationProvider::CITY_NAME_KEY,
+ 'location_latitude' => LocationProvider::LATITUDE_KEY,
+ 'location_longitude' => LocationProvider::LONGITUDE_KEY
+ );
+
+ protected function configure()
+ {
+ $this->setName('usercountry:attribute');
+
+ $this->addArgument(
+ self::DATES_RANGE_ARGUMENT,
+ InputArgument::REQUIRED,
+ 'Attribute visits from this dates.'
+ );
+
+ $this->addArgument(
+ self::PERCENT_STEP_ARGUMENT,
+ InputArgument::OPTIONAL,
+ 'How often command should write about current state.',
+ 5
+ );
+
+ $this->addArgument(
+ self::PROVIDER_ARGUMENT,
+ InputArgument::OPTIONAL,
+ 'Provider id which should be used to attribute visits. If empty then Piwik will use default provider.'
+ );
+
+ $this->repository = new LogsRepository();
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void|int
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $from = $this->getDateArgument($input, self::DATES_RANGE_ARGUMENT, 0);
+ $to = $this->getDateArgument($input, self::DATES_RANGE_ARGUMENT, 1);
+
+ $percentStep = $this->getPercentStep($input);
+
+ if (!$from || !$to) {
+ $output->writeln(
+ sprintf('Invalid from [%s] or to [%s].',
+ $from, $to
+ )
+ );
+
+ return 1;
+ }
+
+ $locationFetcherProvider = new LocationFetcherProvider(
+ $input->getArgument(self::PROVIDER_ARGUMENT)
+ );
+
+ $this->locationFetcher = new LocationFetcher($locationFetcherProvider);
+
+ $logsCursor = $this->repository->getVisitsWithDatesLimit(
+ $from, $to,
+ array_keys($this->logVisitFieldsToUpdate)
+ );
+ $amountOfVisits = $this->repository->countVisitsWithDatesLimit($from, $to);
+
+ $output->writeln(
+ sprintf('Re-attribution for date range: %s to %s. %d visits to process with provider "%s".',
+ $from, $to, $amountOfVisits, $locationFetcherProvider->get()->getId()
+ )
+ );
+
+ $start = time();
+ $processed = 0;
+
+ $percentConfirmed = array();
+
+ /**
+ * @var PDORow $row
+ */
+ while ($row = $logsCursor->fetch()) {
+ if (empty($row->idvisit)) {
+ if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
+ $output->writeln('Empty idvisit field. Skipping...');
+ }
+
+ continue;
+ }
+
+ if (empty($row->location_ip)) {
+ if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
+ $output->writeln(
+ sprintf('Empty location_ip field for idvisit = %s. Skipping...', (string) $row->idvisit)
+ );
+ }
+
+ continue;
+ }
+
+ $ip = IP::N2P($row->location_ip);
+ $location = $this->locationFetcher->getLocation(array('ip' => $ip));
+
+ $columnsToSet = array();
+ $bind = array();
+ foreach ($this->logVisitFieldsToUpdate as $column => $locationKey) {
+ if (!empty($location[$locationKey])) {
+ if ($locationKey === LocationProvider::COUNTRY_CODE_KEY) {
+ if (strtolower($location[$locationKey]) != strtolower($row->{$column})) {
+ $columnsToSet[] = $column;
+ $bind[] = strtolower($location[$locationKey]);
+ }
+ } else {
+ if ($location[$locationKey] != $row->{$column}) {
+ $columnsToSet[] = $column;
+ $bind[] = $location[$locationKey];
+ }
+ }
+ }
+ }
+
+ ++$processed;
+ $percent = ceil($processed / $amountOfVisits * 100);
+
+ if (!in_array($percent, $percentConfirmed, true) && $percent % $percentStep === 0) {
+ $output->writeln(
+ sprintf('%d%% processed. [in %d seconds]', $percent, time() - $start)
+ );
+
+ $percentConfirmed[] = $percent;
+ }
+
+ if (empty($columnsToSet)) {
+ if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
+ $output->writeln(
+ sprintf('Visit with idvisit = %s and ip = %s is attributed. Skipping...', (string) $row->idvisit, $ip)
+ );
+ }
+
+ continue;
+ }
+
+ $bind[] = $row->idvisit;
+
+ if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
+ $output->writeln(
+ sprintf('Updating visit with idvisit = %s and ip = %s.', (string) $row->idvisit, $ip)
+ );
+ }
+
+ $this->repository->updateVisits($columnsToSet, $bind);
+ $this->repository->updateConversions($columnsToSet, $bind);
+ }
+
+ $output->writeln(sprintf('Completed in %d seconds.', time() - $start));
+
+ return 0;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param string $name
+ * @param int $index
+ * @return string
+ */
+ protected function getDateArgument(InputInterface $input, $name, $index)
+ {
+ $option = explode(',', $input->getArgument($name));
+
+ if (!isset($option[$index])) {
+ return false;
+ }
+
+ return date('Y-m-d', strtotime($option[$index]));
+ }
+
+ /**
+ * @param InputInterface $input
+ * @return int
+ */
+ protected function getPercentStep(InputInterface $input)
+ {
+ $percentStep = $input->getArgument(self::PERCENT_STEP_ARGUMENT);
+
+ if (!is_numeric($percentStep)) {
+ return 5;
+ }
+
+ if ($percentStep > 99) {
+ return 100;
+ }
+
+ if ($percentStep < 1) {
+ return 100;
+ }
+
+ return $percentStep;
+ }
+}