<?php

/**
 * @file
 * All the main code for the Pingdom RUM module
 */

/**
 * Hook_page_alter implementation.
 *
 * Adds Pingdom's JS code to HEAD section.
 * This is done using drupal_add_html_head, not drupal_add_js, to guarantee
 * placement in the HEAD section of the final page.
 * The account ID is embedded in this code, rather than being passed to the
 * page using settings, because Pingdom specify that all code must be inline.
 */
function pingdom_rum_page_alter() {
  global $user;
  if (variable_get('pingdom_rum_project_id', '') != ''
    && _pingdom_rum_visibility_pages()
    && _pingdom_rum_visibility_roles($user)
  ) {
    $js = 'var _prum={id:"' . variable_get('pingdom_rum_project_id', '') .
      '"};var PRUM_EPISODES=PRUM_EPISODES||{};PRUM_EPISODES.q=[];PRUM_' .
      'EPISODES.mark=function(b,a){PRUM_EPISODES.q.push(["mark",b,a||new ' .
      'Date().getTime()])};PRUM_EPISODES.measure=function(b,a,b){PRUM_' .
      'EPISODES.q.push(["measure",b,a,b||new Date().getTime()])};PRUM_' .
      'EPISODES.done=function(a){PRUM_EPISODES.q.push(["done",a])};PRUM_' .
      'EPISODES.mark("firstbyte");(function(){var b=document.' .
      'getElementsByTagName("script")[0];var a=document.createElement' .
      '("script");a.type="text/javascript";a.async=true;a.charset="UTF-8";' .
      'a.src="//rum-static.pingdom.net/prum.min.js";b.parentNode.' .
      'insertBefore(a,b)})();';
    $head_array = array(
      '#type' => 'html_tag',
      '#tag' => 'script',
      '#attributes' => array('type' => 'application/javascript'),
      '#value' => $js,
    );
    drupal_add_html_head($head_array, 'pingdom_rum_module');
  }
}

/**
 * Hook_menu implementation.
 *
 * Adds a menu callback for module settings page.
 */
function pingdom_rum_menu() {
  $items['admin/config/services/pingdom'] = array(
    'title' => 'Pingdom RUM Settings',
    'description' => 'Customise your Pingdom RUM account',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('pingdom_rum_admin_settings'),
    'access arguments' => array('administer site configuration'),
    'file' => 'pingdom_rum.admin.inc',
  );
  return $items;
}

/**
 * Function to determine whether to include RUM code, based on user role.
 *
 * Based on visibility setting this function returns TRUE if Pingdom RUM code
 * should be added for the current role and otherwise FALSE.
 */
function _pingdom_rum_visibility_roles($account) {

  $visibility = variable_get('pingdom_rum_roles_type', 0);
  $enabled = $visibility;
  $roles = variable_get('pingdom_rum_roles', array());

  if (array_sum($roles) > 0) {
    // One or more roles are selected.
    foreach (array_keys($account->roles) as $rid) {
      // Is the current user a member of one of these roles?
      if (isset($roles[$rid]) && $rid == $roles[$rid]) {
        // Current user is a member of a role that should be excluded.
        $enabled = !$visibility;
        break;
      }
    }
  }
  else {
    // No role is selected for tracking, therefore all roles should be tracked.
    $enabled = TRUE;
  }
  return $enabled;
}

/**
 * Function to determine whether to include RUM code, based on path of page.
 *
 * Based on visibility setting this function returns TRUE if Pingdom RUM code
 * should be added to the current page and otherwise FALSE.
 */
function _pingdom_rum_visibility_pages() {
  $page_match = TRUE;
  $visibility = variable_get('pingdom_rum_visibility_pages', 0);
  $setting_pages = variable_get('pingdom_rum_pages', '');

  // Match path if necessary.
  if (!empty($setting_pages)) {
    // Convert path to lowercase. This allows comparison of the same path.
    // with different case. Ex: /Page, /page, /PAGE.
    $pages = drupal_strtolower($setting_pages);
    if ($visibility < 2) {
      // Convert the Drupal path to lowercase.
      $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
      // Compare the lowercase internal and lowercase path alias (if any).
      $page_match = drupal_match_path($path, $pages);
      if ($path != $_GET['q']) {
        // Compare the Drupal path without any alias to the list of paths.
        $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
      }
      // When $visibility has a value of 0, the RUM code is displayed on
      // all pages except those listed in $pages. When set to 1, it
      // is displayed only on those pages listed in $pages.
      $page_match = !($visibility xor $page_match);
    }
    else {
      $page_match = FALSE;
    }
  }
  return $page_match;
}
