<?php
// $Id: statistics_filter.module,v 1.8.2.1 2006/04/09 08:21:59 deekayen Exp $

/**
 * @file
 * Filter specified hits out from your statistics.
 */

/**
 * Implementation of hook_help().
 */
function statistics_filter_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Filter out admin and search engine hits on your site.');
    case 'admin/settings/statistics_filter':
      return t('To ignore crawlers, you must '.
        'install and enable the <strong>browscap module</strong>.');
  }
}

/**
 * Implementation of hook_exit().
 *
 * Undo what statistics_exit() did for particular users
 */
function statistics_filter_exit() {
  global $user;

  // No point if statistics aren't enabled
  if (!module_exists('statistics')) {
    return;
  }

  $do_filtering = FALSE;

  // Who are we ignoring?
  $filter_admin = variable_get('statistics_filter_noadmin', FALSE);
  if ($filter_admin && ($user->uid == 1)) {
    $do_filtering = TRUE;
  } else {
    if (is_array($user->roles)) {
      $filtered_roles = variable_get('statistics_filter_roles', FALSE);
      if (is_array($filtered_roles)) {
        $filtered_roles = array_flip($filtered_roles);
        foreach ($user->roles as $key => $value) {
          if (isset($filtered_roles[$key])) {
            $do_filtering = TRUE;
            break;
          }
        }
      }
    }
  }

  // Ignore crawlers if requested
  if (!$do_filtering && module_exists('browscap')) {
    $filter_crawlers = variable_get('statistics_filter_crawlers', FALSE);
    if ($filter_crawlers) {
      $browser = browscap_get_browser();
      if ($browser->crawler) {
        $do_filtering = TRUE;
        $ignoring_because_crawler = TRUE;
      }
    }
  }

  // We don't want these stats to count, precisely undo what
  // statistics.module and browscap.module did
  if ($do_filtering) {
    if (variable_get('statistics_count_content_views', 0)) {
      // We are counting content views.
      if ((arg(0) == 'node') && is_numeric(arg(1)) && arg(2) == '') {
        // A node has been viewed (and logged by the statistics module),
        // so decrement what statistics.module incremented
        db_query('UPDATE {node_counter} SET daycount = daycount - 1, totalcount = totalcount - 1 WHERE nid = %d', arg(1));
      }
    }

    if ((variable_get('statistics_enable_access_log', 0)) && (module_invoke('throttle', 'status') == 0)) {
      // Statistical logs are enabled.
      $referrer = referer_uri();
      $hostname = $_SERVER['REMOTE_ADDR'];

      // Unlog this page access.
      db_query("DELETE FROM {accesslog} WHERE title='%s' AND path='%s' " .
        "AND url='%s' AND hostname='%s' AND uid=%d",
        drupal_get_title(), $_GET['q'], $referrer, $hostname, $user->uid);
    }
    if (!$ignoring_because_crawler && module_exists('browscap')) {
      // If we're ignoring based on role, we don't want to count
      // the browser stats
      browscap_unmonitor();
    }
  }
}

/**
 * Implementation of hook_menu().
 */
function statistics_filter_menu($may_cache) {
  $items = array();

  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/logs/settings/statistics-filter',
      'title' => t('Statistics filter settings'),
      'description' => t("Set up which types of site access you don't want to get logged."),
      'callback' => 'drupal_get_form',
      'callback arguments' => array('statistics_filter_admin_settings'),
      'access' => user_access('administer statistics filter'),
      'type' => MENU_NORMAL_ITEM);
  }
  return $items;
}

/**
 * Implementation of hook_perm().
 *
 * @return array
 */
function statistics_filter_perm() {
  return array('administer statistics filter');
}

/**
 * Admin settings callback.
 */
function statistics_filter_admin_settings() {
  $form = array();

  // Restrict administration of this module
  if (user_access('administer statistics filter') === FALSE) {
    return drupal_access_denied();
  }

  if (!module_exists('statistics')) {
    $output = array('statistics' => array(
                    '#value' => t('<p>The statistics_filter module is an extension of the <b>statistics</b> '.
                                  'module - you must enable <b>statistics</b> to use it.</p>')));
    return $output;
  }

  $form['statistics_filter_noadmin'] = array(
    '#type' => 'checkbox',
    '#title' => t('Ignore administrator'),
    '#default_value' => variable_get('statistics_filter_noadmin', FALSE),
    '#description' => t("Ignore the special administrator account's accesses to this site.")
  );

  $roles = user_roles();
  $variable_roles = variable_get('statistics_filter_roles', array());
  $default_roles = array();
  foreach ($roles as $key => $value) {
    if (in_array($key, $variable_roles)) {
      $default_roles[] = $key;
    }
  }
  $form['statistics_filter_roles'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles to ignore'),
    '#default_value' => $default_roles,
    '#options' => $roles,
    '#description' => t("Ignore accesses by users in any of the checked roles.")
  );

  if (module_exists('browscap')) {
    $form['statistics_filter_crawlers'] = array(
      '#type' => 'checkbox',
      '#title' => t('Ignore crawlers'),
      '#default_value' => variable_get('statistics_filter_crawlers', FALSE),
      '#description' => t("Ignore search engine crawlers' accesses to this site.")
    );
  }

  return system_settings_form($form);
}
