From 482e797236ff984d450dbf5802f7148bdc40d94b Mon Sep 17 00:00:00 2001 From: diosmosis Date: Mon, 8 Sep 2014 20:23:04 -0700 Subject: Allow LogAggregator to work with multiple site IDs, compute unique visitors for archives of multiple sites and add option to control whether unique visitors for multiple sites are processed. --- config/global.ini.php | 5 +++++ core/ArchiveProcessor.php | 26 ++++++++++++++++++++++---- core/DataAccess/LogAggregator.php | 25 +++++++++++++++++-------- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/config/global.ini.php b/config/global.ini.php index 649b1964ba..ff987583d2 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -111,6 +111,11 @@ enable_processing_unique_visitors_month = 1 enable_processing_unique_visitors_year = 0 enable_processing_unique_visitors_range = 0 +; controls whether Unique Visitors will be processed for groups of websites. these metrics describe the number +; of unique visitors across the entire set of websites, so if a visitor visited two websites in the group, she +; would still only be counted as one. only relevant when using plugins that group sites together +enable_processing_unique_visitors_multiple_sites = 0 + ; The list of periods that are available in the Piwik calendar ; Example use case: custom date range requests are processed in real time, ; so they may take a few minutes on very high traffic website: you may remove "range" below to disable this period diff --git a/core/ArchiveProcessor.php b/core/ArchiveProcessor.php index 800db50a11..9cc67f6271 100644 --- a/core/ArchiveProcessor.php +++ b/core/ArchiveProcessor.php @@ -99,13 +99,28 @@ class ArchiveProcessor * @var int */ protected $numberOfVisits = false; + protected $numberOfVisitsConverted = false; + /** + * If true, unique visitors are not calculated when we are aggregating data for multiple sites. + * The `[General] enable_processing_unique_visitors_multiple_sites` INI config option controls + * the value of this variable. + * + * @var bool + */ + private $skipUniqueVisitorsCalculationForMultipleSites = true; + + const SKIP_UNIQUE_VISITORS_FOR_MULTIPLE_SITES = 'enable_processing_unique_visitors_multiple_sites'; + public function __construct(Parameters $params, ArchiveWriter $archiveWriter) { $this->params = $params; $this->logAggregator = new LogAggregator($params); $this->archiveWriter = $archiveWriter; + + $this->skipUniqueVisitorsCalculationForMultipleSites = + Config::getInstance()->General['enable_processing_unique_visitors_multiple_sites'] == 1; } protected function getArchive() @@ -365,12 +380,15 @@ class ArchiveProcessor protected function enrichWithUniqueVisitorsMetric(Row $row) { - if(!$this->getParams()->isSingleSite() ) { - // we only compute unique visitors for a single site + // skip unique visitors metrics calculation if calculating for multiple sites is disabled + if (!$this->getParams()->isSingleSite() + && $this->skipUniqueVisitorsCalculationForMultipleSites + ) { return; } - if ( $row->getColumn('nb_uniq_visitors') !== false - || $row->getColumn('nb_users') !== false) { + if ($row->getColumn('nb_uniq_visitors') !== false + || $row->getColumn('nb_users') !== false + ) { if (SettingsPiwik::isUniqueVisitorsEnabled($this->getParams()->getPeriod()->getLabel())) { $metrics = array(Metrics::INDEX_NB_UNIQ_VISITORS, Metrics::INDEX_NB_USERS); $uniques = $this->computeNbUniques( $metrics ); diff --git a/core/DataAccess/LogAggregator.php b/core/DataAccess/LogAggregator.php index 0170097fe6..95a7603176 100644 --- a/core/DataAccess/LogAggregator.php +++ b/core/DataAccess/LogAggregator.php @@ -9,6 +9,7 @@ namespace Piwik\DataAccess; use Piwik\ArchiveProcessor\Parameters; +use Piwik\Common; use Piwik\DataArray; use Piwik\Db; use Piwik\Metrics; @@ -128,8 +129,8 @@ class LogAggregator /** @var \Piwik\Date */ protected $dateEnd; - /** @var \Piwik\Site */ - protected $site; + /** @var int[] */ + protected $sites; /** @var \Piwik\Segment */ protected $segment; @@ -144,12 +145,12 @@ class LogAggregator $this->dateStart = $params->getDateStart(); $this->dateEnd = $params->getDateEnd(); $this->segment = $params->getSegment(); - $this->site = $params->getSite(); + $this->sites = $params->getIdSites(); } public function generateQuery($select, $from, $where, $groupBy, $orderBy) { - $bind = $this->getBindDatetimeSite(); + $bind = $this->getGeneralQueryBindParams(); $query = $this->segment->getSelectQuery($select, $from, $where, $bind, $orderBy, $groupBy); return $query; } @@ -438,7 +439,7 @@ class LogAggregator { $where = "$tableName.$datetimeField >= ? AND $tableName.$datetimeField <= ? - AND $tableName.idsite = ?"; + AND $tableName.idsite IN (". Common::getSqlStringFieldsArray($this->sites) . ")"; if (!empty($extraWhere)) { $extraWhere = sprintf($extraWhere, $tableName, $tableName); $where .= ' AND ' . $extraWhere; @@ -453,9 +454,17 @@ class LogAggregator return $groupBy; } - protected function getBindDatetimeSite() + /** + * Returns general bind parameters for all log aggregation queries. This includes the datetime + * start of entities, datetime end of entities and IDs of all sites. + * + * @return array + */ + protected function getGeneralQueryBindParams() { - return array($this->dateStart->getDateStartUTC(), $this->dateEnd->getDateEndUTC(), $this->site->getId()); + $bind = array($this->dateStart->getDateStartUTC(), $this->dateEnd->getDateEndUTC()); + $bind = array_merge($bind, $this->sites); + return $bind; } /** @@ -545,7 +554,7 @@ class LogAggregator array( 'log_conversion_item.server_time >= ?', 'log_conversion_item.server_time <= ?', - 'log_conversion_item.idsite = ?', + 'log_conversion_item.idsite IN (' . Common::getSqlStringFieldsArray($this->sites) . ')', 'log_conversion_item.deleted = 0' ) ), -- cgit v1.2.3