diff --git a/core/ArchiveProcessor/Rules.php b/core/ArchiveProcessor/Rules.php index 32699231460ae817ce2b1541baecc7178e1a2569..11142b5d712dd0b20ef0c8c3b103c7c07a70c1f1 100644 --- a/core/ArchiveProcessor/Rules.php +++ b/core/ArchiveProcessor/Rules.php @@ -10,6 +10,7 @@ namespace Piwik\ArchiveProcessor; use Exception; use Piwik\Config; +use Piwik\DataAccess\ArchiveWriter; use Piwik\Date; use Piwik\Log; use Piwik\Option; @@ -109,6 +110,8 @@ class Rules } /** + * Return done flags used to tell how the archiving process for a specific archive was completed, + * * @param array $plugins * @param $segment * @return array @@ -309,4 +312,21 @@ class Rules } return false; } + + /** + * Returns done flag values allowed to be selected + * + * @return string + */ + public static function getSelectableDoneFlagValues() + { + $possibleValues = array(ArchiveWriter::DONE_OK, ArchiveWriter::DONE_OK_TEMPORARY); + + if (!Rules::isRequestAuthorizedToArchive()) { + //If request is not authorized to archive then fetch also invalidated archives + $possibleValues[] = ArchiveWriter::DONE_INVALIDATED; + } + + return $possibleValues; + } } diff --git a/core/CronArchive.php b/core/CronArchive.php index 47bd0c98d884efa11a20e03fea822395984278e5..64fee8ba050246927fb3fe5f47275780e2d56113 100644 --- a/core/CronArchive.php +++ b/core/CronArchive.php @@ -13,7 +13,7 @@ use Piwik\ArchiveProcessor\Rules; use Piwik\CronArchive\FixedSiteIds; use Piwik\CronArchive\SharedSiteIds; use Piwik\Period\Factory as PeriodFactory; -use Piwik\Plugins\CoreAdminHome\InvalidatedReports; +use Piwik\DataAccess\InvalidatedReports; use Piwik\Plugins\SitesManager\API as APISitesManager; /** @@ -607,7 +607,7 @@ class CronArchive if ($this->isOldReportInvalidatedForWebsite($idSite)) { $store = new InvalidatedReports(); - $store->removeWebsiteFromInvalidatedWebsites($idSite); + $store->storeSiteIsReprocessed($idSite); } // when some data was purged from this website @@ -932,7 +932,7 @@ class CronArchive $websiteIds = array_merge( $this->addWebsiteIdsWithVisitsSinceLastRun(), - $this->getWebsiteIdsToInvalidate() + $this->getInvalidatedSitesToReprocess() ); $websiteIds = array_merge($websiteIds, $this->addWebsiteIdsInTimezoneWithNewDay($websiteIds)); return array_unique($websiteIds); @@ -1001,7 +1001,7 @@ class CronArchive private function updateIdSitesInvalidatedOldReports() { $store = new InvalidatedReports(); - $this->idSitesInvalidatedOldReports = $store->getWebsiteIdsToInvalidate(); + $this->idSitesInvalidatedOldReports = $store->getSitesToReprocess(); } /** @@ -1011,7 +1011,7 @@ class CronArchive * * @return array */ - private function getWebsiteIdsToInvalidate() + private function getInvalidatedSitesToReprocess() { $this->updateIdSitesInvalidatedOldReports(); diff --git a/core/DataAccess/ArchiveInvalidator.php b/core/DataAccess/ArchiveInvalidator.php index db84dc935c070767ab79c97928bef0d98c02b42c..6fc593d661634663876a2f17408f3fa51291c68f 100644 --- a/core/DataAccess/ArchiveInvalidator.php +++ b/core/DataAccess/ArchiveInvalidator.php @@ -12,11 +12,17 @@ namespace Piwik\DataAccess; use Piwik\Date; use Piwik\Db; -use Piwik\Plugins\CoreAdminHome\InvalidatedReports; use Piwik\Plugins\PrivacyManager\PrivacyManager; use Piwik\Period; use Piwik\Period\Week; +/** + * Marks archives as Invalidated by setting the done flag to a special value (see Model->updateArchiveAsInvalidated) + * + * Invalidated archives can still be selected and displayed in UI and API (until they are reprocessed by core:archive) + * + * @package Piwik\DataAccess + */ class ArchiveInvalidator { private $warningDates = array(); @@ -43,7 +49,7 @@ class ArchiveInvalidator { $store = new InvalidatedReports(); - $store->setSiteIdsToBeInvalidated($idSites); + $store->storeInvalidatedSitesAndDates($idSites); return $this->makeOutputLogs(); } @@ -129,7 +135,7 @@ class ArchiveInvalidator { private function findOlderDateWithLogs() { -// If using the feature "Delete logs older than N days"... + // If using the feature "Delete logs older than N days"... $purgeDataSettings = PrivacyManager::getPurgeDataSettings(); $logsAreDeletedBeforeThisDate = $purgeDataSettings['delete_logs_schedule_lowest_interval']; $logsDeleteEnabled = $purgeDataSettings['delete_logs_enable']; diff --git a/core/DataAccess/ArchivePurger.php b/core/DataAccess/ArchivePurger.php index 3ae023fdda973e0b27fd81ea3dea5e0afe2c98c5..fc9254ac3b7cdbe294fe280e3040c64b64da4228 100644 --- a/core/DataAccess/ArchivePurger.php +++ b/core/DataAccess/ArchivePurger.php @@ -31,7 +31,7 @@ class ArchivePurger * Select the archives that have already been invalidated and have been since re-processed. * It purges records for each distinct { archive name (includes segment hash) , idsite, date, period } tuple. */ - $result = self::getModel()->purgeInvalidatedArchiveTable($archiveTable); + $result = self::getModel()->getInvalidatedArchiveIdsSafeToDelete($archiveTable); if (count($result) > 0) { $archiveIds = array_map( diff --git a/core/DataAccess/ArchiveSelector.php b/core/DataAccess/ArchiveSelector.php index a342257eca4eb1714643489357890a2e2efc58ad..56dede02b712cc1029e909d81045897cc302ef1b 100644 --- a/core/DataAccess/ArchiveSelector.php +++ b/core/DataAccess/ArchiveSelector.php @@ -9,8 +9,8 @@ namespace Piwik\DataAccess; use Exception; -use Piwik\ArchiveProcessor\Rules; use Piwik\ArchiveProcessor; +use Piwik\ArchiveProcessor\Rules; use Piwik\Common; use Piwik\Date; use Piwik\Db; @@ -63,10 +63,10 @@ class ArchiveSelector $isSkipAggregationOfSubTables = $params->isSkipAggregationOfSubTables(); $plugins = array("VisitsSummary", $requestedPlugin); - $doneFlags = self::getDoneFlags($plugins, $segment, $isSkipAggregationOfSubTables); - $possibleValues = self::getPossibleValues(); + $doneFlags = Rules::getDoneFlags($plugins, $segment, $isSkipAggregationOfSubTables); + $doneFlagValues = Rules::getSelectableDoneFlagValues(); - $results = self::getModel()->getArchiveIdAndVisits($numericTable, $idSite, $period, $dateStartIso, $dateEndIso, $minDatetimeIsoArchiveProcessedUTC, $doneFlags, $possibleValues); + $results = self::getModel()->getArchiveIdAndVisits($numericTable, $idSite, $period, $dateStartIso, $dateEndIso, $minDatetimeIsoArchiveProcessedUTC, $doneFlags, $doneFlagValues); if (empty($results)) { return false; @@ -289,49 +289,14 @@ class ArchiveSelector { // the flags used to tell how the archiving process for a specific archive was completed, // if it was completed - $doneFlags = self::getDoneFlags($plugins, $segment, $isSkipAggregationOfSubTables); + $doneFlags = Rules::getDoneFlags($plugins, $segment, $isSkipAggregationOfSubTables); $allDoneFlags = "'" . implode("','", $doneFlags) . "'"; - $possibleValues = self::getPossibleValues(); + $possibleValues = Rules::getSelectableDoneFlagValues(); // create the SQL to find archives that are DONE return "((name IN ($allDoneFlags)) AND (value IN (" . implode(',', $possibleValues) . ")))"; } - /** - * Returns the SQL condition used to find successfully completed archives that - * this instance is querying for. - * - * @param array $plugins - * @param Segment $segment - * @param bool $isSkipAggregationOfSubTables - * @return string - */ - private static function getDoneFlags(array $plugins, Segment $segment, $isSkipAggregationOfSubTables) - { - // the flags used to tell how the archiving process for a specific archive was completed, - // if it was completed - $doneFlags = Rules::getDoneFlags($plugins, $segment, $isSkipAggregationOfSubTables); - - return $doneFlags; - } - - /** - * Returns the SQL condition used to find successfully completed archives that - * this instance is querying for. - * - * @return string - */ - private static function getPossibleValues() - { - $possibleValues = array(ArchiveWriter::DONE_OK, ArchiveWriter::DONE_OK_TEMPORARY); - - if (!Rules::isRequestAuthorizedToArchive()) { - //If request is not authorized to archive then fetch also invalidated archives - $possibleValues[] = ArchiveWriter::DONE_INVALIDATED; - } - - return $possibleValues; - } } diff --git a/plugins/CoreAdminHome/InvalidatedReports.php b/core/DataAccess/InvalidatedReports.php similarity index 71% rename from plugins/CoreAdminHome/InvalidatedReports.php rename to core/DataAccess/InvalidatedReports.php index 971a49efd9b0bc8393453fb85668ac46f22243e7..e5d55550a02ef7bd1eae29aca5963d65bd5cc608 100644 --- a/plugins/CoreAdminHome/InvalidatedReports.php +++ b/core/DataAccess/InvalidatedReports.php @@ -7,7 +7,7 @@ * */ -namespace Piwik\plugins\CoreAdminHome; +namespace Piwik\DataAccess; use Piwik\Option; use Piwik\Piwik; @@ -27,58 +27,62 @@ class InvalidatedReports const OPTION_INVALIDATED_IDSITES_TO_REPROCESS = 'InvalidatedOldReports_WebsiteIds'; /** - * Returns array of idSites to force re-process next time core:archive command runs - * - * @ignore - * @return mixed - */ - public function getWebsiteIdsToInvalidate() - { - Piwik::checkUserHasSomeAdminAccess(); - - Option::clearCachedOption(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS); - $invalidatedIdSites = Option::get(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS); - if ($invalidatedIdSites - && ($invalidatedIdSites = unserialize($invalidatedIdSites)) - && count($invalidatedIdSites) - ) { - return $invalidatedIdSites; - } - return array(); - } - - - - /** - * Force to re-process data for these websites in the next cron core:archive command run + * Record those website IDs as having been invalidated * * @param $idSites */ - public function setSiteIdsToBeInvalidated($idSites) + public function storeInvalidatedSitesAndDates($idSites) { - $store = new InvalidatedReports(); - $invalidatedIdSites = $store->getWebsiteIdsToInvalidate(); + $invalidatedIdSites = $this->getSitesToReprocess(); $invalidatedIdSites = array_merge($invalidatedIdSites, $idSites); $invalidatedIdSites = array_unique($invalidatedIdSites); $invalidatedIdSites = array_values($invalidatedIdSites); - Option::set(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS, serialize($invalidatedIdSites)); + $this->setSitesToReprocess($invalidatedIdSites); } /** * @param $idSite */ - public function removeWebsiteFromInvalidatedWebsites($idSite) + public function storeSiteIsReprocessed($idSite) { - $websiteIdsInvalidated = $this->getWebsiteIdsToInvalidate(); + $websiteIdsInvalidated = $this->getSitesToReprocess(); if (count($websiteIdsInvalidated)) { $found = array_search($idSite, $websiteIdsInvalidated); if ($found !== false) { unset($websiteIdsInvalidated[$found]); - Option::set(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS, serialize($websiteIdsInvalidated)); + $this->setSitesToReprocess($websiteIdsInvalidated); } } } + /** + * Returns array of idSites to force re-process next time core:archive command runs + * + * @return array of id sites + */ + public function getSitesToReprocess() + { + Option::clearCachedOption(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS); + $invalidatedIdSites = Option::get(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS); + + if ($invalidatedIdSites + && ($invalidatedIdSites = unserialize($invalidatedIdSites)) + && count($invalidatedIdSites) + ) { + return $invalidatedIdSites; + } + return array(); + } + + /** + * @param $websiteIdsInvalidated + */ + private function setSitesToReprocess($websiteIdsInvalidated) + { + Option::set(self::OPTION_INVALIDATED_IDSITES_TO_REPROCESS, serialize($websiteIdsInvalidated)); + } + + } \ No newline at end of file diff --git a/core/DataAccess/Model.php b/core/DataAccess/Model.php index 7f5adb7a45b8649a7e856c86146b9b9ebfc0e8a5..ee2d8702af2cca2c96ddb18ef1fc4a9ce51f9183 100644 --- a/core/DataAccess/Model.php +++ b/core/DataAccess/Model.php @@ -22,15 +22,20 @@ class Model { const PREFIX_SQL_LOCK = "locked_"; - public function purgeInvalidatedArchiveTable($archiveTable) + /** + * Returns the archives IDs that have already been invalidated and have been since re-processed. + * + * These archives { archive name (includes segment hash) , idsite, date, period } will be deleted. + * + * @param $archiveTable + * @return array + * @throws Exception + */ + public function getInvalidatedArchiveIdsSafeToDelete($archiveTable) { // prevent error 'The SELECT would examine more than MAX_JOIN_SIZE rows' Db::get()->query('SET SQL_BIG_SELECTS=1'); - /** - * Select the archives that have already been invalidated and have been since re-processed. - * It purges records for each distinct { archive name (includes segment hash) , idsite, date, period } tuple. - */ $query = 'SELECT t1.idarchive FROM `' . $archiveTable . '` t1 INNER JOIN `' . $archiveTable . '` t2 ON t1.name = t2.name AND t1.idsite=t2.idsite @@ -115,7 +120,7 @@ class Model } } - public function getArchiveIdAndVisits($numericTable, $idSite, $period, $dateStartIso, $dateEndIso, $minDatetimeIsoArchiveProcessedUTC, $doneFlags, $possibleValues) + public function getArchiveIdAndVisits($numericTable, $idSite, $period, $dateStartIso, $dateEndIso, $minDatetimeIsoArchiveProcessedUTC, $doneFlags, $doneFlagValues) { $bindSQL = array($idSite, $dateStartIso, @@ -129,7 +134,7 @@ class Model $bindSQL[] = $minDatetimeIsoArchiveProcessedUTC; } - $sqlWhereArchiveName = self::getNameCondition($doneFlags, $possibleValues); + $sqlWhereArchiveName = self::getNameCondition($doneFlags, $doneFlagValues); $sqlQuery = "SELECT idarchive, value, name, date1 as startDate FROM $numericTable WHERE idsite = ?