From 8a23b7e718ed107abeba1efbfbfbdd2d6b9ab58e Mon Sep 17 00:00:00 2001
From: Thomas Steur <tsteur@users.noreply.github.com>
Date: Mon, 4 Sep 2017 17:02:11 +1200
Subject: [PATCH] Allow different reports pre-archiving frequency for each
 period (#11979)

* Allow different reports pre-archiving frequency for each period

* Add new config settings for archive frequency

* added default config for range dates

* print changed archive periods

* minor change to log output

* Clarify wording, processed != requested.

* Fix integration test
---
 config/global.ini.php                         | 14 +++++++++++++
 core/ArchiveProcessor/Rules.php               | 21 ++++++++++++++++++-
 core/CronArchive.php                          | 12 ++++++++++-
 tests/PHPUnit/Integration/CronArchiveTest.php |  2 +-
 ...rchiveCronTest_archive_php_cron_output.txt |  2 +-
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/config/global.ini.php b/config/global.ini.php
index bb63d92bf1..4ea60cdde4 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -276,6 +276,20 @@ default_period = day
 ; This setting is only used if it hasn't been overriden via the UI yet, or if enable_general_settings_admin=0
 time_before_today_archive_considered_outdated = 150
 
+; Time in seconds after which an archive will be computed again. This setting is used only for week's statistics.
+; If set to "-1" (default), it will fall back to the UI setting under "General settings" unless enable_general_settings_admin=0
+; is set. In this case it will default to "time_before_today_archive_considered_outdated";
+time_before_week_archive_considered_outdated = -1
+
+; Same as config setting "time_before_week_archive_considered_outdated" but it is only applied to monthly archives
+time_before_month_archive_considered_outdated = -1
+
+; Same as config setting "time_before_week_archive_considered_outdated" but it is only applied to yearly archives
+time_before_year_archive_considered_outdated = -1
+
+; Same as config setting "time_before_week_archive_considered_outdated" but it is only applied to range archives
+time_before_range_archive_considered_outdated = -1
+
 ; This setting is overriden in the UI, under "General Settings".
 ; The default value is to allow browsers to trigger the Piwik archiving process.
 ; This setting is only used if it hasn't been overridden via the UI yet, or if enable_general_settings_admin=0
diff --git a/core/ArchiveProcessor/Rules.php b/core/ArchiveProcessor/Rules.php
index 4f8391c281..09be79eea2 100644
--- a/core/ArchiveProcessor/Rules.php
+++ b/core/ArchiveProcessor/Rules.php
@@ -115,8 +115,10 @@ class Rules
     public static function getMinTimeProcessedForTemporaryArchive(
         Date $dateStart, \Piwik\Period $period, Segment $segment, Site $site)
     {
+        $todayArchiveTimeToLive = self::getPeriodArchiveTimeToLiveDefault($period->getLabel());
+
         $now = time();
-        $minimumArchiveTime = $now - Rules::getTodayArchiveTimeToLive();
+        $minimumArchiveTime = $now - $todayArchiveTimeToLive;
 
         $idSites = array($site->getId());
         $isArchivingDisabled = Rules::isArchivingDisabledFor($idSites, $segment, $period->getLabel());
@@ -158,6 +160,23 @@ class Rules
         return self::getTodayArchiveTimeToLiveDefault();
     }
 
+    public static function getPeriodArchiveTimeToLiveDefault($periodLabel)
+    {
+        if (empty($periodLabel) || strtolower($periodLabel) === 'day') {
+            return self::getTodayArchiveTimeToLive();
+        }
+
+        $config = Config::getInstance();
+        $general = $config->General;
+
+        $key = sprintf('time_before_%s_archive_considered_outdated', $periodLabel);
+        if (isset($general[$key]) && is_numeric($general[$key]) && $general[$key] > 0) {
+            return $general[$key];
+        }
+
+        return self::getTodayArchiveTimeToLive();
+    }
+
     public static function getTodayArchiveTimeToLiveDefault()
     {
         return Config::getInstance()->General['time_before_today_archive_considered_outdated'];
diff --git a/core/CronArchive.php b/core/CronArchive.php
index d9ed8c6311..b1489b27dd 100644
--- a/core/CronArchive.php
+++ b/core/CronArchive.php
@@ -1279,9 +1279,19 @@ class CronArchive
         }
         $this->logger->info("- Reports for today will be processed at most every " . $this->todayArchiveTimeToLive
             . " seconds. You can change this value in Piwik UI > Settings > General Settings.");
-        $this->logger->info("- Reports for the current week/month/year will be refreshed at most every "
+
+        $this->logger->info("- Reports for the current week/month/year will be requested at most every "
             . $this->processPeriodsMaximumEverySeconds . " seconds.");
 
+        foreach (array('week', 'month', 'year', 'range') as $period) {
+            $ttl = Rules::getPeriodArchiveTimeToLiveDefault($period);
+
+            if (!empty($ttl) && $ttl !== $this->todayArchiveTimeToLive) {
+                $this->logger->info("- Reports for the current $period will be processed at most every " . $ttl
+                    . " seconds. You can change this value in config/config.ini.php by editing 'time_before_" . $period . "_archive_considered_outdated' in the '[General]' section.");
+            }
+        }
+
         // Try and not request older data we know is already archived
         if ($this->lastSuccessRunTimestamp !== false) {
             $dateLast = time() - $this->lastSuccessRunTimestamp;
diff --git a/tests/PHPUnit/Integration/CronArchiveTest.php b/tests/PHPUnit/Integration/CronArchiveTest.php
index 682425f1e3..e8cfbc45fe 100644
--- a/tests/PHPUnit/Integration/CronArchiveTest.php
+++ b/tests/PHPUnit/Integration/CronArchiveTest.php
@@ -93,7 +93,7 @@ NOTES
 - If you execute this script at least once per hour (or more often) in a crontab, you may disable 'Browser trigger archiving' in Piwik UI > Settings > General Settings.
   See the doc at: http://piwik.org/docs/setup-auto-archiving/
 - Reports for today will be processed at most every %s seconds. You can change this value in Piwik UI > Settings > General Settings.
-- Reports for the current week/month/year will be refreshed at most every %s seconds.
+- Reports for the current week/month/year will be requested at most every %s seconds.
 - Will process all 1 websites
 - Limiting segment archiving to following segments:
   * actions>=2;browserCode=FF
diff --git a/tests/PHPUnit/System/expected/test_ArchiveCronTest_archive_php_cron_output.txt b/tests/PHPUnit/System/expected/test_ArchiveCronTest_archive_php_cron_output.txt
index 95b637e5ce..39ac07c52a 100644
--- a/tests/PHPUnit/System/expected/test_ArchiveCronTest_archive_php_cron_output.txt
+++ b/tests/PHPUnit/System/expected/test_ArchiveCronTest_archive_php_cron_output.txt
@@ -18,7 +18,7 @@ INFO [2017-01-22 00:03:37] NOTES
 INFO [2017-01-22 00:03:37] - If you execute this script at least once per hour (or more often) in a crontab, you may disable 'Browser trigger archiving' in Piwik UI > Settings > General Settings.
 INFO [2017-01-22 00:03:37]   See the doc at: http://piwik.org/docs/setup-auto-archiving/
 INFO [2017-01-22 00:03:37] - Reports for today will be processed at most every 150 seconds. You can change this value in Piwik UI > Settings > General Settings.
-INFO [2017-01-22 00:03:37] - Reports for the current week/month/year will be refreshed at most every 3600 seconds.
+INFO [2017-01-22 00:03:37] - Reports for the current week/month/year will be requested at most every 3600 seconds.
 INFO [2017-01-22 00:03:37] - Will invalidate archived reports for 2012-08-09 for following websites ids: 1
 INFO [2017-01-22 00:03:37] - Will invalidate archived reports for 2012-08-10 for following websites ids: 1
 INFO [2017-01-22 00:03:37] - Will invalidate archived reports for 2012-08-11 for following websites ids: 1
-- 
GitLab