From b588b2bce30e0da5283eea0d5b1830e6fe8bf761 Mon Sep 17 00:00:00 2001
From: diosmosis <benaka@piwik.pro>
Date: Wed, 7 Oct 2015 09:52:27 -0700
Subject: [PATCH] Allow invalidating individual segments in API method &
 invalidate reports command.

---
 core/Archive/ArchiveInvalidator.php           |  10 +-
 core/ArchiveProcessor/Rules.php               |   2 +-
 core/DataAccess/Model.php                     |  17 +-
 plugins/CoreAdminHome/API.php                 |  12 +-
 .../Commands/InvalidateReportData.php         |  45 +++-
 .../Commands/InvalidateReportDataTest.php     |  67 ++++--
 .../DataAccess/ArchiveInvalidatorTest.php     | 227 ++++++++++++------
 7 files changed, 264 insertions(+), 116 deletions(-)

diff --git a/core/Archive/ArchiveInvalidator.php b/core/Archive/ArchiveInvalidator.php
index fa87617339..daa847e520 100644
--- a/core/Archive/ArchiveInvalidator.php
+++ b/core/Archive/ArchiveInvalidator.php
@@ -18,6 +18,7 @@ use Piwik\Option;
 use Piwik\Plugins\CoreAdminHome\Tasks\ArchivesToPurgeDistributedList;
 use Piwik\Plugins\PrivacyManager\PrivacyManager;
 use Piwik\Period;
+use Piwik\Segment;
 
 /**
  * Service that can be used to invalidate archives or add archive references to a list so they will
@@ -125,11 +126,12 @@ class ArchiveInvalidator
      * @param $idSites int[]
      * @param $dates Date[]
      * @param $period string
+     * @param $segment Segment
      * @param bool $cascadeDown
      * @return InvalidationResultInfo
      * @throws \Exception
      */
-    public function markArchivesAsInvalidated(array $idSites, array $dates, $period, $cascadeDown = false)
+    public function markArchivesAsInvalidated(array $idSites, array $dates, $period, Segment $segment = null, $cascadeDown = false)
     {
         $invalidationInfo = new InvalidationResultInfo();
 
@@ -137,7 +139,7 @@ class ArchiveInvalidator
 
         $periods = $this->getPeriodsToInvalidate($datesToInvalidate, $period, $cascadeDown);
         $periods = $this->getPeriodsByYearMonthAndType($periods);
-        $this->markArchivesInvalidated($idSites, $periods);
+        $this->markArchivesInvalidated($idSites, $periods, $segment);
 
         $yearMonths = array_keys($periods);
         $this->markInvalidatedArchivesForReprocessAndPurge($idSites, $yearMonths);
@@ -214,7 +216,7 @@ class ArchiveInvalidator
      * @param Period[][][] $periods
      * @throws \Exception
      */
-    private function markArchivesInvalidated($idSites, $periods)
+    private function markArchivesInvalidated($idSites, $periods, Segment $segment = null)
     {
         $archiveNumericTables = ArchiveTableCreator::getTablesArchivesInstalled($type = ArchiveTableCreator::NUMERIC_TABLE);
         foreach ($archiveNumericTables as $table) {
@@ -223,7 +225,7 @@ class ArchiveInvalidator
                 continue;
             }
 
-            $this->model->updateArchiveAsInvalidated($table, $idSites, $periods[$tableDate]);
+            $this->model->updateArchiveAsInvalidated($table, $idSites, $periods[$tableDate], $segment);
         }
     }
 
diff --git a/core/ArchiveProcessor/Rules.php b/core/ArchiveProcessor/Rules.php
index caa5a627fb..0ec92f7590 100644
--- a/core/ArchiveProcessor/Rules.php
+++ b/core/ArchiveProcessor/Rules.php
@@ -86,7 +86,7 @@ class Rules
         return 'done' . $segment->getHash() . '.' . $plugin ;
     }
 
-    private static function getDoneFlagArchiveContainsAllPlugins(Segment $segment)
+    public static function getDoneFlagArchiveContainsAllPlugins(Segment $segment)
     {
         return 'done' . $segment->getHash();
     }
diff --git a/core/DataAccess/Model.php b/core/DataAccess/Model.php
index da75963e10..f70a934d13 100644
--- a/core/DataAccess/Model.php
+++ b/core/DataAccess/Model.php
@@ -9,11 +9,13 @@
 namespace Piwik\DataAccess;
 
 use Exception;
+use Piwik\ArchiveProcessor\Rules;
 use Piwik\Common;
 use Piwik\Container\StaticContainer;
 use Piwik\Db;
 use Piwik\DbHelper;
 use Piwik\Period;
+use Piwik\Segment;
 use Piwik\Sequence;
 use Psr\Log\LoggerInterface;
 
@@ -99,10 +101,11 @@ class Model
      * @param string $archiveTable Prefixed table name
      * @param int[] $idSites
      * @param Period[][] $periodsByType
+     * @param Segment $segment
      * @return \Zend_Db_Statement
      * @throws Exception
      */
-    public function updateArchiveAsInvalidated($archiveTable, $idSites, $periodsByType)
+    public function updateArchiveAsInvalidated($archiveTable, $idSites, $periodsByType, Segment $segment = null)
     {
         $idSites = array_map('intval', $idSites);
 
@@ -112,19 +115,23 @@ class Model
         foreach ($periodsByType as $periodType => $periods) {
             $dateConditions = array();
 
-            $bind[] = $periodType;
-
             foreach ($periods as $period) {
                 $dateConditions[] = "(date1 <= ? AND ? <= date2)";
                 $bind[] = $period->getDateStart()->toString();
                 $bind[] = $period->getDateStart()->toString();
             }
 
-            $periodConditions[] = "(period = ? AND (" . implode(" OR ", $dateConditions) . "))";
+            $periodConditions[] = "(period = " . (int)$periodType . " AND (" . implode(" OR ", $dateConditions) . "))";
+        }
+
+        if ($segment) {
+            $nameCondition = "name LIKE '" . Rules::getDoneFlagArchiveContainsAllPlugins($segment) . "%'";
+        } else {
+            $nameCondition = "name LIKE 'done%'";
         }
 
         $sql = "UPDATE $archiveTable SET value = " . ArchiveWriter::DONE_INVALIDATED
-             . " WHERE name LIKE 'done%'
+             . " WHERE $nameCondition
                    AND idsite IN (" . implode(", ", $idSites) . ")
                    AND (" . implode(" OR ", $periodConditions) . ")";
 
diff --git a/plugins/CoreAdminHome/API.php b/plugins/CoreAdminHome/API.php
index e3791dcdac..18f5764a5a 100644
--- a/plugins/CoreAdminHome/API.php
+++ b/plugins/CoreAdminHome/API.php
@@ -17,6 +17,7 @@ use Piwik\CronArchive;
 use Piwik\Date;
 use Piwik\Db;
 use Piwik\Piwik;
+use Piwik\Segment;
 use Piwik\Scheduler\Scheduler;
 use Piwik\Site;
 
@@ -65,6 +66,7 @@ class API extends \Piwik\Plugin\API
      *                            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 string|bool $segment Optional. The segment to invalidate reports for.
      * @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.
@@ -72,7 +74,7 @@ class API extends \Piwik\Plugin\API
      * @return array
      * @hideExceptForSuperUser
      */
-    public function invalidateArchivedReports($idSites, $dates, $period = false, $cascadeDown = false)
+    public function invalidateArchivedReports($idSites, $dates, $period = false, $segment = false, $cascadeDown = false)
     {
         $idSites = Site::getIdSitesFromIdSitesString($idSites);
         if (empty($idSites)) {
@@ -81,9 +83,15 @@ class API extends \Piwik\Plugin\API
 
         Piwik::checkUserHasAdminAccess($idSites);
 
+        if (!empty($segment)) {
+            $segment = new Segment($segment, $idSites);
+        } else {
+            $segment = null;
+        }
+
         list($dateObjects, $invalidDates) = $this->getDatesToInvalidateFromString($dates);
 
-        $invalidationResult = $this->invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period, (bool)$cascadeDown);
+        $invalidationResult = $this->invalidator->markArchivesAsInvalidated($idSites, $dateObjects, $period, $segment, (bool)$cascadeDown);
 
         $output = $invalidationResult->makeOutputLogs();
         if ($invalidDates) {
diff --git a/plugins/CoreAdminHome/Commands/InvalidateReportData.php b/plugins/CoreAdminHome/Commands/InvalidateReportData.php
index 488e0a4757..f424afc8e8 100644
--- a/plugins/CoreAdminHome/Commands/InvalidateReportData.php
+++ b/plugins/CoreAdminHome/Commands/InvalidateReportData.php
@@ -13,6 +13,7 @@ use Piwik\Date;
 use Piwik\Period;
 use Piwik\Period\Range;
 use Piwik\Piwik;
+use Piwik\Segment;
 use Piwik\Plugin\ConsoleCommand;
 use Piwik\Plugins\SitesManager\API as SitesManagerAPI;
 use Piwik\Site;
@@ -41,6 +42,8 @@ class InvalidateReportData extends ConsoleCommand
             'List of period types to invalidate report data for. Can be one or more of the following values: day, '
             . 'week, month, year or "all" for all of them.',
             self::ALL_OPTION_VALUE);
+        $this->addOption('segment', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
+            'List of segments to invalidate report data for.');
         $this->addOption('cascade', null, InputOption::VALUE_NONE,
             'If supplied, invalidation will cascade, invalidating child period types even if they aren\'t specified in'
             . ' --periods. For example, if --periods=week, --cascade will cause the days within those weeks to be '
@@ -65,22 +68,27 @@ class InvalidateReportData extends ConsoleCommand
         $sites = $this->getSitesToInvalidateFor($input);
         $periodTypes = $this->getPeriodTypesToInvalidateFor($input);
         $dateRanges = $this->getDateRangesToInvalidateFor($input);
+        $segments = $this->getSegmentsToInvalidateFor($input, $sites);
 
         foreach ($periodTypes as $periodType) {
             foreach ($dateRanges as $dateRange) {
-                $output->writeln("Invalidating $periodType periods in $dateRange...");
+                foreach ($segments as $segment) {
+                    $segmentStr = $segment ? $segment->getString() : '';
 
-                $dates = $this->getPeriodDates($periodType, $dateRange);
+                    $output->writeln("Invalidating $periodType periods in $dateRange [segment = $segmentStr]...");
 
-                if ($dryRun) {
-                    $output->writeln("[Dry-run] invalidating archives for site = [ " . implode(', ', $sites)
-                        . " ], dates = [ " . implode(', ', $dates) . " ], period = [ $periodType ], cascade = [ "
-                        . (int)$cascade . " ]");
-                } else {
-                    $invalidationResult = $invalidator->markArchivesAsInvalidated($sites, $dates, $periodType, $cascade);
+                    $dates = $this->getPeriodDates($periodType, $dateRange);
 
-                    if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
-                        $output->writeln($invalidationResult->makeOutputLogs());
+                    if ($dryRun) {
+                        $output->writeln("[Dry-run] invalidating archives for site = [ " . implode(', ', $sites)
+                            . " ], dates = [ " . implode(', ', $dates) . " ], period = [ $periodType ], segment = [ "
+                            . "$segmentStr ], cascade = [ " . (int)$cascade . " ]");
+                    } else {
+                        $invalidationResult = $invalidator->markArchivesAsInvalidated($sites, $dates, $periodType, $segment, $cascade);
+
+                        if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
+                            $output->writeln($invalidationResult->makeOutputLogs());
+                        }
                     }
                 }
             }
@@ -172,4 +180,21 @@ class InvalidateReportData extends ConsoleCommand
         }
         return $result;
     }
+
+    private function getSegmentsToInvalidateFor(InputInterface $input, $idSites)
+    {
+        $segments = $input->getOption('segment');
+        $segments = array_map('trim', $segments);
+        $segments = array_unique($segments);
+
+        if (empty($segments)) {
+            return array(null);
+        }
+
+        $result = array();
+        foreach ($segments as $segmentString) {
+            $result[] = new Segment($segmentString, $idSites);
+        }
+        return $result;
+    }
 }
diff --git a/plugins/CoreAdminHome/tests/Integration/Commands/InvalidateReportDataTest.php b/plugins/CoreAdminHome/tests/Integration/Commands/InvalidateReportDataTest.php
index d72c0841e0..f565b7105b 100644
--- a/plugins/CoreAdminHome/tests/Integration/Commands/InvalidateReportDataTest.php
+++ b/plugins/CoreAdminHome/tests/Integration/Commands/InvalidateReportDataTest.php
@@ -105,10 +105,26 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
         );
     }
 
+    public function test_Command_FailsWhenAnInvalidSegmentIsUsed()
+    {
+        $code = $this->applicationTester->run(array(
+            'command' => 'core:invalidate-report-data',
+            '--dates' => '2012-01-01',
+            '--periods' => 'day',
+            '--sites' => '1',
+            '--segment' => array('ablksdjfdslkjf'),
+            '--dry-run' => true,
+            '-vvv' => true,
+        ));
+
+        $this->assertNotEquals(0, $code, $this->getCommandDisplayOutputErrorMessage());
+        $this->assertContains("The segment 'ablksdjfdslkjf' is not valid", $this->applicationTester->getDisplay());
+    }
+
     /**
      * @dataProvider getTestDataForSuccessTests
      */
-    public function test_Command_InvalidatesCorrectSitesAndDates($dates, $periods, $sites, $cascade, $expectedOutputs)
+    public function test_Command_InvalidatesCorrectSitesAndDates($dates, $periods, $sites, $cascade, $segments, $expectedOutputs)
     {
         $code = $this->applicationTester->run(array(
             'command' => 'core:invalidate-report-data',
@@ -116,6 +132,7 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
             '--periods' => $periods,
             '--sites' => $sites,
             '--cascade' => $cascade,
+            '--segment' => $segments ?: array(),
             '--dry-run' => true,
             '-vvv' => true,
         ));
@@ -136,8 +153,9 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'day',
                 '1',
                 false,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2012-01-01 ], period = [ day ]',
+                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2012-01-01 ], period = [ day ], segment = [  ]',
                 ),
             ),
 
@@ -146,8 +164,9 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'day',
                 '1',
                 true,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2012-01-01 ], period = [ day ]',
+                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2012-01-01 ], period = [ day ], segment = [  ]',
                 ),
             ),
 
@@ -156,8 +175,9 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'week',
                 '1',
                 false,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2011-12-26 ], period = [ week ]',
+                    '[Dry-run] invalidating archives for site = [ 1 ], dates = [ 2011-12-26 ], period = [ week ], segment = [  ]',
                 ),
             ),
 
@@ -166,13 +186,14 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'month,week',
                 '1,3',
                 false,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-01, 2012-02-01 ], period = [ month ], cascade = [ 0 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-01 ], period = [ month ], cascade = [ 0 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2013-03-01 ], period = [ month ], cascade = [ 0 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2011-12-26, 2012-01-02, 2012-01-09, 2012-01-16, 2012-01-23, 2012-01-30 ], period = [ week ], cascade = [ 0 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-23 ], period = [ week ], cascade = [ 0 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2013-03-18 ], period = [ week ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-01, 2012-02-01 ], period = [ month ], segment = [  ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-01 ], period = [ month ], segment = [  ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2013-03-01 ], period = [ month ], segment = [  ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2011-12-26, 2012-01-02, 2012-01-09, 2012-01-16, 2012-01-23, 2012-01-30 ], period = [ week ], segment = [  ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2012-01-23 ], period = [ week ], segment = [  ], cascade = [ 0 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 3 ], dates = [ 2013-03-18 ], period = [ week ], segment = [  ], cascade = [ 0 ]',
                 ),
             ),
 
@@ -181,8 +202,9 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'week',
                 '2',
                 true,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 2 ], dates = [ 2012-01-30, 2012-02-06 ], period = [ week ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 2 ], dates = [ 2012-01-30, 2012-02-06 ], period = [ week ], segment = [  ], cascade = [ 1 ]',
                 ),
             ),
 
@@ -191,16 +213,27 @@ class InvalidateReportDataTest extends ConsoleCommandTestCase
                 'month,week,day',
                 'all',
                 true,
+                null,
                 array(
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-02-01 ], period = [ month ], cascade = [ 1 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-01 ], period = [ month ], cascade = [ 1 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-01-30 ], period = [ week ], cascade = [ 1 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-12 ], period = [ week ], cascade = [ 1 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-02-03, 2012-02-04 ], period = [ day ], cascade = [ 1 ]',
-                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-15 ], period = [ day ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-02-01 ], period = [ month ], segment = [  ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-01 ], period = [ month ], segment = [  ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-01-30 ], period = [ week ], segment = [  ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-12 ], period = [ week ], segment = [  ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-02-03, 2012-02-04 ], period = [ day ], segment = [  ], cascade = [ 1 ]',
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2012-03-15 ], period = [ day ], segment = [  ], cascade = [ 1 ]',
                 ),
             ),
 
+            array( // cascade, one week, date & period + segment
+                array('2012-01-01,2012-01-14'),
+                'week',
+                'all',
+                true,
+                array('browserCode==FF'),
+                array(
+                    '[Dry-run] invalidating archives for site = [ 1, 2, 3 ], dates = [ 2011-12-26, 2012-01-02, 2012-01-09 ], period = [ week ], segment = [ browserCode==FF ], cascade = [ 1 ]',
+                ),
+            ),
         );
     }
 }
diff --git a/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php b/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php
index 189076f572..76433c0eb4 100644
--- a/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php
+++ b/tests/PHPUnit/Integration/DataAccess/ArchiveInvalidatorTest.php
@@ -8,6 +8,7 @@
 
 namespace Piwik\Tests\Integration\DataAccess;
 
+use Piwik\ArchiveProcessor\Rules;
 use Piwik\CronArchive\SitesToReprocessDistributedList;
 use Piwik\DataAccess\ArchiveTableCreator;
 use Piwik\DataAccess\ArchiveWriter;
@@ -20,6 +21,7 @@ use Piwik\Plugins\CoreAdminHome\Tasks\ArchivesToPurgeDistributedList;
 use Piwik\Plugins\PrivacyManager\PrivacyManager;
 use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
 use Piwik\Archive\ArchiveInvalidator;
+use Piwik\Segment;
 
 /**
  * @group Archiver
@@ -28,11 +30,33 @@ use Piwik\Archive\ArchiveInvalidator;
  */
 class ArchiveInvalidatorTest extends IntegrationTestCase
 {
+    const TEST_SEGMENT_1 = 'browserCode==FF';
+    const TEST_SEGMENT_2 = 'countryCode==uk';
+
     /**
      * @var ArchiveInvalidator
      */
     private $invalidator;
 
+    /**
+     * @var Segment
+     */
+    private static $segment1;
+
+    /**
+     * @var Segment
+     */
+    private static $segment2;
+
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+
+        // these are static because it takes a long time to create new Segment instances (for some reason)
+        self::$segment1 = new Segment(self::TEST_SEGMENT_1, array());
+        self::$segment2 = new Segment(self::TEST_SEGMENT_2, array());
+    }
+
     public function setUp()
     {
         parent::setUp();
@@ -257,16 +281,20 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
     /**
      * @dataProvider getTestDataForMarkArchivesAsInvalidated
      */
-    public function test_markArchivesAsInvalidated_MarksCorrectArchivesAsInvalidated($idSites, $dates, $period, $cascadeDown,
+    public function test_markArchivesAsInvalidated_MarksCorrectArchivesAsInvalidated($idSites, $dates, $period, $segment, $cascadeDown,
                                                                                      $expectedIdArchives)
     {
         $dates = array_map(array('Piwik\Date', 'factory'), $dates);
 
         $this->insertArchiveRowsForTest();
 
+        if (!empty($segment)) {
+            $segment = new Segment($segment, $idSites);
+        }
+
         /** @var ArchiveInvalidator $archiveInvalidator */
         $archiveInvalidator = self::$fixture->piwikEnvironment->getContainer()->get('Piwik\Archive\ArchiveInvalidator');
-        $result = $archiveInvalidator->markArchivesAsInvalidated($idSites, $dates, $period, $cascadeDown);
+        $result = $archiveInvalidator->markArchivesAsInvalidated($idSites, $dates, $period, $segment, $cascadeDown);
 
         $this->assertEquals($dates, $result->processedDates);
 
@@ -282,44 +310,45 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
                 array(1, 2),
                 array('2015-01-01', '2015-02-05', '2015-04-30'),
                 'day',
+                null,
                 true,
                 array(
                     '2014_01' => array(
-                        '1.2014-01-01.2014-12-31.4.done',
-                        '2.2014-01-01.2014-12-31.4.done',
+                        '1.2014-01-01.2014-12-31.4.done3736b708e4d20cfc10610e816a1b2341',
+                        '2.2014-01-01.2014-12-31.4.done.VisitsSummary',
                     ),
                     '2015_03' => array(),
                     '2015_04' => array(
-                        '1.2015-04-30.2015-04-30.1.done',
-                        '2.2015-04-30.2015-04-30.1.done',
+                        '1.2015-04-30.2015-04-30.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '2.2015-04-30.2015-04-30.1.done5447835b0a861475918e79e932abdfd8',
                         '1.2015-04-27.2015-05-03.2.done',
-                        '2.2015-04-27.2015-05-03.2.done',
-                        '1.2015-04-01.2015-04-30.3.done',
-                        '2.2015-04-01.2015-04-30.3.done',
+                        '2.2015-04-27.2015-05-03.2.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-04-01.2015-04-30.3.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '2.2015-04-01.2015-04-30.3.done5447835b0a861475918e79e932abdfd8',
                     ),
                     '2014_12' => array(
-                        '1.2014-12-29.2015-01-04.2.done',
-                        '2.2014-12-29.2015-01-04.2.done',
-                        '1.2014-12-01.2014-12-31.3.done',
+                        '1.2014-12-29.2015-01-04.2.done3736b708e4d20cfc10610e816a1b2341',
+                        '2.2014-12-29.2015-01-04.2.done.VisitsSummary',
+                        '1.2014-12-01.2014-12-31.3.done5447835b0a861475918e79e932abdfd8',
                         '2.2014-12-01.2014-12-31.3.done',
                     ),
                     '2015_01' => array(
-                        '1.2015-01-01.2015-01-01.1.done',
-                        '2.2015-01-01.2015-01-01.1.done',
-                        '1.2015-01-01.2015-01-31.3.done',
-                        '2.2015-01-01.2015-01-31.3.done',
+                        '1.2015-01-01.2015-01-01.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '2.2015-01-01.2015-01-01.1.done.VisitsSummary',
+                        '1.2015-01-01.2015-01-31.3.done3736b708e4d20cfc10610e816a1b2341',
+                        '2.2015-01-01.2015-01-31.3.done.VisitsSummary',
                     ),
                     '2015_02' => array(
-                        '1.2015-02-05.2015-02-05.1.done',
-                        '2.2015-02-05.2015-02-05.1.done',
+                        '1.2015-02-05.2015-02-05.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '2.2015-02-05.2015-02-05.1.done5447835b0a861475918e79e932abdfd8',
                         '1.2015-02-02.2015-02-08.2.done',
-                        '2.2015-02-02.2015-02-08.2.done',
-                        '1.2015-02-01.2015-02-28.3.done',
-                        '2.2015-02-01.2015-02-28.3.done',
+                        '2.2015-02-02.2015-02-08.2.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-02-01.2015-02-28.3.done.VisitsSummary',
+                        '2.2015-02-01.2015-02-28.3.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
                     ),
                     '2015_05' => array(
-                        '1.2015-05-01.2015-05-31.3.done',
-                        '2.2015-05-01.2015-05-31.3.done',
+                        '1.2015-05-01.2015-05-31.3.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '2.2015-05-01.2015-05-31.3.done5447835b0a861475918e79e932abdfd8',
                     ),
                 ),
             ),
@@ -329,12 +358,13 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
                 array(1),
                 array('2015-01-01'),
                 'month',
+                null,
                 false,
                 array(
                     '2014_01' => array(),
                     '2014_12' => array(),
                     '2015_01' => array(
-                        '1.2015-01-01.2015-01-31.3.done',
+                        '1.2015-01-01.2015-01-31.3.done3736b708e4d20cfc10610e816a1b2341',
                     ),
                     '2015_02' => array(),
                     '2015_03' => array(),
@@ -348,49 +378,50 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
                 array(1),
                 array('2015-01-15'),
                 'month',
+                null,
                 true,
                 array(
                     '2014_01' => array(),
                     '2014_12' => array(
-                        '1.2014-12-29.2015-01-04.2.done',
+                        '1.2014-12-29.2015-01-04.2.done3736b708e4d20cfc10610e816a1b2341',
                     ),
                     '2015_01' => array(
-                        '1.2015-01-01.2015-01-01.1.done',
-                        '1.2015-01-02.2015-01-02.1.done',
-                        '1.2015-01-03.2015-01-03.1.done',
+                        '1.2015-01-01.2015-01-01.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-02.2015-01-02.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-03.2015-01-03.1.done.VisitsSummary',
                         '1.2015-01-04.2015-01-04.1.done',
-                        '1.2015-01-05.2015-01-05.1.done',
-                        '1.2015-01-06.2015-01-06.1.done',
-                        '1.2015-01-07.2015-01-07.1.done',
-                        '1.2015-01-08.2015-01-08.1.done',
+                        '1.2015-01-05.2015-01-05.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-06.2015-01-06.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-07.2015-01-07.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-08.2015-01-08.1.done.VisitsSummary',
                         '1.2015-01-09.2015-01-09.1.done',
-                        '1.2015-01-10.2015-01-10.1.done',
-                        '1.2015-01-11.2015-01-11.1.done',
-                        '1.2015-01-12.2015-01-12.1.done',
-                        '1.2015-01-13.2015-01-13.1.done',
+                        '1.2015-01-10.2015-01-10.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-11.2015-01-11.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-12.2015-01-12.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-13.2015-01-13.1.done.VisitsSummary',
                         '1.2015-01-14.2015-01-14.1.done',
-                        '1.2015-01-15.2015-01-15.1.done',
-                        '1.2015-01-16.2015-01-16.1.done',
-                        '1.2015-01-17.2015-01-17.1.done',
-                        '1.2015-01-18.2015-01-18.1.done',
+                        '1.2015-01-15.2015-01-15.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-16.2015-01-16.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-17.2015-01-17.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-18.2015-01-18.1.done.VisitsSummary',
                         '1.2015-01-19.2015-01-19.1.done',
-                        '1.2015-01-20.2015-01-20.1.done',
-                        '1.2015-01-21.2015-01-21.1.done',
-                        '1.2015-01-22.2015-01-22.1.done',
-                        '1.2015-01-23.2015-01-23.1.done',
+                        '1.2015-01-20.2015-01-20.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-21.2015-01-21.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-22.2015-01-22.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-23.2015-01-23.1.done.VisitsSummary',
                         '1.2015-01-24.2015-01-24.1.done',
-                        '1.2015-01-25.2015-01-25.1.done',
-                        '1.2015-01-26.2015-01-26.1.done',
-                        '1.2015-01-27.2015-01-27.1.done',
-                        '1.2015-01-28.2015-01-28.1.done',
+                        '1.2015-01-25.2015-01-25.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-26.2015-01-26.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-27.2015-01-27.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-28.2015-01-28.1.done.VisitsSummary',
                         '1.2015-01-29.2015-01-29.1.done',
-                        '1.2015-01-30.2015-01-30.1.done',
-                        '1.2015-01-31.2015-01-31.1.done',
-                        '1.2015-01-05.2015-01-11.2.done',
-                        '1.2015-01-12.2015-01-18.2.done',
+                        '1.2015-01-30.2015-01-30.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-31.2015-01-31.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-05.2015-01-11.2.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-12.2015-01-18.2.done.VisitsSummary',
                         '1.2015-01-19.2015-01-25.2.done',
-                        '1.2015-01-26.2015-02-01.2.done',
-                        '1.2015-01-01.2015-01-31.3.done',
+                        '1.2015-01-26.2015-02-01.2.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-01.2015-01-31.3.done3736b708e4d20cfc10610e816a1b2341',
                     ),
                     '2015_02' => array(),
                     '2015_03' => array(),
@@ -404,35 +435,36 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
                 array(1),
                 array('2015-01-02', '2015-01-03', '2015-01-31'),
                 'week',
+                null,
                 true,
                 array(
                     '2014_01' => array(
-                        '1.2014-01-01.2014-12-31.4.done',
+                        '1.2014-01-01.2014-12-31.4.done3736b708e4d20cfc10610e816a1b2341',
                     ),
                     '2014_12' => array(
                         '1.2014-12-29.2014-12-29.1.done',
-                        '1.2014-12-30.2014-12-30.1.done',
-                        '1.2014-12-31.2014-12-31.1.done',
-                        '1.2014-12-29.2015-01-04.2.done',
-                        '1.2014-12-01.2014-12-31.3.done',
+                        '1.2014-12-30.2014-12-30.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2014-12-31.2014-12-31.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2014-12-29.2015-01-04.2.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2014-12-01.2014-12-31.3.done5447835b0a861475918e79e932abdfd8',
                     ),
                     '2015_01' => array(
-                        '1.2015-01-01.2015-01-01.1.done',
-                        '1.2015-01-02.2015-01-02.1.done',
-                        '1.2015-01-03.2015-01-03.1.done',
+                        '1.2015-01-01.2015-01-01.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-02.2015-01-02.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-03.2015-01-03.1.done.VisitsSummary',
                         '1.2015-01-04.2015-01-04.1.done',
-                        '1.2015-01-26.2015-01-26.1.done',
-                        '1.2015-01-27.2015-01-27.1.done',
-                        '1.2015-01-28.2015-01-28.1.done',
+                        '1.2015-01-26.2015-01-26.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-27.2015-01-27.1.done5447835b0a861475918e79e932abdfd8',
+                        '1.2015-01-28.2015-01-28.1.done.VisitsSummary',
                         '1.2015-01-29.2015-01-29.1.done',
-                        '1.2015-01-30.2015-01-30.1.done',
-                        '1.2015-01-31.2015-01-31.1.done',
-                        '1.2015-01-26.2015-02-01.2.done',
-                        '1.2015-01-01.2015-01-31.3.done',
+                        '1.2015-01-30.2015-01-30.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-31.2015-01-31.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-26.2015-02-01.2.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-01.2015-01-31.3.done3736b708e4d20cfc10610e816a1b2341',
                     ),
                     '2015_02' => array(
-                        '1.2015-02-01.2015-02-01.1.done',
-                        '1.2015-02-01.2015-02-28.3.done',
+                        '1.2015-02-01.2015-02-01.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-02-01.2015-02-28.3.done.VisitsSummary',
                     ),
                     '2015_03' => array(),
                     '2015_04' => array(),
@@ -445,18 +477,55 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
                 array(1),
                 array('2015-01-02', '2015-03-05'),
                 'range',
+                null,
                 true,
                 array(
                     '2014_01' => array(),
                     '2014_12' => array(),
                     '2015_01' => array(
-                        '1.2015-01-01.2015-01-10.5.done',
+                        '1.2015-01-01.2015-01-10.5.done5447835b0a861475918e79e932abdfd8',
                     ),
                     '2015_02' => array(),
                     '2015_03' => array(
-                        '1.2015-03-04.2015-03-05.5.done',
-                        '1.2015-03-05.2015-03-10.5.done',
+                        '1.2015-03-04.2015-03-05.5.done.VisitsSummary',
+                        '1.2015-03-05.2015-03-10.5.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                    ),
+                    '2015_04' => array(),
+                    '2015_05' => array(),
+                ),
+            ),
+
+            // week period, one site, cascade = true, segment
+            array(
+                array(1),
+                array('2015-01-05'),
+                'month',
+                self::TEST_SEGMENT_1,
+                true,
+                array(
+                    '2014_01' => array(),
+                    '2014_12' => array(
+                        '1.2014-12-29.2015-01-04.2.done3736b708e4d20cfc10610e816a1b2341',
                     ),
+                    '2015_01' => array(
+                        '1.2015-01-01.2015-01-01.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-05.2015-01-05.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-06.2015-01-06.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-10.2015-01-10.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-11.2015-01-11.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-15.2015-01-15.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-16.2015-01-16.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-20.2015-01-20.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-21.2015-01-21.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-25.2015-01-25.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-26.2015-01-26.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-30.2015-01-30.1.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-31.2015-01-31.1.done3736b708e4d20cfc10610e816a1b2341',
+                        '1.2015-01-26.2015-02-01.2.done3736b708e4d20cfc10610e816a1b2341.UserCountry',
+                        '1.2015-01-01.2015-01-31.3.done3736b708e4d20cfc10610e816a1b2341',
+                    ),
+                    '2015_02' => array(),
+                    '2015_03' => array(),
                     '2015_04' => array(),
                     '2015_05' => array(),
                 ),
@@ -530,10 +599,14 @@ class ArchiveInvalidatorTest extends IntegrationTestCase
         $periodId = Piwik::$idPeriods[$periodLabel];
 
         $doneFlag = 'done';
-        if ($doneFlag % 3 == 1) {
-            $doneFlag .= "09348lakdjfslfjasldfjwaekht";
-        } else if ($doneFlag % 3 == 2) {
+        if ($idArchive % 5 == 1) {
+            $doneFlag = Rules::getDoneFlagArchiveContainsAllPlugins(self::$segment1);
+        } else if ($idArchive % 5 == 2) {
             $doneFlag .= '.VisitsSummary';
+        } else if ($idArchive % 5 == 3) {
+            $doneFlag = Rules::getDoneFlagArchiveContainsOnePlugin(self::$segment1, 'UserCountry');
+        } else if ($idArchive % 5 == 4) {
+            $doneFlag = Rules::getDoneFlagArchiveContainsAllPlugins(self::$segment2);
         }
 
         $sql = "INSERT INTO $table (idarchive, name, idsite, date1, date2, period, ts_archived)
-- 
GitLab