Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
340 lines (299 sloc) 10.5 KB
<?php
/**
* Implementation of hook_init().
*/
function mixpanel_init() {
$token = variable_get('mixpanel_token', '');
if (!empty($token)) {
global $user;
if ($user->uid != 0) {
drupal_add_js(drupal_get_path('module', 'mixpanel') . "/mixpanel.js");
$defaults_wrapped = array('defaults' => mixpanel_get_defaults());
drupal_add_js(array('mixpanel' => $defaults_wrapped), 'setting');
}
// Add the Mixpanel tracking code to HTML Head.
$mixpanel_init_code = <<<code
<script type="text/javascript">
var mpq = [];
mpq.push(["init", "$token"]);
(function() {
var mp = document.createElement("script"); mp.type = "text/javascript"; mp.async = true;
mp.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + "//api.mixpanel.com/site_media/js/api/mixpanel.js";
var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(mp, s);
})();
</script>
code;
drupal_set_html_head($mixpanel_init_code);
}
// Track visits to user pages.
if (arg(0) == "user" && is_numeric(arg(1))) {
mixpanel_track("user-view-profile", array('visited-user' => arg(1)));
}
}
/**
* Setup default variables for Mixpanel to send.
*
* @return array of the default mixpanel variables.
**/
function mixpanel_get_defaults($reset = FALSE) {
static $defaults;
global $user;
if (!isset($defaults) || $reset) {
$cohort = format_date($user->created, 'custom', "M-Y");
$defaults = array('uid' => $user->uid,
'cohort' => $cohort,
'distinct_id' => $user->uid,
'ip' => $_SERVER['REMOTE_ADDR'],
);
// Let other modules alter the defaults.
drupal_alter('mixpanel_defaults', $defaults);
}
return $defaults;
}
/**
* Implementation of hook_menu().
*/
function mixpanel_menu() {
# Administration
$items['admin/settings/mixpanel'] = array(
'title' => 'Mixpanel',
'description' => t('Add your Mixpanel token for this domain.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('mixpanel_admin_settings'),
'access arguments' => array('access administration pages'),
);
return $items;
}
/**
* Admin settings form
*/
function mixpanel_admin_settings() {
$form['mixpanel_token'] = array(
'#title' => t('Mixpanel Token'),
'#type' => 'textfield',
'#default_value' => variable_get('mixpanel_token', ''),
'#description' => t('The token you got from mixpanel.com for this domain.'),
);
return system_settings_form($form);
}
/**
* Implementation of hook_requirements().
*/
function mixpanel_requirements($phase) {
$requirements = array();
if ($phase == 'runtime') {
// Raise warning if mixpanel token has not been set yet.
if (variable_get('mixpanel_token', '') == '') {
$requirements['mixpanel'] = array(
'title' => t('Mixpanel module'),
'description' => t('The Mixpanel module has not been configured yet. Please configure its settings from the <a href="@url">Mixpanel settings page</a>.', array('@url' => url('admin/settings/mixpanel'))),
'severity' => REQUIREMENT_ERROR,
'value' => t('Not configured'),
);
}
}
return $requirements;
}
/**
* Implementation of hook_form_alter().
*/
function mixpanel_form_alter(&$form, &$form_state, $form_id) {
//dpm($form_id);
switch ($form_id) {
case 'contact_mail_user':
$form['#submit'][] = "mixpanel_contact_mail_user_submit";
break;
case 'user_profile_form':
$form['#submit'][] = "mixpanel_user_profile_form_submit";
break;
case 'search_theme_form':
$form['#submit'][] = "mixpanel_search_theme_form_submit";
break;
}
}
/**
* Submit function for contact_mail_user to track usage of the contact form.
*/
function mixpanel_contact_mail_user_submit($form, $form_state) {
mixpanel_track("contact-form-user");
}
/**
* Submit function for the user_profile_form to let us track user changes
* to their accounts.
*/
function mixpanel_user_profile_form_submit($form, $form_state) {
mixpanel_track("user-account-updated");
// If a picture was uploaded, submit an event for that as well.
if (isset($form_state['values']['picture'])) {
mixpanel_track("user-picture-changed");
}
}
/**
* Submit function for the search form to let us track searches.
*/
function mixpanel_search_theme_form_submit($form, $form_state) {
mixpanel_track("search", array('search-string' => $form_state['values']['search_theme_form']));
}
/*
* Implementation of hook_og().
*/
function mixpanel_og($op, $gid, $uid, $args) {
if (variable_get('mixpanel_token', '') == '') {
return;
}
$account = user_load($uid);
$group_node = node_load($gid);
switch ($op) {
case 'user insert':
mixpanel_track("group-join", array("group-id" => $gid, "group-name" => $group_node->title), $account);
break;
case 'user delete':
mixpanel_track("group-left", array("group-id" => $gid, "group-name" => $group_node->title), $account);
break;
}
}
/*
* Implementation of hook_user().
*/
function mixpanel_user($op, $edit, $account, $category) {
if (variable_get('mixpanel_token', '') == '') {
return;
}
switch($op) {
case 'insert':
mixpanel_track("user-inserted", null, $account);
break;
case 'delete':
mixpanel_track("user-deleted", null, $acccount);
break;
case 'update':
// We can't use this unfortunately as the LDAP module updates a person's account each time they login.
// We'll use hook_form_alter instead to detect someone submittng an account update.
//mixpanel_track("user-account-updated", null, $account);
break;
case 'login':
mixpanel_track("user-login", null, $account);
break;
case 'logout':
mixpanel_track("user-logout", null, $account);
break;
}
}
/*
* Implementation of hook_nodeapi().
*/
function mixpanel_nodeapi($node, $op) {
if (variable_get('mixpanel_token', '') == '') {
return;
}
switch($op) {
case 'delete':
mixpanel_track("node-deleted", array('node-title' => $node->title,
'group-id' => array_pop(array_values($node->og_groups)),
'node-id' => $node->nid,
'node-type' => $node->type));
break;
case 'insert':
mixpanel_track("node-created", array('node-title' => $node->title,
'group-id' => array_pop(array_values($node->og_groups)),
'node-id' => $node->nid,
'node-type' => $node->type));
break;
case 'update':
mixpanel_track("node-updated", array('node-title' => $node->title,
'group-id' => array_pop(array_values($node->og_groups)),
'node-id' => $node->nid,
'node-type' => $node->type));
}
}
/*
* Implementation of hook_comment().
*/
function mixpanel_comment($comment, $op) {
if (variable_get('mixpanel_token', '') == '') {
return;
}
// $comment can be an object or an array.
$comment = (object)$comment;
$group_results = db_fetch_array(db_query("SELECT o.group_nid, n.title
FROM {og_ancestry} o
JOIN {node} n
ON n.nid = o.group_nid
WHERE o.nid = %d", $comment->nid));
$node_results = db_fetch_array(db_query("SELECT title, type
FROM {node}
WHERE nid = %d", $comment->nid));
switch($op) {
case 'publish':
mixpanel_track("comment-created", array('node-id' => $comment->nid,
'node-title' => $node_results['title'],
'node-type' => $node_results['type'],
'comment-id' => $comment->cid,
'group-id' => $group_results['group_nid'],
'group-name' => $group_results['title']));
break;
}
}
function mixpanel_track($event, $custom_properties = array(), $account = null) {
if (variable_get('mixpanel_token', '') == '') {
return;
}
global $user;
// We don't track events for anonymous users.
if ($user->uid == 0 && empty($account)) {
return;
}
// If user object is passed in, favor that, otherwise, set $account = the current object.
if (empty($account)) {
$account = $user;
}
// Setup default properties.
$cohort = format_date($account->created, 'custom', "M-Y");
$properties = mixpanel_get_defaults();
// Let other modules alter the properties.
drupal_alter('mixpanel_event_properties', $properties);
// Merge default properties with any passed-in properties. Any passed-in properties will overwrite the defaults.
if (!empty($custom_properties)) {
$properties = array_merge($properties, $custom_properties);
}
$token = variable_get('mixpanel_token', '');
$metrics = new MetricsTracker($token);
$metrics->track($event, $properties);
}
/**
* If you wish to do metric logging from your backend, the best method of doing this is
* to do it in a non-blocking way. This will let your pages continue to execute at
* about the same speed while logging metric data in the background. Please note: If
* you're on a shared host, you may be limited in logging metric data with a background
* process.
*
* Feel free to modify this code to your own environments liking.
*
*/
class MetricsTracker {
public $token;
public $host = 'http://api.mixpanel.com/';
public function __construct($token_string) {
$this->token = $token_string;
}
function track($event, $properties=array()) {
$params = array(
'event' => $event,
'properties' => $properties
);
if (!isset($params['properties']['token'])){
$params['properties']['token'] = $this->token;
}
$url = $this->host . 'track/?data=' . base64_encode(json_encode($params));
// You still need to run as a background process.
exec("curl '" . $url . "' >/dev/null 2>&1 &");
// Uncomment the following line and comment the previous line to send events to /tmp/drupal_debug (devel module must be installed).
//dd($params);
}
function track_funnel($funnel, $step, $goal, $properties=array()) {
$properties['funnel'] = $funnel;
$properties['step'] = $step;
$properties['goal'] = $goal;
$this->track('mp_funnel', $properties);
}
}