You are here

function piwik_footer in Piwik Web Analytics 6.2

Same name and namespace in other branches
  1. 5 piwik.module \piwik_footer()
  2. 6 piwik.module \piwik_footer()

Implementation of hook_footer() to insert Javascript at the end of the page.

File

./piwik.module, line 80
Drupal Module: Piwik

Code

function piwik_footer($main = 0) {
  global $user;
  $id = variable_get('piwik_site_id', '');

  // 1. Check if the piwik account number has a value.
  // 2. Track page views based on visibility value.
  // 3. Check if we should track the currently active user's role.
  if (preg_match('/^\\d{1,}$/', $id) && _piwik_visibility_pages() && _piwik_visibility_user($user)) {
    $url_http = variable_get('piwik_url_http', '');
    $url_https = variable_get('piwik_url_https', '');
    $set_custom_url = '';
    $set_document_title = '';
    $set_custom_data = array();

    // Piwik can show a tree view of page titles that represents the site structure
    // if setDocumentTitle() provides the page titles as a "/" delimited list.
    // This may makes it easier to browse through the statistics of page titles
    // on larger sites.
    if (variable_get('piwik_page_title_hierarchy', FALSE) == TRUE) {
      $titles = _piwik_get_hierarchy_titles();
      if (variable_get('piwik_page_title_hierarchy_exclude_home', TRUE)) {

        // Remove the "Home" item from the titles to flatten the tree view.
        array_shift($titles);
      }

      // Remove all empty titles.
      $titles = array_filter($titles);
      if (!empty($titles)) {

        // Encode title, at least to keep "/" intact.
        $titles = array_map('rawurlencode', $titles);
        $set_document_title = drupal_to_js(implode('/', $titles));
      }
    }

    // If this node is a translation of another node, pass the original
    // node instead.
    if (module_exists('translation') && variable_get('piwik_translation_set', 0)) {

      // Check we have a node object, it supports translation, and its
      // translated node ID (tnid) doesn't match its own node ID.
      $node = menu_get_object();
      if ($node && translation_supported_type($node->type) && isset($node->tnid) && $node->tnid != $node->nid) {
        $source_node = node_load($node->tnid);
        $languages = language_list();
        $set_custom_url = drupal_to_js(url('node/' . $source_node->nid, array(
          'language' => $languages[$source_node->language],
          'absolute' => TRUE,
        )));
      }
    }

    // Track access denied (403) and file not found (404) pages.
    if (function_exists('drupal_get_headers')) {
      $headers = drupal_get_headers();
      if (strstr($headers, '403 Forbidden')) {
        $set_document_title = '"403/URL = " + encodeURIComponent(document.location.pathname+document.location.search) + "/From = " + encodeURIComponent(document.referrer)';
      }
      elseif (strstr($headers, '404 Not Found')) {
        $set_document_title = '"404/URL = " + encodeURIComponent(document.location.pathname+document.location.search) + "/From = " + encodeURIComponent(document.referrer)';
      }
    }

    // Add any custom code snippets if specified.
    $codesnippet_before = variable_get('piwik_codesnippet_before', '');
    $codesnippet_after = variable_get('piwik_codesnippet_after', '');

    // Build tracker code. See http://piwik.org/docs/javascript-tracking/#toc-asynchronous-tracking
    $script = 'var _paq = _paq || [];';
    $script .= '(function(){';
    $script .= 'var u=(("https:" == document.location.protocol) ? "' . check_url($url_https) . '" : "' . check_url($url_http) . '");';
    $script .= '_paq.push(["setSiteId", ' . drupal_to_js(variable_get('piwik_site_id', '')) . ']);';
    $script .= '_paq.push(["setTrackerUrl", u+"piwik.php"]);';

    // Track logged in users across all devices.
    if (variable_get('piwik_trackuserid', 0) && user_is_logged_in()) {

      // The USER_ID value should be a unique, persistent, and non-personally
      // identifiable string identifier that represents a user or signed-in
      // account across devices.
      $script .= '_paq.push(["setUserId", ' . drupal_to_js(_piwik_hmac_base64($user->uid, drupal_get_private_key() . _piwik_get_hash_salt())) . ']);';
    }

    // Set custom data.
    if (!empty($set_custom_data)) {
      foreach ($set_custom_data as $custom_data) {
        $script .= '_paq.push(["setCustomData", ' . $custom_data . ']);';
      }
    }

    // Set custom url.
    if (!empty($set_custom_url)) {
      $script .= '_paq.push(["setCustomUrl", ' . $set_custom_url . ']);';
    }

    // Set custom document title.
    if (!empty($set_document_title)) {
      $script .= '_paq.push(["setDocumentTitle", ' . $set_document_title . ']);';
    }

    // Custom file download extensions.
    if (variable_get('piwik_track', 1) && !(variable_get('piwik_trackfiles_extensions', PIWIK_TRACKFILES_EXTENSIONS) == PIWIK_TRACKFILES_EXTENSIONS)) {
      $script .= '_paq.push(["setDownloadExtensions", ' . drupal_to_js(variable_get('piwik_trackfiles_extensions', PIWIK_TRACKFILES_EXTENSIONS)) . ']);';
    }

    // Disable tracking for visitors who have opted out from tracking via DNT (Do-Not-Track) header.
    if (variable_get('piwik_privacy_donottrack', 1)) {
      $script .= '_paq.push(["setDoNotTrack", 1]);';
    }

    // Domain tracking type.
    global $cookie_domain;
    $domain_mode = variable_get('piwik_domain_mode', 0);

    // Per RFC 2109, cookie domains must contain at least one dot other than the
    // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
    if ($domain_mode == 1 && count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
      $script .= '_paq.push(["setCookieDomain", ' . drupal_to_js($cookie_domain) . ']);';
    }
    if (!empty($codesnippet_before)) {
      $script .= $codesnippet_before;
    }

    // Site search tracking support.
    // NOTE: It's recommended not to call trackPageView() on the Site Search Result page.
    if (module_exists('search') && variable_get('piwik_site_search', FALSE) && arg(0) == 'search' && ($keys = search_get_keys())) {

      // Parameters:
      // 1. Search keyword searched for. Example: "Banana"
      // 2. Search category selected in your search engine. If you do not need
      //    this, set to false. Example: "Organic Food"
      // 3. Number of results on the Search results page. Zero indicates a
      //    'No Result Search Keyword'. Set to false if you don't know.
      //
      // hook_preprocess_search_results() is not executed if search result is
      // empty. Make sure the counter is set to 0 if there are no results.
      $script .= '_paq.push(["trackSiteSearch", ' . drupal_to_js($keys) . ', false, (window.piwik_search_results) ? window.piwik_search_results : 0]);';
    }
    else {
      $script .= '_paq.push(["trackPageView"]);';
    }

    // Add link tracking.
    if (variable_get('piwik_track', 1)) {

      // Disable tracking of links with ".no-tracking" and ".colorbox" classes.
      $ignore_classes = array(
        'no-tracking',
        'colorbox',
      );

      // Disable the download & outlink tracking for specific CSS classes.
      // Custom code snippets with 'setIgnoreClasses' will override the value.
      // http://developer.piwik.org/api-reference/tracking-javascript#disable-the-download-amp-outlink-tracking-for-specific-css-classes
      $script .= '_paq.push(["setIgnoreClasses", ' . drupal_to_js($ignore_classes) . ']);';

      // Enable download & outlink link tracking.
      $script .= '_paq.push(["enableLinkTracking"]);';
    }
    if (!empty($codesnippet_after)) {
      $script .= $codesnippet_after;
    }
    $script .= 'var d=document,';
    $script .= 'g=d.createElement("script"),';
    $script .= 's=d.getElementsByTagName("script")[0];';
    $script .= 'g.type="text/javascript";';
    $script .= 'g.defer=true;';
    $script .= 'g.async=true;';

    // Should a local cached copy of the tracking code be used?
    if (variable_get('piwik_cache', 0) && variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC && ($url = _piwik_cache($url_http . 'piwik.js'))) {

      // A dummy query-string is added to filenames, to gain control over
      // browser-caching. The string changes on every update or full cache
      // flush, forcing browsers to load a new copy of the files, as the
      // URL changed.
      $query_string = '?' . substr(variable_get('css_js_query_string', '0'), 0, 1);
      $script .= 'g.src="' . $url . $query_string . '";';
    }
    else {
      $script .= 'g.src=u+"piwik.js";';
    }
    $script .= 's.parentNode.insertBefore(g,s);';
    $script .= '})();';
    drupal_add_js($script, 'inline', 'footer');
  }
}