diff --git a/dist/angulartics-ga.min.js b/dist/angulartics-ga.min.js index 1d71e61..39f4505 100644 --- a/dist/angulartics-ga.min.js +++ b/dist/angulartics-ga.min.js @@ -1,2 +1,2 @@ -!function(window,angular,undefined){"use strict";angular.module("angulartics.google.analytics",["angulartics"]).config(["$analyticsProvider",function($analyticsProvider){function dimensionsAndMetrics(properties){if(detectUniversalAnalytics()){var key,customData={};for(key in properties)key.indexOf("dimension")&&key.indexOf("metric")||(customData[key]=properties[key]);return customData}}function eventTrack(action,properties){if(!$analyticsProvider.settings.ga.disableEventTracking){if(properties&&properties.category||(properties=properties||{},properties.category="Event"),properties.value){var parsed=parseInt(properties.value,10);properties.value=isNaN(parsed)?0:parsed}if(properties.hitCallback&&"function"!=typeof properties.hitCallback&&(properties.hitCallback=null),properties.hasOwnProperty("nonInteraction")||(properties.nonInteraction=properties.noninteraction),detectUniversalAnalytics()){var eventOptions={eventCategory:properties.category,eventAction:action,eventLabel:properties.label,eventValue:properties.value,nonInteraction:properties.nonInteraction,page:properties.page||window.location.hash.substring(1)||window.location.pathname,userId:$analyticsProvider.settings.ga.userId,hitCallback:properties.hitCallback},dimsAndMets=dimensionsAndMetrics(properties);angular.extend(eventOptions,dimsAndMets),$analyticsProvider.settings.ga.transport&&angular.extend(eventOptions,$analyticsProvider.settings.ga.transport),ga("send","event",eventOptions),angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){ga(accountName+".send","event",eventOptions)})}else detectClassicAnalytics()&&_gaq.push(["_trackEvent",properties.category,action,properties.label,properties.value,properties.nonInteraction])}}function transactionTrackUa(transaction){var product,item,i,isEnhancedEcommerce=$analyticsProvider.settings.ga.enhancedEcommerce,plugin=isEnhancedEcommerce?"ec":"ecommerce",addTransCmd=isEnhancedEcommerce?["ec:setAction","purchase"]:["ecommerce:addTransaction"],addItemCmd=isEnhancedEcommerce?"ec:addProduct":"ecommerce:addItem",dimsAndMets=dimensionsAndMetrics(transaction),purchase={id:transaction.id,affiliation:transaction.affiliation,revenue:transaction.revenue,tax:transaction.tax,shipping:transaction.shipping,coupon:transaction.coupon,currency:transaction.currency,currencyCode:transaction.currency};for(isEnhancedEcommerce||angular.extend(purchase,dimsAndMets),addTransCmd.push(purchase),ga("require",plugin),ga.apply(this,addTransCmd),i=0;i-1&&$analyticsProvider.settings.ga.enhancedEcommerce)switch(command){case"ecommerce:addTransaction":command=["ec:setAction","purchase"];break;case"ecommerce:addItem":command="ec:addProduct",fieldsObj.id=fieldsObj.sku;break;case"ecommerce:send":command="send",fieldsObj.hitType="event",fieldsObj.eventCategory="Angulartics Enhanced Ecommerce",fieldsObj.eventAction="Purchase",fieldsObj.nonInteraction=!0}"require"===command&&"ecommerce"===fieldsObj&&$analyticsProvider.settings.ga.enhancedEcommerce&&(fieldsObj="ec"),uaCommand=command instanceof Array?command.concat(fieldsObj):[command,fieldsObj],window[gaNamespace].apply(this,uaCommand),shouldCopyHit&&(userId&&!$analyticsProvider.settings.ga.additionalAccountHitTypes.userId&&delete fieldsObj.userId,angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){var uaCommandClone=[].slice.call(uaCommand);uaCommandClone[0]=accountName+"."+uaCommandClone[0],window[gaNamespace].apply(this,uaCommandClone)}))}function dispatchToClassic_(command,fieldsObj,shouldCopyHit){if("set"===command)return console.log('Classic Analytics does not support the "set" command or Custom Dimensions. Command ignored.');var classicCommand;if("send"===command)switch(fieldsObj.hitType){case"pageview":classicCommand=["_trackPageview",fieldsObj.page];break;case"event":classicCommand=["_trackEvent",fieldsObj.category,fieldsObj.action,fieldsObj.label,fieldsObj.value,fieldsObj.nonInteraction];break;case"timing":classicCommand=["_trackTiming",fieldsObj.timingCategory,fieldsObj.timingVar,fieldsObj.timingValue,fieldsObj.timingLabel,fieldsObj.optSampleRate]}return"ecommerce:addTransaction"===command&&(classicCommand=["_addTrans",fieldsObj.id,fieldsObj.affiliation,fieldsObj.revenue,fieldsObj.tax,fieldsObj.shipping,fieldsObj.billingCity,fieldsObj.billingRegion,fieldsObj.billingCountry]),"ecommerce:addItem"===command&&(classicCommand=["_addItem",fieldsObj.id,fieldsObj.sku,fieldsObj.name,fieldsObj.category,fieldsObj.price,fieldsObj.quantity]),"_set"===command&&(classicCommand=["_set","currencyCode",fieldsObj]),"ecommerce:send"===command&&(classicCommand=["_trackTrans"]),classicCommand?(window._gaq.push(classicCommand),void(shouldCopyHit&&angular.forEach($analyticsProvider.settings.ga.additionalAccountNames,function(accountName){var classicCommandClone=[].slice.call(classicCommand);classicCommandClone[0]=accountName+"."+classicCommandClone[0],window._gaq.push(classicCommandClone)}))):console.log("Unable to find command "+command+" or fieldsObj missing required properties. Command ignored.")}var handler;return detectClassicAnalytics()&&(handler=dispatchToClassic_),detectUniversalAnalytics()&&(handler=dispatchToUniversal_),handler?function(method,command,fieldsObj){var shouldCopyHit=$analyticsProvider.settings.ga.additionalAccountHitTypes[method];handler(command,fieldsObj,shouldCopyHit)}:(console.log("Error: neither Classic nor Universal Analytics detected at bootstrap. Angulartics-GA will ignore all commands!"),angular.noop)}()}])}(window,window.angular); //# sourceMappingURL=../dist/angulartics-ga.min.js.map \ No newline at end of file diff --git a/dist/angulartics-ga.min.js.map b/dist/angulartics-ga.min.js.map index e5548e9..4db0ba9 100644 --- a/dist/angulartics-ga.min.js.map +++ b/dist/angulartics-ga.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lib/angulartics-ga.js"],"names":["window","angular","undefined","module","config","$analyticsProvider","dimensionsAndMetrics","properties","detectUniversalAnalytics","key","customData","indexOf","eventTrack","action","settings","ga","disableEventTracking","category","value","parsed","parseInt","isNaN","hitCallback","hasOwnProperty","nonInteraction","noninteraction","eventOptions","eventCategory","eventAction","eventLabel","label","eventValue","page","location","hash","substring","pathname","userId","dimsAndMets","extend","transport","forEach","additionalAccountNames","accountName","detectClassicAnalytics","_gaq","push","transactionTrackUa","transaction","product","item","i","isEnhancedEcommerce","enhancedEcommerce","plugin","addTransCmd","addItemCmd","purchase","id","affiliation","revenue","tax","shipping","coupon","currency","currencyCode","apply","this","products","length","name","price","quantity","brand","variant","sku","transactionTrackClassic","total","billingCity","billingRegion","billingCountry","gaNamespace","GoogleAnalyticsObject","pageTracking","trackRelativePath","disablePageTracking","registerPageTrack","path","registerEventTrack","registerExceptionTrack","error","cause","toString","stack","registerSetUsername","registerSetUserProperties","registerUserTimings","timingCategory","timingVar","timingValue","console","log","registerTransactionTrack"],"mappings":"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","file":"dist/angulartics-ga.min.js","sourceRoot":".."} \ No newline at end of file +{"version":3,"sources":["lib/angulartics-ga.js"],"names":["window","angular","undefined","module","config","$analyticsProvider","detectUniversalAnalytics","gaNamespace","GoogleAnalyticsObject","detectClassicAnalytics","isUndefined","_gaq","dimensionsAndMetrics","properties","key","customData","indexOf","settings","pageTracking","trackRelativePath","ga","additionalAccountNames","additionalAccountHitTypes","pageview","event","exception","ecommerce","userTiming","setUserProperties","userId","disableEventTracking","disablePageTracking","enhancedEcommerce","registerPageTrack","path","dispatchToGa","extend","hitType","page","registerEventTrack","action","console","log","category","value","parsed","parseInt","isNaN","isFunction","hitCallback","nonInteraction","noninteraction","eventCategory","eventAction","eventLabel","label","eventValue","location","hash","substring","pathname","registerExceptionTrack","error","cause","toString","stack","isException","registerSetUsername","registerSetUserProperties","registerUserTimings","isObject","isArray","forEach","prop","timingCategory","timingVar","timingValue","timingLabel","optSampleRate","registerTransactionTrack","transaction","product","i","products","length","sku","id","currencyCode","dispatchToUniversal_","command","fieldsObj","shouldCopyHit","uaCommand","Array","concat","apply","this","accountName","uaCommandClone","slice","call","dispatchToClassic_","classicCommand","affiliation","revenue","tax","shipping","billingCity","billingRegion","billingCountry","name","price","quantity","push","classicCommandClone","handler","method","noop"],"mappings":"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","file":"dist/angulartics-ga.min.js","sourceRoot":".."} \ No newline at end of file diff --git a/lib/angulartics-ga.js b/lib/angulartics-ga.js index 31a17a2..3671657 100644 --- a/lib/angulartics-ga.js +++ b/lib/angulartics-ga.js @@ -16,48 +16,44 @@ angular.module('angulartics.google.analytics', ['angulartics']) // Set the default settings for this module $analyticsProvider.settings.ga = { additionalAccountNames: undefined, + // Select hits to send to all additional accounts + additionalAccountHitTypes: { + pageview: true, + event: true, + exception: false, + ecommerce: false, + userTiming: false, + setUserProperties: false, + userId: false + }, disableEventTracking: null, disablePageTracking: null, userId: null, enhancedEcommerce: false }; - function dimensionsAndMetrics(properties) { - if (detectUniversalAnalytics()) { - // add custom dimensions and metrics - var customData = {}; - var key; - - for (key in properties) { - if (!key.indexOf('dimension') || !key.indexOf('metric')) { - customData[key] = properties[key]; - } - } - return customData; - } - } - + /** + * Track Pageview in GA + * @name pageTrack + * + * @param {string} path value of Page dimension stored with hit e.g. '/home' + * @param {object} properties Object with optional addtional Custom Dimensions/Metrics + * + * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/pages + * @link https://developers.google.com/analytics/devguides/collection/gajs/ + */ $analyticsProvider.registerPageTrack(function (path, properties) { + properties = properties || {}; + // Do nothing if page tracking is disabled if ($analyticsProvider.settings.ga.disablePageTracking) return; - if (detectClassicAnalytics()) { - _gaq.push(['_trackPageview', path]); - angular.forEach($analyticsProvider.settings.ga.additionalAccountNames, function (accountName){ - _gaq.push([accountName + '._trackPageview', path]); - }); - } - if (detectUniversalAnalytics()) { - var dimsAndMets = dimensionsAndMetrics(properties); - if ($analyticsProvider.settings.ga.userId) { - ga('set', 'userId', $analyticsProvider.settings.ga.userId); - } - ga('send', 'pageview', path, dimsAndMets); - angular.forEach($analyticsProvider.settings.ga.additionalAccountNames, function (accountName){ - ga(accountName +'.send', 'pageview', path, dimsAndMets); - }); - } + dispatchToGa('pageview', 'send', angular.extend(dimensionsAndMetrics(properties), { + hitType: 'pageview', + page: path + })); + }); /** @@ -71,18 +67,19 @@ angular.module('angulartics.google.analytics', ['angulartics']) * * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/events */ - $analyticsProvider.registerEventTrack(eventTrack); - - function eventTrack (action, properties) { + $analyticsProvider.registerEventTrack(function(action, properties) { // Do nothing if event tracking is disabled if ($analyticsProvider.settings.ga.disableEventTracking) return; - // Google Analytics requires an Event Category - if (!properties || !properties.category) { - properties = properties || {}; - properties.category = 'Event'; + if (!action && action + '' !== '0') { + return console.log('Missing required argument action'); } + + // Sets default properties + properties = properties || {}; + properties.category = properties.category || 'Event'; + // GA requires that eventValue be an integer, see: // https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventValue // https://github.com/luisfarzati/angulartics/issues/81 @@ -93,49 +90,26 @@ angular.module('angulartics.google.analytics', ['angulartics']) // GA requires that hitCallback be an function, see: // https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits#hitcallback - if (properties.hitCallback && (typeof properties.hitCallback !== 'function')) { + if (!angular.isFunction(properties.hitCallback)) { properties.hitCallback = null; } // Making nonInteraction parameter more intuitive, includes backwards compatibilty // https://github.com/angulartics/angulartics-google-analytics/issues/49 - if (!properties.hasOwnProperty('nonInteraction')) { - properties.nonInteraction = properties.noninteraction; - } - - if (detectUniversalAnalytics()) { - - var eventOptions = { - eventCategory: properties.category, - eventAction: action, - eventLabel: properties.label, - eventValue: properties.value, - nonInteraction: properties.nonInteraction, - page: properties.page || window.location.hash.substring(1) || window.location.pathname, - userId: $analyticsProvider.settings.ga.userId, - hitCallback: properties.hitCallback - }; - - // Round up any dimensions and metrics for this hit - var dimsAndMets = dimensionsAndMetrics(properties); - angular.extend(eventOptions, dimsAndMets); - - // Add transport settings - if($analyticsProvider.settings.ga.transport) { - angular.extend(eventOptions, $analyticsProvider.settings.ga.transport); - } + properties.nonInteraction = properties.nonInteraction || properties.noninteraction; + + dispatchToGa('event', 'send', angular.extend(dimensionsAndMetrics(properties), { + hitType: 'event', + eventCategory: properties.category, + eventAction: action, + eventLabel: properties.label, + eventValue: properties.value, + nonInteraction: properties.nonInteraction, + page: properties.page || window.location.hash.substring(1) || window.location.pathname, + hitCallback: properties.hitCallback, + })); - ga('send', 'event', eventOptions); - - angular.forEach($analyticsProvider.settings.ga.additionalAccountNames, function (accountName){ - ga(accountName +'.send', 'event', eventOptions); - }); - - } else if (detectClassicAnalytics()) { - _gaq.push(['_trackEvent', properties.category, action, properties.label, properties.value, properties.nonInteraction]); - } - - } + }); /** * Exception Track Event in GA @@ -148,10 +122,14 @@ angular.module('angulartics.google.analytics', ['angulartics']) * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/events */ $analyticsProvider.registerExceptionTrack(function (error, cause) { - eventTrack(error.toString(), { - category: 'Exceptions', - label: error.stack, - nonInteraction: true + dispatchToGa('exception', 'send', { + hitType: 'event', + eventCategory: 'Exceptions', + eventAction: error.toString(), + eventLabel: error.stack, + nonInteraction: true, + page: window.location.hash.substring(1) || window.location.pathname, + isException: true }); }); @@ -176,11 +154,11 @@ angular.module('angulartics.google.analytics', ['angulartics']) * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs */ $analyticsProvider.registerSetUserProperties(function (properties) { - if(properties && detectUniversalAnalytics()) { - // add custom dimensions and metrics to each hit - var dimsAndMets = dimensionsAndMetrics(properties); - ga('set', dimsAndMets); + + if (properties) { + dispatchToGa('setUserProperties', 'set', dimensionsAndMetrics(properties)); } + }); /** @@ -193,18 +171,33 @@ angular.module('angulartics.google.analytics', ['angulartics']) * 'timingValue' (number) * Properties can also have the optional fields: * 'timingLabel' (string) + * 'optSampleRate' (number) Classic Analytics only - determines % of users to collect data from, handled serverside by UA + * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings#sampling_considerations * * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings */ $analyticsProvider.registerUserTimings(function (properties) { - if (!properties || !properties.timingCategory || !properties.timingVar || typeof properties.timingValue === 'undefined') { - console.log('Properties timingCategory, timingVar, and timingValue are required to be set.'); - return; - } - if(detectUniversalAnalytics()) { - ga('send', 'timing', properties); + if (!angular.isObject(properties) || angular.isArray(properties)) { + return console.log('Required argument properties is missing or not an object'); } + + angular.forEach(['timingCategory', 'timingVar', 'timingValue'], function(prop) { + if (angular.isUndefined(properties[prop])) { + return console.log('Argument properties missing required property ' + prop); + } + }); + + dispatchToGa('userTiming', 'send', { + hitType: 'timing', + timingCategory: properties.timingCategory, + timingVar: properties.timingVar, + timingValue: properties.timingValue, + timingLabel: properties.timingLabel, + optSampleRate: properties.optSampleRate, // Classic Analytics only + page: properties.page || window.location.hash.substring(1) || window.location.pathname, + }); + }); /** @@ -251,204 +244,327 @@ angular.module('angulartics.google.analytics', ['angulartics']) * Docs on Enhanced Ecommerce * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce * - * * Docs on Classic Ecommerce (_gaq) * @link https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingEcommerce **/ $analyticsProvider.registerTransactionTrack(function(transaction) { - if (!transaction.id && transaction.id + '' !== '0') { + var product; + var i; + + // Universal Analytics splits off the ecommerce code into a separate + // library we must include by using the "require" command + dispatchToGa('ecommerce', 'require', 'ecommerce'); + dispatchToGa('ecommerce', 'ecommerce:addTransaction', transaction); + + if (transaction.products) { + for (i = 0; i < transaction.products.length; i++) { + + product = transaction.products[i]; - return console.log('Missing required field transaction.id'); + // GA uses a SKU property and stores the transaction ID in the ID Field + product.sku = product.id; + product.id = transaction.id; + dispatchToGa('ecommerce', 'ecommerce:addItem', transaction.products[i]); + + } } - if (detectUniversalAnalytics()) { + if (transaction.currencyCode) { + + dispatchToGa('ecommerce', '_set', transaction.currencyCode); // Classic Anayltics only - UA uses fieldsObj.currencyCode instead + + } + + dispatchToGa('ecommerce', 'ecommerce:send', dimensionsAndMetrics(transaction)); + + }); + + /** + * Detects if Universal Analytics is installed + * + * @name detectUniversalAnalytics + */ + function detectUniversalAnalytics() { + + // Use the GoogleAnalyticsObject property set by the default GA snippet + // to correctly determine the namespace of the GA global + var gaNamespace = window.GoogleAnalyticsObject; + return gaNamespace && window[gaNamespace]; + + } + + /** + * Detects if Classic Analytics is installed + * + * @name detectClassicAnalytics + */ + function detectClassicAnalytics() { + + // If _gaq is undefined, we're trusting Classic Analytics to be there + return !angular.isUndefined(window._gaq); - return transactionTrackUa(transaction); + } + + /** + * Extract Custom Data for a hit + * @name dimensionsAndMetrics + * + * @param {object} properties properties object from an API call that is filtered for Custom Dimensions & Metrics + * + * @returns {object} customData object with only Custom Dimensions/Metrics from properties argument + */ + function dimensionsAndMetrics(properties) { + // add custom dimensions and metrics + var customData = {}; + var key; + + for (key in properties) { + // Keys must be dimensionXX or metricXX, e.g. dimension1, metric155, so + // if those strings aren't at zero (which evaluates to falsey), ignore + // the key + if (!key.indexOf('dimension') || !key.indexOf('metric')) { + customData[key] = properties[key]; + } + } + return customData; + } - } else if (detectClassicAnalytics()) { + /** + * Handler for hits to GA. Dynamically adjusts syntax for + * targeted version based on global detection. + * + * @name dispatchToGa + * + * @param {string} method Name of angulartics method for checking if hits should be duplicated + * @param {string} command Standard Universal Analytics command (create, send, set) + * @param {object} fieldsObj object with hit-specific fields. Fields are whitelisted in handler - non-supported fields are ignored. + * + */ + var dispatchToGa = (function() { - return transactionTrackClassic(transaction); + var handler; + if (detectClassicAnalytics()) { + handler = dispatchToClassic_; } - }); + if (detectUniversalAnalytics()) { + handler = dispatchToUniversal_; + } - function transactionTrackUa(transaction) { - - // Detect whether the plugin has been configured for traditional or enhanced - var isEnhancedEcommerce = $analyticsProvider.settings.ga.enhancedEcommerce; - // Dynamically establish the name of the Google Analytics plugin we'll need to require - var plugin = isEnhancedEcommerce ? 'ec' : 'ecommerce'; - // Dynamically establish the name of the command that creates a transaction - var addTransCmd = isEnhancedEcommerce ? ['ec:setAction', 'purchase'] : ['ecommerce:addTransaction']; - // Dynamically establish the name of the command that adds an item to the purchase - var addItemCmd = isEnhancedEcommerce ? 'ec:addProduct' : 'ecommerce:addItem'; - // Get any dimensions and metrics set on the transaction ready - var dimsAndMets = dimensionsAndMetrics(transaction); - // Create our purchase object. EE properties are ignored by GA if the - // transaction is being tracked with traditional ecommerce, so we - // set those even if the hit isn't an EE transaction - var purchase = { - id: transaction.id, - affiliation: transaction.affiliation, - revenue: transaction.revenue, - tax: transaction.tax, - shipping: transaction.shipping, - coupon: transaction.coupon, // Enhanced Ecommerce only - currency: transaction.currency, - currencyCode: transaction.currency - }; - // Declare some variables for later - var product; - var item; - var i; + // If neither has been detected, GA is not above the angular code + if (!handler) { + console.log('Error: neither Classic nor Universal Analytics detected at bootstrap. Angulartics-GA will ignore all commands!'); + return angular.noop; + } - if (!isEnhancedEcommerce) { + return function(method, command, fieldsObj) { - angular.extend(purchase, dimsAndMets); + var shouldCopyHit = $analyticsProvider.settings.ga.additionalAccountHitTypes[method]; + handler(command, fieldsObj, shouldCopyHit); } - - // Add our purchase to our addTransCmd - addTransCmd.push(purchase); - - // Tell Google Analytics to load the necessary plugin - ga('require', plugin); - - ga.apply(this, addTransCmd); - - for (i = 0; i < transaction.products.length; i++) { - - product = transaction.products[i]; - // Products can have product-level custom dimensions - // and metrics, so we fish any of those out of the - // product object and then extend the result with - // the standard product fields. - item = angular.extend(dimensionsAndMetrics(product), { - name: product.name, - price: product.price, - category: product.category, - quantity: product.quantity - }); - - // If we're using Enhanced Ecommerce, add in EE-specific - // product fields, too - if (isEnhancedEcommerce) { - - item.brand = product.brand; - item.variant = product.variant; - item.coupon = product.coupon; - item.id = product.id; - item.currencyCode = product.currencyCode; - - } else { - - // Traditional ecommerce requires the Transaction ID as a field - // for all products - item.id = transaction.id; - item.sku = product.id; - item.currency = product.currencyCode; + + /** + * Dispatches a hit using Universal syntax + * + * @name dispatchToUniversal_ + * @private + * + * @param {string} command Standard Universal Analytics command (create, send, set) + * @param {object} fieldsObj object with hit-specific fields. Fields are whitelisted in handler - non-supported fields are ignored. + * @param {boolean} shouldCopyHit should hit be propogated to all trackers + */ + function dispatchToUniversal_(command, fieldsObj, shouldCopyHit) { + + var gaNamespace = window.GoogleAnalyticsObject; + var userId = $analyticsProvider.settings.ga.userId; + var uaCommand; + + if (userId && angular.isObject(fieldsObj)) fieldsObj.userId = userId; + + if (command.indexOf('ecommerce:') > -1 && $analyticsProvider.settings.ga.enhancedEcommerce) { + + switch (command) { + case 'ecommerce:addTransaction': + command = ['ec:setAction', 'purchase']; + break; + case 'ecommerce:addItem': + command = 'ec:addProduct'; + // Enhanced Ecommerce reverts to using the ID property for the SKU, + // so we swap them back here + fieldsObj.id = fieldsObj.sku; + break; + case 'ecommerce:send': + command = 'send'; + fieldsObj.hitType = 'event'; + fieldsObj.eventCategory = 'Angulartics Enhanced Ecommerce'; + fieldsObj.eventAction = 'Purchase'; + fieldsObj.nonInteraction = true; + break; + } } + + if (command === 'require' && fieldsObj === 'ecommerce') { + + if ($analyticsProvider.settings.ga.enhancedEcommerce) { - // Issue the command to add our item to the transaction - ga(addItemCmd, item); + fieldsObj = 'ec'; - } + } + + } - if (isEnhancedEcommerce) { + uaCommand = command instanceof Array ? command.concat(fieldsObj) : [command, fieldsObj]; + + window[gaNamespace].apply(this, uaCommand); - // Enhanced Ecommerce data must be combined with - // another hit, and is not transmitted by itself. - // Google Analytics will send the transaction we've created - // with the next hit we dispatch, then clear the stored data - // and since GA won't read the dims and mets off our transaction - // we need to apply them to our Event hit instead. - eventTrack(purchase.id, angular.extend(dimsAndMets, { - category: 'Enhanced Ecommerce', - nonInteraction: true - })); + if (shouldCopyHit) { - } else { + // If the userId shouldn't be duplicated, remove from the fieldsObj + if (userId && !$analyticsProvider.settings.ga.additionalAccountHitTypes.userId) { + delete fieldsObj.userId; + } - // Dispatch the transaction per usual - ga('ecommerce:send', dimsAndMets); + angular.forEach($analyticsProvider.settings.ga.additionalAccountNames, function (accountName){ + + var uaCommandClone = [].slice.call(uaCommand); + uaCommandClone[0] = accountName + '.' + uaCommandClone[0]; + + window[gaNamespace].apply(this, uaCommandClone); + + }); + + } } - } + /** + * Dispatches a hit using Classic syntax + * Translates Universal Syntax to Classic syntax + * + * @name dispatchToClassic_ + * @private + * + * @param {string} command Standard Universal Analytics command (create, send, set) + * @param {object} fieldsObj object with hit-specific fields. Fields are whitelisted in handler - non-supported fields are ignored. + * @param {boolean} shouldCopyHit should hit be propogated to all trackers + */ + function dispatchToClassic_(command, fieldsObj, shouldCopyHit) { + + if (command === 'set') { + return console.log('Classic Analytics does not support the "set" command or Custom Dimensions. Command ignored.'); + } - function transactionTrackClassic(transaction) { - - // Build our purchase array - var purchase = [ - '_addTrans', - transaction.id, - transaction.affiliation, - transaction.total, - transaction.tax, - transaction.shipping, - transaction.billingCity, - transaction.billingRegion, - transaction.billingCountry - ]; - var product; - var item; - var i; + var classicCommand; + + // Transpose our syntax from Universal Analytics to Classic Analytics + // Currently we only support 'send' style commands + if (command === 'send') { + + switch(fieldsObj.hitType) { + case 'pageview': + classicCommand = ['_trackPageview', fieldsObj.page]; + break; + case 'event': + classicCommand = [ + '_trackEvent', + fieldsObj.category, + fieldsObj.action, + fieldsObj.label, + fieldsObj.value, + fieldsObj.nonInteraction + ]; + break; + case 'timing': + classicCommand = [ + '_trackTiming', + fieldsObj.timingCategory, + fieldsObj.timingVar, + fieldsObj.timingValue, + fieldsObj.timingLabel, + fieldsObj.optSampleRate + ]; + break; + } - // Issue the command to create a purchase - _gaq.push(purchase); + } - // Add in our products - for (i = 0; i < transaction.products.length; i++) { + if (command === 'ecommerce:addTransaction') { - product = transaction.products[i]; - item = [ - '_addItem', - transaction.id, - product.id, - product.name, - product.category, - product.price, - product.quantity - ]; + classicCommand = [ + '_addTrans', + fieldsObj.id, + fieldsObj.affiliation, + fieldsObj.revenue, + fieldsObj.tax, + fieldsObj.shipping, + fieldsObj.billingCity, + fieldsObj.billingRegion, + fieldsObj.billingCountry + ]; - _gaq.push(item); + } - } + if (command === 'ecommerce:addItem') { - // If a currencyCode is set for the transaction, set it - if (transaction.currencyCode) { + classicCommand = [ + '_addItem', + fieldsObj.id, + fieldsObj.sku, + fieldsObj.name, + fieldsObj.category, + fieldsObj.price, + fieldsObj.quantity + ]; - _gaq.push(['_set', 'currencyCode', transaction.currencyCode]); + } - } + if (command === '_set') { - // Issue the command to fire our transaction - _gaq.push(['_trackTrans']); + classicCommand = [ + '_set', + 'currencyCode', + fieldsObj + ]; - } + } - function detectUniversalAnalytics() { + if (command === 'ecommerce:send') { - // The Google Analytics snippet stores the name of the GA Global - // in the window property GoogleAnalyticsObject. Detecting UA - // with this parameter accounts for edge cases where the user - // has manually changed this value by adjusting the default - // snippet. - var gaNamespace = window.GoogleAnalyticsObject; - return gaNamespace && window[gaNamespace]; + classicCommand = [ + '_trackTrans' + ]; - } + } - function detectClassicAnalytics() { + if (!classicCommand) { + return console.log('Unable to find command ' + command + ' or fieldsObj missing required properties. Command ignored.'); + } - // If _gaq is undefined, we're trusting Classic Analytics to be there - return typeof window._gaq !== 'undefined'; + // Issue our command to GA + window._gaq.push(classicCommand); - } + if (shouldCopyHit) { + + angular.forEach($analyticsProvider.settings.ga.additionalAccountNames, function (accountName){ + + var classicCommandClone = [].slice.call(classicCommand); + // Namespace the command as required + classicCommandClone[0] = accountName + '.' + classicCommandClone[0]; + + window._gaq.push(classicCommandClone); + + }); + + } + + } + + })(); }]); })(window, window.angular);