From ec9ba706e2d39adde233df1fc418588cc39b83c1 Mon Sep 17 00:00:00 2001 From: diosmosis <benaka@piwik.pro> Date: Fri, 18 Sep 2015 01:49:25 -0700 Subject: [PATCH] Add event that allows plugins to archive data even if there are no visits for the period. Undocumented for now. --- core/ArchiveProcessor/Loader.php | 29 +++++- core/ArchiveProcessor/PluginsArchiver.php | 4 +- tests/PHPUnit/Framework/Fixture.php | 2 + .../Integration/ArchiveWithNoVisitsTest.php | 88 +++++++++++++++++++ 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/PHPUnit/Integration/ArchiveWithNoVisitsTest.php diff --git a/core/ArchiveProcessor/Loader.php b/core/ArchiveProcessor/Loader.php index f4c139b1ea..c08bf2c52c 100644 --- a/core/ArchiveProcessor/Loader.php +++ b/core/ArchiveProcessor/Loader.php @@ -9,10 +9,12 @@ namespace Piwik\ArchiveProcessor; use Piwik\Archive; +use Piwik\Cache; use Piwik\Config; use Piwik\DataAccess\ArchiveSelector; use Piwik\Date; use Piwik\Period; +use Piwik\Piwik; /** * This class uses PluginsArchiver class to trigger data aggregation and create archives. @@ -118,7 +120,9 @@ class Loader $visitsConverted = $metrics['nb_visits_converted']; } - if ($this->isThereSomeVisits($visits)) { + if ($this->isThereSomeVisits($visits) + || $this->shouldArchiveForSiteEvenWhenNoVisits() + ) { $pluginsArchiver->callAggregateAllPlugins($visits, $visitsConverted); } @@ -223,4 +227,27 @@ class Loader return $this->temporaryArchive; } + + private function shouldArchiveForSiteEvenWhenNoVisits() + { + $idSitesToArchive = $this->getIdSitesToArchiveWhenNoVisits(); + return in_array($this->params->getSite()->getId(), $idSitesToArchive); + } + + private function getIdSitesToArchiveWhenNoVisits() + { + $cache = Cache::getTransientCache(); + $cacheKey = 'Archiving.getIdSitesToArchiveWhenNoVisits'; + + if (!$cache->contains($cacheKey)) { + $idSites = array(); + + // leaving undocumented unless decided otherwise + Piwik::postEvent('Archiving.getIdSitesToArchiveWhenNoVisits', array(&$idSites)); + + $cache->save($cacheKey, $idSites); + } + + return $cache->fetch($cacheKey); + } } diff --git a/core/ArchiveProcessor/PluginsArchiver.php b/core/ArchiveProcessor/PluginsArchiver.php index ff9ddca499..28c90cb15c 100644 --- a/core/ArchiveProcessor/PluginsArchiver.php +++ b/core/ArchiveProcessor/PluginsArchiver.php @@ -41,9 +41,11 @@ class PluginsArchiver private $logAggregator; /** + * Public only for tests. Won't be necessary after DI changes are complete. + * * @var Archiver[] $archivers */ - private static $archivers = array(); + public static $archivers = array(); public function __construct(Parameters $params, $isTemporaryArchive) { diff --git a/tests/PHPUnit/Framework/Fixture.php b/tests/PHPUnit/Framework/Fixture.php index 3d53b796d8..391e5ef896 100644 --- a/tests/PHPUnit/Framework/Fixture.php +++ b/tests/PHPUnit/Framework/Fixture.php @@ -10,6 +10,7 @@ namespace Piwik\Tests\Framework; use Piwik\Access; use Piwik\Application\Environment; use Piwik\Archive; +use Piwik\ArchiveProcessor\PluginsArchiver; use Piwik\Auth; use Piwik\Cache\Backend\File; use Piwik\Cache as PiwikCache; @@ -352,6 +353,7 @@ class Fixture extends \PHPUnit_Framework_Assert ArchiveTableCreator::clear(); \Piwik\Plugins\ScheduledReports\API::$cache = array(); Singleton::clearAll(); + PluginsArchiver::$archivers = array(); $_GET = $_REQUEST = array(); Translate::reset(); diff --git a/tests/PHPUnit/Integration/ArchiveWithNoVisitsTest.php b/tests/PHPUnit/Integration/ArchiveWithNoVisitsTest.php new file mode 100644 index 0000000000..2063efdb25 --- /dev/null +++ b/tests/PHPUnit/Integration/ArchiveWithNoVisitsTest.php @@ -0,0 +1,88 @@ +<?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\Tests\Integration; + +use Piwik\ArchiveProcessor\PluginsArchiver; +use Piwik\Cache; +use Piwik\EventDispatcher; +use Piwik\Plugin\Archiver; +use Piwik\Tests\Framework\Fixture; +use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI; +use Piwik\Tests\Framework\TestCase\IntegrationTestCase; + +class ArchiveWithNoVisitsTest_MockArchiver extends Archiver +{ + public static $methodsCalled = array(); + + public function aggregateDayReport() + { + self::$methodsCalled[] = 'aggregateDayReport'; + } + + public function aggregateMultipleReports() + { + self::$methodsCalled[] = 'aggregateMultipleReports'; + } +} + +class ArchiveWithNoVisitsTest extends IntegrationTestCase +{ + public function setUp() + { + parent::setUp(); + + Fixture::createWebsite('2011-01-01'); + + ArchiveWithNoVisitsTest_MockArchiver::$methodsCalled = array(); + } + + public function test_getIdSitesToArchiveWhenNoVisits_CanBeUsedToTriggerArchiving_EvenIfSiteHasNoVisits() + { + // add our mock archiver instance + // TODO: should use a dummy plugin that is activated for this test explicitly, but that can be tricky, especially in the future + + PluginsArchiver::$archivers['VisitsSummary'] = 'Piwik\Tests\Integration\ArchiveWithNoVisitsTest_MockArchiver'; + + // initiate archiving w/o adding the event and make sure no methods are called + VisitsSummaryAPI::getInstance()->get($idSite = 1, 'week', '2012-01-01'); + + $this->assertEmpty(ArchiveWithNoVisitsTest_MockArchiver::$methodsCalled); + + // mark our only site as should archive when no visits + $eventDispatcher = $this->getEventDispatcher(); + $eventDispatcher->addObserver('Archiving.getIdSitesToArchiveWhenNoVisits', function (&$idSites) { + $idSites[] = 1; + }); + + Cache::getTransientCache()->flushAll(); + + // initiate archiving and make sure both aggregate methods are called correctly + VisitsSummaryAPI::getInstance()->get($idSite = 1, 'week', '2012-01-10'); + + $expectedMethodCalls = array( + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateDayReport', + 'aggregateMultipleReports', + ); + $this->assertEquals($expectedMethodCalls, ArchiveWithNoVisitsTest_MockArchiver::$methodsCalled); + } + + /** + * @return EventDispatcher + */ + private function getEventDispatcher() + { + return self::$fixture->piwikEnvironment->getContainer()->get('Piwik\EventDispatcher'); + } +} -- GitLab