From 7c178b330a3ba6d8b568733a274294f11bd4d3c0 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 4 Nov 2022 09:36:54 +0800 Subject: [PATCH 1/6] WIP measurement component --- Plugin.php | 3 ++- classes/Measurement.php | 0 components/Measurement.php | 20 ++++++++++++++++++++ components/measurement/default.htm | 5 +++++ lang/en/lang.php | 6 ++++++ models/settings/fields.yaml | 13 +++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 classes/Measurement.php create mode 100644 components/Measurement.php create mode 100644 components/measurement/default.htm diff --git a/Plugin.php b/Plugin.php index b2b363c..b639973 100644 --- a/Plugin.php +++ b/Plugin.php @@ -19,7 +19,8 @@ public function pluginDetails() public function registerComponents() { return [ - '\Winter\GoogleAnalytics\Components\Tracker' => 'googleTracker' + \Winter\GoogleAnalytics\Components\Tracker::class => 'googleTracker', + \Winter\GoogleAnalytics\Components\Measurement::class => 'googleMeasurement', ]; } diff --git a/classes/Measurement.php b/classes/Measurement.php new file mode 100644 index 0000000..e69de29 diff --git a/components/Measurement.php b/components/Measurement.php new file mode 100644 index 0000000..379829c --- /dev/null +++ b/components/Measurement.php @@ -0,0 +1,20 @@ + 'winter.googleanalytics::lang.strings.measurement', + 'description' => 'winter.googleanalytics::lang.strings.measurement_desc' + ]; + } + + public function onRender() + { + $this->page['clientId'] = null; + } +} diff --git a/components/measurement/default.htm b/components/measurement/default.htm new file mode 100644 index 0000000..cf5b7e7 --- /dev/null +++ b/components/measurement/default.htm @@ -0,0 +1,5 @@ +{% put scripts %} + +{% endput %} diff --git a/lang/en/lang.php b/lang/en/lang.php index 9946d14..fd1d767 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -50,6 +50,8 @@ 'current' => 'Current', 'goal' => 'Goal', 'engagement' => 'Engagement', + 'measurement' => 'Measurement', + 'measurement_desc' => 'Add event tracking in your pages.', ], 'settings' => [ 'project_name' => 'Google API Project name', @@ -70,6 +72,10 @@ 'domain_name_comment' => 'Specify the domain name you are going to track', 'force_ssl' => 'Force SSL', 'force_ssl_comment' => 'Always use SSL to send data to Google', + 'measurement_id' => 'Measurement ID', + 'measurement_id_comment' => 'You can find the Measurement ID on the Admin / Data Streams page', + 'measurement_secret' => 'Measurement Secret', + 'measurement_secret_comment' => 'You must create a Measurement Protocal API secret and copy the secret into this field.', ], 'mediums' => [ 'organic' => 'Search engines', diff --git a/models/settings/fields.yaml b/models/settings/fields.yaml index 180968c..640b8c1 100644 --- a/models/settings/fields.yaml +++ b/models/settings/fields.yaml @@ -39,3 +39,16 @@ tabs: span: left label: winter.googleanalytics::lang.settings.force_ssl commentAbove: winter.googleanalytics::lang.settings.force_ssl_comment + + measurement_id: + tab: winter.googleanalytics::lang.strings.measurement + span: left + label: winter.googleanalytics::lang.settings.measurement_id + commentAbove: winter.googleanalytics::lang.settings.measurement_id_comment + + measurement_secret: + tab: winter.googleanalytics::lang.strings.measurement + span: right + label: winter.googleanalytics::lang.settings.measurement_secret + type: sensitive + commentAbove: winter.googleanalytics::lang.settings.measurement_secret_comment From c730dbac73661c00b5717cc243011d66a7f90019 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 4 Nov 2022 12:54:30 +0800 Subject: [PATCH 2/6] Drop deprecated settings GA4 already anonymizes IP addresses, and forcing SSL appears to no longer be a configuration option. --- components/tracker/default.htm | 14 ++++---------- models/settings/fields.yaml | 14 -------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/components/tracker/default.htm b/components/tracker/default.htm index 8c03881..2de1bd1 100644 --- a/components/tracker/default.htm +++ b/components/tracker/default.htm @@ -3,14 +3,8 @@ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); -{% if __SELF__.domainName %} - gtag('set', { 'cookie_domain': '{{ __SELF__.domainName }}' }); -{% endif %} -{% if __SELF__.forceSSL %} - gtag('set', { 'force_ssl': true }); -{% endif %} -{% if __SELF__.anonymizeIp %} - gtag('set', { 'anonymize_ip': true }); -{% endif %} - gtag('config', '{{ __SELF__.trackingId }}'); + + gtag('config', '{{ __SELF__.trackingId }}', { + cookie_domain: '{{ __SELF__.domainName|default('auto') }}', + }); diff --git a/models/settings/fields.yaml b/models/settings/fields.yaml index 640b8c1..45d5b81 100644 --- a/models/settings/fields.yaml +++ b/models/settings/fields.yaml @@ -26,20 +26,6 @@ tabs: label: winter.googleanalytics::lang.settings.domain_name commentAbove: winter.googleanalytics::lang.settings.domain_name_comment - anonymize_ip: - tab: winter.googleanalytics::lang.strings.tracking - type: switch - span: left - label: winter.googleanalytics::lang.settings.anonymize_ip - commentAbove: winter.googleanalytics::lang.settings.anonymize_ip_comment - - force_ssl: - tab: winter.googleanalytics::lang.strings.tracking - type: switch - span: left - label: winter.googleanalytics::lang.settings.force_ssl - commentAbove: winter.googleanalytics::lang.settings.force_ssl_comment - measurement_id: tab: winter.googleanalytics::lang.strings.measurement span: left From aad910297c2551894d79b3516eb0f518ea5d01e3 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 4 Nov 2022 12:55:47 +0800 Subject: [PATCH 3/6] Drop deprecated settings from the component itself --- components/Tracker.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/components/Tracker.php b/components/Tracker.php index 08a5187..9de610b 100644 --- a/components/Tracker.php +++ b/components/Tracker.php @@ -22,14 +22,4 @@ public function domainName() { return Settings::get('domain_name'); } - - public function anonymizeIp() - { - return Settings::get('anonymize_ip'); - } - - public function forceSSL() - { - return Settings::get('force_ssl'); - } } From c8848822cded3127f192f9f61566a92b3584b9b3 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 4 Nov 2022 14:56:15 +0800 Subject: [PATCH 4/6] Add initial client ID recording and JS-side event recording --- components/Measurement.php | 49 ++++++++++++- components/Tracker.php | 4 +- .../measurement/assets/js/Measurement.js | 73 +++++++++++++++++++ components/measurement/default.htm | 5 +- lang/en/lang.php | 2 + 5 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 components/measurement/assets/js/Measurement.js diff --git a/components/Measurement.php b/components/Measurement.php index 379829c..19bcc60 100644 --- a/components/Measurement.php +++ b/components/Measurement.php @@ -1,8 +1,16 @@ - + */ class Measurement extends ComponentBase { public function componentDetails() @@ -13,8 +21,43 @@ public function componentDetails() ]; } - public function onRender() + public function onRender(): void + { + $this->addJs('components/measurement/assets/js/Measurement.js'); + $this->page['clientId'] = $this->clientId(); + } + + /** + * Returns the currently stored client ID for Google Analytics tracking. + */ + public function clientId(): ?string { - $this->page['clientId'] = null; + $clientId = null; + + if (Session::has('winter.googleanalytics.clientId')) { + $clientId = Session::get('winter.googleanalytics.clientId'); + } + + return $clientId; + } + + /** + * Returns the measurement ID. + */ + public function measurementId() + { + return Settings::get('measurement_id'); + } + + /** + * Stores a client ID, retrieved from the client side. + */ + public function onStoreClientId(): void + { + $clientId = post('clientId'); + + if ($clientId) { + Session::put('winter.googleanalytics.clientId', $clientId); + } } } diff --git a/components/Tracker.php b/components/Tracker.php index 9de610b..c5a5a51 100644 --- a/components/Tracker.php +++ b/components/Tracker.php @@ -1,4 +1,6 @@ - { + class Measurement extends Snowboard.Singleton { + construct() { + this.enabled = false; + this.alias = null; + this.measurementId = null; + this.clientId = null; + this.events = []; + } + + listens() { + return { + ready: 'ready', + } + } + + ready() { + this.alias = WINTER_GA_ALIAS; + this.measurementId = WINTER_GA_MEASUREMENT_ID; + this.clientId = WINTER_GA_CLIENT_ID; + + if (!this.alias) { + console.info('Missing Google Analytics measurement component alias. Measurement cannot be enabled.'); + return; + } + + if (!this.measurementId) { + console.info('Missing Google Analytics measurement ID. Measurement cannot be enabled.'); + return; + } + + if (!gtag) { + console.info('Google Tag Manager is not available on this page. Measurement cannot be enabled.'); + return; + } + + gtag('get', this.measurementId, 'client_id', (clientId) => { + if (this.clientId !== clientId) { + Snowboard.request(`${this.alias}::onStoreClientId`, { + data: { + clientId + } + }); + this.clientId = clientId; + } + + this.enabled = true; + this.runEvents(); + }); + } + + event(name, data) { + this.events.push({ + name, + data, + }); + + if (this.enabled) { + this.runEvents(); + } + } + + runEvents() { + this.events.forEach((event) => { + gtag('event', event.name, event.data); + console.log('logged event', event); + }); + this.events = []; + } + } + + Snowboard.addPlugin('winter.googleanalytics.measurement', Measurement); +})(window.Snowboard, window.gtag); diff --git a/components/measurement/default.htm b/components/measurement/default.htm index cf5b7e7..ce0f49f 100644 --- a/components/measurement/default.htm +++ b/components/measurement/default.htm @@ -1,5 +1,6 @@ {% put scripts %} + const WINTER_GA_ALIAS = '{{ __SELF__.alias }}'; + const WINTER_GA_MEASUREMENT_ID = '{{ __SELF__.measurementId }}'; + const WINTER_GA_CLIENT_ID = '{{ __SELF__.clientId }}'; {% endput %} diff --git a/lang/en/lang.php b/lang/en/lang.php index fd1d767..933038a 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -52,6 +52,8 @@ 'engagement' => 'Engagement', 'measurement' => 'Measurement', 'measurement_desc' => 'Add event tracking in your pages.', + 'measurement_view_event' => 'View page event', + 'measurement_view_event_desc' => 'Defines an event to fire off when the page loads.', ], 'settings' => [ 'project_name' => 'Google API Project name', From a14a0aa01aec72ca9d7f785f5a6046f31dfc2a66 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 4 Nov 2022 15:43:18 +0800 Subject: [PATCH 5/6] Fix missing script end tag --- components/measurement/default.htm | 1 + 1 file changed, 1 insertion(+) diff --git a/components/measurement/default.htm b/components/measurement/default.htm index ce0f49f..f7c2aa3 100644 --- a/components/measurement/default.htm +++ b/components/measurement/default.htm @@ -3,4 +3,5 @@ const WINTER_GA_ALIAS = '{{ __SELF__.alias }}'; const WINTER_GA_MEASUREMENT_ID = '{{ __SELF__.measurementId }}'; const WINTER_GA_CLIENT_ID = '{{ __SELF__.clientId }}'; + {% endput %} From 71ce62f7be7b9df62e9dd9864f78ab633f3807d8 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 29 Nov 2022 14:34:28 -0600 Subject: [PATCH 6/6] Update components/tracker/default.htm --- components/tracker/default.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/tracker/default.htm b/components/tracker/default.htm index 2de1bd1..471a6fc 100644 --- a/components/tracker/default.htm +++ b/components/tracker/default.htm @@ -5,6 +5,6 @@ gtag('js', new Date()); gtag('config', '{{ __SELF__.trackingId }}', { - cookie_domain: '{{ __SELF__.domainName|default('auto') }}', + cookie_domain: '{{ __SELF__.domainName | default('auto') }}', });