You are here

commerce_google_tag_manager.module in Commerce Google Tag Manager 7

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

Based on Commerce Google Analytics module.

File

commerce_google_tag_manager.module
View source
<?php

/**
 * @file
 * Adds the required Javascript to the checkout completion page to allow
 * e-commerce statistics tracking through Google Tag Manager.
 *
 * Based on Commerce Google Analytics module.
 */

/**
 * Build the e-commerce JS transaction.
 *
 * @param object $order
 *   The fully loaded order object to convert into transaction JS.
 *
 * @return string
 *   The JS that should be added to the page header.
 */
function commerce_google_tag_manager_ecommerce_js($order) {
  $script = 'var dataLayer = dataLayer || []; ';
  if (!$order instanceof EntityMetadataWrapper) {
    $order = entity_metadata_wrapper('commerce_order', $order);
  }
  $datalayer_type = variable_get('commerce_google_tag_manager_datalayer_type', 'legacy');
  $tax_sum = 0;
  if (module_exists('commerce_tax')) {
    foreach (commerce_tax_rates() as $name => $tax_rate) {
      if ($tax_rate['price_component']) {
        $tax_component = commerce_price_component_load($order->commerce_order_total
          ->value(), $tax_rate['price_component']);

        // Some taxes may not have been applied.
        if (isset($tax_component[0]['price']['amount'])) {
          $tax_sum += commerce_currency_amount_to_decimal($tax_component[0]['price']['amount'], $tax_component[0]['price']['currency_code']);
        }
      }
    }
  }
  $shipping = 0;
  if (module_exists('commerce_shipping')) {
    foreach ($order->commerce_line_items as $item) {
      if ($item->type
        ->value() == 'shipping') {
        $shipping += commerce_currency_amount_to_decimal($item->commerce_total->amount
          ->value(), $item->commerce_total->currency_code
          ->value());
      }
    }
  }
  $products = array();

  // Loop through the products on the order.
  foreach ($order->commerce_line_items as $line_item_wrapper) {
    $properties = $line_item_wrapper
      ->getPropertyInfo();
    $product_data = array();
    if (isset($properties['commerce_product'])) {
      $product_id = $line_item_wrapper->commerce_product
        ->getIdentifier();
      if (!empty($product_id)) {

        // Build the item arguments.
        $sku = $line_item_wrapper->commerce_product->sku
          ->value();
        $name = $line_item_wrapper->commerce_product->title
          ->value();
        $category = '';
        $variant = commerce_product_type_get_name($line_item_wrapper->commerce_product
          ->getBundle());
        $price = commerce_currency_amount_to_decimal($line_item_wrapper->commerce_unit_price->amount
          ->value(), $line_item_wrapper->commerce_unit_price->currency_code
          ->value());
        $quantity = (int) $line_item_wrapper->quantity
          ->value();
        if ($datalayer_type == 'enhanced') {
          $product_data = array(
            'id' => $sku,
            'name' => $name,
            'category' => $category,
            'variant' => $variant,
            'price' => $price,
            'quantity' => $quantity,
          );
        }
        else {
          $product_data = array(
            'sku' => $sku,
            'name' => $name,
            'category' => $category,
            'price' => $price,
            'quantity' => $quantity,
          );
        }
      }
    }

    // Allow other modules add other types of products.
    drupal_alter('commerce_google_tag_manager_product_data', $product_data, $line_item_wrapper, $order);
    if ($product_data) {
      $products[] = $product_data;
    }
  }

  // Build the transaction arguments.
  $order_id = $order->order_id
    ->value();
  $order_number = $order->order_number
    ->value() ? $order->order_number
    ->value() : $order_id;
  $order_currency_code = $order->commerce_order_total->currency_code
    ->value();
  $order_total = commerce_currency_amount_to_decimal($order->commerce_order_total->amount
    ->value(), $order_currency_code);
  $affiliation = variable_get('site_name', '');
  if ($datalayer_type == 'enhanced') {
    $transaction = array(
      'event' => 'transactionComplete',
      'ecommerce' => array(
        'currencyCode' => $order_currency_code,
        'purchase' => array(
          'actionField' => array(
            'id' => $order_number,
            'affiliation' => $affiliation,
            'revenue' => $order_total,
            'tax' => $tax_sum,
            'shipping' => $shipping,
          ),
          'products' => $products,
        ),
      ),
    );
  }
  else {
    $transaction = array(
      'event' => 'trackTrans',
      'transactionId' => $order_number,
      'transactionAffiliation' => $affiliation,
      'transactionTotal' => $order_total,
      'transactionTax' => $tax_sum,
      'transactionShipping' => $shipping,
      'transactionProducts' => $products,
    );
  }

  // Allow other modules implement hook_commerce_google_tag_manager_transaction_data_alter.
  drupal_alter('commerce_google_tag_manager_transaction_data', $transaction, $order);

  // Add the transaction line to the JS array.
  $script .= 'dataLayer.push(' . drupal_json_encode($transaction) . ');';
  return $script;
}

/**
 * Callback for the rules action which creates the javascript.
 *
 * Uses the $order and stores the script in the session to inject it using
 * hook_page_build on the next page request.
 *
 * @param object $order
 *   The order object
 */
function commerce_google_tag_manager_send_order($order) {

  // Add the javascript only when we are on the order complete page.
  $script = commerce_google_tag_manager_ecommerce_js($order);
  $_SESSION['commerce_google_tag_manager'] = $script;
}

/**
 * Implements hook_page_build().
 */
function commerce_google_tag_manager_page_build(&$page) {
  if (!empty($_SESSION['commerce_google_tag_manager'])) {

    // Data escaped via drupal_json_encode().
    $script = $_SESSION['commerce_google_tag_manager'];
    $page['page_top']['#attached']['js'][] = array(
      'type' => 'inline',
      'data' => $script,
    );
    unset($_SESSION['commerce_google_tag_manager']);
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 *
 * Extends Google Tag module with ecommerce settings.
 */
function commerce_google_tag_manager_form_google_tag_settings_form_alter(&$form, &$form_state) {
  $form['tabs']['ecommerce'] = commerce_google_tag_manager_ecommerce_fieldset($form_state);
}

/**
 * Eocmmerce Fieldset builder for the module settings form.
 */
function commerce_google_tag_manager_ecommerce_fieldset(&$form_state) {

  // Build form elements.
  $fieldset = array(
    '#type' => 'fieldset',
    '#title' => t('Ecommerce'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#tree' => FALSE,
  );
  $options = array(
    'legacy' => t('Ecommerce (legacy) - <a href="!url">documentation</a>', array(
      '!url' => 'https://support.google.com/tagmanager/answer/3002596?hl=en',
    )),
    'enhanced' => t('Enhanced Ecommerce for Universal Analytics - <a href="!url">documentation</a>', array(
      '!url' => 'https://developers.google.com/tag-manager/enhanced-ecommerce',
    )),
  );
  $fieldset['commerce_google_tag_manager_datalayer_type'] = array(
    '#type' => 'radios',
    '#title' => t('Select Data Layer type'),
    '#options' => $options,
    '#default_value' => variable_get('commerce_google_tag_manager_datalayer_type', 'legacy'),
  );
  $fieldset['description'] = array(
    '#markup' => t('For debugging you can use Chrome extension <a href="!url">Tag Assistant</a>.', array(
      '!url' => 'https://chrome.google.com/webstore/detail/tag-assistant-by-google/kejbdjndbnbjgmefkgdddjlbokphdefk',
    )),
  );
  return $fieldset;
}

Functions

Namesort descending Description
commerce_google_tag_manager_ecommerce_fieldset Eocmmerce Fieldset builder for the module settings form.
commerce_google_tag_manager_ecommerce_js Build the e-commerce JS transaction.
commerce_google_tag_manager_form_google_tag_settings_form_alter Implementation of hook_form_FORM_ID_alter().
commerce_google_tag_manager_page_build Implements hook_page_build().
commerce_google_tag_manager_send_order Callback for the rules action which creates the javascript.