Compare commits

..

5 Commits

Author SHA1 Message Date
a18bcd35c4 [Changed] condition to trigger event-firing 2024-10-25 20:06:29 +02:00
2ec373c95f [Bump] Metadata && Changelog 2024-09-21 16:23:06 +02:00
6fcb9f8b84 [Changed] add "internal_names" to constant 2024-09-21 16:20:48 +02:00
53b3c878ce [Fixed] Consentmanager doesn't get delivered
false value given for important decision-making. Since the value was false, we got "false" as return for D3blShowGtmScript() which made consentmanager not send the data to GTM
2024-09-21 16:08:08 +02:00
65b618e25c [Removed] unnecessary "none" entry for CMP-choosability 2024-09-21 16:06:32 +02:00
9 changed files with 184 additions and 65 deletions

View File

@ -7,19 +7,25 @@ use D3\GoogleAnalytics4\Application\Model\CMP\Usercentrics;
class ManagerTypes class ManagerTypes
{ {
const EXTERNAL_SERVICE = "eigener Service"; const EXTERNAL_SERVICE = "eigener Service";
const INTERNAL_EXTERNAL_SERVICE = "externalService";
const NET_COOKIE_MANAGER = "Netensio Cookie Manager"; const NET_COOKIE_MANAGER = "Netensio Cookie Manager";
const INTERNAL_NET_COOKIE_MANAGER = "net_cookie_manager";
/** /**
* Further information's: * Further information's:
* https://github.com/aggrosoft/oxid-cookie-compliance * https://github.com/aggrosoft/oxid-cookie-compliance
*/ */
const AGCOOKIECOMPLIANCE = "Aggrosoft Cookie Compliance"; const AGCOOKIECOMPLIANCE = "Aggrosoft Cookie Compliance";
const INTERNAL_AGCOOKIECOMPLIANCE = "agcookiecompliance";
const CONSENTMANAGER = "Consentmanager"; const CONSENTMANAGER = "Consentmanager";
const INTERNAL_CONSENTMANAGER = "cmconsentmanager";
const COOKIEFIRST = "Cookiefirst"; const COOKIEFIRST = "Cookiefirst";
const INTERNAL_COOKIEFIRST = "cookiefirst";
const COOKIEBOT = "Cookiebot"; const COOKIEBOT = "Cookiebot";
const INTERNAL_COOKIEBOT = "cookiebot";
/** /**
* @return array * @return array
@ -27,14 +33,14 @@ class ManagerTypes
public function getManagerList(): array public function getManagerList(): array
{ {
return [ return [
"externalService" => self::EXTERNAL_SERVICE, self::INTERNAL_EXTERNAL_SERVICE => self::EXTERNAL_SERVICE,
"agcookiecompliance" => self::AGCOOKIECOMPLIANCE, self::INTERNAL_AGCOOKIECOMPLIANCE => self::AGCOOKIECOMPLIANCE,
"net_cookie_manager" => self::NET_COOKIE_MANAGER, self::INTERNAL_NET_COOKIE_MANAGER => self::NET_COOKIE_MANAGER,
Usercentrics::sModuleIncludationInternalName => Usercentrics::sModuleIncludationPublicName, Usercentrics::sModuleIncludationInternalName => Usercentrics::sModuleIncludationPublicName,
Usercentrics::sExternalIncludationInternalName => Usercentrics::sExternalIncludationPublicName, Usercentrics::sExternalIncludationInternalName => Usercentrics::sExternalIncludationPublicName,
"cmconsentmanager" => self::CONSENTMANAGER, self::INTERNAL_CONSENTMANAGER => self::CONSENTMANAGER,
"cookiefirst" => self::COOKIEFIRST, self::INTERNAL_COOKIEFIRST => self::COOKIEFIRST,
"cookiebot" => self::COOKIEBOT, self::INTERNAL_COOKIEBOT => self::COOKIEBOT,
]; ];
} }
@ -46,4 +52,21 @@ class ManagerTypes
{ {
return in_array($sManager, array_keys($this->getManagerList()), true); return in_array($sManager, array_keys($this->getManagerList()), true);
} }
/**
* @return array
*
* the CMP from this method always needs the script tag delivered to the dom.
*/
public function scriptTagDeliveredByDefaultArray() :array
{
return [
Usercentrics::sModuleIncludationInternalName,
Usercentrics::sExternalIncludationInternalName,
ManagerTypes::INTERNAL_CONSENTMANAGER,
ManagerTypes::INTERNAL_COOKIEFIRST,
ManagerTypes::INTERNAL_COOKIEBOT,
ManagerTypes::INTERNAL_EXTERNAL_SERVICE
];
}
} }

View File

@ -80,7 +80,6 @@
[{oxmultilang ident="D3CMP"}] [{oxmultilang ident="D3CMP"}]
</label> </label>
<select class="form-select w-50" name="editval[select][_HAS_STD_MANAGER]" aria-label="Default select example"> <select class="form-select w-50" name="editval[select][_HAS_STD_MANAGER]" aria-label="Default select example">
<option value="NONE" selected>[{oxmultilang ident="D3NONE"}]</option>
[{foreach from=$d3ManagerTypeArray key="sInternalName" item="sPublicName" name="editval[aCmpNameArray]"}] [{foreach from=$d3ManagerTypeArray key="sInternalName" item="sPublicName" name="editval[aCmpNameArray]"}]
<option value="[{$sInternalName}]" [{if $sInternalName === $d3CurrentCMP}]SELECTED[{/if}]>[{$sPublicName}]</option> <option value="[{$sInternalName}]" [{if $sInternalName === $d3CurrentCMP}]SELECTED[{/if}]>[{$sPublicName}]</option>
[{/foreach}] [{/foreach}]

View File

@ -1,3 +1,3 @@
[{$smarty.block.parent}] [{$smarty.block.parent}]
[{include file="event/purchase.tpl"}] [{include file="event/purchase.tpl"}]

View File

@ -1,5 +1,5 @@
[{if $d3CmpBasket && $d3CmpBasket->getAddToBasketDecision() && $d3CmpBasket->d3GtmRequestedArticleLoadedByAnid() !== null}] [{if $d3CmpBasket && $d3CmpBasket->d3GtmRequestedArticleLoadedByAnid() !== null}]
[{assign var="oGtmProduct" value=$d3CmpBasket->d3GtmRequestedArticleLoadedByAnid()}] [{assign var="oGtmProduct" value=$d3CmpBasket->d3GtmRequestedArticleLoadedByAnid()}]
[{assign var="oGtmAmountArticlesAdded" value=$d3CmpBasket->getD3GtmAddToCartAmountArticles()}] [{assign var="oGtmAmountArticlesAdded" value=$d3CmpBasket->getD3GtmAddToCartAmountArticles()}]
[{*$smarty.block.parent*}] [{*$smarty.block.parent*}]
@ -12,50 +12,50 @@
[{block name="d3_ga4_add_to_cart_list_block"}] [{block name="d3_ga4_add_to_cart_list_block"}]
[{capture name="d3_ga4_add_to_cart_listtpl"}] [{capture name="d3_ga4_add_to_cart_listtpl"}]
[{strip}] [{strip}]
dataLayer.push({"event": null, "eventLabel": null, "ecommerce": null}); /* Clear the previous ecommerce object. */
[{*** Debug cases ***}] $(document).ready(function() {
[{*event.preventDefault();*}] $('#toBasket').on('click', function() {
dataLayer.push({"event": null, "eventLabel": null, "ecommerce": null}); /* Clear the previous ecommerce object. */
let iArtQuantity = $("[{$htmlIdAmountOfArticles}]").val(); [{*** Debug cases ***}]
let iArtQuantityAdded = [{$oGtmAmountArticlesAdded}]; [{*event.preventDefault();*}]
if(!iArtQuantity && (iArtQuantityAdded === 1)){ let iArtQuantity = $("[{$htmlIdAmountOfArticles}]").val();
iArtQuantity = 1; let iPriceValue = [{$d3PriceObject->getPrice()}];
}else{ let iSumPrice = iArtQuantity*iPriceValue;
iArtQuantity = iArtQuantityAdded;
}
dataLayer.push({ dataLayer.push({
'isAddToBasket': true, 'isAddToBasket': true,
'event':'add_to_cart', 'event':'add_to_cart',
'eventLabel': 'add_to_cart', 'eventLabel': 'add_to_cart',
'ecommerce': { 'ecommerce': {
'currency': "[{$currency->name}]", 'currency': "[{$currency->name}]",
'value': iArtQuantity*[{$d3PriceObject->getPrice()}], 'value': parseInt(iSumPrice.toFixed(2)),
'items': [ 'items': [
{ {
'item_id': '[{$oGtmProduct->getFieldData('oxartnum')}]', 'item_id': '[{$oGtmProduct->getFieldData('oxartnum')}]',
'item_name': '[{$oGtmProduct->getFieldData('oxtitle')}]', 'item_name': '[{$oGtmProduct->getFieldData('oxtitle')}]',
'price': [{$d3PriceObject->getPrice()}], 'price': [{$d3PriceObject->getPrice()}],
'item_brand': '[{if $gtmManufacturer}][{$gtmManufacturer->oxmanufacturers__oxtitle->value}][{/if}]', 'item_brand': '[{if $gtmManufacturer}][{$gtmManufacturer->oxmanufacturers__oxtitle->value}][{/if}]',
'item_variant': '[{if $oGtmProduct->getFieldData('oxvarselect')}][{$oGtmProduct->getFieldData('oxvarselect')}][{/if}]', 'item_variant': '[{if $oGtmProduct->getFieldData('oxvarselect')}][{$oGtmProduct->getFieldData('oxvarselect')}][{/if}]',
[{if $gtmCategory}] [{if $gtmCategory}]
'item_category': '[{$gtmCategory->getSplitCategoryArray(0, true)}]', 'item_category': '[{$gtmCategory->getSplitCategoryArray(0, true)}]',
'item_category_2':'[{$gtmCategory->getSplitCategoryArray(1, true)}]', 'item_category_2':'[{$gtmCategory->getSplitCategoryArray(1, true)}]',
'item_category_3':'[{$gtmCategory->getSplitCategoryArray(2, true)}]', 'item_category_3':'[{$gtmCategory->getSplitCategoryArray(2, true)}]',
'item_category_4':'[{$gtmCategory->getSplitCategoryArray(3, true)}]', 'item_category_4':'[{$gtmCategory->getSplitCategoryArray(3, true)}]',
'item_list_name':'[{$gtmCategory->getSplitCategoryArray()}]', 'item_list_name':'[{$gtmCategory->getSplitCategoryArray()}]',
[{/if}] [{/if}]
'quantity': iArtQuantity 'quantity': iArtQuantity
} }
] ]
}[{if $oViewConf->isDebugModeOn()}], }[{if $oViewConf->isDebugModeOn()}],
'debug_mode': 'true' 'debug_mode': 'true'
[{/if}] [{/if}]
});
});
}); });
[{/strip}] [{/strip}]
[{/capture}] [{/capture}]
[{oxscript add=$smarty.capture.d3_ga4_add_to_cart_listtpl}] [{oxscript add=$smarty.capture.d3_ga4_add_to_cart_listtpl}]
[{/block}] [{/block}]
[{/if}] [{/if}]

View File

@ -0,0 +1,48 @@
[{$smarty.block.parent}]
[{block name="d3_ga4_remove_from_cart_block"}]
[{if $hasBeenReloaded}]
[{assign var="d3BasketPrice" value=$oxcmp_basket->getPrice()}]
[{capture assign=d3_ga4_remove_from_cart}]
[{strip}]
dataLayer.push({"event": null, "eventLabel": null, "ecommerce": null}); /* Clear the previous ecommerce object. */
dataLayer.push({
'isRemoveFromCart': true,
'event': 'remove_from_cart',
'eventLabel':'remove_from_cart',
'ecommerce': {
'actionField': "step: 1",
'currency': "[{$currency->name}]",
'value': [{$d3BasketPrice->getPrice()}],
'coupon': '[{foreach from=$oxcmp_basket->getVouchers() item=sVoucher key=key name=Voucher}][{$sVoucher->sVoucherNr}][{if !$smarty.foreach.Voucher.last}], [{/if}][{/foreach}]',
'items': [
[{foreach from=$toRemoveArticles->getArray() name=gtmRemovedItems item=rmItem key=rmItemindex}]
[{assign var="d3oItemPrice" value=$rmItem->getPrice()}]
[{assign var="gtmBasketItemCategory" value=$rmItem->getCategory()}]
{
'item_id': '[{$rmItem->getFieldData('oxartnum')}]',
'item_name': '[{$rmItem->getFieldData('oxtitle')}]',
'item_variant': '[{$rmItem->getFieldData('oxvarselect')}]',
[{if $gtmBasketItemCategory}]
'item_category': '[{$gtmBasketItemCategory->getSplitCategoryArray(0)}]',
'item_category_2': '[{$gtmBasketItemCategory->getSplitCategoryArray(1)}]',
'item_category_3': '[{$gtmBasketItemCategory->getSplitCategoryArray(2)}]',
'item_category_4': '[{$gtmBasketItemCategory->getSplitCategoryArray(3)}]',
'item_list_name': '[{$gtmBasketItemCategory->getSplitCategoryArray()}]',
[{/if}]
'price': [{$d3oItemPrice->getPrice()}],
'coupon': '[{foreach from=$oxcmp_basket->getVouchers() item=sVoucher key=key name=Voucher}][{$sVoucher->sVoucherNr}][{if !$smarty.foreach.Voucher.last}], [{/if}][{/foreach}]',
'quantity': '[{$rmItem->getFieldData('d3AmountThatGotRemoved')}]',
'position': [{$smarty.foreach.gtmRemovedItems.index}]
}[{if !$smarty.foreach.gtmRemovedItems.last}],[{/if}]
[{/foreach}]
]
}[{if $oViewConf->isDebugModeOn()}],
'debug_mode': 'true'
[{/if}]
});
[{/strip}]
[{/capture}]
[{oxscript add=$d3_ga4_remove_from_cart}]
[{/if}]
[{/block}]

View File

@ -0,0 +1,44 @@
[{$smarty.block.parent}]
[{assign var="gtmProducts" value=$oView->getArticleList()}]
[{block name="d3_ga4_view_search_result_block"}]
[{if $gtmProducts}]
[{capture assign=d3_ga4_view_search_result}]
[{strip}]
dataLayer.push({"event": null, "eventLabel": null, "ecommerce": null}); /* Clear the previous ecommerce object. */
dataLayer.push({
'event': 'view_search_result',
'eventLabel':'view_search_result[{if $oViewConf->isDebugModeOn()}]_test[{/if}]',
'ecommerce': {
'search_term': '[{$searchparamforhtml}]',
'items': [
[{foreach from=$gtmProducts name="gtmProducts" item="gtmProduct"}]
[{assign var="d3PriceObject" value=$gtmProduct->getPrice()}]
[{assign var="gtmManufacturer" value=$gtmProduct->getManufacturer()}]
[{assign var="gtmCategory" value=$gtmProduct->getCategory()}]
{
'item_id': '[{$gtmProduct->getFieldData("oxartnum")}]',
'item_name': '[{$gtmProduct->getFieldData("oxtitle")}]',
'price': [{$d3PriceObject->getPrice()}],
'item_brand': '[{if $gtmManufacturer}][{$gtmManufacturer->oxmanufacturers__oxtitle->value}][{/if}]',
[{if $gtmCategory}]
'item_category': '[{$gtmCategory->getSplitCategoryArray(0)}]',
'item_category_2':'[{$gtmCategory->getSplitCategoryArray(1)}]',
'item_category_3':'[{$gtmCategory->getSplitCategoryArray(2)}]',
'item_category_4':'[{$gtmCategory->getSplitCategoryArray(3)}]',
'item_list_name':'[{$gtmCategory->getSplitCategoryArray()}]',
[{/if}]
'quantity': 1
}[{if !$smarty.foreach.gtmProducts.last}],[{/if}]
[{/foreach}]
]
}[{if $oViewConf->isDebugModeOn()}],
'debug_mode': 'true'
[{/if}]
});
[{/strip}]
[{/capture}]
[{oxscript add=$d3_ga4_view_search_result}]
[{/if}]
[{/block}]

View File

@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.17.2...rel_2.x) - 2024-x ## [unreleased](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.17.2...rel_2.x) - 2024-x
## [2.22.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.21.0...2.22.0) - 2024-09-21
### Fixed
- Consentmanager didn't get delivered
### Changed
- write "internal_names" of CMP to constants
## [2.21.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.20.1...2.21.0) - 2024-09-19 ## [2.21.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.20.1...2.21.0) - 2024-09-19
### Fixed ### Fixed
- missing parameters for widget.php call - missing parameters for widget.php call

View File

@ -17,9 +17,8 @@ use D3\GoogleAnalytics4\Application\Model\Constants;
use D3\GoogleAnalytics4\Application\Model\ManagerHandler; use D3\GoogleAnalytics4\Application\Model\ManagerHandler;
use D3\GoogleAnalytics4\Application\Model\ManagerTypes; use D3\GoogleAnalytics4\Application\Model\ManagerTypes;
use OxidEsales\Eshop\Application\Controller\FrontendController; use OxidEsales\Eshop\Application\Controller\FrontendController;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Core\Config; use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Application\Model\User;use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface;
use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerExceptionInterface;
@ -58,6 +57,7 @@ class ViewConfig extends ViewConfig_parent
$this->sCookieManagerType = $oManagerHandler->getCurrManager(); $this->sCookieManagerType = $oManagerHandler->getCurrManager();
} }
} }
/** /**
* @return bool * @return bool
*/ */
@ -88,7 +88,7 @@ class ViewConfig extends ViewConfig_parent
$sCookieID = trim($this->d3GetModuleConfigParam('_sControlParameter')); $sCookieID = trim($this->d3GetModuleConfigParam('_sControlParameter'));
// Netensio Cookie Manager // Netensio Cookie Manager
if ($this->sCookieManagerType === ManagerTypes::NET_COOKIE_MANAGER) { if ($this->sCookieManagerType === ManagerTypes::INTERNAL_NET_COOKIE_MANAGER) {
$oSession = Registry::getSession(); $oSession = Registry::getSession();
$aCookies = $oSession->getVariable("aCookieSel"); $aCookies = $oSession->getVariable("aCookieSel");
@ -96,26 +96,25 @@ class ViewConfig extends ViewConfig_parent
} }
// Aggrosoft Cookie Consent // Aggrosoft Cookie Consent
if ($this->sCookieManagerType === ManagerTypes::AGCOOKIECOMPLIANCE) { if ($this->sCookieManagerType === ManagerTypes::INTERNAL_AGCOOKIECOMPLIANCE) {
if (method_exists($this, "isCookieCategoryEnabled")) { if (method_exists($this, "isCookieCategoryEnabled")) {
return $this->isCookieCategoryEnabled($sCookieID); return $this->isCookieCategoryEnabled($sCookieID);
} }
} }
// UserCentrics or consentmanager
if ( if (
$this->sCookieManagerType === Usercentrics::sModuleIncludationInternalName in_array
or $this->sCookieManagerType === Usercentrics::sExternalIncludationInternalName (
or $this->sCookieManagerType === ManagerTypes::CONSENTMANAGER $this->sCookieManagerType,
or $this->sCookieManagerType === ManagerTypes::COOKIEFIRST (oxNew(ManagerTypes::class)->scriptTagDeliveredByDefaultArray())
or $this->sCookieManagerType === ManagerTypes::COOKIEBOT )
or $this->sCookieManagerType === ManagerTypes::EXTERNAL_SERVICE
) )
{ {
// Always needs the script-tags delivered to the DOM. // Always needs the script-tags delivered to the DOM.
return true; return true;
} }
// Cookie Manager not (yet) supported
return false; return false;
} }
@ -140,16 +139,16 @@ class ViewConfig extends ViewConfig_parent
return 'data-usercentrics="' . $sControlParameter . '" type="text/plain" async=""'; return 'data-usercentrics="' . $sControlParameter . '" type="text/plain" async=""';
} }
if ($this->sCookieManagerType === ManagerTypes::CONSENTMANAGER) if ($this->sCookieManagerType === ManagerTypes::INTERNAL_CONSENTMANAGER)
{ {
return 'type="text/plain" class="cmplazyload" data-cmp-vendor="'.$sControlParameter.'"'; return 'type="text/plain" class="cmplazyload" data-cmp-vendor="'.$sControlParameter.'"';
} }
if ($this->sCookieManagerType === ManagerTypes::COOKIEFIRST){ if ($this->sCookieManagerType === ManagerTypes::INTERNAL_COOKIEFIRST){
return 'type="text/plain" data-cookiefirst-category="' . $sControlParameter .'"'; return 'type="text/plain" data-cookiefirst-category="' . $sControlParameter .'"';
} }
if ($this->sCookieManagerType === ManagerTypes::COOKIEBOT){ if ($this->sCookieManagerType === ManagerTypes::INTERNAL_COOKIEBOT){
return 'type="text/plain" data-cookieconsent="' . $sControlParameter .'"'; return 'type="text/plain" data-cookieconsent="' . $sControlParameter .'"';
} }

View File

@ -52,7 +52,7 @@ $aModule = [
Die Entwicklung basiert auf einem Fork von Marat Bedoev - <a href='https://github.com/vanilla-thunder/oxid-module-gtm'>Github-Link</a> Die Entwicklung basiert auf einem Fork von Marat Bedoev - <a href='https://github.com/vanilla-thunder/oxid-module-gtm'>Github-Link</a>
", ",
'thumbnail' => 'thumbnail.png', 'thumbnail' => 'thumbnail.png',
'version' => '2.21.0', 'version' => '2.22.0',
'author' => 'Data Development (Inh.: Thomas Dartsch)', 'author' => 'Data Development (Inh.: Thomas Dartsch)',
'email' => 'support@shopmodule.com', 'email' => 'support@shopmodule.com',
'url' => 'https://www.oxidmodule.com/', 'url' => 'https://www.oxidmodule.com/',