You are here

uc_googleanalytics.module in Ubercart 8.4

Adds Google Analytics Javascript to the checkout completion page.

Adds the required Javascript to the checkout completion page to allow e-commerce statistics tracking through Google Analytics.

Refer to http://code.google.com/apis/analytics/docs/gaTrackingEcommerce.html for documentation on the functions used to submit e-commerce statistics to Google Analytics.

File

uc_googleanalytics/uc_googleanalytics.module
View source
<?php

/**
 * @file
 * Adds Google Analytics Javascript to the checkout completion page.
 *
 * Adds the required Javascript to the checkout completion page to allow
 * e-commerce statistics tracking through Google Analytics.
 *
 * Refer to http://code.google.com/apis/analytics/docs/gaTrackingEcommerce.html
 * for documentation on the functions used to submit e-commerce statistics to
 * Google Analytics.
 */
use Drupal\Component\Serialization\Json;
use Drupal\uc_order\Entity\Order;
use Drupal\uc_order\OrderInterface;
use Drupal\node\Entity\Node;

/**
 * Implements hook_page_attachments_alter().
 */
function uc_googleanalytics_page_attachments_alter(&$page) {

  // Check to see if we are at the order completion page.
  if (uc_googleanalytics_display()) {

    // If so, then if we can load the order...
    $session = \Drupal::service('session');
    if ($session
      ->has('ucga_order_id') && ($order = Order::load($session
      ->get('ucga_order_id')))) {

      // Build the GA tracking code.
      $script = uc_googleanalytics_ecommerce_js($order);

      // Add the code to the footer.
      drupal_add_js($script, [
        'type' => 'inline',
        'scope' => 'footer',
        'preprocess' => FALSE,
      ]);
    }

    // Clean out the session variable.
    if ($session
      ->has('ucga_order_id')) {
      $session
        ->remove('ucga_order_id');
    }
  }
}

/**
 * Implements hook_uc_order_create().
 */
function uc_googleanalytics_uc_order_create(OrderInterface $order) {

  // If a new order is created during the checkout process...
  // Store the order ID for later use.
  \Drupal::service('session')
    ->set('ucga_order_id', $order
    ->id());
}

/**
 * Determines whether or not to display the e-commerce related JS through GA.
 *
 * @return bool
 *   TRUE or FALSE indicating whether or not to display the GA e-commerce JS.
 */
function uc_googleanalytics_display() {

  // Display the GA e-commerce JS if the URL is cart/checkout/complete...
  $route_match = \Drupal::routeMatch();
  if ($route_match
    ->getRouteName() == 'uc_cart.checkout_complete') {
    return TRUE;
  }

  // Or if another module says this is the page through hook_ucga_display().
  foreach (\Drupal::moduleHandler()
    ->invokeAll('ucga_display') as $result) {
    if ($result === TRUE) {
      return TRUE;
    }
  }

  // Otherwise return FALSE.
  return FALSE;
}

/**
 * Builds the e-commerce JS passed to Google Analytics for order tracking.
 *
 * @param \Drupal\uc_order\OrderInterface $order
 *   The fully loaded order object to convert into GA JS.
 *
 * @return string
 *   The JS that should be added to the page footer.
 */
function uc_googleanalytics_ecommerce_js(OrderInterface $order) {
  $script = '';

  // Calculate order tax and shipping totals.
  $order->tax_total = 0;
  $order->shipping_total = 0;
  foreach ($order->line_items as $line_item) {
    if ($line_item['type'] == 'tax') {
      $order->tax_total += $line_item['amount'];
    }
    elseif ($line_item['type'] == 'shipping') {
      $order->shipping_total += $line_item['amount'];
    }
  }

  // Build the transaction arguments.
  $country = \Drupal::service('country_manager')
    ->getCountry($order->billing_country);
  $trans = [
    'order_id' => $order
      ->id(),
    'store' => uc_store_name(),
    'total' => $order
      ->getTotal(),
    'tax' => $order->tax_total,
    'shipping' => $order->shipping_total,
    'city' => $order->billing_city,
    'state' => $country->zones[$order->billing_zone_name],
    'country' => $country->name,
  ];

  // Allow modules to alter the transaction arguments.
  \Drupal::moduleHandler()
    ->alter('ucga_trans', $trans, $order);

  // Put the arguments into an array that is safe to implode directly.
  $args = [
    '"' . $trans['order_id'] . '"',
    Json::encode($trans['store']),
    '"' . $trans['total'] . '"',
    '"' . $trans['tax'] . '"',
    '"' . $trans['shipping'] . '"',
    Json::encode($trans['city']),
    Json::encode($trans['state']),
    Json::encode($trans['country']),
  ];

  // Add the transaction line to the JS.
  $script .= '_gaq.push(["_addTrans", ' . implode(', ', $args) . ']);';

  // Loop through the products on the order.
  foreach ($order->products as $product) {
    $product->category = '';

    // Try to find a category (term) for the product. Since products most often
    // only have one category, the first one returned (in the
    // $node->taxonomy_catalog) is chosen.
    if (\Drupal::moduleHandler()
      ->moduleExists('taxonomy')) {
      $node = Node::load($product->nid);
      if (isset($node->taxonomy_catalog[LANGUAGE_NOT_SPECIFIED][0]['tid'])) {
        $term = taxonomy_term_load($node->taxonomy_catalog[LANGUAGE_NOT_SPECIFIED][0]['tid']);
        $product->category = $term->name;
      }
    }
    if (empty($product->category)) {
      $product->category = t('No category');
    }

    // Build the item arguments.
    $item = [
      'order_id' => $order
        ->id(),
      'sku' => $product->model,
      'name' => $product->title,
      'category' => $product->category,
      'price' => $product->price,
      'qty' => $product->qty,
    ];

    // Allow modules to alter the item arguments.
    \Drupal::moduleHandler()
      ->alter('ucga_item', $item, $product, $trans, $order);

    // Put the arguments into an array that is safe to implode directly.
    $args = [
      '"' . $item['order_id'] . '"',
      Json::encode($item['sku']),
      Json::encode($item['name']),
      Json::encode((string) $item['category']),
      '"' . $item['price'] . '"',
      '"' . $item['qty'] . '"',
    ];

    // Add the item line to the JS.
    $script .= '_gaq.push(["_addItem", ' . implode(', ', $args) . ']);';
  }

  // Add the function to submit the transaction to GA.
  $script .= '_gaq.push(["_trackTrans"]);';
  return $script;
}

Functions

Namesort descending Description
uc_googleanalytics_display Determines whether or not to display the e-commerce related JS through GA.
uc_googleanalytics_ecommerce_js Builds the e-commerce JS passed to Google Analytics for order tracking.
uc_googleanalytics_page_attachments_alter Implements hook_page_attachments_alter().
uc_googleanalytics_uc_order_create Implements hook_uc_order_create().