Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Google consent mode tag, #PG-4039 #971

Merged
merged 8 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Template/Tag/AxeptioTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function getDescription()

public function getCategory()
{
return Piwik::translate('TagManager_ConsentManagementPlatform');
return Piwik::translate('TagManager_ConsentManagement');
}

public function getIcon()
Expand Down
2 changes: 1 addition & 1 deletion Template/Tag/CookieYesTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function getDescription()

public function getCategory()
{
return Piwik::translate('TagManager_ConsentManagementPlatform');
return Piwik::translate('TagManager_ConsentManagement');
}

public function getIcon()
Expand Down
2 changes: 1 addition & 1 deletion Template/Tag/CookiebotTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function getHelp()

public function getCategory()
{
return Piwik::translate('TagManager_ConsentManagementPlatform');
return Piwik::translate('TagManager_ConsentManagement');
}

public function getIcon()
Expand Down
100 changes: 100 additions & 0 deletions Template/Tag/GoogleConsentModeV2Tag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?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\TagManager\Template\Tag;

use Piwik\Piwik;
use Piwik\Settings\FieldConfig;
use Piwik\Url;
use Piwik\Validators\NotEmpty;

class GoogleConsentModeV2Tag extends BaseTag
{
public function getName()
{
// By default, the name will be automatically fetched from the TagManager_CustomHtmlTagName translation key.
// you can either adjust/create/remove this translation key, or return a different value here directly.
return parent::getName();
}

public function getDescription()
{
// By default, the description will be automatically fetched from the TagManager_CustomHtmlTagDescription
// translation key. you can either adjust/create/remove this translation key, or return a different value
// here directly.
return parent::getDescription();
}

public function getHelp()
{
// By default, the help will be automatically fetched from the TagManager_CustomHtmlTagHelp translation key.
// you can either adjust/create/remove this translation key, or return a different value here directly.
return parent::getHelp();
}

public function getCategory()
{
return Piwik::translate('TagManager_ConsentManagement');
}

public function getIcon()
{
// You may optionally specify a path to an image icon URL, for example:
//
// return 'plugins/TagManager/images/MyIcon.png';
//
// to not return default icon call:
// return parent::getIcon();
//
// The image should have ideally a resolution of about 64x64 pixels.
return 'plugins/TagManager/images/icons/google-consent-mode.svg';
}

public function getParameters()
{
$default = [
['consent_type' => 'ad_storage', 'consent_state' => 'granted'],
['consent_type' => 'ad_user_data', 'consent_state' => 'granted'],
['consent_type' => 'ad_personalization', 'consent_state' => 'granted'],
['consent_type' => 'analytics_storage', 'consent_state' => 'granted'],
['consent_type' => 'functionality_storage', 'consent_state' => 'granted'],
['consent_type' => 'personalization_storage', 'consent_state' => 'granted'],
['consent_type' => 'security_storage', 'consent_state' => 'granted'],
];

return array(
$this->makeSetting('consentAction', 'update', FieldConfig::TYPE_ARRAY, function (FieldConfig $field) {
$field->title = Piwik::translate('TagManager_GoogleConsentModeV2TagConsentActionTitle');
$field->description = Piwik::translate('TagManager_GoogleConsentModeV2TagConsentActionDescription');
$field->uiControl = FieldConfig::UI_CONTROL_SINGLE_SELECT;
$field->availableValues = array(
'default' => 'default',
'update' => 'update',
);
$field->validators[] = new NotEmpty();
}),

$this->makeSetting('consentTypes', $default, FieldConfig::TYPE_ARRAY, function (FieldConfig $field) {
$field->uiControl = FieldConfig::UI_CONTROL_MULTI_TUPLE;
$field->title = Piwik::translate('TagManager_GoogleConsentModeV2TagConsentTypesTitle');
$faqURL = Url::addCampaignParametersToMatomoLink('https://matomo.org/faq/tag-manager/google-consent-tag-in-matomo-tag-manager/', null, null, 'Tag.TagManager.GoogleConsentMode');
$field->inlineHelp = Piwik::translate('TagManager_GoogleConsentModeV2TagConsentTypesDescription', ['<a href="' . $faqURL . '" target="_blank" rel="noreferrer noopener">', '</a>']);

$field1 = new FieldConfig\MultiPair(Piwik::translate('TagManager_GoogleConsentModeV2TagConsentTypeTitle'), 'consent_type', FieldConfig::UI_CONTROL_TEXT);
$field1->customFieldComponent = self::FIELD_VARIABLE_COMPONENT;

$field2 = new FieldConfig\MultiPair(Piwik::translate('TagManager_GoogleConsentModeV2TagConsentStateTitle'), 'consent_state', FieldConfig::UI_CONTROL_TEXT);
$field2->customFieldComponent = self::FIELD_VARIABLE_COMPONENT;

$field->uiControlAttributes['field1'] = $field1->toArray();
$field->uiControlAttributes['field2'] = $field2->toArray();
}),
);
}
}
23 changes: 23 additions & 0 deletions Template/Tag/GoogleConsentModeV2Tag.web.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(function () {
return function (parameters, TagManager) {
this.fire = function () {

var consentAction = parameters.get("consentAction")[0];
var consentTypes = parameters.get("consentTypes");

var typesObject = {};
consentTypes.forEach(function (type) {
if (type.consent_type && type.consent_state) {
typesObject[type.consent_type] = type.consent_state;
}
});

window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag("consent", consentAction, typesObject);

};
};
})();
2 changes: 1 addition & 1 deletion Template/Tag/OneTrustTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function getDescription()

public function getCategory()
{
return Piwik::translate('TagManager_ConsentManagementPlatform');
return Piwik::translate('TagManager_ConsentManagement');
}

public function getIcon()
Expand Down
10 changes: 10 additions & 0 deletions images/icons/google-consent-mode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,7 @@
"GoogleTagTagIdTitle": "Tag ID",
"GoogleTagTagIdDescription": "A tag ID is an identifier that you put on your page to load a given Google tag. %1$sLearn more.%2$s",
"ConsentManagementPlatform": "Consent Management Platform",
"ConsentManagement": "Consent Management",
"CookiebotTagName": "Cookiebot",
"CookiebotTagDescription": "Cookiebot CMP makes the use of cookies and online tracking of your website GDPR compliant.",
"CookiebotTagHelp": "",
Expand Down Expand Up @@ -1167,6 +1168,14 @@
"MatomoConfigurationMatomoSetCountPreRenderedDescription": "If enabled, it will count sites in pre-rendered state.",
"MatomoConfigurationMatomoSetRequestQueueIntervalTitle": "Set Request Queue Interval",
"MatomoConfigurationMatomoSetRequestQueueIntervalDescription": "Defines after how many ms a queued requests will be executed after the request was queued initially. The higher the value the more tracking requests can be sent together at once. interval has to be at least 1000 (1000ms = 1s) and defaults to 2.5 seconds.",
"ErrorDeleteReferencedVariable": "This variable is in use elsewhere and cannot be deleted. Please remove all references to it and try again."
"ErrorDeleteReferencedVariable": "This variable is in use elsewhere and cannot be deleted. Please remove all references to it and try again.",
"GoogleConsentModeV2TagName": "Google Consent Mode",
"GoogleConsentModeV2TagDescription": "Consent mode v2 allows you to communicate to Google the consent status of your users regarding cookies or application IDs.",
"GoogleConsentModeV2TagConsentActionTitle": "Consent mode action",
"GoogleConsentModeV2TagConsentActionDescription": "Select 'default' to set default values, and 'update' to handle users consent.",
"GoogleConsentModeV2TagConsentTypesTitle": "Consent type",
"GoogleConsentModeV2TagConsentTypesDescription": "The consent state must be 'denied' before the user gives consent. Once consent is received, you can trigger this tag with the action mode set to 'update' and all consents state set to 'granted' for all consent types. (All consent types are available in the Google documentation). Consent state must be 'denied' or 'granted', no other values are allowed. %1$sLearn more%2$s.",
"GoogleConsentModeV2TagConsentTypeTitle": "Consent type",
"GoogleConsentModeV2TagConsentStateTitle": "Consent state"
}
}
4 changes: 4 additions & 0 deletions stylesheets/manageEdit.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
width: ~"calc(100% - 60px)";
}

.fieldUiControl:has(input[id^='consentTypes-p1-']) {
width: 300px !important;
}

.innerFormField input, select{
width: 100%;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1477,13 +1477,13 @@
</types>
</row>
<row>
<name>Consent Management Platform</name>
<name>Consent Management</name>
<types>
<row>
<id>Axeptio</id>
<name>Axeptio</name>
<description>Axeptio is a low-code Consent Management Platform.</description>
<category>Consent Management Platform</category>
<category>Consent Management</category>
<icon>plugins/TagManager/images/icons/axeptio.svg</icon>
<help />
<order>9999</order>
Expand Down Expand Up @@ -1519,7 +1519,7 @@
<id>CookieYes</id>
<name>CookieYes</name>
<description>CookieYes is a cookie consent solution that helps your website achieve GDPR and CCPA compliance.</description>
<category>Consent Management Platform</category>
<category>Consent Management</category>
<icon>plugins/TagManager/images/icons/cookieyes.svg</icon>
<help />
<order>9999</order>
Expand Down Expand Up @@ -1555,7 +1555,7 @@
<id>Cookiebot</id>
<name>Cookiebot</name>
<description>Cookiebot CMP makes the use of cookies and online tracking of your website GDPR compliant.</description>
<category>Consent Management Platform</category>
<category>Consent Management</category>
<icon>plugins/TagManager/images/icons/cookiebot.svg</icon>
<help />
<order>9999</order>
Expand Down Expand Up @@ -1587,11 +1587,140 @@
</row>
</parameters>
</row>
<row>
<id>GoogleConsentModeV2</id>
<name>Google Consent Mode</name>
<description>Consent mode v2 allows you to communicate to Google the consent status of your users regarding cookies or application IDs.</description>
<category>Consent Management</category>
<icon>plugins/TagManager/images/icons/google-consent-mode.svg</icon>
<help />
<order>9999</order>
<contexts>
<row>web</row>
</contexts>
<hasAdvancedSettings>1</hasAdvancedSettings>
<isCustomTemplate>0</isCustomTemplate>
<parameters>
<row>
<name>consentAction</name>
<title>Consent mode action</title>
<value>update</value>
<defaultValue>update</defaultValue>
<type>array</type>
<uiControl>select</uiControl>
<uiControlAttributes>
</uiControlAttributes>
<availableValues>
<default>default</default>
<update>update</update>
</availableValues>
<description>Select 'default' to set default values, and 'update' to handle users consent.</description>
<inlineHelp />
<introduction />
<condition />
<fullWidth>0</fullWidth>
</row>
<row>
<name>consentTypes</name>
<title>Consent type</title>
<value>
<row>
<consent_type>ad_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>ad_user_data</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>ad_personalization</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>analytics_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>functionality_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>personalization_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>security_storage</consent_type>
<consent_state>granted</consent_state>
</row>
</value>
<defaultValue>
<row>
<consent_type>ad_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>ad_user_data</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>ad_personalization</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>analytics_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>functionality_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>personalization_storage</consent_type>
<consent_state>granted</consent_state>
</row>
<row>
<consent_type>security_storage</consent_type>
<consent_state>granted</consent_state>
</row>
</defaultValue>
<type>array</type>
<uiControl>multituple</uiControl>
<uiControlAttributes>
<field1>
<key>consent_type</key>
<title>Consent type</title>
<uiControl>text</uiControl>
<component>
<plugin>TagManager</plugin>
<name>FieldVariableTemplate</name>
</component>
<availableValues />
</field1>
<field2>
<key>consent_state</key>
<title>Consent state</title>
<uiControl>text</uiControl>
<component>
<plugin>TagManager</plugin>
<name>FieldVariableTemplate</name>
</component>
<availableValues />
</field2>
</uiControlAttributes>
<availableValues />
<description />
<inlineHelp>The consent state must be 'denied' before the user gives consent. Once consent is received, you can trigger this tag with the action mode set to 'update' and all consents state set to 'granted' for all consent types. (All consent types are available in the Google documentation). Consent state must be 'denied' or 'granted', no other values are allowed. &lt;a href="https://matomo.org/faq/tag-manager/google-consent-tag-in-matomo-tag-manager/?mtm_campaign=Matomo_App&amp;mtm_source=Matomo_App_OnPremise&amp;mtm_medium=Tag.TagManager.GoogleConsentMode" target="_blank" rel="noreferrer noopener"&gt;Learn more&lt;/a&gt;.</inlineHelp>
<introduction />
<condition />
<fullWidth>0</fullWidth>
</row>
</parameters>
</row>
<row>
<id>OneTrust</id>
<name>OneTrust</name>
<description>The OneTrust Consent Management Platform orchestrates the collection of consent across web, mobile, and CTV.</description>
<category>Consent Management Platform</category>
<category>Consent Management</category>
<icon>plugins/TagManager/images/icons/one-trust.svg</icon>
<help />
<order>9999</order>
Expand Down
4 changes: 2 additions & 2 deletions tests/UI/expected-screenshots/ContainerTag_create_new.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading