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..19bcc60 --- /dev/null +++ b/components/Measurement.php @@ -0,0 +1,63 @@ + + */ +class Measurement extends ComponentBase +{ + public function componentDetails() + { + return [ + 'name' => 'winter.googleanalytics::lang.strings.measurement', + 'description' => 'winter.googleanalytics::lang.strings.measurement_desc' + ]; + } + + 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 + { + $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 08a5187..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 new file mode 100644 index 0000000..f7c2aa3 --- /dev/null +++ b/components/measurement/default.htm @@ -0,0 +1,7 @@ +{% put scripts %} + +{% endput %} diff --git a/components/tracker/default.htm b/components/tracker/default.htm index 8c03881..471a6fc 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/lang/en/lang.php b/lang/en/lang.php index 9946d14..933038a 100644 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -50,6 +50,10 @@ 'current' => 'Current', 'goal' => 'Goal', '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', @@ -70,6 +74,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..45d5b81 100644 --- a/models/settings/fields.yaml +++ b/models/settings/fields.yaml @@ -26,16 +26,15 @@ 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 + measurement_id: + tab: winter.googleanalytics::lang.strings.measurement span: left - label: winter.googleanalytics::lang.settings.anonymize_ip - commentAbove: winter.googleanalytics::lang.settings.anonymize_ip_comment + label: winter.googleanalytics::lang.settings.measurement_id + commentAbove: winter.googleanalytics::lang.settings.measurement_id_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_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