better_statistics.statistics.inc in Better Statistics 7
Statistics API functions and hooks for the Better Statistics module.
File
better_statistics.statistics.incView source
<?php
/**
* @file
* Statistics API functions and hooks for the Better Statistics module.
*/
/**
* Implements hook_better_statistics_fields().
*/
function better_statistics_better_statistics_fields() {
$fields = array();
$path = drupal_get_path('module', 'better_statistics');
// Pass all user-facing strings through t(), but always use English when first
// declaring fields. They will be run through t() normally on output.
$en = array(
'langcode' => 'en',
);
// Declare a cache status field.
$fields['cache'] = array(
'schema' => array(
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
'description' => 'Cache hit, miss, or not applicable.',
),
'callback' => 'better_statistics_get_field_value',
'views_field' => array(
'title' => t('Cache status', array(), $en),
'help' => t('The cache status of the page (HIT, MISS, or NULL).', array(), $en),
),
'js' => array(
'data' => $path . '/js/fields/custom.js',
'type' => 'file',
),
);
// Declare a user agent field.
$fields['user_agent'] = array(
'schema' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
'description' => 'User-agent string used on the request.',
),
'callback' => 'better_statistics_get_field_value',
'views_field' => array(
'title' => t('User-agent', array(), $en),
'help' => t('User-agent string of the user who visited your page.', array(), $en),
),
'js' => array(
'data' => $path . '/js/fields/custom.js',
'type' => 'file',
),
);
// Declare a peak memory field.
$fields['peak_memory'] = array(
'schema' => array(
'type' => 'int',
'size' => 'normal',
'not null' => TRUE,
'default' => 0,
'unsigned' => TRUE,
'description' => 'Peak memory in bytes allocated for the request.',
),
'callback' => 'memory_get_peak_usage',
'views_field' => array(
'title' => t('Peak memory', array(), $en),
'help' => t('Size in bytes of the peak memory allocated for the request.', array(), $en),
),
'js' => array(
'data' => $path . '/js/fields/custom.js',
'type' => 'file',
),
);
return $fields;
}
/**
* Implements hook_better_statistics_methods().
*/
function better_statistics_better_statistics_methods() {
$mod_path = drupal_get_path('module', 'better_statistics');
$methods['accesslog'] = $mod_path . '/js/methods/better_statistics.accesslog.js';
$methods['entity_view'] = $mod_path . '/js/methods/better_statistics.entity_view.js';
return $methods;
}
/**
* Returns a value to be inserted into the accesslog based on a field name
* provided. This handles Drupal Core's values as well as our own.
*
* @param $field
* The name of the field for which to return data.
*
* @return
* The data to be inserted into the accesslog for the provided field.
*/
function better_statistics_get_field_value($field) {
switch ($field) {
case 'title':
return truncate_utf8(strip_tags(drupal_get_title()), 255);
case 'path':
return truncate_utf8($_GET['q'], 255);
case 'url':
return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
case 'hostname':
return ip_address();
case 'uid':
global $user;
return $user->uid;
case 'sid':
return session_id();
case 'timer':
return (int) timer_read('page');
case 'timestamp':
return REQUEST_TIME;
case 'cache':
$cached = NULL;
$cache_status = better_statistics_served_from_cache();
if ($cache_status === TRUE) {
$cached = 'HIT';
}
elseif ($cache_status === FALSE) {
$cached = 'MISS';
}
return $cached;
case 'user_agent':
return isset($_SERVER['HTTP_USER_AGENT']) ? truncate_utf8($_SERVER['HTTP_USER_AGENT'], 255) : '';
}
}
/**
* Implements hook_better_statistics_prelog().
*
* Better Statistics provides inclusion/exclusion restrictions for collecting
* access log data based on request paths, user roles and cache status.
*/
function better_statistics_better_statistics_prelog() {
// Skip if page is served from cache and Better Statistics is set to
// exclude logging cached requests.
$cache_status = better_statistics_served_from_cache();
if ($cache_status && !variable_get('statistics_access_log_restrictions_cache', TRUE)) {
better_statistics_request_is_loggable(FALSE);
return;
}
// If there are page-based restrictions, check the page.
$restrict_pages = variable_get('statistics_access_log_restrictions_page', 0);
$pages = drupal_strtolower(variable_get('statistics_access_log_restrictions_pages', ''));
if ($restrict_pages || !empty($pages)) {
// Make sure drupal_match_path() is available.
require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'includes/path.inc');
// Make sure language is initialized for drupal_get_path_alias().
global $language_url;
if (!isset($language_url)) {
drupal_language_initialize();
}
// 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']) {
$page_match = $page_match || drupal_match_path($_GET['q'], $pages);
}
if ($page_match xor $restrict_pages) {
better_statistics_request_is_loggable(FALSE);
return;
}
}
// If role restrictions are specified, check the array.
$roles = variable_get('statistics_access_log_restrictions_roles', array());
$restrictions_count = array_count_values($roles);
if (isset($restrictions_count[0]) && $restrictions_count[0] < count($roles)) {
// Skip if user is not part of an included role.
global $user;
$roles_check = array_intersect($roles, array_keys($user->roles));
if (empty($roles_check)) {
better_statistics_request_is_loggable(FALSE);
return;
}
}
// If DNT restrictions are specified, check headers.
if (variable_get('statistics_access_log_restrictions_dnt', FALSE)) {
// Respect the "do not track" header.
if (isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT']) {
better_statistics_request_is_loggable(FALSE);
}
}
// If mixed-mode logging is enabled, check the page cache status.
$mixed_mode = variable_get('statistics_enable_access_log', BETTER_STATISTICS_ACCESSLOG_DISABLED) == BETTER_STATISTICS_ACCESSLOG_MIXED;
if ($mixed_mode && $cache_status) {
better_statistics_request_is_loggable(FALSE);
return;
}
}
/**
* Implements hook_better_statistics_log().
*
* Logs Statistics data in the {accesslog} table.
*/
function better_statistics_better_statistics_log($data) {
// Check that we're meant to log Statistics to the DB.
if (variable_get('statistics_log_to_db', TRUE)) {
// Now that we have data, try to insert it.
try {
db_insert('accesslog')
->fields($data)
->execute();
} catch (Exception $e) {
// At least log core fields.
$defaults = better_statistics_get_default_fields();
$core_fields = array_intersect_key($data, $defaults);
db_insert('accesslog')
->fields($core_fields)
->execute();
// Log the error.
watchdog('better statistics', 'There was an error collecting statistics data:<br /><br />@error', array(
'@error' => $e
->getMessage(),
), WATCHDOG_ERROR);
}
}
}
/**
* Implements hook_better_statistics_ajax().
*/
function better_statistics_better_statistics_ajax($type, $payload) {
switch ($type) {
// @todo When API backwards compatibility can be broken, there should be no
// need to duplicate this code from hook_exit().
case 'accesslog':
// Allow all modules to react before logging begins.
module_invoke_all('better_statistics_prelog');
// Get all declared fields and their computed values.
$fields = better_statistics_get_fields_data();
// Pluck only values passed that correspond to statistics fields that are
// actually configured, then sanitize them.
$configured_from_ajax = array_intersect_key($payload, $fields);
foreach ($configured_from_ajax as &$value) {
$value = filter_xss($value);
}
// Merge values from AJAX fields into server-side generated fields.
$payload = array_merge($fields, $configured_from_ajax);
// Allow modules to log statistics data.
module_invoke_all('better_statistics_log', $payload);
break;
case 'entity_view':
$entity_type = isset($payload['entity_type']) ? $payload['entity_type'] : '';
$entity_id = isset($payload['entity_id']) ? $payload['entity_id'] : '';
$timestamp = isset($payload['timestamp']) ? $payload['timestamp'] : REQUEST_TIME;
if ($entity_type == 'node' && is_numeric($entity_id)) {
// A node has been viewed, so update the node's counters.
db_merge('node_counter')
->key(array(
'nid' => $payload['entity_id'],
))
->fields(array(
'daycount' => 1,
'totalcount' => 1,
'timestamp' => $timestamp,
))
->expression('daycount', 'daycount + 1')
->expression('totalcount', 'totalcount + 1')
->execute();
}
break;
}
}
Functions
Name![]() |
Description |
---|---|
better_statistics_better_statistics_ajax | Implements hook_better_statistics_ajax(). |
better_statistics_better_statistics_fields | Implements hook_better_statistics_fields(). |
better_statistics_better_statistics_log | Implements hook_better_statistics_log(). |
better_statistics_better_statistics_methods | Implements hook_better_statistics_methods(). |
better_statistics_better_statistics_prelog | Implements hook_better_statistics_prelog(). |
better_statistics_get_field_value | Returns a value to be inserted into the accesslog based on a field name provided. This handles Drupal Core's values as well as our own. |