Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for tracking measurements #5

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
];
}

Expand Down
Empty file added classes/Measurement.php
Empty file.
63 changes: 63 additions & 0 deletions components/Measurement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Winter\GoogleAnalytics\Components;

use Session;
use Cms\Classes\ComponentBase;
use Winter\GoogleAnalytics\Models\Settings;

/**
* Add measurement capabilities to a page.
*
* @author Ben Thomson <git@alfreido.com>
*/
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);
}
}
}
14 changes: 3 additions & 11 deletions components/Tracker.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace Winter\GoogleAnalytics\Components;
<?php

namespace Winter\GoogleAnalytics\Components;

use Cms\Classes\ComponentBase;
use Winter\GoogleAnalytics\Models\Settings;
Expand All @@ -22,14 +24,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');
}
}
73 changes: 73 additions & 0 deletions components/measurement/assets/js/Measurement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
((Snowboard, gtag) => {
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still required?

});
this.events = [];
}
}

Snowboard.addPlugin('winter.googleanalytics.measurement', Measurement);
})(window.Snowboard, window.gtag);
7 changes: 7 additions & 0 deletions components/measurement/default.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% put scripts %}
<script type="text/javascript">
const WINTER_GA_ALIAS = '{{ __SELF__.alias }}';
const WINTER_GA_MEASUREMENT_ID = '{{ __SELF__.measurementId }}';
const WINTER_GA_CLIENT_ID = '{{ __SELF__.clientId }}';
</script>
{% endput %}
14 changes: 4 additions & 10 deletions components/tracker/default.htm
Original file line number Diff line number Diff line change
Expand Up @@ -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') }}',
});
</script>
8 changes: 8 additions & 0 deletions lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand Down
21 changes: 10 additions & 11 deletions models/settings/fields.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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