Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burgess <88810029+bx80@users.noreply.github.com>2021-12-01 05:27:48 +0300
committerGitHub <noreply@github.com>2021-12-01 05:27:48 +0300
commit74a6bb09477a175f06bffbef14cf533ba8744b69 (patch)
treed582cea51ba22234ab35a3f86d9d98bf2e061378 /plugins/Transitions
parent9efa63a654145fcb315d16c5e6d21ab3b96c6f01 (diff)
Configuration option to disable transition periods (#18366)
* Added config option to disable transition periods * Config section checks * Hide transitions row action if period is not allowed * Added system test * Add default values for requests vars * Do allowed period checks for transition row actions in javascript * Code tidy up, fix for range get day count bug, improved tests * Added UI test for disabled period
Diffstat (limited to 'plugins/Transitions')
-rw-r--r--plugins/Transitions/API.php53
-rw-r--r--plugins/Transitions/Controller.php3
-rw-r--r--plugins/Transitions/Transitions.php42
-rw-r--r--plugins/Transitions/javascripts/transitions.js43
-rw-r--r--plugins/Transitions/lang/en.json2
-rw-r--r--plugins/Transitions/tests/Integration/TransitionsMaxAllowedPeriodTest.php133
-rw-r--r--plugins/Transitions/tests/UI/Transitions_spec.js16
7 files changed, 288 insertions, 4 deletions
diff --git a/plugins/Transitions/API.php b/plugins/Transitions/API.php
index 67a388eb8a..0dc1c726c5 100644
--- a/plugins/Transitions/API.php
+++ b/plugins/Transitions/API.php
@@ -66,6 +66,10 @@ class API extends \Piwik\Plugin\API
{
Piwik::checkUserHasViewAccess($idSite);
+ if (!$this->isPeriodAllowed($idSite, $period, $date)) {
+ throw new Exception('PeriodNotAllowed');
+ }
+
// get idaction of the requested action
$idaction = $this->deriveIdAction($actionName, $actionType);
if ($idaction < 0) {
@@ -656,4 +660,53 @@ class API extends \Piwik\Plugin\API
$this->totalTransitionsToFollowingPages += $actions;
}
}
+
+
+ /**
+ * Check if a period is allowed by config settings
+ *
+ * @param $idSite
+ * @param $period
+ * @param $date
+ *
+ * @return bool
+ */
+ public function isPeriodAllowed($idSite, $period, $date) : bool
+ {
+ $maxPeriodAllowed = Transitions::getPeriodAllowedConfig($idSite);
+ if ($maxPeriodAllowed === 'all') {
+ return true;
+ }
+
+ // If the period is a range then the number of days in the range must be less or equal to the max period allowed
+ if ($period === 'range') {
+
+ $range = new Period\Range($period, $date);
+ $rangeDays = $range->getDayCount();
+
+ switch ($maxPeriodAllowed) {
+ case 'day':
+ return $rangeDays == 1;
+ case 'week':
+ return $rangeDays <= 7;
+ case 'month':
+ return $rangeDays <= 31;
+ case 'year':
+ return $rangeDays <= 365;
+ }
+ }
+
+ switch ($maxPeriodAllowed) {
+ case 'day':
+ return $period === 'day';
+ case 'week':
+ return in_array($period, ['day', 'week']);
+ case 'month':
+ return in_array($period, ['day', 'week', 'month']);
+ case 'year':
+ return in_array($period, ['day', 'week', 'month', 'year']);
+ }
+
+ return false;
+ }
}
diff --git a/plugins/Transitions/Controller.php b/plugins/Transitions/Controller.php
index 2cabbc62d2..a8a85e0115 100644
--- a/plugins/Transitions/Controller.php
+++ b/plugins/Transitions/Controller.php
@@ -60,6 +60,9 @@ class Controller extends \Piwik\Plugin\Controller
'NoDataForAction' => 'Transitions_NoDataForAction',
'NoDataForActionDetails' => 'Transitions_NoDataForActionDetails',
'NoDataForActionBack' => 'Transitions_ErrorBack',
+ 'PeriodNotAllowed' => 'Transitions_PeriodNotAllowed',
+ 'PeriodNotAllowedDetails'=> 'Transitions_PeriodNotAllowedDetails',
+ 'PeriodNotAllowedBack' => 'Transitions_ErrorBack',
'ShareOfAllPageviews' => 'Transitions_ShareOfAllPageviews',
'DateRange' => 'General_DateRange'
);
diff --git a/plugins/Transitions/Transitions.php b/plugins/Transitions/Transitions.php
index 67d5be7f25..afd5f3a2fc 100644
--- a/plugins/Transitions/Transitions.php
+++ b/plugins/Transitions/Transitions.php
@@ -9,6 +9,10 @@
namespace Piwik\Plugins\Transitions;
+use Piwik\Common;
+use Piwik\Plugins\Transitions\API;
+use Piwik\Config;
+
/**
*/
class Transitions extends \Piwik\Plugin
@@ -22,7 +26,8 @@ class Transitions extends \Piwik\Plugin
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
- 'API.getPagesComparisonsDisabledFor' => 'getPagesComparisonsDisabledFor',
+ 'API.getPagesComparisonsDisabledFor' => 'getPagesComparisonsDisabledFor',
+ 'Template.jsGlobalVariables' => 'addJsGlobalVariables',
);
}
@@ -55,4 +60,39 @@ class Transitions extends \Piwik\Plugin
$translationKeys[] = 'CoreHome_ThereIsNoDataForThisReport';
$translationKeys[] = 'General_Others';
}
+
+ public function addJsGlobalVariables(&$out)
+ {
+ $idSite = Common::getRequestVar('idSite', 1, 'int');
+ $maxPeriodAllowed = self::getPeriodAllowedConfig($idSite);
+
+ $out .= ' piwik.transitionsMaxPeriodAllowed = "'.($maxPeriodAllowed ? $maxPeriodAllowed : 'all').'"'."\n";
+ }
+
+ /**
+ * Retrieve the period allowed config setting for a site or all sites if null
+ *
+ * @param $idSite
+ *
+ * @return string
+ */
+ public static function getPeriodAllowedConfig($idSite) : string
+ {
+ $transitionsGeneralConfig = Config::getInstance()->Transitions;
+ $generalMaxPeriodAllowed = ($transitionsGeneralConfig && !empty($transitionsGeneralConfig['max_period_allowed']) ? $transitionsGeneralConfig['max_period_allowed']: null);
+
+ $siteMaxPeriodAllowed = null;
+ if ($idSite) {
+ $sectionName = 'Transitions_'.$idSite;
+ $transitionsSiteConfig = Config::getInstance()->$sectionName;
+ $siteMaxPeriodAllowed = ($transitionsSiteConfig && !empty($transitionsSiteConfig['max_period_allowed']) ? $transitionsSiteConfig['max_period_allowed'] : null);
+ }
+
+ if (!$generalMaxPeriodAllowed && !$siteMaxPeriodAllowed) {
+ return 'all'; // No config setting, so all periods are valid
+ }
+
+ // Site setting overrides general, if it exists
+ return $siteMaxPeriodAllowed ?? $generalMaxPeriodAllowed;
+ }
}
diff --git a/plugins/Transitions/javascripts/transitions.js b/plugins/Transitions/javascripts/transitions.js
index 19bd467b14..caabaa0b69 100644
--- a/plugins/Transitions/javascripts/transitions.js
+++ b/plugins/Transitions/javascripts/transitions.js
@@ -123,6 +123,45 @@ DataTable_RowActions_Registry.register({
},
isAvailableOnReport: function (dataTableParams) {
+
+ if (piwik.transitionsMaxPeriodAllowed && dataTableParams['period']) {
+
+ if (dataTableParams['period'] === 'range') {
+
+ var piwikPeriods = piwikHelper.getAngularDependency('piwikPeriods');
+ if (piwikPeriods) {
+ var range = piwikPeriods.parse(dataTableParams['period'], dataTableParams['date']);
+ if (range) {
+ var rangeDays = range.getDayCount();
+ if ((piwik.transitionsMaxPeriodAllowed === 'day' && rangeDays > 1) ||
+ (piwik.transitionsMaxPeriodAllowed === 'week' && rangeDays > 7) ||
+ (piwik.transitionsMaxPeriodAllowed === 'month' && rangeDays > 31) ||
+ (piwik.transitionsMaxPeriodAllowed === 'year' && rangeDays > 365))
+ {
+ return false;
+ }
+ }
+ }
+ } else {
+ if (piwik.transitionsMaxPeriodAllowed === 'day' && dataTableParams['period'] !== 'day') {
+ return false;
+ }
+ if (piwik.transitionsMaxPeriodAllowed === 'week' && dataTableParams['period'] !== 'day'
+ && dataTableParams['period'] !== 'week') {
+ return false;
+ }
+ if (piwik.transitionsMaxPeriodAllowed === 'month' && dataTableParams['period'] !== 'day'
+ && dataTableParams['period'] !== 'week' && dataTableParams['period'] !== 'month') {
+ return false;
+ }
+ if (piwik.transitionsMaxPeriodAllowed === 'year' && dataTableParams['period'] !== 'day'
+ && dataTableParams['period'] !== 'week' && dataTableParams['period'] !== 'month'
+ && dataTableParams['period'] !== 'year'
+ ) {
+ return false;
+ }
+ }
+ }
var i = 0;
for (i; i < DataTable_RowActions_Transitions.registeredReports.length; i++) {
var report = DataTable_RowActions_Transitions.registeredReports[i];
@@ -1586,8 +1625,8 @@ Piwik_Transitions_Ajax.prototype.callApi = function (method, params, callback) {
if (typeof Piwik_Transitions_Translations == 'undefined') {
self.callApi('Transitions.getTranslations', {}, function (response) {
- if (typeof response[0] == 'object') {
- Piwik_Transitions_Translations = response[0];
+ if (typeof response == 'object') {
+ Piwik_Transitions_Translations = response;
} else {
Piwik_Transitions_Translations = {};
}
diff --git a/plugins/Transitions/lang/en.json b/plugins/Transitions/lang/en.json
index 321557d613..71cdb25bb5 100644
--- a/plugins/Transitions/lang/en.json
+++ b/plugins/Transitions/lang/en.json
@@ -24,6 +24,8 @@
"LoopsInline": "%s page reloads",
"NoDataForAction": "There's no data for %s",
"NoDataForActionDetails": "Either the action had no pageviews during the period %s or it is invalid.",
+ "PeriodNotAllowed": "Time period not allowed",
+ "PeriodNotAllowedDetails": "This feature is not available for this period, try selecting a period with fewer days",
"OutgoingTraffic": "Outgoing traffic",
"PluginDescription": "Reports previous and following actions for each page URL in a new Transitions report, available in the Actions reports via a new icon.",
"ShareOfAllPageviews": "This page had %1$s pageviews (%2$s of all pageviews)",
diff --git a/plugins/Transitions/tests/Integration/TransitionsMaxAllowedPeriodTest.php b/plugins/Transitions/tests/Integration/TransitionsMaxAllowedPeriodTest.php
new file mode 100644
index 0000000000..b074e7d3ab
--- /dev/null
+++ b/plugins/Transitions/tests/Integration/TransitionsMaxAllowedPeriodTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+namespace Piwik\Plugins\Transitions\tests\Integration;
+
+use Piwik\Plugins\Transitions\Transitions;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+use Piwik\Config;
+use Piwik\Tests\Framework\Fixture;
+use Piwik\Plugins\Transitions\API;
+
+/**
+ * Tests the transitions plugin max_period_allowed setting
+ *
+ * @group TransitionsMaxAllowedPeriodTest
+ * @group Plugins
+ */
+class TransitionsMaxAllowedPeriodTest extends IntegrationTestCase
+{
+
+ public $api;
+
+ protected static function configureFixture($fixture)
+ {
+ parent::configureFixture($fixture);
+ $fixture->createSuperUser = true;
+ }
+
+ public function setUp(): void
+ {
+ parent::setUp();
+ Fixture::createWebsite('2010-02-03 00:00:00');
+ $this->api = API::getInstance();
+
+ $t = Fixture::getTracker(1, '2012-08-09 01:02:03', $defaultInit = true, $useLocalTracker = false);
+
+ $t->setUrl('http://example.org/page/one.html');
+ $t->doTrackPageView('incredible title ');
+ }
+
+ public function test_ShouldThrowException_IfPeriodNotAllowed()
+ {
+ $invalidPeriods = [
+ 'day' => ['week', 'month', 'year'],
+ 'week' => ['month', 'year'],
+ 'month' => ['year'],
+ ];
+ foreach ($invalidPeriods as $period => $invalids) {
+ Config::setSetting('Transitions_1', 'max_period_allowed', $period);
+ foreach ($invalids as $ip) {
+ try {
+ $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url',
+ 1, $ip, '2012-08-09');
+ $this->fail("Failed asserting that exception 'PeriodNotAllowed' was thrown");
+ } catch (\Exception $e) {
+ $this->assertEquals('PeriodNotAllowed', $e->getMessage());
+ }
+ }
+ }
+ }
+
+ public function test_ShouldReturnData_IfPeriodAllowed()
+ {
+ $validPeriods = [
+ 'day' => ['day'],
+ 'week' => ['day', 'week'],
+ 'month' => ['day', 'week', 'month'],
+ 'year' => ['day', 'week', 'month', 'year'],
+ 'all' => ['day', 'week', 'month', 'year'],
+ ];
+ foreach ($validPeriods as $period => $valids) {
+ Config::setSetting('Transitions_1', 'max_period_allowed', $period);
+ foreach ($valids as $vp) {
+ $r = $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url',
+ 1, $vp, '2012-08-09');
+ self::assertEquals(1, $r['pageMetrics']['pageviews']);
+ }
+ }
+ }
+
+ public function test_ShouldThrowException_IfRangeDayCountIsLargerThanDayPeriod()
+ {
+ Config::setSetting('Transitions_1', 'max_period_allowed', 'day');
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('PeriodNotAllowed');
+ $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url', 1,
+ 'range','2012-08-09,2012-08-10');
+ }
+
+ public function test_ShouldThrowException_IfRangeDayCountIsLargerThanWeekPeriod()
+ {
+ Config::setSetting('Transitions_1', 'max_period_allowed', 'day');
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('PeriodNotAllowed');
+ $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url', 1,
+ 'range','2012-08-09,2012-08-17');
+ }
+
+ public function test_ShouldThrowException_IfRangeDayCountIsLargerThanMonthPeriod()
+ {
+ Config::setSetting('Transitions_1', 'max_period_allowed', 'day');
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('PeriodNotAllowed');
+ $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url', 1,
+ 'range','2012-08-09,2012-09-10');
+ }
+
+ public function test_ShouldThrowException_IfRangeDayCountIsLargerThanYearPeriod()
+ {
+ Config::setSetting('Transitions_1', 'max_period_allowed', 'day');
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('PeriodNotAllowed');
+ $this->api->getTransitionsForAction('http://example.org/page/one.html', 'url', 1,
+ 'range','2012-08-09,2013-08-10');
+ }
+
+ public function test_ShouldUseSiteConfigInsteadOfGeneral_IfSiteConfigExists()
+ {
+ Config::setSetting('Transitions_1', 'max_period_allowed', null);
+ Config::setSetting('Transitions', 'max_period_allowed', 'month');
+ $maxAllowedPeriod = Transitions::getPeriodAllowedConfig(1);
+ $this->assertEquals('month', $maxAllowedPeriod);
+
+ Config::setSetting('Transitions_1', 'max_period_allowed', 'week');
+ $maxAllowedPeriod = Transitions::getPeriodAllowedConfig(1);
+ $this->assertEquals('week', $maxAllowedPeriod);
+ }
+
+}
diff --git a/plugins/Transitions/tests/UI/Transitions_spec.js b/plugins/Transitions/tests/UI/Transitions_spec.js
index ed125f3078..4e0d716d09 100644
--- a/plugins/Transitions/tests/UI/Transitions_spec.js
+++ b/plugins/Transitions/tests/UI/Transitions_spec.js
@@ -84,4 +84,18 @@ describe("Transitions", function () {
expect(await page.screenshotSelector('body')).to.matchImage('transitions_report_switch_type_title');
});
-}); \ No newline at end of file
+ it('should show period not allowed for disabled periods', async function () {
+
+ testEnvironment.overrideConfig('Transitions_1', 'max_period_allowed', 'day');
+ testEnvironment.save();
+
+ await page.goto("?" + urlBase + "#?" + generalParams + "&category=General_Actions&subcategory=Transitions_Transitions");
+ await page.waitForNetworkIdle();
+ expect(await page.screenshotSelector('.pageWrap')).to.matchImage('transitions_report_period_not_allowed');
+
+ testEnvironment.overrideConfig('Transitions_1', 'max_period_allowed', 'all');
+ testEnvironment.save();
+ });
+
+
+});