From e78ef88a875c4f5c5638e239a6ecd9a518b922aa Mon Sep 17 00:00:00 2001 From: diosmosis <benaka@piwik.pro> Date: Wed, 7 Oct 2015 07:45:02 -0700 Subject: [PATCH] Make sure archive invalidation works for range periods. --- core/Archive/ArchiveInvalidator.php | 8 ++- plugins/CoreAdminHome/API.php | 32 ++++++------ .../DataAccess/ArchiveInvalidatorTest.php | 50 ++++++++++++++++--- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/core/Archive/ArchiveInvalidator.php b/core/Archive/ArchiveInvalidator.php index e17a16311c..fa87617339 100644 --- a/core/Archive/ArchiveInvalidator.php +++ b/core/Archive/ArchiveInvalidator.php @@ -124,7 +124,7 @@ class ArchiveInvalidator /** * @param $idSites int[] * @param $dates Date[] - * @param $period string TODO: make multiple + * @param $period string * @param bool $cascadeDown * @return InvalidationResultInfo * @throws \Exception @@ -162,6 +162,10 @@ class ArchiveInvalidator $periodsToInvalidate = array(); foreach ($dates as $date) { + if ($periodType == 'range') { + $date = $date . ',' . $date; + } + $period = Period\Factory::build($periodType, $date); $periodsToInvalidate[] = $period; @@ -207,7 +211,7 @@ class ArchiveInvalidator /** * @param int[] $idSites - * @param Period[][] $periods + * @param Period[][][] $periods * @throws \Exception */ private function markArchivesInvalidated($idSites, $periods) diff --git a/plugins/CoreAdminHome/API.php b/plugins/CoreAdminHome/API.php index 9d780ec876..e3791dcdac 100644 --- a/plugins/CoreAdminHome/API.php +++ b/plugins/CoreAdminHome/API.php @@ -55,28 +55,24 @@ class API extends \Piwik\Plugin\API } /** - * When tracking data in the past (using Tracking API), this function - * can be used to invalidate reports for the idSites and dates where new data - * was added. - * DEV: If you call this API, the UI should display the data correctly, but will process - * in real time, which could be very slow after large data imports. - * After calling this function via REST, you can manually force all data - * to be reprocessed by visiting the script as the Super User: - * http://example.net/piwik/misc/cron/archive.php?token_auth=$SUPER_USER_TOKEN_AUTH_HERE - * REQUIREMENTS: On large piwik setups, you will need in PHP configuration: max_execution_time = 0 - * We recommend to use an hourly schedule of the script. - * More information: http://piwik.org/setup-auto-archiving/ + * Invalidates report data, forcing it to be recomputed during the next archiving run. * - * @param string $idSites Comma separated list of idSite that have had data imported for the specified dates - * @param string $dates Comma separated list of dates to invalidate for all these websites - * @param string $period If specified (one of day, week, month, year, range) it will only invalidates archives for this period. - * Note: because week, month, year, range reports aggregate day reports then you need to specifically invalidate day reports to see - * other periods reports processed.. + * Note: This is done automatically when tracking or importing visits in the past. + * + * @param string $idSites Comma separated list of site IDs to invalidate reports for. + * @param string $dates Comma separated list of dates of periods to invalidate reports for. + * @param string|bool $period The type of period to invalidate: either 'day', 'week', 'month', 'year', 'range'. + * The command will automatically cascade up, invalidating reports for parent periods as + * well. So invalidating a day will invalidate the week it's in, the month it's in and the + * year it's in, since those periods will need to be recomputed too. + * @param bool $cascadeDown If true, child periods will be invalidated as well. So if it is requested to invalidate + * a month, then all the weeks and days within that month will also be invalidated. But only + * if this parameter is set. * @throws Exception * @return array * @hideExceptForSuperUser */ - public function invalidateArchivedReports($idSites, $dates, $period = false) + public function invalidateArchivedReports($idSites, $dates, $period = false, $cascadeDown = false) { $idSites = Site::getIdSitesFromIdSitesString($idSites); if (empty($idSites)) { @@ -87,7 +83,7 @@ class API extends \Piwik\Plugin\API list($dateObjects, $invalidDates) = $this->getDatesToInvalidateFromString($dates); - $invalidationResult = $this->invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period); + $invalidationResult = $this->invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period, (bool)$cascadeDown); $output = $invalidationResult->makeOutputLogs(); if ($invalidDates) { diff --git a/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php b/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php index a1f09690b5..189076f572 100644 --- a/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php +++ b/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php @@ -284,6 +284,10 @@ class ArchiveInvalidatorTest extends IntegrationTestCase 'day', true, array( + '2014_01' => array( + '1.2014-01-01.2014-12-31.4.done', + '2.2014-01-01.2014-12-31.4.done', + ), '2015_03' => array(), '2015_04' => array( '1.2015-04-30.2015-04-30.1.done', @@ -327,6 +331,7 @@ class ArchiveInvalidatorTest extends IntegrationTestCase 'month', false, array( + '2014_01' => array(), '2014_12' => array(), '2015_01' => array( '1.2015-01-01.2015-01-31.3.done', @@ -345,6 +350,7 @@ class ArchiveInvalidatorTest extends IntegrationTestCase 'month', true, array( + '2014_01' => array(), '2014_12' => array( '1.2014-12-29.2015-01-04.2.done', ), @@ -400,6 +406,9 @@ class ArchiveInvalidatorTest extends IntegrationTestCase 'week', true, array( + '2014_01' => array( + '1.2014-01-01.2014-12-31.4.done', + ), '2014_12' => array( '1.2014-12-29.2014-12-29.1.done', '1.2014-12-30.2014-12-30.1.done', @@ -430,6 +439,28 @@ class ArchiveInvalidatorTest extends IntegrationTestCase '2015_05' => array(), ), ), + + // range period, one site, cascade = true + array( + array(1), + array('2015-01-02', '2015-03-05'), + 'range', + true, + array( + '2014_01' => array(), + '2014_12' => array(), + '2015_01' => array( + '1.2015-01-01.2015-01-10.5.done', + ), + '2015_02' => array(), + '2015_03' => array( + '1.2015-03-04.2015-03-05.5.done', + '1.2015-03-05.2015-03-10.5.done', + ), + '2015_04' => array(), + '2015_05' => array(), + ), + ), ); } @@ -474,23 +505,28 @@ class ArchiveInvalidatorTest extends IntegrationTestCase foreach ($periods as $periodLabel) { for ($date = $startDate; $date->isEarlier($endDate); $date = $date->addPeriod(1, $periodLabel)) { foreach ($sites as $idSite) { - $this->insertArchiveRow($idSite, $date, $periodLabel); + $this->insertArchiveRow($idSite, $date->toString(), $periodLabel); } } } + + $rangePeriods = array('2015-03-04,2015-03-05', '2014-12-05,2015-01-01', '2015-03-05,2015-03-10', '2015-01-01,2015-01-10'); + foreach ($rangePeriods as $dateRange) { + $this->insertArchiveRow($idSite = 1, $dateRange, 'range'); + } } - private function insertArchiveRow($idSite, Date $date, $periodLabel) + private function insertArchiveRow($idSite, $date, $periodLabel) { - $table = ArchiveTableCreator::getNumericTable($date); + $periodObject = \Piwik\Period\Factory::build($periodLabel, $date); + $dateStart = $periodObject->getDateStart(); + $dateEnd = $periodObject->getDateEnd(); + + $table = ArchiveTableCreator::getNumericTable($dateStart); $idArchive = (int) Db::fetchOne("SELECT MAX(idarchive) FROM $table WHERE name LIKE 'done%'"); $idArchive = $idArchive + 1; - $periodObject = \Piwik\Period\Factory::build($periodLabel, $date->toString()); - $dateStart = $periodObject->getDateStart(); - $dateEnd = $periodObject->getDateEnd(); - $periodId = Piwik::$idPeriods[$periodLabel]; $doneFlag = 'done'; -- GitLab