Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
198 lines (153 sloc) 6.68 KB
<?php
// $Id$
/**
* Google Analytics Custom Variables
* by Ben Buckman @ NewLeafDigital.com
*
* see README for more info
*/
// vars to define scopes (see http://code.google.com/intl/en/apis/analytics/docs/tracking/gaTrackingCustomVariables.html)
// [not entirely intuitive, read the docs]
define('GA_CUSTOMVARS_PAGE_LEVEL', 3);
define('GA_CUSTOMVARS_SESSION_LEVEL', 2);
define('GA_CUSTOMVARS_VISITOR_LEVEL', 1);
/**
* Implementation of hook_perm().
* used mostly for _lookup submodule
*/
function ga_customvars_perm() {
return array('administer ga_customvars');
}
/**
* get a list of custom vars to set - some hard-coded, some hooked/custom
* just the variable KEYS, not the values
*/
function ga_customvars_get_var_keys() {
// indexes should be fixed; only 5 allowed
$keys = array_fill_keys(array(1,2,3,4,5), NULL); // placeholders
// hook_ga_customvars_define: should return an array of #s => keys (with #s being 3-5)
// - requesting # so it's consistent, can be queried from API
$additional_keys = module_invoke_all('ga_customvars_define');
foreach((array) $additional_keys as $key => $spec) {
// allow for simple key=>slot returns for page vars
if (! is_array($spec)) $spec = array('slot' => $spec, 'scope' => GA_CUSTOMVARS_PAGE_LEVEL);
if (! array_key_exists($spec['slot'], $keys)) { // no such key
drupal_set_message(t("Too many Google Analytics custom variables set, no room for @key", array('@key' => $key)), 'error');
}
elseif (! is_null($keys[ $spec['slot'] ])) { // already used
drupal_set_message(t("Google Analytics custom variable #@ind already set to @used, can't use for @key",
array('@ind' => $spec['slot'], '@used' => $keys[ $spec['slot'] ], '@key' => $key)), 'error');
}
else { // available
// flip the structure -- index by SLOT this time
$keys[ $spec['slot'] ] = array('key' => $key, 'scope' => GA_CUSTOMVARS_PAGE_LEVEL);
}
}
return $keys;
}
/**
* set a variable value (by key)
* key needs to be defined separately to be used
* also used to GET variables if no key/value set
*/
function ga_customvars_set($key = NULL, $value = NULL) {
static $ga_vars = array();
if (! is_null($key)) {
$ga_vars[$key] = $value;
}
return $ga_vars;
}
/**
* default hook_ga_customvars_define
* should return an array of $key => array('slot' => [1-5], 'scope' => [scope constant])
*/
function ga_customvars_ga_customvars_define() {
return array(
'nid' => array('slot' => 1, 'scope' => GA_CUSTOMVARS_PAGE_LEVEL),
'nodetype' => array('slot' => 2, 'scope' => GA_CUSTOMVARS_PAGE_LEVEL),
// -- disabling these, won't work w/ cached pages and probably violates GA ToS --
// 'uid' => array('slot' => 2, 'scope' => GA_CUSTOMVARS_SESSION_LEVEL),
// 'loggedin' => array('slot' => 3, 'scope' => GA_CUSTOMVARS_SESSION_LEVEL),
);
}
/**
* get the JS for all the vars
*/
function _ga_customvars_js() {
$js = '';
// $keys are structured $slot => array(key, scope)
$keys = ga_customvars_get_var_keys();
// $values are structured $key => $value
$values = ga_customvars_set();
foreach($keys as $slot => $spec) {
$key = $spec['key'];
if (empty($key)) continue;
$value = isset($values[$key]) ? $values[$key] : '';
// - example from the docs (old async method) -
// pageTracker._setCustomVar(
// 1, // This custom var is set to slot #1. Required parameter.
// "Items Removed", // The name acts as a kind of category for the user activity. Required parameter.
// "Yes", // This value of the custom variable. Required parameter.
// 2 // Sets the scope to session-level. Optional parameter.
// );
// - and new sync method -
// _gaq.push(['_setCustomVar',
// 1, // This custom var is set to slot #1. Required parameter.
// 'Items Removed', // The name acts as a kind of category for the user activity. Required parameter.
// 'Yes', // This value of the custom variable. Required parameter.
// 2 // Sets the scope to session-level. Optional parameter.
// ]);
// JS if async script is running
$async_js = '_gaq.push(' . drupal_to_js( array('_setCustomVar', $slot, $key, $value, $spec['scope']) ) . ');';
// JS if sync script is running
$sync_js = 'pageTracker._setCustomVar(' . drupal_to_js($slot) . ','
. drupal_to_js($key) . ',' . drupal_to_js($value) . ',' . drupal_to_js($spec['scope']) . ');';
// put in both -- only knows which is running in the JS itself
// (ANY SUGGESTIONS FOR A RELIABLE PHP-SIDE WAY TO CHECK THIS ARE WELCOME)
$js .= 'if(typeof pageTracker != \'undefined\'){' . $sync_js . '} '
. 'else if(typeof _gaq != \'undefined\'){ if(typeof _gaq.push != \'undefined\'){ ' . $async_js . '} } ';
}
// wrap in some error handling & start/end markers
if (! empty($js)) $js = ' /*START-GA-CUSTOMVARS*/ try{ ' . $js . ' } '
. 'catch(e){ if(typeof console != \'undefined\'){ if(typeof console.log != \'undefined\') console.log(\'GA custom var error:\',e);} } '
. '/*END-GA-CUSTOMVARS*/ ';
return $js;
}
/**
* implementation of hook_footer:
* inject our new JS into the 'googleanalytics_codesnippet_before' var used by googleanalytics.module
* [this should run first b/c of weight]
* - hook_footer is invoked in template_preprocess_page, so make sure variable setting is done before that
*/
function ga_customvars_footer() {
$js = _ga_customvars_js();
// hack it in...
// ...what if the existing snippet doesn't end w/ a semicolon, or the new snippet messed it up some other way?
// ...form instructions say to put a semicolon... handle later if it's a real problem
$GLOBALS['conf']['googleanalytics_codesnippet_before'] = (isset($GLOBALS['conf']['googleanalytics_codesnippet_before']) ?
(string)$GLOBALS['conf']['googleanalytics_codesnippet_before'] : '')
. $js;
}
/**
* Implementation of hook_init(): set uid
* -- disabled, see comment above --
*/
// function ga_customvars_init() {
// global $user;
// if (user_is_logged_in()) {
// ga_customvars_set('uid', $user->uid); // segment by individual users
// ga_customvars_set('loggedin', '1'); // segment by general authenticated/anon
// }
// else {
// ga_customvars_set('loggedin', '0');
// }
// }
/**
* Implementation of hook_nodeapi(): set 'nid' var on node pages
*/
function ga_customvars_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($op === 'view' && $page == TRUE) {
ga_customvars_set('nid', $node->nid);
ga_customvars_set('nodetype', $node->type);
}
}