diff --git a/core/Metrics.php b/core/Metrics.php index 60054329525..a2e26405176 100644 --- a/core/Metrics.php +++ b/core/Metrics.php @@ -640,7 +640,7 @@ public static function makeGoalColumnsRow(int $idGoal, array $goalsMetrics): arr $values = []; foreach ($columns as $column) { - $values[$column] = $goalsMetrics[$column] ?? 0; + $values[$column] = (float)($goalsMetrics[$column] ?? 0); } return $values; } diff --git a/plugins/VisitTime/Archiver.php b/plugins/VisitTime/Archiver.php index 53372c644b6..bb4ea8b59ef 100644 --- a/plugins/VisitTime/Archiver.php +++ b/plugins/VisitTime/Archiver.php @@ -9,85 +9,8 @@ namespace Piwik\Plugins\VisitTime; -use Piwik\DataArray; -use Piwik\Date; - class Archiver extends \Piwik\Plugin\Archiver { const SERVER_TIME_RECORD_NAME = 'VisitTime_serverTime'; const LOCAL_TIME_RECORD_NAME = 'VisitTime_localTime'; - - public function aggregateDayReport() - { - $this->aggregateByLocalTime(); - $this->aggregateByServerTime(); - } - - public function aggregateMultipleReports() - { - $dataTableRecords = array( - self::LOCAL_TIME_RECORD_NAME, - self::SERVER_TIME_RECORD_NAME, - ); - $columnsAggregationOperation = null; - $this->getProcessor()->aggregateDataTableRecords( - $dataTableRecords, - $maximumRowsInDataTableLevelZero = null, - $maximumRowsInSubDataTable = null, - $columnToSortByBeforeTruncation = null, - $columnsAggregationOperation, - $columnsToRenameAfterAggregation = null, - $countRowsRecursive = array()); - } - - protected function aggregateByServerTime() - { - $dataArray = $this->getLogAggregator()->getMetricsFromVisitByDimension(array("label" => "HOUR(log_visit.visit_first_action_time)")); - $query = $this->getLogAggregator()->queryConversionsByDimension(array("label" => "HOUR(log_conversion.server_time)")); - if ($query === false) { - return; - } - - while ($conversionRow = $query->fetch()) { - $dataArray->sumMetricsGoals($conversionRow['label'], $conversionRow); - } - $dataArray->enrichMetricsWithConversions(); - $dataArray = $this->convertTimeToLocalTimezone($dataArray); - $this->ensureAllHoursAreSet($dataArray); - $report = $dataArray->asDataTable()->getSerialized(); - $this->getProcessor()->insertBlobRecord(self::SERVER_TIME_RECORD_NAME, $report); - } - - protected function aggregateByLocalTime() - { - $array = $this->getLogAggregator()->getMetricsFromVisitByDimension("HOUR(log_visit.visitor_localtime)"); - $this->ensureAllHoursAreSet($array); - $report = $array->asDataTable()->getSerialized(); - $this->getProcessor()->insertBlobRecord(self::LOCAL_TIME_RECORD_NAME, $report); - } - - protected function convertTimeToLocalTimezone(DataArray &$array) - { - $date = Date::factory($this->getProcessor()->getParams()->getDateStart()->getDateStartUTC())->toString(); - $timezone = $this->getProcessor()->getParams()->getSite()->getTimezone(); - - $converted = array(); - foreach ($array->getDataArray() as $hour => $stats) { - $datetime = $date . ' ' . $hour . ':00:00'; - $hourInTz = (int)Date::factory($datetime, $timezone)->toString('H'); - $converted[$hourInTz] = $stats; - } - return new DataArray($converted); - } - - private function ensureAllHoursAreSet(DataArray &$array) - { - $data = $array->getDataArray(); - for ($i = 0; $i <= 23; $i++) { - if (empty($data[$i])) { - $array->sumMetricsVisits($i, DataArray::makeEmptyRow()); - } - } - } - } diff --git a/plugins/VisitTime/RecordBuilders/Base.php b/plugins/VisitTime/RecordBuilders/Base.php new file mode 100644 index 00000000000..f41645d16aa --- /dev/null +++ b/plugins/VisitTime/RecordBuilders/Base.php @@ -0,0 +1,37 @@ + 0, + Metrics::INDEX_NB_VISITS => 0, + Metrics::INDEX_NB_ACTIONS => 0, + Metrics::INDEX_NB_USERS => 0, + Metrics::INDEX_MAX_ACTIONS => 0, + Metrics::INDEX_SUM_VISIT_LENGTH => 0, + Metrics::INDEX_BOUNCE_COUNT => 0, + Metrics::INDEX_NB_VISITS_CONVERTED => 0, + ]; + + for ($i = 0; $i <= 23; $i++) { + if (!$record->getRowFromLabel($i)) { + $record->addRowFromSimpleArray(['label' => $i] + $emptyRow); + } + } + } +} diff --git a/plugins/VisitTime/RecordBuilders/LocalTime.php b/plugins/VisitTime/RecordBuilders/LocalTime.php new file mode 100644 index 00000000000..7b719532c36 --- /dev/null +++ b/plugins/VisitTime/RecordBuilders/LocalTime.php @@ -0,0 +1,58 @@ +getLogAggregator(); + + $record = new DataTable(); + + $query = $logAggregator->queryVisitsByDimension(["label" => "HOUR(log_visit.visitor_localtime)"]); + while ($row = $query->fetch()) { + $columns = [ + Metrics::INDEX_NB_UNIQ_VISITORS => $row[Metrics::INDEX_NB_UNIQ_VISITORS], + Metrics::INDEX_NB_VISITS => $row[Metrics::INDEX_NB_VISITS], + Metrics::INDEX_NB_ACTIONS => $row[Metrics::INDEX_NB_ACTIONS], + Metrics::INDEX_NB_USERS => $row[Metrics::INDEX_NB_USERS], + Metrics::INDEX_MAX_ACTIONS => $row[Metrics::INDEX_MAX_ACTIONS], + Metrics::INDEX_SUM_VISIT_LENGTH => $row[Metrics::INDEX_SUM_VISIT_LENGTH], + Metrics::INDEX_BOUNCE_COUNT => $row[Metrics::INDEX_BOUNCE_COUNT], + Metrics::INDEX_NB_VISITS_CONVERTED => $row[Metrics::INDEX_NB_VISITS_CONVERTED], + ]; + + $record->sumRowWithLabel($row['label'], $columns); + } + + $this->ensureAllHoursAreSet($record); + + $record->filter(Sort::class, ['label', 'asc']); + + return [ + Archiver::LOCAL_TIME_RECORD_NAME => $record, + ]; + } +} diff --git a/plugins/VisitTime/RecordBuilders/ServerTime.php b/plugins/VisitTime/RecordBuilders/ServerTime.php new file mode 100644 index 00000000000..0a07c5fab4c --- /dev/null +++ b/plugins/VisitTime/RecordBuilders/ServerTime.php @@ -0,0 +1,86 @@ +getLogAggregator(); + + $record = new DataTable(); + + $query = $logAggregator->queryVisitsByDimension(["label" => "HOUR(log_visit.visit_first_action_time)"]); + while ($row = $query->fetch()) { + $row['label'] = $this->convertTimeToLocalTimezone($row['label'], $archiveProcessor); + + $columns = [ + Metrics::INDEX_NB_UNIQ_VISITORS => $row[Metrics::INDEX_NB_UNIQ_VISITORS], + Metrics::INDEX_NB_VISITS => $row[Metrics::INDEX_NB_VISITS], + Metrics::INDEX_NB_ACTIONS => $row[Metrics::INDEX_NB_ACTIONS], + Metrics::INDEX_NB_USERS => $row[Metrics::INDEX_NB_USERS], + Metrics::INDEX_MAX_ACTIONS => $row[Metrics::INDEX_MAX_ACTIONS], + Metrics::INDEX_SUM_VISIT_LENGTH => $row[Metrics::INDEX_SUM_VISIT_LENGTH], + Metrics::INDEX_BOUNCE_COUNT => $row[Metrics::INDEX_BOUNCE_COUNT], + Metrics::INDEX_NB_VISITS_CONVERTED => $row[Metrics::INDEX_NB_VISITS_CONVERTED], + ]; + + $record->sumRowWithLabel($row['label'], $columns); + } + + $query = $logAggregator->queryConversionsByDimension(["label" => "HOUR(log_conversion.server_time)"]); + while ($conversionRow = $query->fetch()) { + $idGoal = $conversionRow['idgoal']; + $columns = [ + Metrics::INDEX_GOALS => [ + $idGoal => Metrics::makeGoalColumnsRow($idGoal, $conversionRow), + ], + ]; + + $conversionRow['label'] = $this->convertTimeToLocalTimezone($conversionRow['label'], $archiveProcessor); + $record->sumRowWithLabel($conversionRow['label'], $columns); + } + + $record->filter(DataTable\Filter\EnrichRecordWithGoalMetricSums::class); + + $this->ensureAllHoursAreSet($record); + + $record->filter(Sort::class, ['label', 'asc']); + + return [ + Archiver::SERVER_TIME_RECORD_NAME => $record, + ]; + } + + protected function convertTimeToLocalTimezone(int $hour, ArchiveProcessor $archiveProcessor): int + { + $date = Date::factory($archiveProcessor->getParams()->getDateStart()->getDateStartUTC())->toString(); + $timezone = $archiveProcessor->getParams()->getSite()->getTimezone(); + + $datetime = $date . ' ' . $hour . ':00:00'; + $hourInTz = (int)Date::factory($datetime, $timezone)->toString('H'); + return $hourInTz; + } +} diff --git a/tests/PHPUnit/System/OneVisitorOneWebsiteSeveralDaysDateRangeArchivingTest.php b/tests/PHPUnit/System/OneVisitorOneWebsiteSeveralDaysDateRangeArchivingTest.php index 6e2c92e0a7b..088cd2d313d 100644 --- a/tests/PHPUnit/System/OneVisitorOneWebsiteSeveralDaysDateRangeArchivingTest.php +++ b/tests/PHPUnit/System/OneVisitorOneWebsiteSeveralDaysDateRangeArchivingTest.php @@ -122,7 +122,7 @@ public function test_checkArchiveRecords_whenPeriodIsRange() $tests = array( 'archive_blob_2010_12' => ( ($expectedActionsBlobs+1) /*Actions*/ + 1 /* Resolution */ - + 2 /* VisitTime */) * 3, + + 1 /* VisitTime */) * 3, /** * segments: 9 (including all visits)