diff --git a/CHANGELOG.md b/CHANGELOG.md index 799d865..d7da4b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Option for requiring cookie consent (#23) + ## [1.6.0] - 2023-05-21 ### Added diff --git a/Classes/Entity/Configuration.php b/Classes/Entity/Configuration.php index a70ec20..7038761 100644 --- a/Classes/Entity/Configuration.php +++ b/Classes/Entity/Configuration.php @@ -60,6 +60,10 @@ final class Configuration * @readonly */ public bool $performanceTracking = false; + /** + * @readonly + */ + public bool $requireConsent = false; /** * @readonly */ diff --git a/Classes/EventListener/RequireCookieConsent.php b/Classes/EventListener/RequireConsent.php similarity index 68% rename from Classes/EventListener/RequireCookieConsent.php rename to Classes/EventListener/RequireConsent.php index 5814ebe..82fcab4 100644 --- a/Classes/EventListener/RequireCookieConsent.php +++ b/Classes/EventListener/RequireConsent.php @@ -16,10 +16,17 @@ /** * @internal */ -final class RequireCookieConsent +final class RequireConsent { public function __invoke(BeforeTrackPageViewEvent $event): void { + if ($event->getConfiguration()->requireConsent) { + $event->addMatomoMethodCall('requireConsent'); + // "requireConsent" is more restrictive, so this one wins + // if both options are set. + return; + } + if ($event->getConfiguration()->requireCookieConsent) { $event->addMatomoMethodCall('requireCookieConsent'); } diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 91e0298..f65d7e6 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -61,10 +61,10 @@ services: identifier: 'matomo-integration/performance-tracking' event: Brotkrueml\MatomoIntegration\Event\AfterTrackPageViewEvent - Brotkrueml\MatomoIntegration\EventListener\RequireCookieConsent: + Brotkrueml\MatomoIntegration\EventListener\RequireConsent: tags: - name: event.listener - identifier: 'matomo-integration/require-cookie-consent' + identifier: 'matomo-integration/require-consent' event: Brotkrueml\MatomoIntegration\Event\BeforeTrackPageViewEvent Brotkrueml\MatomoIntegration\EventListener\TrackJavaScriptErrors: diff --git a/Configuration/SiteConfiguration/Overrides/sites.php b/Configuration/SiteConfiguration/Overrides/sites.php index 2ded23f..8751e96 100644 --- a/Configuration/SiteConfiguration/Overrides/sites.php +++ b/Configuration/SiteConfiguration/Overrides/sites.php @@ -32,6 +32,10 @@ 'label' => Brotkrueml\MatomoIntegration\Extension::LANGUAGE_PATH_SITECONF . ':noScript', 'value' => 'noScript', ], + [ + 'label' => Brotkrueml\MatomoIntegration\Extension::LANGUAGE_PATH_SITECONF . ':requireConsent', + 'value' => 'requireConsent', + ], [ 'label' => Brotkrueml\MatomoIntegration\Extension::LANGUAGE_PATH_SITECONF . ':requireCookieConsent', 'value' => 'requireCookieConsent', diff --git a/Documentation/Changelog/Index.rst b/Documentation/Changelog/Index.rst index cdd266c..5caaf68 100644 --- a/Documentation/Changelog/Index.rst +++ b/Documentation/Changelog/Index.rst @@ -11,6 +11,9 @@ and this project adheres to `Semantic Versioning `_ ------------------------------------------------------------------------------------------------ + +* Option for requiring cookie consent (#23) + `1.6.0 `_ - 2023-05-21 ---------------------------------------------------------------------------------------------------------- @@ -20,7 +23,7 @@ Added * Multiple tag manager container IDs can be used (#14) * Option for requiring cookie consent (#20) -* Add nonce attribute to script tag in TYPO3 v12+, if available (#7) +* CSP nonce attribute to script tag in TYPO3 v12+, if available (#7) `1.5.1 `_ - 2023-04-01 ---------------------------------------------------------------------------------------------------------- diff --git a/Documentation/Configuration/Index.rst b/Documentation/Configuration/Index.rst index 781c475..63cdaba 100644 --- a/Documentation/Configuration/Index.rst +++ b/Documentation/Configuration/Index.rst @@ -55,15 +55,30 @@ Track users with JavaScript disabled Default: *disabled* +Require consent + .. versionadded:: 1.7.0 + + Enable this option when a consent manager is used which sets up consent + tracking: no tracking request will be sent to Matomo and no cookies will be + set. For more information have a look into + `Implementing tracking or cookie consent with the Matomo JavaScript Tracking Client`_. + + Default: *disabled* + Require cookie consent .. versionadded:: 1.6.0 Enable this option when a consent manager is used which sets up consent - tracking. For more information have a look into + tracking: tracking requests will still be sent but no cookies will be set. + For more information have a look into `Implementing tracking or cookie consent with the Matomo JavaScript Tracking Client`_. Default: *disabled* + .. important:: + When enabling this option *and* the option "Require consent", "Require + cookie consent" will be ignored in favour of the more restrictive one. + Cookie tracking Activating this option `enables cookies tracking`_. diff --git a/Documentation/Images/SiteConfiguration.png b/Documentation/Images/SiteConfiguration.png index 12e3780..dada4a5 100644 Binary files a/Documentation/Images/SiteConfiguration.png and b/Documentation/Images/SiteConfiguration.png differ diff --git a/Resources/Private/Language/SiteConfiguration.xlf b/Resources/Private/Language/SiteConfiguration.xlf index 2e14ad1..ed8c77e 100644 --- a/Resources/Private/Language/SiteConfiguration.xlf +++ b/Resources/Private/Language/SiteConfiguration.xlf @@ -1,6 +1,6 @@ - + @@ -32,6 +32,9 @@ + + + diff --git a/Tests/Unit/Entity/ConfigurationTest.php b/Tests/Unit/Entity/ConfigurationTest.php index 30ce431..4689f68 100644 --- a/Tests/Unit/Entity/ConfigurationTest.php +++ b/Tests/Unit/Entity/ConfigurationTest.php @@ -26,6 +26,7 @@ public function createFromSiteConfigurationWithEmptyArrayReturnsInstanceWithDefa self::assertSame('', $subject->url); self::assertSame(0, $subject->siteId); self::assertFalse($subject->noScript); + self::assertFalse($subject->requireConsent); self::assertFalse($subject->requireCookieConsent); self::assertFalse($subject->cookieTracking); self::assertFalse($subject->disableBrowserFeatureDetection); @@ -102,6 +103,18 @@ public function createFromSiteConfigurationWithRequireCookieConsentEnabledSetsIn self::assertTrue($subject->requireCookieConsent); } + /** + * @test + */ + public function createFromSiteConfigurationWithRequireConsentEnabledSetsInstanceValuesCorrectly(): void + { + $subject = Configuration::createFromSiteConfiguration([ + 'matomoIntegrationOptions' => 'requireConsent', + ]); + + self::assertTrue($subject->requireConsent); + } + /** * @test */ diff --git a/Tests/Unit/EventListener/RequireCookieConsentTest.php b/Tests/Unit/EventListener/RequireConsentTest.php similarity index 51% rename from Tests/Unit/EventListener/RequireCookieConsentTest.php rename to Tests/Unit/EventListener/RequireConsentTest.php index 806955a..7583c77 100644 --- a/Tests/Unit/EventListener/RequireCookieConsentTest.php +++ b/Tests/Unit/EventListener/RequireConsentTest.php @@ -13,29 +13,29 @@ use Brotkrueml\MatomoIntegration\Entity\Configuration; use Brotkrueml\MatomoIntegration\Event\BeforeTrackPageViewEvent; -use Brotkrueml\MatomoIntegration\EventListener\RequireCookieConsent; +use Brotkrueml\MatomoIntegration\EventListener\RequireConsent; use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; -final class RequireCookieConsentTest extends TestCase +final class RequireConsentTest extends TestCase { /** * @var ServerRequestInterface&Stub */ private $requestStub; - private RequireCookieConsent $subject; + private RequireConsent $subject; protected function setUp(): void { $this->requestStub = $this->createStub(ServerRequestInterface::class); - $this->subject = new RequireCookieConsent(); + $this->subject = new RequireConsent(); } /** * @test */ - public function disabledOption(): void + public function disabledBothOptions(): void { $configuration = Configuration::createFromSiteConfiguration([ 'matomoIntegrationUrl' => 'https://www.example.net/', @@ -52,7 +52,26 @@ public function disabledOption(): void /** * @test */ - public function enabledOption(): void + public function enabledOptionRequireConsent(): void + { + $configuration = Configuration::createFromSiteConfiguration([ + 'matomoIntegrationUrl' => 'https://www.example.net/', + 'matomoIntegrationSiteId' => 123, + 'matomoIntegrationOptions' => 'requireConsent', + ]); + + $event = new BeforeTrackPageViewEvent($configuration, $this->requestStub); + $this->subject->__invoke($event); + + $actual = $event->getMatomoMethodCalls(); + self::assertCount(1, $actual); + self::assertSame('_paq.push(["requireConsent"]);', (string)$actual[0]); + } + + /** + * @test + */ + public function enabledOptionRequireCookieConsent(): void { $configuration = Configuration::createFromSiteConfiguration([ 'matomoIntegrationUrl' => 'https://www.example.net/', @@ -67,4 +86,23 @@ public function enabledOption(): void self::assertCount(1, $actual); self::assertSame('_paq.push(["requireCookieConsent"]);', (string)$actual[0]); } + + /** + * @test + */ + public function enabledBothOptionsRequireConsentAndRequireCookieConsentThenOnlyRequireConsentIsConsidered(): void + { + $configuration = Configuration::createFromSiteConfiguration([ + 'matomoIntegrationUrl' => 'https://www.example.net/', + 'matomoIntegrationSiteId' => 123, + 'matomoIntegrationOptions' => 'requireConsent,requireCookieConsent', + ]); + + $event = new BeforeTrackPageViewEvent($configuration, $this->requestStub); + $this->subject->__invoke($event); + + $actual = $event->getMatomoMethodCalls(); + self::assertCount(1, $actual); + self::assertSame('_paq.push(["requireConsent"]);', (string)$actual[0]); + } }