Skip to content

Commit

Permalink
Improved JS tracking code to support multiple calls to mt() without h…
Browse files Browse the repository at this point in the history
…aving to use a timeout, use CORS for page events by default, and update fingerprintjs to 1.4.4
  • Loading branch information
alanhartless committed Jan 6, 2017
1 parent aa4d9a8 commit a6150e8
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 51 deletions.
108 changes: 81 additions & 27 deletions app/bundles/CoreBundle/EventListener/BuildJsSubscriber.php

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions app/bundles/PageBundle/Config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
'path' => '/mtracking.gif',
'controller' => 'MauticPageBundle:Public:trackingImage',
],
'mautic_page_tracker_cors' => [
'path' => '/mtc/event',
'controller' => 'MauticPageBundle:Public:tracking',
],
'mautic_page_tracker_getcontact' => [
'path' => '/mtc',
'controller' => 'MauticPageBundle:Public:getContactId',
Expand Down
16 changes: 15 additions & 1 deletion app/bundles/PageBundle/Controller/PublicController.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,28 @@ public function previewAction($id)
*/
public function trackingImageAction()
{
//Create page entry
/** @var \Mautic\PageBundle\Model\PageModel $model */
$model = $this->getModel('page');
$model->hitPage(null, $this->request);

return TrackingPixelHelper::getResponse($this->request);
}

/**
* @return JsonResponse
*/
public function trackingAction()
{
/** @var \Mautic\PageBundle\Model\PageModel $model */
$model = $this->getModel('page');
$model->hitPage(null, $this->request);

/** @var LeadModel $leadModel */
$leadModel = $this->getModel('lead');

return new JsonResponse(['success' => 1, 'id' => $leadModel->getCurrentLead()->getId()]);
}

/**
* @param $redirectId
*
Expand Down
85 changes: 66 additions & 19 deletions app/bundles/PageBundle/EventListener/BuildJsSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,17 @@ public function onBuildJs(BuildJsEvent $event)
'',
$this->router->generate('mautic_page_tracker', [], UrlGeneratorInterface::ABSOLUTE_URL)
);

$pageTrackingCORSUrl = str_replace(
['http://', 'https://'],
'',
$this->router->generate('mautic_page_tracker_cors', [], UrlGeneratorInterface::ABSOLUTE_URL)
);
$contactIdUrl = $this->router->generate('mautic_page_tracker_getcontact', [], UrlGeneratorInterface::ABSOLUTE_URL);

$js = <<<JS
(function(m, l, n, d) {
m.pageTrackingUrl = (l.protocol == 'https:' ? 'https:' : 'http:') + '//{$pageTrackingUrl}';
m.pageTrackingCORSUrl = (l.protocol == 'https:' ? 'https:' : 'http:') + '//{$pageTrackingCORSUrl}';
m.fingerprint = null;
m.fingerprintComponents = null;
Expand All @@ -89,6 +94,17 @@ public function onBuildJs(BuildJsEvent $event)
params.fingerprint = m.fingerprint;
}
m.deliverPageEvent = function(event, params) {
MauticJS.makeCORSRequest('POST', m.pageTrackingCORSUrl, params,
function(response) {
MauticJS.dispatchEvent('mauticPageEventDelivered', {'event': event, 'params': params, 'response': response});
},
function() {
// CORS failed so load an image
m.buildTrackingImage(event, params);
});
}
m.buildTrackingImage = function(pageview, params) {
m.addFingerprint(params);
delete m.trackingPixel;
Expand All @@ -103,42 +119,73 @@ public function onBuildJs(BuildJsEvent $event)
}
}
}
m.trackingPixel.onload = function(e) {
MauticJS.dispatchEvent('mauticPageEventDelivered', {'event': pageview, 'params': params, 'image': true});
};
m.trackingPixel.src = m.pageTrackingUrl + '?' + m.serialize(params);
}
m.fingerprintIsLoading = false;
m.pageViewCounter = 0;
m.sendPageview = function(pageview) {
var queue = [];
if (!pageview) {
if (typeof m.getInput === 'function') {
var pageview = m.getInput('send', 'pageview');
queue = m.getInput('send', 'pageview');
} else {
return false;
}
} else {
queue.push(pageview);
}
var params = {
page_title: d.title,
page_language: n.language,
page_referrer: (d.referrer) ? d.referrer.split('/')[2] : '',
page_url: l.href
};
if (queue) {
for (var i in queue) {
var event = queue[i];
var params = {
page_title: d.title,
page_language: n.language,
page_referrer: (d.referrer) ? d.referrer.split('/')[2] : '',
page_url: l.href,
counter: m.pageViewCounter
};
// Merge user defined tracking pixel parameters.
if (typeof event[2] === 'object') {
for (var attr in event[2]) {
params[attr] = event[2][attr];
}
}
// Merge user defined tracking pixel parameters.
if (typeof pageview[2] === 'object') {
for (var attr in pageview[2]) {
params[attr] = pageview[2][attr];
m.handleFingerprintInit(event, params);
m.pageViewCounter++;
}
}
}
if (!m.fingerprint) {
m.handleFingerprintInit = function(event, params) {
if (!m.fingerprint && m.fingerprintIsLoading === false) {
m.fingerprintIsLoading = true;
new Fingerprint2().get(function(result, components) {
m.fingerprintIsLoading = false;
m.fingerprint = result;
m.fingerprintComponents = components;
m.buildTrackingImage(pageview, params);
m.deliverPageEvent(event, params);
});
} else if (m.fingerprintIsLoading === true) {
var fingerprintLoop;
fingerprintLoop = window.setInterval(function() {
if (m.fingerprintIsLoading === false) {
m.deliverPageEvent(event, params);
clearInterval(fingerprintLoop);
}
}, 5);
} else {
m.buildTrackingImage(pageview, params);
m.deliverPageEvent(event, params);
}
}
Expand All @@ -149,24 +196,24 @@ public function onBuildJs(BuildJsEvent $event)
document.addEventListener('eventAddedToMauticQueue', function(e) {
m.sendPageview(e.detail);
});
})(MauticJS, location, navigator, document);

MauticJS.getTrackedContact = function () {
var url = '$contactIdUrl';
MauticJS.makeCORSRequest('GET', url, {}, function(response, xhr) {
if (response.id) {
document.cookie = "mtc_id="+response.id+";";
MauticJS.setCookie('mtc_id', response.id);
}
});
};

MauticJS.pixelLoaded(MauticJS.getTrackedContact);
JS;

$event->appendJs($js, 'Mautic Tracking Pixel');
}

/**
* @param BuildJsEvent $event
*/
public function onBuildJsForVideo(BuildJsEvent $event)
{
$formSubmitUrl = $this->router->generate('mautic_form_postresults_ajax', [], UrlGeneratorInterface::ABSOLUTE_URL);
Expand Down
17 changes: 13 additions & 4 deletions app/bundles/PageBundle/Model/PageModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -670,13 +670,22 @@ public function getHitQuery(Request $request, $page = null)
} else {
//use current URL

// Tracking pixel is used
if (strpos($request->server->get('REQUEST_URI'), '/mtracking.gif') !== false) {
$isPageEvent = false;
if (strpos($request->server->get('REQUEST_URI'), $this->router->generate('mautic_page_tracker')) !== false) {
// Tracking pixel is used
if ($request->server->get('QUERY_STRING')) {
parse_str($request->server->get('QUERY_STRING'), $query);
}
} elseif (strpos($request->server->get('REQUEST_URI'), $this->router->generate('mautic_page_tracker_cors')) !== false) {
$query = $request->request->all();
$isPageEvent = true;
}

if ($isPageEvent) {
$pageURL = $request->server->get('HTTP_REFERER');

// if additional data were sent with the tracking pixel
if ($request->server->get('QUERY_STRING')) {
parse_str($request->server->get('QUERY_STRING'), $query);
if (isset($query)) {

// URL attr 'd' is encoded so let's decode it first.
$decoded = false;
Expand Down

0 comments on commit a6150e8

Please sign in to comment.