diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..f0512a0 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,13 @@ +in(__DIR__) +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + '@PHP73Migration' => true, + '@PSR12' => true + ]) + ->setFinder($finder) +; \ No newline at end of file diff --git a/Application/Extend/.ide-helper.php b/Application/Extend/.ide-helper.php deleted file mode 100644 index 75eb3c4..0000000 --- a/Application/Extend/.ide-helper.php +++ /dev/null @@ -1,5 +0,0 @@ - .groupExp a.rc b {font-size:medium;color:#ff3600;} .groupExp dt .txt, .groupExp dt .select, - .groupExp dt .txtfield {width:250px !important; margin: 2px !important; padding: 1px 4px !important; border: 1px solid #ccc !important; } +.groupExp dt .txtfield {width:250px !important; margin: 2px !important; padding: 1px 4px !important; border: 1px solid #ccc !important; } .groupExp dt textarea.txtfield { min-height: 125px;} .groupExp dl { display:block !important;} input.confinput {position:fixed;top:20px;right:70px;background:#008B2D;padding:10px 25px;color:white;border:1px solid black;cursor:pointer;font-size:125%;} input.confinput:hover {outline:3px solid #ff3600;} '; $aLang = [ - 'charset' => 'UTF-8', - 'SHOP_MODULE_GROUP_vt_gtm_settings' => $style . 'Einstellungen', + 'charset' => 'UTF-8', 'SHOP_MODULE_vt_gtm_sContainerID' => 'Container ID', - 'SHOP_MODULE_vt_gtm_promotionlistids' => 'Promotion Produktlisten IDs
Weitere Infos zu dieser Einstellung: Modui-Wiki
', + 'SHOP_MODULE_GROUP_vt_gtm_settings' => 'Einstellungen', + 'SHOP_MODULE_vt_gtm_blGA4enab' => 'GA4 Aktivieren', + 'SHOP_MODULE_vt_gtm_blUAenabled' => 'UA Aktivieren', + 'SHOP_MODULE_vt_gtm_blEnableDebug' => 'Debug-Modus aktivieren', + + // for cookie manager settings + 'SHOP_MODULE_GROUP_vt_gtm_settings_cookiemanager' => 'Cookie Manager Einstellungen', + 'SHOP_MODULE_vt_gtm_settings_hasOwnCookieManager' => 'Eigenen Cookie Manager nutzen? + Hinweis (Fragezeichen) lesen!', + 'HELP_SHOP_MODULE_vt_gtm_settings_hasOwnCookieManager' => 'Stellen Sie sicher, dass Sie ein Modul installiert haben, + dass die Methode "blAcceptedCookie" implementiert.
Sollten Sie sich nicht sicher sein kontaktieren Sie Ihren + technischen Ansprechpartner.

+ + Wichtig! Das Aktivieren dieser Checkbox kann ohne dem nötigen technischen Wissen den Shop-Ablauf im Frontend stören!
+ Die Checkbox muss nicht aktiviert werden, sofern die Cookies beispielsweise direkt via Google Cookie-Banner integriert werden. + Bei Fragen kontaktieren Sie bitte auch hier einen entsprechenden technischen Ansprechpartner.', + 'SHOP_MODULE_vt_gtm_settings_cookieName' => 'Cookie-Name', ]; diff --git a/Application/views/blocks/_gtm_js.tpl b/Application/views/blocks/_gtm_js.tpl index 3539472..0f22c6f 100755 --- a/Application/views/blocks/_gtm_js.tpl +++ b/Application/views/blocks/_gtm_js.tpl @@ -1,25 +1,61 @@ -[{if $oViewConf->getGtmContainerId()}][{strip}] - - + + [{$oViewConf->triggerGA4events()}] + [{if $oViewConf->getTopActionClassName() === "alist" }] + [{* include file="ga4_view_item_list.tpl" gtmCategory=$oView->getActiveCategory() gtmProducts=$oView->getArticleList() listtype=$oView->getListType() *}] + [{elseif $oViewConf->getTopActionClassName() === "details" }] + [{* include file="ga4_view_item.tpl" gtmProduct=$oView->getProduct() *}] + [{elseif $oViewConf->getTopActionClassName() === "search" }] + [{elseif $oViewConf->getTopActionClassName() === "basket" }] + + [{/if}] + [{/strip}][{/if}] + [{else}] + + [{/if}] +[{else}] + [{if $oViewConf->getGtmContainerId()}][{strip}] + + [{$oViewConf->triggerGA4events()}] [{if $oViewConf->getTopActionClassName() === "alist" }] - [{* include file="ga4_view_item_list.tpl" gtmCategory=$oView->getActiveCategory() gtmProducts=$oView->getArticleList() listtype=$oView->getListType() *}] + [{* include file="ga4_view_item_list.tpl" gtmCategory=$oView->getActiveCategory() gtmProducts=$oView->getArticleList() listtype=$oView->getListType() *}] [{elseif $oViewConf->getTopActionClassName() === "details" }] - [{* include file="ga4_view_item.tpl" gtmProduct=$oView->getProduct() *}] + [{* include file="ga4_view_item.tpl" gtmProduct=$oView->getProduct() *}] [{elseif $oViewConf->getTopActionClassName() === "search" }] [{elseif $oViewConf->getTopActionClassName() === "basket" }] [{/if}] -[{/strip}][{/if}] + [{/strip}][{/if}] +[{/if}] + [{$smarty.block.parent}] diff --git a/Application/views/blocks/checkout_s1.tpl b/Application/views/blocks/checkout_s1.tpl index 26d293a..12cab6b 100644 --- a/Application/views/blocks/checkout_s1.tpl +++ b/Application/views/blocks/checkout_s1.tpl @@ -1,57 +1,31 @@ -[{strip}] - [{assign var='gtmCartArticles' value=$oView->getBasketArticles()}] - -[{/strip}] -[{$smarty.block.parent}] \ No newline at end of file +[{assign var='gtmCartArticles' value=$oView->getBasketArticles()}] +[{strip}][{capture assign=d3_ga4_view_cart}] + dataLayer.push({"event": null, "eventLabel": null, "ecommerce": null}); /* Clear the previous ecommerce object. */ + dataLayer.push({ + 'event': 'view_cart', + 'eventLabel':'Checkout Step 1', + 'ecommerce': { + 'actionField': "step: 1", + 'currency': "[{$currency->name}]", + 'value': [{$oxcmp_basket->getBruttoSum()}], + 'items': [ + [{foreach from=$oxcmp_basket->getContents() item=basketitem name=gtmCartContents key=basketindex}] + [{assign var='_price' value=$basketitem->getUnitPrice()}] + { + 'item_id': '[{$gtmCartArticles[$basketindex]->oxarticles__oxartnum->value}]', + 'item_name': '[{$gtmCartArticles[$basketindex]->oxarticles__oxtitle->value}]', + 'item_variant': '[{$gtmCartArticles[$basketindex]->oxarticles__oxvarselect->value}]', + 'price': [{$_price->getPrice()}], + 'quantity':[{$basketitem->getAmount()}], + 'position':[{$smarty.foreach.gtmCartContents.index}] + }[{if !$smarty.foreach.gtmCartContents.last}],[{/if}] + [{/foreach}] + ] + } + }); +[{/capture}][{/strip}] +[{oxscript add=$d3_ga4_view_cart}] \ No newline at end of file diff --git a/Application/views/blocks/checkout_s5.tpl b/Application/views/blocks/checkout_s5.tpl index 87c1e19..64a8713 100644 --- a/Application/views/blocks/checkout_s5.tpl +++ b/Application/views/blocks/checkout_s5.tpl @@ -1,3 +1,5 @@ +[{$smarty.block.parent}] + [{strip}] [{/strip}] -[{$smarty.block.parent}] diff --git a/Application/views/blocks/detail.tpl b/Application/views/blocks/detail.tpl index 072f5bf..bf4322a 100644 --- a/Application/views/blocks/detail.tpl +++ b/Application/views/blocks/detail.tpl @@ -2,26 +2,24 @@ [{assign var="gtmProduct" value=$oView->getProduct()}] [{assign var="gtmCategory" value=$gtmProduct->getCategory()}] [{assign var="gtmManufacturer" value=$gtmProduct->getManufacturer()}] -[{strip}][{/strip}] + \ No newline at end of file diff --git a/Application/views/ga4/add_to_cart.tpl b/Application/views/ga4/add_to_cart.tpl index a3d5e3a..37316b1 100644 --- a/Application/views/ga4/add_to_cart.tpl +++ b/Application/views/ga4/add_to_cart.tpl @@ -1,41 +1,58 @@ -[{strip}] - [{$gtmProduct|@var_dump}] - [{* variable $gtmProduct is passed from parent tempalte *}] - [{* - [{assign var="gtmCurrency" value=$oView->getActCurrency()}] - [{assign var="gtmManufacturer" value=$gtmProduct->getManufacturer()}] - [{assign var="gtmCategory" value=$gtmProduct->getCategory()}] - - *}] [{/strip}] \ No newline at end of file diff --git a/Application/views/ga4/purchase.tpl b/Application/views/ga4/purchase.tpl index e69de29..f4f1e29 100755 --- a/Application/views/ga4/purchase.tpl +++ b/Application/views/ga4/purchase.tpl @@ -0,0 +1,36 @@ +[{strip}] + +[{/strip}] \ No newline at end of file diff --git a/Application/views/ga4/search.tpl b/Application/views/ga4/search.tpl index e69de29..d71f6ea 100755 --- a/Application/views/ga4/search.tpl +++ b/Application/views/ga4/search.tpl @@ -0,0 +1,32 @@ +[{$smarty.block.parent}] + +[{assign var="gtmProducts" value=$oView->getArticleList()}] + +[{if $gtmProducts|@count}] + [{strip}] + + [{/strip}] +[{/if}] \ No newline at end of file diff --git a/Application/views/ga4/view_item_list.tpl b/Application/views/ga4/view_item_list.tpl index 13d9ce6..2479eec 100644 --- a/Application/views/ga4/view_item_list.tpl +++ b/Application/views/ga4/view_item_list.tpl @@ -1,12 +1,18 @@ +[{assign var="gtmProducts" value=$products}] + +[{assign var="breadCrumb" value=''}] + [{if $gtmProducts|@count}] [{strip}] [{/strip}] [{/if}] \ No newline at end of file diff --git a/Application/views/ua/impression.tpl b/Application/views/ua/impression.tpl deleted file mode 100644 index 09dcacc..0000000 --- a/Application/views/ua/impression.tpl +++ /dev/null @@ -1,29 +0,0 @@ -[{strip}] - [{assign var="gtmCategory" value=$gtmProduct->getCategory()}] - [{assign var="gtmManufacturer" value=$gtmProduct->getManufacturer()}] - -[{/strip}] diff --git a/Application/views/ua/s1_cart.tpl b/Application/views/ua/s1_cart.tpl deleted file mode 100644 index d590b9f..0000000 --- a/Application/views/ua/s1_cart.tpl +++ /dev/null @@ -1,62 +0,0 @@ -[{strip}] - [{assign var="gtmCartArticles" value=$oView->getBasketArticles()}] - -[{/strip}] -[{$smarty.block.parent}] \ No newline at end of file diff --git a/Application/views/ua/s2_user.tpl b/Application/views/ua/s2_user.tpl deleted file mode 100644 index 989f980..0000000 --- a/Application/views/ua/s2_user.tpl +++ /dev/null @@ -1,13 +0,0 @@ - -[{$smarty.block.parent}] \ No newline at end of file diff --git a/Application/views/ua/s3_payment.tpl b/Application/views/ua/s3_payment.tpl deleted file mode 100644 index 6a36e93..0000000 --- a/Application/views/ua/s3_payment.tpl +++ /dev/null @@ -1,8 +0,0 @@ - -[{$smarty.block.parent}] \ No newline at end of file diff --git a/Application/views/ua/s4_order.tpl b/Application/views/ua/s4_order.tpl deleted file mode 100644 index d1c3222..0000000 --- a/Application/views/ua/s4_order.tpl +++ /dev/null @@ -1,8 +0,0 @@ - -[{$smarty.block.parent}] \ No newline at end of file diff --git a/Application/views/ua/s5_thankyou.tpl b/Application/views/ua/s5_thankyou.tpl deleted file mode 100644 index 2523682..0000000 --- a/Application/views/ua/s5_thankyou.tpl +++ /dev/null @@ -1,44 +0,0 @@ - -[{$smarty.block.parent}] diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9ff37b2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased](https://git.d3data.de/D3Public/MyModule/compare/1.1.0.0...rel_1.x) + +## [1.1.0.0](https://git.d3data.de/D3Public/MyModule/compare/1.0.0.0...1.1.0.0) - 2022-07-26 +### Added +- another feature + +### Changed +- changed old code + +### Deprecated +- ... + +### Removed +- ... + +### Fixed +- ... + +### Security +- ... + +## [1.0.0.0](https://git.d3data.de/D3Public/MyModule/releases/tag/1.0.0.0) - 2022-07-25 +### Added +- implemented features \ No newline at end of file diff --git a/IntelliSenseHelper.php b/IntelliSenseHelper.php new file mode 100644 index 0000000..90f5882 --- /dev/null +++ b/IntelliSenseHelper.php @@ -0,0 +1,18 @@ + + * @link http://www.oxidmodule.com + */ + +namespace D3\GoogleAnalytics4\Modules\Core{ + class ViewConfig_parent extends \OxidEsales\Eshop\Core\ViewConfig{} +} \ No newline at end of file diff --git a/Application/Extend/ViewConfig.php b/Modules/Core/ViewConfig.php old mode 100755 new mode 100644 similarity index 83% rename from Application/Extend/ViewConfig.php rename to Modules/Core/ViewConfig.php index 15b2ecd..ca5cc37 --- a/Application/Extend/ViewConfig.php +++ b/Modules/Core/ViewConfig.php @@ -1,129 +1,123 @@ - - */ - -namespace VanillaThunder\GoogleTagManager\Application\Extend; - -use OxidEsales\Eshop\Application\Controller\FrontendController; -use OxidEsales\Eshop\Core\Registry; -use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; -use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface; - -class ViewConfig extends ViewConfig_parent -{ - - // Google Tag Manager Container ID - private $sContainerId = null; - - public function getGtmContainerId() - { - if ($this->sContainerId === null) - { - $this->sContainerId = ContainerFactory::getInstance() - ->getContainer() - ->get(ModuleSettingBridgeInterface::class) - ->get('vt_gtm_sContainerID', 'vt-gtm'); - } - return $this->sContainerId; - } - - private $blGA4enabled = null; - - public function isGA4enabled() - { - if ($this->blGA4enabled === null) - { - $this->sContainerId = ContainerFactory::getInstance() - ->getContainer() - ->get(ModuleSettingBridgeInterface::class) - ->get('vt_gtm_blEnableGA4', 'vt-gtm'); - } - - return $this->blGA4enabled; - } - - public function getGtmDataLayer() - { - if (!$this->getGtmContainerId()) return "[]"; - - $oConfig = Registry::getConfig(); - $oView = $oConfig->getTopActiveView(); - /** @var FrontendController $oShop */ - //$oShop = oxRegistry::getConfig()->getActiveShop(); /** @var oxShop $oShop */ - $oUser = $oConfig->getUser(); - - $cl = $this->getTopActionClassName(); - $aPageTypes = [ - "content" => "cms", - "details" => "product", - "alist" => "listing", - "search" => "listing", - "basket" => "checkout", - "user" => "checkout", - "payment" => "checkout", - "order" => "checkout", - "thankyou" => "checkout", - ]; - - $dataLayer = [ - 'page' => [ - 'type' => $aPageTypes[$cl] ?? "unknown", - 'title' => $oView->getTitle(), - 'cl' => $cl, - ], - 'userid' => ($oUser ? $oUser->getId() : false), - 'sessionid' => session_id() ?? false, - //'httpref' => $_SERVER["HTTP_REFERER"] ?? "unknown" - ]; - - return json_encode([$dataLayer], JSON_PRETTY_PRINT); - - unset($dataLayer["user"]["http"]); // das brauchen wir hier nicht - - - return json_encode([$dataLayer], JSON_PRETTY_PRINT); - /* - // --- Produktdaten --- - $transactionProducts = []; - foreach($oOrder->getOrderArticles() as $_prod ) $transactionProducts[] = [ - 'name' => '', // (erforderlich) Produktname String - 'sku' => '', // (erforderlich) Produkt-SKU String - 'category' => '', // (optional) Produktkategorie String - 'price' => '', // (erforderlich) Preis pro Einheit Numerischer Wert - 'quantity' => '' // (erforderlich) Anzahl der Artikel Numerischer Wert - ]; - - // --- Transaktionsdaten --- - - $dataLayer['transactionId'] = $oOrder->oxorder__oxordernr->value; // (erforderlich) Eindeutige Transaktionskennung String - $dataLayer['transactionAffiliation'] = $oShop->oxshops__oxname->value; // (optional) Partner oder Geschäft String - $dataLayer['transactionTotal'] = $oOrder->oxorder__oxtotalordersum->value; // (erforderlich) Gesamtwert der Transaktion Numerischer Wert - $dataLayer['transactionShipping'] = $oOrder->oxorder__oxdelcost->value; // (optional) Versandkosten für die Transaktion Numerischer Wert - $dataLayer['transactionTax'] = ''; // (optional) Steuerbetrag für die Transaktion Numerischer Wert - $dataLayer['transactionProducts'] = $transactionProducts; // (optional) Liste der bei der Transaktion erworbenen Artikel Array von Produktobjekten - */ - } - - public function triggerGA4events() - { - // general events - - } - - public function isPromotionList($listId) - { - $oConfig = Registry::getConfig(); - $aPromotionListIds = $oConfig->getConfigParam("") ?? ['bargainItems', 'newItems', 'topBox', 'alsoBought', 'accessories', 'cross']; - } + + */ + +namespace D3\GoogleAnalytics4\Modules\Core; + +use OxidEsales\Eshop\Application\Controller\FrontendController; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; +use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleSettingBridgeInterface; + +class ViewConfig extends ViewConfig_parent +{ + + // Google Tag Manager Container ID + private $sContainerId = null; + + public function getGtmContainerId() + { + if ($this->sContainerId === null) + { + $this->sContainerId = $this->getConfig()->getConfigParam('vt_gtm_sContainerID'); + } + return $this->sContainerId; + } + + private $blGA4enabled = null; + + public function isGA4enabled() + { + if ($this->blGA4enabled === null) + { + $this->sContainerId = $this->getConfig()->getConfigParam('vt_gtm_blEnableGA4'); + } + + return $this->blGA4enabled; + } + + public function getGtmDataLayer() + { + if (!$this->getGtmContainerId()) return "[]"; + + $oConfig = Registry::getConfig(); + $oView = $oConfig->getTopActiveView(); + /** @var FrontendController $oShop */ + //$oShop = oxRegistry::getConfig()->getActiveShop(); /** @var oxShop $oShop */ + $oUser = $oConfig->getUser(); + + $cl = $this->getTopActionClassName(); + $aPageTypes = [ + "content" => "cms", + "details" => "product", + "alist" => "listing", + "search" => "listing", + "basket" => "checkout", + "user" => "checkout", + "payment" => "checkout", + "order" => "checkout", + "thankyou" => "checkout", + ]; + + $dataLayer = [ + 'page' => [ + 'type' => $aPageTypes[$cl] ?? "unknown", + 'title' => $oView->getTitle(), + 'cl' => $cl, + ], + 'userid' => ($oUser ? $oUser->getId() : false), + 'sessionid' => session_id() ?? false, + //'httpref' => $_SERVER["HTTP_REFERER"] ?? "unknown" + ]; + + #return json_encode([$dataLayer], JSON_PRETTY_PRINT); + + unset($dataLayer["user"]["http"]); // das brauchen wir hier nicht + + + return json_encode([$dataLayer], JSON_PRETTY_PRINT); + /* + // --- Produktdaten --- + $transactionProducts = []; + foreach($oOrder->getOrderArticles() as $_prod ) $transactionProducts[] = [ + 'name' => '', // (erforderlich) Produktname String + 'sku' => '', // (erforderlich) Produkt-SKU String + 'category' => '', // (optional) Produktkategorie String + 'price' => '', // (erforderlich) Preis pro Einheit Numerischer Wert + 'quantity' => '' // (erforderlich) Anzahl der Artikel Numerischer Wert + ]; + + // --- Transaktionsdaten --- + + $dataLayer['transactionId'] = $oOrder->oxorder__oxordernr->value; // (erforderlich) Eindeutige Transaktionskennung String + $dataLayer['transactionAffiliation'] = $oShop->oxshops__oxname->value; // (optional) Partner oder Geschäft String + $dataLayer['transactionTotal'] = $oOrder->oxorder__oxtotalordersum->value; // (erforderlich) Gesamtwert der Transaktion Numerischer Wert + $dataLayer['transactionShipping'] = $oOrder->oxorder__oxdelcost->value; // (optional) Versandkosten für die Transaktion Numerischer Wert + $dataLayer['transactionTax'] = ''; // (optional) Steuerbetrag für die Transaktion Numerischer Wert + $dataLayer['transactionProducts'] = $transactionProducts; // (optional) Liste der bei der Transaktion erworbenen Artikel Array von Produktobjekten + */ + } + + public function triggerGA4events() + { + // general events + + } + + public function isPromotionList($listId) + { + $oConfig = Registry::getConfig(); + $aPromotionListIds = $oConfig->getConfigParam("") ?? ['bargainItems', 'newItems', 'topBox', 'alsoBought', 'accessories', 'cross']; + } } \ No newline at end of file diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 2508a71..b7a7ea6 --- a/README.md +++ b/README.md @@ -1,60 +1,96 @@ -# [vt] Google Tag Manager -Google Tag Manager integration for OXID eShop v6.2 und höher -module version 0.5.0 ( 2021-12-10 ) +[![deutsche Version](https://logos.oxidmodule.com/de2_xs.svg)](README.md) + +# ![D3 Logo](https://logos.oxidmodule.com/d3logo_24x24.svg) Google-Analytics 4 für OXID eShop + +Dieses Modul bietet die Möglichkeit in Ihrem OXID eShop (6.x) die neue 'Property' Google Analytics 4 (GA4) von Google +zu integrieren. +Hierfür stehen Ihnen verschiedene 'templates' zur verfügung, mit denen Sie bestimmte Events tracken können. +Beispiele dafür sind: view_item, add_to_basket, purchase, ... + +Weiterführende Informationen: https://developers.google.com/analytics/devguides/collection/ga4 + +## Inhaltsverzeichnis + +- [Installation](#installation) +- [Verwendung](#verwendung) +- [Changelog](#changelog) +- [Lizenz](#lizenz) ## Installation -* ``composer require vanilla-thunder/oxid-module-gtm --no-update`` -* Modul aktivieren und Moduleinstellungen konfigurieren -## Tag Manager konfigurieren: -+ https://support.google.com/tagmanager/answer/9442095 +Dieses Paket erfordert einen mit Composer installierten OXID eShop in einer in der [composer.json](composer.json) definierten Version. -## Google Analytics 4 Einrichtung +Bitte tragen Sie den folgenden Abschnitt in die `composer.json` Ihres Projektes ein: -## GA4 Events / Customizing -für alle implementierten GA4 Events existieren Templates unter `source/modules/GoogleTagManager/Application/views/ga4/`, dabei entspricht der Dateiname dem Eventnamen in GA4. -Die Einbindung dieser Event-Templates erfolgt über TPL-Blöcke unter `source/modules/GoogleTagManager/Application/views/blocks/`. +``` + "extra": { + "oxideshop": { + "blacklist-filter": [ + "*.md", + "composer.json", + ".php-cs-fixer.php", + "*.xml", + "*.neon" + ], + "target-directory": "d3/googleanalytics" + } +``` -## Universal Analytics Events - -**"EE-Trigger" für Ecomemrce-Tags (Beispiel für Google Tag Manager):** -+ Triggertyp: Benutzerdefiniertes Ereignis -+ Ereignisname: ``ee\..*`` -+ Übereinstimmung mit regulärem Ausdruck verwenden -+ Diesen Trigger auslösen bei: Alle benutzerdefinierten Ereignisse - -**"EE-Tag" für Google Analytics Enhanced Ecommerce:** -+ Tag-Typ: Google Analytics - Universal Analytics -+ Tracking-Typ: Ereignis -+ Aktion: {{Event}} -+ Label: {{Event Label}} -+ Trigger : EE-Trigger - -## Verfügbare Datalayer Variablen -Für die einfachste Übersicht der enthaltenen Daten empfehle ich den Vorschau-Modus vom Google Tag Manager. - -Bei jedem Seitenaufruf wird die Datenschicht mit einigen wenigen Infos erstellt, die man zum reinen Erfassen der Seitenaufrufe benötigt: - + **page.type** - Seitentyp: default / cms / product / listing / checkout (an google analytics angelehnt) - + **page.title** - Seitentitel (außer Startseite, sie hat keinen Titel. Danke OXID...) - + **page.cl** - OXID Controller Klasse (start, search, etc) - + **userid** - oxID vom Benutzer bzw `false` falls nicht eingeloggt - + **sessionid** - session iD - -Alle für Ecommerce Tracking releavanten Daten werden mit speziellen Ecommerce Events in die Datenschicht eingefügt. -Hier ist ein Beispiel für die Einrichtung von Enhanced Ecomemrce Tracking über Google Tag Manager: +Öffnen Sie eine Kommandozeile und navigieren Sie zum Stammverzeichnis des Shops (Elternverzeichnis von source und vendor). Führen Sie den folgenden Befehl aus. Passen Sie die Pfadangaben an Ihre Installationsumgebung an. +```bash +php composer require d3/google-analytics4:^1 +``` +Sofern nötig, bestätigen Sie bitte, dass Sie `package-name` erlauben, Code auszuführen. -### LICENSE AGREEMENT - [vt] google-tag-manager - Copyright (C) 2021 Marat Bedoev - info: info@mb-dev.pro oder so /** @todo: überarbeiten, wenn ich wieder nüchtern bin */ - - This program is free software; - you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; - either version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with this program; if not, see \ No newline at end of file +Aktivieren Sie das Modul im Shopadmin unter "Erweiterungen -> Module". + +## Verwendung + +Nach erfolgreicher Installation finden Sie in Ihrem Shop-Admin unter "Erweiterungen > Module" +den Eintrag 'Google Analytics 4'. +Aktivieren Sie dieses Modul, um die Funktionalitäten nutzen zu können. + +Navigieren Sie danach zum Reiter 'Einstell.'. +Tragen Sie die nötige sog. 'Container ID' ein. Diese sieht in etwa so aus: 'GTM-W34LLOP'. + +Aktivieren Sie GA4 selbst, indem Sie dieses direkt darunter anhaken. + +--- + +Sie nutzen einen eigenen, als Modul im Shop installierten, Cookie-manager? Dann tragen Sie in den Folgeeinstellungen +unter "Cookie Manager Einstellungen", die Cookie-ID des zugehörigen Cookies ein. Und aktivieren Sie diese Weiche, +indem Sie den Haken bei "Eigenen Cookie Manager nutzen?" setzen. + +## Changelog + +Siehe [CHANGELOG](CHANGELOG.md) für weitere Informationen. + +## Beitragen + +Wenn Sie einen Verbesserungsvorschlag haben, legen Sie einen Fork des Repositories an und erstellen Sie einen Pull Request. Alternativ können Sie einfach ein Issue erstellen. Fügen Sie das Projekt zu Ihren Favoriten hinzu. Vielen Dank. + +- Erstellen Sie einen Fork des Projekts +- Erstellen Sie einen Feature Branch (git checkout -b feature/AmazingFeature) +- Fügen Sie Ihre Änderungen hinzu (git commit -m 'Add some AmazingFeature') +- Übertragen Sie den Branch (git push origin feature/AmazingFeature) +- Öffnen Sie einen Pull Request + +## Lizenz +(Stand: 06.05.2021) + +Vertrieben unter der GPLv3 Lizenz. + +``` +Copyright (c) D3 Data Development (Inh. Thomas Dartsch) + +Diese Software wird unter der GNU GENERAL PUBLIC LICENSE Version 3 vertrieben. +``` + +Die vollständigen Copyright- und Lizenzinformationen entnehmen Sie bitte der [LICENSE](LICENSE.md)-Datei, die mit diesem Quellcode verteilt wurde. + +## weitere Lizenzen und Nutzungsbedingungen + +... \ No newline at end of file diff --git a/__README.md b/__README.md new file mode 100644 index 0000000..dadb102 --- /dev/null +++ b/__README.md @@ -0,0 +1,67 @@ +# [D3] Google Tag Manager +Google Tag Manager integration for OXID eShop v6.x + +## Installation +* ``composer require vanilla-thunder/oxid-module-gtm --no-update`` +* Modul aktivieren und Moduleinstellungen konfigurieren + +## Tag Manager konfigurieren: ++ https://support.google.com/tagmanager/answer/9442095 + +## Google Analytics 4 Einrichtung + +## GA4 Events / Customizing +für alle implementierten GA4 Events existieren Templates unter `source/modules/GoogleTagManager/Application/views/ga4/`, dabei entspricht der Dateiname dem Eventnamen in GA4. +Die Einbindung dieser Event-Templates erfolgt über TPL-Blöcke unter `source/modules/GoogleTagManager/Application/views/blocks/`. + +### aktuell zu beachtende Blöcke +- Suchergebnisse: search_results +- (muss hinzugefügt werden) aList: d3Ga4_view_item_list +- Detailseite: details_productmain_title +- add_to_basket-button: details_productmain_tobasket +- Warenkorb: checkout_basket_main +- Purchase | abgeschlossener Kauf: checkout_thankyou_main + +## Universal Analytics Events + +**"EE-Trigger" für Ecomemrce-Tags (Beispiel für Google Tag Manager):** ++ Triggertyp: Benutzerdefiniertes Ereignis ++ Ereignisname: ``ee\..*`` ++ Übereinstimmung mit regulärem Ausdruck verwenden ++ Diesen Trigger auslösen bei: Alle benutzerdefinierten Ereignisse + +**"EE-Tag" für Google Analytics Enhanced Ecommerce:** ++ Tag-Typ: Google Analytics - Universal Analytics ++ Tracking-Typ: Ereignis ++ Aktion: {{Event}} ++ Label: {{Event Label}} ++ Trigger : EE-Trigger + +## Verfügbare Datalayer Variablen +Für die einfachste Übersicht der enthaltenen Daten empfehle ich den Vorschau-Modus vom Google Tag Manager. + +Bei jedem Seitenaufruf wird die Datenschicht mit einigen wenigen Infos erstellt, die man zum reinen Erfassen der Seitenaufrufe benötigt: + + **page.type** - Seitentyp: default / cms / product / listing / checkout (an google analytics angelehnt) + + **page.title** - Seitentitel (außer Startseite, sie hat keinen Titel. Danke OXID...) + + **page.cl** - OXID Controller Klasse (start, search, etc) + + **userid** - oxID vom Benutzer bzw `false` falls nicht eingeloggt + + **sessionid** - session iD + +Alle für Ecommerce Tracking releavanten Daten werden mit speziellen Ecommerce Events in die Datenschicht eingefügt. +Hier ist ein Beispiel für die Einrichtung von Enhanced Ecomemrce Tracking über Google Tag Manager: + + + + +### LICENSE AGREEMENT + [vt] google-tag-manager + Copyright (C) 2021 Marat Bedoev + info: info@mb-dev.pro oder so /** @todo: überarbeiten, wenn ich wieder nüchtern bin */ + + This program is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; + either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program; if not, see \ No newline at end of file diff --git a/composer.json b/composer.json index d3a5ad8..42c6045 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,19 @@ { - "name": "vanilla-thunder/oxid-module-gtm", - "description": "Google Tag Manager with new Google Analytics 4 for OXID eShop v6.2+
more about GA4: Ecommerce (GA4) Developer Guide", + "name": "d3/google-analytics4", + "description": "Google Tag Manager with new Google Analytics 4 for OXID eShop v6", "type": "oxideshop-module", - "homepage": "https://github.com/vanilla-thunder/oxid-module-gtm", + "keywords": [ + "oxid", + "modules", + "eShop", + "d3", + "google", + "ga4", + "googleanalytics", + "gtm", + "configuration" + ], + "homepage": "https://www.d3data.de", "license": [ "GPL-3.0" ], @@ -10,21 +21,36 @@ { "name": "Marat Bedoev", "email": "hello@mb-dev.pro" + }, + { + "name": "D3 Data Development (Inh. Thomas Dartsch)", + "email": "info@shopmodule.com", + "homepage": "https://www.d3data.de" } ], + "support": { + "email": "support@shopmodule.com" + }, "extra": { "oxideshop": { - "target-directory": "vt/GoogleTagManager" + "blacklist-filter": [ + "*.md", + "composer.json", + ".php-cs-fixer.php", + "*.xml", + "*.neon" + ], + "target-directory": "d3/googleanalytics4" } }, "require": { "php": ">=7.1", - "oxid-esales/oxideshop-ce": "~v6.5", + "oxid-esales/oxideshop-ce": "v6.0 - 6.3", "google/apiclient":" ^2.0" }, "autoload": { "psr-4": { - "VanillaThunder\\": "../../../source/modules/vt" + "D3\\GoogleAnalytics4\\": "../../../source/modules/d3/googleanalytics4" } } } \ No newline at end of file diff --git a/metadata.php b/metadata.php index 8dee4b4..f0ce6d2 100755 --- a/metadata.php +++ b/metadata.php @@ -1,49 +1,50 @@ - **/ + + +use D3\GoogleAnalytics4\Modules\Core\ViewConfig; +use OxidEsales\Eshop\Core\ViewConfig as OEViewConfig; $sMetadataVersion = '2.1'; $aModule = [ - 'id' => 'vt-gtm', - 'title' => '[vt] Google Tag Manager', - 'description' => 'Google Tag Manager Integration for OXID eShop v6.2+', + 'id' => 'd3googleanalytics4', + 'title' => 'Google Analytics 4', + 'description' => "Dieses Modul bietet die Möglichkeit in Ihrem OXID eShop (6.x) die neue 'Property' + Google Analytics 4 (GA4) von Google zu integrieren.
+ Hierfür stehen Ihnen verschiedene 'templates' zur verfügung, + mit denen Sie bestimmte Events tracken können.
+ Beispiele dafür sind: view_item, add_to_basket, purchase, ...

+ Die Integration und Verbindung zu Google wird mithilfe des gtag (Google Tag Manager) realisiert.

+ Weiterführende Informationen: https://developers.google.com/analytics/devguides/collection/ga4
+
+ Die Entwicklung basiert auf einem Fork von Marat Bedoev - Github-Link + ", 'thumbnail' => 'thumbnail.png', - 'version' => '0.5.0 ( 2021-07-17 )', - 'author' => 'Marat Bedoev', - 'email' => openssl_decrypt("Az6pE7kPbtnTzjHlPhPCa4ktJLphZ/w9gKgo5vA//p4=", str_rot13("nrf-128-pop"), str_rot13("gvalzpr")), - 'url' => 'https://github.com/vanilla-thunder/oxid-module-gtm', + 'version' => '1.0.0.0', + 'author' => 'Data Development (Inh.: Thomas Dartsch)', + 'email' => 'support@shopmodule.com', + 'url' => 'https://www.oxidmodule.com/', 'extend' => [ - \OxidEsales\Eshop\Core\ViewConfig::class => VanillaThunder\GoogleTagManager\Application\Extend\ViewConfig::class + OEViewConfig::class => ViewConfig::class ], 'templates' => [ // GA4 events - 'ga4_add_payment_info.tpl' => 'vt/GoogleTagManager/Application/views/ga4/add_payment_info.tpl', - 'add_shipping_info.tpl' => 'vt/GoogleTagManager/Application/views/ga4/add_shipping_info.tpl', - 'ga4_add_to_cart.tpl' => 'vt/GoogleTagManager/Application/views/ga4/add_to_cart.tpl', - 'ga4_begin_checkout.tpl' => 'vt/GoogleTagManager/Application/views/ga4/begin_checkout.tpl', - 'ga4_generate_lead.tpl' => 'vt/GoogleTagManager/Application/views/ga4/generate_lead.tpl', - 'ga4_login.tpl' => 'vt/GoogleTagManager/Application/views/ga4/login.tpl', - 'ga4_purchase.tpl' => 'vt/GoogleTagManager/Application/views/ga4/purchase.tpl', - 'ga4_remove_from_cart.tpl' => 'vt/GoogleTagManager/Application/views/ga4/remove_from_cart.tpl', - 'ga4_search.tpl' => 'vt/GoogleTagManager/Application/views/ga4/search.tpl', - 'ga4_select_content.tpl' => 'vt/GoogleTagManager/Application/views/ga4/select_content.tpl', - 'ga4_select_item.tpl' => 'vt/GoogleTagManager/Application/views/ga4/select_item.tpl', - 'ga4_select_promotion.tpl' => 'vt/GoogleTagManager/Application/views/ga4/select_promotion.tpl', - 'ga4_sign_up.tpl' => 'vt/GoogleTagManager/Application/views/ga4/sign_up.tpl', - 'ga4_view_cart.tpl' => 'vt/GoogleTagManager/Application/views/ga4/view_cart.tpl', - 'ga4_view_item.tpl' => 'vt/GoogleTagManager/Application/views/ga4/view_item.tpl', - 'ga4_view_item_list.tpl' => 'vt/GoogleTagManager/Application/views/ga4/view_item_list.tpl', - 'ga4_view_promotion.tpl' => 'vt/GoogleTagManager/Application/views/ga4/view_promotion.tpl', + 'ga4_add_payment_info.tpl' => 'd3/googleanalytics4/Application/views/ga4/add_payment_info.tpl', + 'add_shipping_info.tpl' => 'd3/googleanalytics4/Application/views/ga4/add_shipping_info.tpl', + 'ga4_add_to_cart.tpl' => 'd3/googleanalytics4/Application/views/ga4/add_to_cart.tpl', + 'ga4_begin_checkout.tpl' => 'd3/googleanalytics4/Application/views/ga4/begin_checkout.tpl', + 'ga4_generate_lead.tpl' => 'd3/googleanalytics4/Application/views/ga4/generate_lead.tpl', + 'ga4_login.tpl' => 'd3/googleanalytics4/Application/views/ga4/login.tpl', + 'ga4_purchase.tpl' => 'd3/googleanalytics4/Application/views/ga4/purchase.tpl', + 'ga4_remove_from_cart.tpl' => 'd3/googleanalytics4/Application/views/ga4/remove_from_cart.tpl', + 'ga4_search.tpl' => 'd3/googleanalytics4/Application/views/ga4/search.tpl', + 'ga4_select_content.tpl' => 'd3/googleanalytics4/Application/views/ga4/select_content.tpl', + 'ga4_select_item.tpl' => 'd3/googleanalytics4/Application/views/ga4/select_item.tpl', + 'ga4_select_promotion.tpl' => 'd3/googleanalytics4/Application/views/ga4/select_promotion.tpl', + 'ga4_sign_up.tpl' => 'd3/googleanalytics4/Application/views/ga4/sign_up.tpl', + 'ga4_view_cart.tpl' => 'd3/googleanalytics4/Application/views/ga4/view_cart.tpl', + 'ga4_view_item.tpl' => 'd3/googleanalytics4/Application/views/ga4/view_item.tpl', + 'ga4_view_item_list.tpl' => 'd3/googleanalytics4/Application/views/ga4/view_item_list.tpl', + 'ga4_view_promotion.tpl' => 'd3/googleanalytics4/Application/views/ga4/view_promotion.tpl', /* 'gtm_ua_impression' => 'vt/GoogleTagManager/Application/views/ua/impression.tpl' 'gtm_view_promotion.tpl' => 'vt/GoogleTagManager/Application/views/view_promotion.tpl', @@ -80,7 +81,8 @@ $aModule = [ [ 'template' => 'page/details/inc/productmain.tpl', 'block' => 'details_productmain_title', - 'file' => '/Application/views/blocks/detail.tpl' + 'file' => '/Application/views/blocks/detail.tpl', + 'position' => 150 ], // checkout [ @@ -117,6 +119,25 @@ $aModule = [ 'template' => 'page/checkout/thankyou.tpl', 'block' => 'checkout_thankyou_main', 'file' => '/Application/views/blocks/checkout_s5.tpl' + ], + // Lists + // view_item_list + [ + 'template' => 'widget/product/list.tpl', + 'block' => 'd3Ga4_view_item_list', + 'file' => '/Application/views/ga4/view_item_list.tpl' + ], + // view_search_result + [ + 'template' => 'page/search/search.tpl', + 'block' => 'search_results', + 'file' => '/Application/views/ga4/search.tpl' + ], + // add_to_cart + [ + 'template' => 'page/details/inc/productmain.tpl', + 'block' => 'details_productmain_tobasket', + 'file' => '/Application/views/ga4/add_to_cart.tpl' ] ], 'settings' => [ @@ -129,39 +150,31 @@ $aModule = [ ], [ 'group' => 'vt_gtm_settings', - 'name' => 'vt_gtm_blGA4enabled', + 'name' => 'vt_gtm_blGA4enab', 'type' => 'bool', 'value' => true, 'position' => 1 ], - [ - 'group' => 'vt_gtm_settings', - 'name' => 'vt_gtm_blUAenabled', - 'type' => 'bool', - 'value' => true, - 'position' => 2 - ], - [ - 'group' => 'vt_gtm_settings', - 'name' => 'vt_gtm_sMpapisecret', - 'type' => 'str', - 'value' => '', - 'position' => 3 - ], - [ - 'group' => 'vt_gtm_settings', - 'name' => 'vt_gtm_aPromotionlistIDs', - 'type' => 'arr', - 'value' => [], - 'position' => 4 - ], [ 'group' => 'vt_gtm_settings', 'name' => 'vt_gtm_blEnableDebug', 'type' => 'bool', 'value' => false, 'position' => 999 - ] - + ], + [ + 'group' => 'vt_gtm_settings_cookiemanager', + 'name' => 'vt_gtm_settings_hasOwnCookieManager', + 'type' => 'bool', + 'value' => false, + 'position' => 999 + ], + [ + 'group' => 'vt_gtm_settings_cookiemanager', + 'name' => 'vt_gtm_settings_cookieName', + 'type' => 'str', + 'value' => 'example', + 'position' => 999 + ], ] ]; \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..b6e0779 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +parameters: + scanFiles: + - IntelliSenseHelper.php + - ../../oxid-esales/oxideshop-ce/source/oxfunctions.php + - ../../oxid-esales/oxideshop-ce/source/overridablefunctions.php + level: 9 + phpVersion: 70100 + checkMissingIterableValueType: false + ignoreErrors: + - '#Psr\\Container\\ContainerExceptionInterface is not subtype of Throwable#' diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..516e222 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,20 @@ + + + + + src + + + + + + + ./Tests + + +