diff --git a/Application/Controller/Admin/GA4AdminUserInterface_main.php b/Application/Controller/Admin/GA4AdminUserInterface_main.php new file mode 100644 index 0000000..b0e6a46 --- /dev/null +++ b/Application/Controller/Admin/GA4AdminUserInterface_main.php @@ -0,0 +1,85 @@ +addTplParam('d3ViewObject', $this); + $this->addTplParam('d3ViewConfObject', Registry::get(ViewConfig::class)); + $this->addTplParam('d3ManagerTypeArray', oxNew(ManagerTypes::class)->getManagerList()); + $this->addTplParam('d3CurrentCMP', oxNew(ManagerHandler::class)->getCurrManager()); + + return $return; + } + + public function save() + { + parent::save(); + + $aParams = Registry::getRequest()->getRequestEscapedParameter('editval'); + + $aCheckBoxParams = [ + '_blEnableGa4', + '_blEnableDebug', + '_blEnableConsentMode', + '_blEnableOwnCookieManager', + '_blEnableMeasurementCapabilities', + '_blEnableUsercentricsConsentModeApi', + ]; + + foreach ($aCheckBoxParams as $checkBoxName){ + if (isset($aParams['bool'][$checkBoxName])){ + $aParams['bool'][$checkBoxName] = true; + }else{ + $aParams['bool'][$checkBoxName] = false; + } + } + + $this->d3SaveShopConfigVars($aParams); + } + + /** + * @param array $aParams + * @return void + */ + protected function d3SaveShopConfigVars(array $aParams) + { + $oConfig = Registry::getConfig(); + foreach ($aParams as $sConfigType => $aConfigParams) { + foreach ($aConfigParams as $sParamName => $sParamValue){ + if($this->d3GetModuleConfigParam($sParamName) !== $sParamValue){ + $oConfig->saveShopConfVar( + $sConfigType, + Constants::OXID_MODULE_ID.$sParamName, + $sParamValue, + $oConfig->getShopId(), + Constants::OXID_MODULE_ID + ); + } + } + } + } + + /** + * @param string $configParamName + * @return mixed + */ + public function d3GetModuleConfigParam(string $configParamName) + { + return Registry::get(ViewConfig::class)->d3GetModuleConfigParam($configParamName); + } +} \ No newline at end of file diff --git a/Application/Model/CMP/ConsentManagementPlatformBaseModel.php b/Application/Model/CMP/ConsentManagementPlatformBaseModel.php new file mode 100644 index 0000000..dfb6618 --- /dev/null +++ b/Application/Model/CMP/ConsentManagementPlatformBaseModel.php @@ -0,0 +1,19 @@ +sCMPName; + } +} \ No newline at end of file diff --git a/Application/Model/CMP/ConsentManagementPlatformInterface.php b/Application/Model/CMP/ConsentManagementPlatformInterface.php new file mode 100644 index 0000000..2591738 --- /dev/null +++ b/Application/Model/CMP/ConsentManagementPlatformInterface.php @@ -0,0 +1,8 @@ +getManagerList(); - foreach ($aManagerList as $managerName){ - if ($oViewConfig->isModuleActive($managerName)){ - return $managerName; + if ($this->getModuleSettingExplicitManagerSelectValue()){ + return $this->getExplicitManager(); + } + + foreach ($aManagerList as $shopModuleId => $publicCMPName){ + if ($oViewConfig->isModuleActive($shopModuleId)){ + $this->d3SaveShopConfVar($shopModuleId); + return $shopModuleId; } } - return $this->getExplicitManager(); + return ""; + } + + /** + * @param string $sParam + * @return void + */ + public function d3SaveShopConfVar(string $sParam){ + Registry::getConfig()->saveShopConfVar( + 'select', + Constants::OXID_MODULE_ID."_HAS_STD_MANAGER", + $sParam, + Registry::getConfig()->getShopId(), + Constants::OXID_MODULE_ID + ); } /** @@ -34,7 +55,7 @@ class ManagerHandler */ public function getModuleSettingExplicitManagerSelectValue() :string { - return Registry::getConfig()->getConfigParam('d3_gtm_settings_HAS_STD_MANAGER'); + return Registry::get(ViewConfig::class)->d3GetModuleConfigParam('_HAS_STD_MANAGER')?:""; } /** @@ -46,8 +67,12 @@ class ManagerHandler /** @var ManagerTypes $oManagerTypes */ $oManagerTypes = oxNew(ManagerTypes::class); - return $oManagerTypes->isManagerInList($sPotentialManagerName) + $sCMPName = $oManagerTypes->isManagerInList($sPotentialManagerName) ? $sPotentialManagerName : "NONE"; + + $this->d3SaveShopConfVar($sCMPName); + + return $sCMPName; } } \ No newline at end of file diff --git a/Application/Model/ManagerTypes.php b/Application/Model/ManagerTypes.php index f12af76..5db77ff 100644 --- a/Application/Model/ManagerTypes.php +++ b/Application/Model/ManagerTypes.php @@ -2,41 +2,24 @@ namespace D3\GoogleAnalytics4\Application\Model; +use D3\GoogleAnalytics4\Application\Model\CMP\Usercentrics; + class ManagerTypes { - #ToDo: make own classes for each of the manager - - - const EXTERNAL_SERVICE = "externalService"; - const NET_COOKIE_MANAGER = "net_cookie_manager"; + const EXTERNAL_SERVICE = "eigener Service"; + const NET_COOKIE_MANAGER = "Netensio Cookie Manager"; /** * Further information's: * https://github.com/aggrosoft/oxid-cookie-compliance */ - const AGCOOKIECOMPLIANCE = "agcookiecompliance"; + const AGCOOKIECOMPLIANCE = "Aggrosoft Cookie Compliance"; - /** - * Used the OXID Module. - * - * Further information's: - * https://docs.oxid-esales.com/modules/usercentrics/de/latest/einfuehrung.html - * - * Usercentrics homepage: - * https://usercentrics.com - */ - const USERCENTRICS_MODULE = "oxps_usercentrics"; + const CONSENTMANAGER = "Consentmanager"; - /** - * manually included usercentrics script - */ - const USERCENTRICS_MANUALLY = "USERCENTRICS"; + const COOKIEFIRST = "Cookiefirst"; - const CONSENTMANAGER = "CONSENTMANAGER"; - - const COOKIEFIRST = "COOKIEFIRST"; - - const COOKIEBOT = "COOKIEBOT"; + const COOKIEBOT = "Cookiebot"; /** * @return array @@ -47,9 +30,9 @@ class ManagerTypes "externalService" => self::EXTERNAL_SERVICE, "agcookiecompliance" => self::AGCOOKIECOMPLIANCE, "net_cookie_manager" => self::NET_COOKIE_MANAGER, - "oxps_usercentrics" => self::USERCENTRICS_MODULE, - "usercentrics" => self::USERCENTRICS_MANUALLY, - "consentmanager" => self::CONSENTMANAGER, + Usercentrics::sModuleIncludationInternalName => Usercentrics::sModuleIncludationPublicName, + Usercentrics::sExternalIncludationInternalName => Usercentrics::sExternalIncludationPublicName, + "cmconsentmanager" => self::CONSENTMANAGER, "cookiefirst" => self::COOKIEFIRST, "cookiebot" => self::COOKIEBOT, ]; @@ -61,6 +44,6 @@ class ManagerTypes */ public function isManagerInList(string $sManager) :bool { - return in_array($sManager, $this->getManagerList(), true); + return in_array($sManager, array_keys($this->getManagerList()), true); } } \ No newline at end of file diff --git a/Application/views/admin/de/d3googleanalytics4_lang.php b/Application/views/admin/de/d3googleanalytics4_lang.php new file mode 100644 index 0000000..7608463 --- /dev/null +++ b/Application/views/admin/de/d3googleanalytics4_lang.php @@ -0,0 +1,123 @@ + 'UTF-8', + + 'd3mxgoogleanalytics4' => 'Google Analytics 4', + 'd3mxgoogleanalytics4set' => 'Einstellungen', + + // Base Translations + 'D3BASECONFIG' => 'Grundeinstellungen', + 'D3CLOSE' => 'Schließen', + 'D3NONE' => '- keinen -', + 'D3CONTAINERID' => 'Container-ID', + 'D3CONTAINERID_HELP' => ' Was ist die Container-ID?', + 'D3ACTIVATEMOD' => 'Modul aktivieren', + 'D3CNTRLPARAM' => 'Steuerungsparameter', + 'D3CNTRLPARAM_HELP' => ' Was ist der Steuerungsparameter?', + 'D3INACTIVATEMOD' => 'Modul ist nicht aktiv! Es werden keine Funktionen ausgespielt!', + // Usercentrics Dynamische Optionen + 'D3USRCNTRCSDYNOPT' => 'Usercentrics Dynamische Optionen', + + // Use debug mode? + 'D3USEDEBUGMODE' => "Debug-Modus aktivieren", + 'D3USEDEBUGMODE_HELP' => "Der Debug Modus setzt an alle DataLayer ( also Daten Sammlungen im Frontend ) + 'debug_mode': 'true' und ermöglicht im Google Tag Manager selbst ein detaillierteres + Auswerten des einfließenden Datenstroms.", + + // Use Consentmode? + 'D3USEGOOGLECONSENTMODE' => "Google Consent Mode 'Default Values' akivieren", + 'D3USEGOOGLECONSENTMODE_HELP' => "Der Consent Mode 'Default Values' setzt im Frontend, + vor jedem Sammeln und Senden von Daten, einen Befehl der die Bearbeitung der Daten fortlaufend verändert.
+
+ Diese Veränderte Berarbeitung heißt im Detail, dass der Google Tag Manager ( GTM ) + bzw. in erster Instanz die Consent Management Platform ( CMP ) keine Daten zur Verarbeitung an Google sendet, + bis ein entsprechendes Zustimmungs-Signal vom Kunden explizit erteilt wurde.
+ Die CMP ist sogar derartig restriktiv, dass diese den Datenstrom zum GTM ( Vorinstanz zu Google Analytics ) + völlig verhindert, solange keine Zustimmung erteilt wurde.
+
+ Ein einfaches anschalten dieser Funktion regelt noch nicht die völlige Funktionsweise + aller beteiligten Instanzen; diese bedarf eine detailliertere Konfiguration!
", + + // Use CMP? + 'D3CMPTABTITLE' => 'Cookie Manager Einstellungen', + 'D3CMPUSEQ' => 'Consent Management Platform ( CMP ) nutzen?', + 'D3CMPUSEQ_HELP' => '"Eine Consent Management Platform ( CMP ) ist eine Software, mit der Website-Betreiber + oder Anbieter von Web-Apps über ein Banner oder ein Pop-up eine datenschutzrechtliche + Einwilligung der Besucher einholen und speichern, bevor Nutzerdaten über + Website-Skripte erfasst werden (Tracking)." Wikipedia Beschreibung
+
+ Um Google Analytics 4 ( Google Analytics ) weiterhin nutzen zu können, + und dank fortschreitendem Datenschutz unserer personenbezogener Daten, ist das Nutzen eines konformen CMP + heute zwangläufig nötig.
+
+ Diese konformen CMP sind in + offizieller Partnerschaft mit Google ( Liste der Partner ) + und unterliegen strengen Vorschriften, um ein ordnungsgemäßes Senden und + Verarbeiten der Zustimmung unterliegenden Daten sicher stellen zu können.', + 'D3CMP' => 'Consent Management Platform ( CMP ) wählen', + + // Usercentrics Config + // activate Individual Default Values + 'D3USRCNTRCSCFG_ACT_INDIVDEFVAL' => "Usercentrics individual 'Default Values' aktiveren", + // standard Consent + 'D3USRCNTRCSCFG_STD_CNST' => "GTM Standard Consent", + // activate consent mode API + 'D3USRCNTRCSCFG_ACT_CNSTMDE_API' => "Usercentrics Consent Mode API aktivieren", + // consent mode api + 'D3USRCNTRCSCFG_CNSTMDE_API' => "Consent Mode API", + 'D3USRCNTRCSCFG_DOCS' => 'Nähere Infos zu den hier konfigurierbaren Einstellungen entnehmen Sie bitte der offiziellen + Dokumentation von Usercentrics selbst: Dokumentation', + 'D3USRCNTRCSCFG_WARNING' => "Bevor Sie hier Anpassungen machen, konsultieren Sie bitte einen technischen Support!
+ Anpassungen können zu Beeinträchtigungen und Ausfall von Funktionen im Frontend führen!", + + // Additional Config + // Server-Side tagging + 'D3SERVERSIDETAGGING' => 'Server-Side tagging', + 'D3DETAILED_DESC' => 'Detailliertere Erklärung der Funktion', + 'D3SERVERSIDETAGGING_HINT' => 'Die Conatiner-ID wird weiterhin unter "Grundeinstellungen" eingetragen!

+ "Serverseitiges Tagging ist eine neue Möglichkeit, mit Google Tag Manager Ihre Anwendung geräteübergreifend zu verwalten.
+ Servercontainer verwenden dasselbe Tag-, Trigger- und Variablenmodell, das Sie gewohnt sind.
+ Außerdem bieten sie neue Tools, mit denen Sie Nutzeraktivitäten überall messen können."
+
+ - Quelle Developers-Google Server-Side tagging
+
+ Verändern Sie die Werte nur, wenn Sie Server-Side tagging verwenden wollen! Gegebenenfalls fragen Sie einen technischen Ansprechpartner. + ', + 'D3SERVERSIDETAGGING_TITLE_ACTIVE' => 'Ausführender code', + 'D3SERVERSIDETAGGING_ACTIVE' => 'Diese Domain wird im aktiven-code ausgefüht. Das heißt, + dass es sich hierbei um das HTML-Tag script handelt. + Dieses kümmert sich darum, dass die im DataLayer + zusammengefassten Daten an den GTM weitergeleitet werden.
+
+

Folgend eine Darstellung, was genau ausgetauscht wird

+
+
+Vorher:
+https://www.googletagmanager.com/gtm.js?id=
+
+Nachher:
+{Domain}?id=
+
+                                                                        
', + 'D3SERVERSIDETAGGING_TITLE_PASSIVE' => 'nicht Ausführneder code', + 'D3SERVERSIDETAGGING_PASSIVE' => 'Diese Domain wird im passiven-code ausgefüht. Das heißt, + dass es sich hierbei um das HTML-Tag noscript handelt. + Dieses wird ausgeführt, wenn aus einem bestimmten Grund + das Javascript nicht ausgeführt wird.
+ ( keine Cookies erlaubt, JavaScript-Unterbindung, ... ) +
+

Folgend eine Darstellung, was genau ausgetauscht wird

+
+
+Vorher:
+src="https://www.googletagmanager.com/ns.html?id={Container-ID}"
+
+Nachher:
+src="{Domain}?id={Container-ID}"
+
+                                                                        
', +); \ No newline at end of file diff --git a/Application/views/admin/de/module_options.php b/Application/views/admin/de/module_options.php index 555ae53..fed5414 100755 --- a/Application/views/admin/de/module_options.php +++ b/Application/views/admin/de/module_options.php @@ -10,6 +10,8 @@ * @link https://www.oxidmodule.com */ +use D3\GoogleAnalytics4\Application\Model\Constants as Constants; + $style = ''; $aLang = [ 'charset' => 'UTF-8', - 'SHOP_MODULE_d3_gtm_sContainerID' => 'Container ID', - 'SHOP_MODULE_GROUP_d3_gtm_settings' => 'Einstellungen', - 'SHOP_MODULE_d3_gtm_blGA4enab' => 'GA4 Aktivieren', - 'SHOP_MODULE_d3_gtm_blUAenabled' => 'UA Aktivieren', - 'SHOP_MODULE_d3_gtm_blEnableDebug' => 'Debug-Modus aktivieren', + + // STD-Einstellungen + 'SHOP_MODULE_GROUP_'.Constants::OXID_MODULE_ID.'_settings' => 'Einstellungen', + 'SHOP_MODULE_'. Constants::OXID_MODULE_ID.'_sContainerID' => 'Container ID', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_blGA4enab' => 'GA4 Aktivieren', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_blUAenabled' => 'UA Aktivieren', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_blEnableDebug' => 'Debug-Modus aktivieren', + + // Serverside - tagging + 'SHOP_MODULE_GROUP_'.Constants::OXID_MODULE_ID.'_serversidetagging' => 'Server-Side tagging', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_serversidetagging_js' => 'Servercontainer Ausführender-Code', + 'HELP_SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_serversidetagging_js' => 'Diese Domain wird im aktiven-code ausgefüht. Das heißt, + dass es sich hierbei um das HTML-Tag script handelt. + Dieses kümmert sich darum, dass die, im data_layer + zusammengefassten Daten an den GTM weitergeleitet werden.
+
+

Folgend eine Darstellung, was genau ausgetauscht wird

+
+
+Vorher:
+https://www.googletagmanager.com/gtm.js?id=
+
+Nachher:
+{Domain}?id=
+
+                                                                        
+ Die Conatiner-ID wird weiterhin im Punkt "Einstellung" eingetragen! + ', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_serversidetagging_nojs' => 'Servercontainer NICHT Ausführender-Code

+ "Serverseitiges Tagging ist eine neue Möglichkeit, mit Google Tag Manager Ihre Anwendung geräteübergreifend zu verwalten.
+ Servercontainer verwenden dasselbe Tag-, Trigger- und Variablenmodell, das Sie gewohnt sind.
+ Außerdem bieten sie neue Tools, mit denen Sie Nutzeraktivitäten überall messen können."
+
+ - Quelle Developers-Google Server-Side tagging
+
+ Verändern Sie die Werte nur, wenn Sie Server-Side tagging verwenden wollen! +', + 'HELP_SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_serversidetagging_nojs' => 'Diese Domain wird im passiven-code ausgefüht. Das heißt, + dass es sich hierbei um das HTML-Tag noscript handelt. + Dieses wird ausgeführt, wenn aus einem bestimmten Grund + das Javascript nicht ausgeführt wird.
+ ( keine Cookies erlaubt, JavaScript-Unterbindung, ... ) +
+

Folgend eine Darstellung, was genau ausgetauscht wird

+
+
+Vorher:
+src="https://www.googletagmanager.com/ns.html?id={Container-ID}"
+
+Nachher:
+src="{Domain}?id={Container-ID}"
+
+                                                                        
+ Die Conatiner-ID wird weiterhin im Punkt "Einstellung" eingetragen! + ', // for cookie manager settings - 'SHOP_MODULE_GROUP_d3_gtm_settings_cookiemanager' => 'Cookie Manager Einstellungen', - 'SHOP_MODULE_d3_gtm_settings_hasOwnCookieManager' => 'Cookie Manager nutzen?', - 'HELP_SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER' => 'Mehr Informationen zu den genannten Coookie-Manager finden Sie auf den folgenden Home-Pages

+ 'SHOP_MODULE_GROUP_'.Constants::OXID_MODULE_ID.'_cookiemanager' => 'Cookie Manager Einstellungen', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_hasOwnCookieManager' => 'Cookie Manager nutzen?', + 'HELP_SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER' => 'Mehr Informationen zu den genannten Coookie-Manager finden Sie auf den folgenden Home-Pages

Consentmanager
Usercentrics
Cookiefirst

Bei weiteren Fragen stehen wir gern zur Verfügung! Kontaktieren Sie uns einfach unter https://www.d3data.de/', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER' => 'Nutzen Sie eine der folgenden Einbindungen?
+ 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER' => 'Nutzen Sie eine der folgenden Einbindungen?
Dann wählen Sie bitte die zutreffende aus.', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER_NONE' => '---', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER_CONSENTMANAGER' => 'consentmanager', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER_USERCENTRICS' => 'usercentrics', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER_COOKIEFIRST' => 'cookiefirst', - 'SHOP_MODULE_d3_gtm_settings_HAS_STD_MANAGER_COOKIEBOT' => 'Cookiebot', - 'SHOP_MODULE_d3_gtm_settings_controlParameter' => 'Steuerungsparameter', - 'HELP_SHOP_MODULE_d3_gtm_settings_controlParameter' => 'Nähere infos zum "Steuerungsparameter"
+ 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER_NONE' => '---', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER_CONSENTMANAGER' => 'consentmanager', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER_USERCENTRICS' => 'usercentrics', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER_COOKIEFIRST' => 'cookiefirst', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_HAS_STD_MANAGER_COOKIEBOT' => 'Cookiebot', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_controlParameter' => 'Steuerungsparameter', + 'HELP_SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_controlParameter' => 'Nähere infos zum "Steuerungsparameter"
Beachte:
Sofern Sie die consentmanager CMP verwenden, bitte ich Sie, gründlichst, die Hinweise der Moduldokumentation/Consentmanager zu lesen. - ' + ', + 'SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_blActivateConsentMode' => "Google Consent Mode 'Default Values' aktivieren", + 'HELP_SHOP_MODULE_'.Constants::OXID_MODULE_ID.'_blActivateConsentMode' => 'Diese Einstellung ist zu aktivieren, wenn Sie den Google-Consent-Mode ( Einwilligungsmodus ) verwenden wollen. +
+ "Im Einwilligungsmodus können Sie Google über den Cookie- oder App-ID-Einwilligungsstatus Ihrer Nutzer informieren. + Mit Tags wird das Verhalten angepasst. Dabei werden die Einstellungen der Nutzer berücksichtigt." ~ Google Einwilligungsmodus', ]; diff --git a/Application/views/admin/tpl/d3googleanalytics4_headitem.tpl b/Application/views/admin/tpl/d3googleanalytics4_headitem.tpl new file mode 100644 index 0000000..1cc5d7a --- /dev/null +++ b/Application/views/admin/tpl/d3googleanalytics4_headitem.tpl @@ -0,0 +1,108 @@ + + + + [{$title}] + + [{if isset($meta_refresh_sec,$meta_refresh_url)}] + + [{/if}] + + + [{block name="admin_headitem_inccss"}] + + + + [{/block}] + + [{block name="admin_headitem_incjs"}] + + + + [{/block}] + + [{block name="admin_headitem_js"}] + + [{/block}] + + + +[{include file="tooltips.tpl"}] +
+ +
+ [{include file="inc_error.tpl" Errorlist=$Errors.default}] + + +
+
+
\ No newline at end of file diff --git a/Application/views/admin/tpl/d3googleanalytics4_main.tpl b/Application/views/admin/tpl/d3googleanalytics4_main.tpl new file mode 100644 index 0000000..33455a4 --- /dev/null +++ b/Application/views/admin/tpl/d3googleanalytics4_main.tpl @@ -0,0 +1,198 @@ +[{include file="ga4/admin/d3ga4uiheaditem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}] + + + + + + +[{if $readonly}] + [{assign var="readonly" value="readonly disabled"}] + [{else}] + [{assign var="readonly" value=""}] + [{/if}] + +
+
+
+
+ [{$oViewConf->getHiddenSid()}] + + + + +
+
+ [{oxmultilang ident="D3BASECONFIG"}] +
+
+
+ d3GetModuleConfigParam('_blEnableGa4')}]checked[{/if}] id="blGA4enab"> + +
+
+
+ [{oxmultilang ident="D3CONTAINERID"}] + +
+
[{oxmultilang ident="D3CONTAINERID_HELP"}]
+
+
+ d3GetModuleConfigParam('_blEnableDebug')}]checked[{/if}]> + +
+
+ d3GetModuleConfigParam('_blEnableConsentMode')}]checked[{/if}]> + +
+
+ +
+
+
+
+
+
+

+ +

+
+
+
+ d3GetModuleConfigParam('_blEnableOwnCookieManager')}]checked[{/if}]> + +
+
+ + +
+
+
+ [{oxmultilang ident="D3CNTRLPARAM"}] + +
+
[{oxmultilang ident="D3CNTRLPARAM_HELP"}]
+
+
+ +
+
+
+

+ +

+
+
+
+
+ [{oxmultilang ident="D3SERVERSIDETAGGING_HINT"}] +
+
+
+ [{oxmultilang ident="D3SERVERSIDETAGGING_TITLE_ACTIVE"}] + +
+
+ [{oxmultilang ident="D3SERVERSIDETAGGING_TITLE_PASSIVE"}] + +
+ +
+ + + + +
+
+ +
+
+ [{if $d3ViewConfObject->d3IsUsercentricsCMPChosen()}] +
+

+ +

+
+
+
+
+
+ [{oxmultilang ident="D3USRCNTRCSCFG_WARNING"}] +
+ [{oxmultilang ident="D3USRCNTRCSCFG_DOCS"}] +
+
+ +
+ d3GetModuleConfigParam('_blEnableMeasurementCapabilities')}]checked[{/if}]> + +
+
+ [{oxmultilang ident="D3USRCNTRCSCFG_STD_CNST"}] + +
+ +
+ d3GetModuleConfigParam('_blEnableUsercentricsConsentModeApi')}]checked[{/if}]> + +
+
+ [{oxmultilang ident="D3USRCNTRCSCFG_CNSTMDE_API"}] + +
+
+ +
+
+ [{/if}] +
+
+
+
+
+
\ No newline at end of file diff --git a/Application/views/blocks/_gtm_js.tpl b/Application/views/blocks/_gtm_js.tpl index de0cb3e..090310c 100755 --- a/Application/views/blocks/_gtm_js.tpl +++ b/Application/views/blocks/_gtm_js.tpl @@ -1,11 +1,41 @@ [{* Always prepare the data layer to avoid errors *}] - +[{if $oViewConf->isGA4enabled()}] + [{assign var="d3GtmContainerIdString" value=$oViewConf->getGtmContainerId()}] + +[{/if}] -[{if $oViewConf->D3blShowGtmScript()}] - [{if $oViewConf->getGtmContainerId()}] +[{if $oViewConf->isGA4enabled() and $oViewConf->D3blShowGtmScript()}] + [{if $d3GtmContainerIdString}] [{strip}] + + [{if $oViewConf->isGtmConsentModeSetActivated()}] + + [{/if}] + + [{if $oViewConf->d3IsUsercentricsCMPChosen() and $oViewConf->d3GetModuleConfigParam('_blEnableUsercentricsConsentModeApi')}] + + [{/if}] + [{/strip}] diff --git a/Application/views/blocks/_gtm_nojs.tpl b/Application/views/blocks/_gtm_nojs.tpl index 98a47ad..e15907e 100644 --- a/Application/views/blocks/_gtm_nojs.tpl +++ b/Application/views/blocks/_gtm_nojs.tpl @@ -2,7 +2,7 @@ [{if $oViewConf->getGtmContainerId()}][{strip}] diff --git a/Application/views/event/add_to_cart.tpl b/Application/views/event/add_to_cart.tpl index 8d85631..ecb54f0 100644 --- a/Application/views/event/add_to_cart.tpl +++ b/Application/views/event/add_to_cart.tpl @@ -1,5 +1,5 @@ -[{if $d3CmpBasket->getAddToBasketDecision() && $d3CmpBasket->d3GtmRequestedArticleLoadedByAnid() !== null}] +[{if $d3CmpBasket && $d3CmpBasket->getAddToBasketDecision() && $d3CmpBasket->d3GtmRequestedArticleLoadedByAnid() !== null}] [{assign var="oGtmProduct" value=$d3CmpBasket->d3GtmRequestedArticleLoadedByAnid()}] [{assign var="oGtmAmountArticlesAdded" value=$d3CmpBasket->getD3GtmAddToCartAmountArticles()}] [{*$smarty.block.parent*}] diff --git a/CHANGELOG.md b/CHANGELOG.md index ed1ef38..aa7cf0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,69 @@ 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/GoogleAnalytics4/compare/2.17.2...rel_2.x) - 2024-x + +## [2.19.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.18.2...2.19.0) - 2024-08-10 +### Fixed +- usage of not yet existing function + +## [2.18.2](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.18.1...2.18.2) - 2024-06-25 +### Fixed +- oe-console apply-configuration triggers on-activate and overwrites existing values + +## [2.18.1](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.18.0...2.18.1) - 2024-06-04 +### Fixed +- missing return statement, on null/ none + +## [2.18.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.17.2...2.18.0) - 2024-06-03 +### Added +- trait for generalized method +- new admin UI +- additional check for properly activated module +- admin headitem alternative +- usercentrips step/ option 2 +- group CMP-Functionalities/ properties into own Model +- additional help texts, translations, explanations +- extended docs +- auto safe on first approach ga4 + cmp-mod +- onActivate/ onDeactivate +## Changed +- declare module settings consistency +- configParamGetter +- clear dead code +- template code upgrade +- lang text +- amount of save-buttons +- Usercentrics-Class constants and adjust global-module-code to it +- CMP-output in tpl +- clear code and adjust Naming +## Fixed +- false class-property declaration +- wrong to-save param +## Removed +- deprecated and obsolete module-settings +- false composer xml-excludation + +## [2.17.2](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.17.1...2.17.2) - 2024-04-11 +### Fixed +- error on missing necessary-component + +## [2.17.1](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.17.0...2.17.1) - 2024-04-10 +### Fixed +- second call of getGtmContainerId() ( returned false ) + +## [2.17.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.16.0...2.17.0) - 2024-04-10 +### Added +- Google-Analytics default values +- default values switch ( admin module settings ) +- translations +## Changed +- centralized metadata-id + +## [2.16.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.15.0...2.16.0) - 2024-03-20 +### Added +- ( Google ) Server-Side tagging usability + ## [2.15.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/2.14.0...2.15.0) - 2024-02-05 ### Fixed - missing Component-ArticleDetails extension, missing ManufacturerListController extension @@ -142,6 +205,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - using of ContainerFactory in ViewConfig +## [1.17.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/1.16.0...1.17.0) - 2024-04-11 +### Added +- multilang translations +- GA4 consent-mode default values +### Changed +- metadataID centralized + +## [1.16.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/1.15.1...1.16.0) - 2024-04-11 +### Added +- ( Google ) Server-Side tagging usability + ## [1.15.0](https://git.d3data.de/D3Public/GoogleAnalytics4/compare/1.14.0...1.15.0) - 2024-01-25 ### Fixed - missing Component-ArticleDetails extension, missing ManufacturerListController extension diff --git a/Docs/README.md b/Docs/README.md index 29b581b..e214985 100644 --- a/Docs/README.md +++ b/Docs/README.md @@ -5,6 +5,13 @@ Die Einbindung dieser Event-Templates erfolgt über TPL-Blöcke unter `source/mo *Hinweis: nicht alle templates sind bereits gefüllt. Wünschen Sie die Implementierung eines unausgefüllten templates? Kommen Sie auf uns zu unter https://www.d3data.de/ +## Container-ID +Diese finden Sie im "Google-Tag-Manager"-Arbeitsbereich in der Navigationsleiste. +Sie beginnt mit GTM, gefolgt von einem Bindestrich und einer Zeichenkette. + +Diese ID wird benötigt, um Google anzuweise, zu welchem "Google Tag Manager"-Arbeitsbereich die +gesammelten Daten im Daten-Stream geleitet werden sollen. + ## Steuerungsparameter Tragen Sie hier im Normalfall die ID des zu prüfenden Cookies ein. In bestimmten Fällen, müssen Sie hier alternative Werte eintragen. Diese Fälle sind bedingt diff --git a/Modules/Application/Model/Category.php b/Modules/Application/Model/Category.php index 713e4a5..42c3cb7 100644 --- a/Modules/Application/Model/Category.php +++ b/Modules/Application/Model/Category.php @@ -4,41 +4,5 @@ namespace D3\GoogleAnalytics4\Modules\Application\Model; class Category extends Category_parent { - /** - * @param int $indexOfArray - * @return string - */ - public function getSplitCategoryArray(int $indexOfArray = -1, bool $bShallTakeStd = false) :string - { - if ($bShallTakeStd){ - $splitCatArray = - array_values( - array_filter( - explode( - '/', - trim( - parse_url( - $this->getLink(), - 5 - ) - ) - ) - ) - ); - - if (($indexOfArray >= 0) and (false === empty($splitCatArray[$indexOfArray]))){ - return $splitCatArray[$indexOfArray]; - }else{ - return ""; - } - } - - return - trim( - parse_url( - $this->getLink(), - 5 - ) - ); - } + use articleTreeStructure; } \ No newline at end of file diff --git a/Modules/Application/Model/Manufacturer.php b/Modules/Application/Model/Manufacturer.php index 1d98dda..3bf2de6 100644 --- a/Modules/Application/Model/Manufacturer.php +++ b/Modules/Application/Model/Manufacturer.php @@ -4,41 +4,5 @@ namespace D3\GoogleAnalytics4\Modules\Application\Model; class Manufacturer extends Manufacturer_parent { - /** - * @param int $indexOfArray - * @return string - */ - public function getSplitCategoryArray(int $indexOfArray = -1, bool $bShallTakeStd = false) :string - { - if ($bShallTakeStd){ - $splitCatArray = - array_values( - array_filter( - explode( - '/', - trim( - parse_url( - $this->getLink(), - 5 - ) - ) - ) - ) - ); - - if (($indexOfArray >= 0) and (false === empty($splitCatArray[$indexOfArray]))){ - return $splitCatArray[$indexOfArray]; - }else{ - return ""; - } - } - - return - trim( - parse_url( - $this->getLink(), - 5 - ) - ); - } + use articleTreeStructure; } \ No newline at end of file diff --git a/Modules/Application/Model/Vendor.php b/Modules/Application/Model/Vendor.php new file mode 100644 index 0000000..87caded --- /dev/null +++ b/Modules/Application/Model/Vendor.php @@ -0,0 +1,11 @@ +getLink(), + 5 + ) + ) + ) + ) + ); + + if (($indexOfArray >= 0) and (false === empty($splitCatArray[$indexOfArray]))){ + return $splitCatArray[$indexOfArray]; + }else{ + return ""; + } + } + + return + trim( + parse_url( + $this->getLink(), + 5 + ) + ); + } +} \ No newline at end of file diff --git a/Modules/Core/ViewConfig.php b/Modules/Core/ViewConfig.php index 9f75176..af9a7c7 100644 --- a/Modules/Core/ViewConfig.php +++ b/Modules/Core/ViewConfig.php @@ -12,6 +12,8 @@ namespace D3\GoogleAnalytics4\Modules\Core; +use D3\GoogleAnalytics4\Application\Model\CMP\Usercentrics; +use D3\GoogleAnalytics4\Application\Model\Constants; use D3\GoogleAnalytics4\Application\Model\ManagerHandler; use D3\GoogleAnalytics4\Application\Model\ManagerTypes; use OxidEsales\Eshop\Application\Controller\FrontendController; @@ -28,16 +30,18 @@ class ViewConfig extends ViewConfig_parent // Google Tag Manager Container ID private $sContainerId = null; - private $sCookieManagerType = null; + + // used CMP + private $sCookieManagerType = null;# + + // isModule Activated properly? + private $blGA4enabled = null; public function getGtmContainerId() { if ($this->sContainerId === null) { - $this->sContainerId = ContainerFactory::getInstance() - ->getContainer() - ->get(ModuleSettingBridgeInterface::class) - ->get('d3_gtm_sContainerID', 'd3googleanalytics4'); + $this->sContainerId = $this->d3GetModuleConfigParam("_sContainerID"); } return $this->sContainerId; } @@ -59,7 +63,7 @@ class ViewConfig extends ViewConfig_parent */ public function shallUseOwnCookieManager() :bool { - return (bool) Registry::getConfig()->getConfigParam('d3_gtm_settings_hasOwnCookieManager'); + return (bool) $this->d3GetModuleConfigParam('_blEnableOwnCookieManager'); } /** @@ -70,14 +74,18 @@ class ViewConfig extends ViewConfig_parent /** @var Config $oConfig */ $oConfig = Registry::getConfig(); + if (false === $this->isGA4enabled()){ + return false; + } + // No Cookie Manager in use - if (!$this->shallUseOwnCookieManager()) { + if (false === $this->shallUseOwnCookieManager()) { return true; } $this->defineCookieManagerType(); - $sCookieID = trim($oConfig->getConfigParam('d3_gtm_settings_controlParameter')); + $sCookieID = trim($this->d3GetModuleConfigParam('_sControlParameter')); // Netensio Cookie Manager if ($this->sCookieManagerType === ManagerTypes::NET_COOKIE_MANAGER) { @@ -96,8 +104,8 @@ class ViewConfig extends ViewConfig_parent // UserCentrics or consentmanager if ( - $this->sCookieManagerType === ManagerTypes::USERCENTRICS_MODULE - or $this->sCookieManagerType === ManagerTypes::USERCENTRICS_MANUALLY + $this->sCookieManagerType === Usercentrics::sModuleIncludationInternalName + or $this->sCookieManagerType === Usercentrics::sExternalIncludationInternalName or $this->sCookieManagerType === ManagerTypes::CONSENTMANAGER or $this->sCookieManagerType === ManagerTypes::COOKIEFIRST or $this->sCookieManagerType === ManagerTypes::COOKIEBOT @@ -118,15 +126,15 @@ class ViewConfig extends ViewConfig_parent */ public function getGtmScriptAttributes() :string { - $sControlParameter = trim(Registry::getConfig()->getConfigParam('d3_gtm_settings_controlParameter')); + $sControlParameter = trim($this->d3GetModuleConfigParam('_sControlParameter')); if (false === $this->shallUseOwnCookieManager() or ($sControlParameter === '')){ return ""; } if ( - $this->sCookieManagerType === ManagerTypes::USERCENTRICS_MODULE - or $this->sCookieManagerType === ManagerTypes::USERCENTRICS_MANUALLY + $this->sCookieManagerType === Usercentrics::sModuleIncludationInternalName + or $this->sCookieManagerType === Usercentrics::sExternalIncludationInternalName ) { return 'data-usercentrics="' . $sControlParameter . '" type="text/plain" async=""'; @@ -148,8 +156,6 @@ class ViewConfig extends ViewConfig_parent return ""; } - private $blGA4enabled = null; - /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface @@ -158,15 +164,17 @@ class ViewConfig extends ViewConfig_parent { if ($this->blGA4enabled === null) { - $this->sContainerId = ContainerFactory::getInstance() - ->getContainer() - ->get(ModuleSettingBridgeInterface::class) - ->get('d3_gtm_blEnableGA4', 'd3googleanalytics4'); + $this->blGA4enabled = $this->d3GetModuleConfigParam("_blEnableGA4"); } return $this->blGA4enabled; } + public function isGtmConsentModeSetActivated() :bool + { + return $this->d3GetModuleConfigParam("_blEnableConsentMode")?: false; + } + public function getGtmDataLayer() { if (!$this->getGtmContainerId()) return "[]"; @@ -206,12 +214,47 @@ class ViewConfig extends ViewConfig_parent public function isDebugModeOn() :bool { - return Registry::getConfig()->getConfigParam('d3_gtm_blEnableDebug'); + return $this->d3GetModuleConfigParam("_blEnableDebug")?: false; } - public function isPromotionList($listId) + /** + * @return string + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function getServerSidetaggingJsDomain() :string { - $oConfig = Registry::getConfig(); - $aPromotionListIds = $oConfig->getConfigParam("") ?? ['bargainItems', 'newItems', 'topBox', 'alsoBought', 'accessories', 'cross']; + return $this->d3GetModuleConfigParam("_sServersidetagging_js")?: ""; + } + + /** + * @return string + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function getServerSidetaggingNoJsDomain() :string + { + return $this->d3GetModuleConfigParam('_sServersidetagging_nojs')?: ""; + } + + /** + * @param string $configParamName + * @return mixed + */ + public function d3GetModuleConfigParam(string $configParamName) + { + return Registry::getConfig()->getShopConfVar(Constants::OXID_MODULE_ID.$configParamName, null, Constants::OXID_MODULE_ID); + } + + /** + * @return bool + */ + public function d3IsUsercentricsCMPChosen() :bool + { + $sCMPPubName = $this->d3GetModuleConfigParam('_HAS_STD_MANAGER'); + $aPossibleCMP = (oxNew(ManagerTypes::class))->getManagerList(); + + return (bool) ($sCMPPubName === Usercentrics::sExternalIncludationInternalName + or $sCMPPubName === Usercentrics::sModuleIncludationInternalName); } } \ No newline at end of file diff --git a/Setup/Actions.php b/Setup/Actions.php new file mode 100644 index 0000000..256b834 --- /dev/null +++ b/Setup/Actions.php @@ -0,0 +1,44 @@ +d3GetModuleConfigParam($sSettingName) and (trim($this->d3GetModuleConfigParam($sSettingName)) !== trim($sSettingValue))){ + $sSettingValue = trim($this->d3GetModuleConfigParam($sSettingName)); + } + + $oConfig->saveShopConfVar( + $sVarType, + Constants::OXID_MODULE_ID.$sSettingName, + $sSettingValue, + $oConfig->getShopId(), + Constants::OXID_MODULE_ID + ); + } + + /** + * @param string $configParamName + * @return mixed + */ + public function d3GetModuleConfigParam(string $configParamName) + { + return Registry::getConfig()->getShopConfVar(Constants::OXID_MODULE_ID.$configParamName, null, Constants::OXID_MODULE_ID); + } +} \ No newline at end of file diff --git a/Setup/Events.php b/Setup/Events.php new file mode 100644 index 0000000..30ac24e --- /dev/null +++ b/Setup/Events.php @@ -0,0 +1,37 @@ +d3SaveDefaultSettings( + 'str', + '_sServersidetagging_js', + 'https://www.googletagmanager.com/gtm.js' + ); + $oActions->d3SaveDefaultSettings( + 'str', + '_sServersidetagging_nojs', + 'https://www.googletagmanager.com/ns.html' + ); + $oActions->d3SaveDefaultSettings( + 'str', + '_sContainerID', + 'GTM-' + ); + } + + /** + * @return void + */ + public static function onDeactivate(){} +} \ No newline at end of file diff --git a/composer.json b/composer.json index 0f66013..f6c687b 100644 --- a/composer.json +++ b/composer.json @@ -37,15 +37,14 @@ "*.md", "composer.json", ".php-cs-fixer.php", - "*.xml", "*.neon" ], "target-directory": "d3/googleanalytics4" } }, "require": { - "php": ">=7.1", - "oxid-esales/oxideshop-ce": "^6.5", + "php": "7.1 - 8.2", + "oxid-esales/oxideshop-ce": "^6.5.3", "google/apiclient":" ^2.0", "phpstan/phpstan": "^1.10" }, diff --git a/menu.xml b/menu.xml new file mode 100644 index 0000000..9096fa4 --- /dev/null +++ b/menu.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/metadata.php b/metadata.php index fb8c1c7..0f88d92 100755 --- a/metadata.php +++ b/metadata.php @@ -1,5 +1,7 @@ 'd3googleanalytics4', + 'id' => Constants::OXID_MODULE_ID, '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.
@@ -48,10 +50,13 @@ $aModule = [ Die Entwicklung basiert auf einem Fork von Marat Bedoev - Github-Link ", 'thumbnail' => 'thumbnail.png', - 'version' => '2.15.0', + 'version' => '2.19.0', 'author' => 'Data Development (Inh.: Thomas Dartsch)', 'email' => 'support@shopmodule.com', 'url' => 'https://www.oxidmodule.com/', + 'controllers' => [ + 'd3googleanalytics4_main' => GA4AdminUserInterfaceMainController::class + ], 'extend' => [ // Core OEViewConfig::class => ViewConfig::class, @@ -92,6 +97,10 @@ $aModule = [ 'page/account/d3gtmnoticelist.tpl' => 'd3/googleanalytics4/Application/views/tpl/page/account/d3gtmnoticelist.tpl', 'page/account/d3gtmrecommendationlist.tpl' => 'd3/googleanalytics4/Application/views/tpl/page/account/d3gtmrecommendationlist.tpl', 'page/account/d3gtmwishlist.tpl' => 'd3/googleanalytics4/Application/views/tpl/page/account/d3gtmwishlist.tpl', + + // Admin Templates + 'ga4/admin/d3ga4uimain.tpl' => 'd3/googleanalytics4/Application/views/admin/tpl/d3googleanalytics4_main.tpl', + 'ga4/admin/d3ga4uiheaditem.tpl' => 'd3/googleanalytics4/Application/views/admin/tpl/d3googleanalytics4_headitem.tpl', ], 'blocks' => [ // tag manager js @@ -167,48 +176,8 @@ $aModule = [ 'position' => 150 ] ], - 'settings' => [ - [ - 'group' => 'd3_gtm_settings', - 'name' => 'd3_gtm_sContainerID', - 'type' => 'str', - 'value' => 'GTM-', - 'position' => 0 - ], - [ - 'group' => 'd3_gtm_settings', - 'name' => 'd3_gtm_blGA4enab', - 'type' => 'bool', - 'value' => true, - 'position' => 1 - ], - [ - 'group' => 'd3_gtm_settings', - 'name' => 'd3_gtm_blEnableDebug', - 'type' => 'bool', - 'value' => false, - 'position' => 999 - ], - [ - 'group' => 'd3_gtm_settings_cookiemanager', - 'name' => 'd3_gtm_settings_hasOwnCookieManager', - 'type' => 'bool', - 'value' => false, - 'position' => 999 - ], - [ - 'group' => 'd3_gtm_settings_cookiemanager', - 'name' => 'd3_gtm_settings_controlParameter', - 'type' => 'str', - 'value' => '', - 'position' => 999 - ], - [ - 'group' => 'd3_gtm_settings_cookiemanager', - 'name' => 'd3_gtm_settings_HAS_STD_MANAGER', - 'type' => 'select', - 'value' => 'none', - 'constraints' => 'NONE|CONSENTMANAGER|USERCENTRICS|COOKIEFIRST|COOKIEBOT', - ], - ] + 'events' => [ + 'onActivate' => '\D3\GoogleAnalytics4\Setup\Events::onActivate', + 'onDeactivate' => '\D3\GoogleAnalytics4\Setup\Events::onDeactivate', + ], ]; \ No newline at end of file