pagenotfound_reports.module in Page Not Found Reports 7
Same filename and directory in other branches
Page Not Found Reports
Adds admin reports about common 404 errors.
File
pagenotfound_reports.moduleView source
<?php
/**
* @file
* Page Not Found Reports
*
* Adds admin reports about common 404 errors.
*/
/**
* Implements hook_menu().
*/
function pagenotfound_reports_menu() {
$items = array();
$items['admin/reports/404'] = array(
'title' => '404 Reports',
'description' => 'Reports on 404 (page not found) errors',
'page callback' => 'pagenotfound_reports_top_404s',
'access arguments' => array(
'access site reports',
),
);
$items['admin/reports/404/overview'] = array(
'title' => 'Most Common',
'description' => 'Reports on 404 (page not found) errors',
'page callback' => 'pagenotfound_reports_top_404s',
'access arguments' => array(
'access site reports',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/reports/404/referers'] = array(
'title' => 'Referers',
'description' => 'Pages that link to or include (as images or Javascript) paths that are not defined.',
'page callback' => 'pagenotfound_reports_referers',
'access arguments' => array(
'access site reports',
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items['admin/reports/404/all'] = array(
'title' => 'All 404s',
'description' => 'All 404 errors in the log.',
'page callback' => 'pagenotfound_reports_all',
'access arguments' => array(
'access site reports',
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['admin/reports/404/tips'] = array(
'title' => 'Tips',
'description' => 'Tips to minimize 404 errors.',
'page callback' => 'pagenotfound_reports_tips',
'access arguments' => array(
'access site reports',
),
'type' => MENU_LOCAL_TASK,
'weight' => 4,
);
return $items;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Modify the redirect add/edit form to prepopualate the source field with
* the path of a 404 record referenced in the querystring.
*/
function pagenotfound_reports_form_redirect_edit_form_alter(&$form, &$form_state) {
$wid = $_REQUEST['pagenotfound-wid'];
if (!empty($wid) && is_numeric($wid) && empty($form['source']['#default_value'])) {
$path = db_select('watchdog', 'w')
->fields('w', array(
'message',
))
->condition('type', 'page not found')
->condition('wid', $wid)
->execute()
->fetchField();
if (!empty($path)) {
$form['source']['#default_value'] = $path;
}
}
}
/**
* Add a set of operation links to a single dblog (404) entry.
*/
function _pagenotfound_reports_add_operations($dblog) {
$operations = array();
if (module_exists('redirect') && ($path = $dblog->message)) {
if ($existing = redirect_load_by_source($path)) {
$operations[] = l(t('Edit redirect'), 'admin/config/search/redirect/edit/' . $existing->rid, array(
'query' => drupal_get_destination(),
));
$operations[] = l(t('Delete redirect'), 'admin/config/search/redirect/delete/' . $existing->rid, array(
'query' => drupal_get_destination(),
));
}
elseif (!empty($dblog->wid)) {
$operations[] = l(t('Add redirect'), 'admin/config/search/redirect/add', array(
'query' => drupal_get_destination() + array(
'pagenotfound-wid' => $dblog->wid,
),
));
}
}
return !empty($operations) ? implode(' | ', $operations) : NULL;
}
/**
* List of all 404s sorted by most common
*/
function pagenotfound_reports_top_404s() {
$oldest_item = db_select('watchdog', 'w')
->fields('w', array(
'timestamp',
))
->condition('type', 'page not found')
->orderBy('timestamp', 'ASC')
->range(0, 1)
->execute()
->fetchAssoc();
$item_count = db_select('watchdog', 'w')
->fields('w', array(
'wid',
))
->condition('type', 'page not found')
->execute()
->rowCount();
// Stats
$output = _pagenotfound_reports_summary_stats($oldest_item['timestamp'], $item_count);
$header = array(
array(
'data' => t('Count'),
'field' => 'count',
'sort' => 'desc',
),
array(
'data' => t('Path'),
'field' => 'message',
),
array(
'data' => t('Operations'),
),
);
$result = db_select('watchdog', 'w')
->fields('w', array(
'wid',
'message',
))
->condition('type', 'page not found')
->extend('PagerDefault')
->limit(30)
->extend('TableSort')
->orderByHeader($header)
->groupBy('message');
$result
->addExpression('COUNT(wid)', 'count');
$result = $result
->execute();
$rows = array();
foreach ($result as $dblog) {
$rows[] = array(
$dblog->count,
truncate_utf8($dblog->message, 56, TRUE, TRUE),
_pagenotfound_reports_add_operations($dblog),
);
}
if (empty($rows)) {
$rows[] = array(
array(
'data' => t('No log messages available.'),
'colspan' => 3,
),
);
}
$output .= theme('table', array(
'header' => $header,
'rows' => $rows,
));
$output .= theme('pager', array(
'tags' => NULL,
'element' => 0,
));
return $output;
}
/**
* List of 404s with referers.
*/
function pagenotfound_reports_referers() {
$oldest_item = db_select('watchdog', 'w')
->fields('w', array(
'timestamp',
))
->condition('type', 'page not found')
->condition('referer', '', '!=')
->isNotNull('referer')
->orderBy('timestamp', 'ASC')
->range(0, 1)
->execute()
->fetchAssoc();
$item_count = db_select('watchdog', 'w')
->fields('w', array(
'wid',
))
->condition('type', 'page not found')
->condition('referer', '', '!=')
->isNotNull('referer')
->execute()
->rowCount();
// Stats
// Do NOT call _pagenotfound_reports_summary_stats(), since only 404 erros
// with referrers are shown in this report
$list_items = array();
$list_items[] = t('%count: Total 404 errors with a referer available in log', array(
'%count' => $item_count,
));
$output = theme('item_list', array(
'items' => $list_items,
));
$header = array(
array(
'data' => t('Count'),
'field' => 'count',
'sort' => 'desc',
),
array(
'data' => t('Path'),
'field' => 'message',
),
array(
'data' => t('Referer'),
'field' => 'referer',
),
array(
'data' => t('Operations'),
),
);
$result = db_select('watchdog', 'w')
->fields('w', array(
'wid',
'message',
'referer',
))
->condition('type', 'page not found')
->condition('referer', '', '!=')
->isNotNull('referer')
->extend('PagerDefault')
->limit(30)
->extend('TableSort')
->orderByHeader($header)
->groupBy('message')
->groupBy('referer');
$result
->addExpression('COUNT(wid)', 'count');
$result = $result
->execute();
$rows = array();
foreach ($result as $dblog) {
$rows[] = array(
$dblog->count,
truncate_utf8($dblog->message, 56, TRUE, TRUE),
l(truncate_utf8($dblog->referer, 56, TRUE, TRUE), $dblog->referer),
_pagenotfound_reports_add_operations($dblog),
);
}
if (empty($rows)) {
$rows[] = array(
array(
'data' => t('No log messages available.'),
'colspan' => 4,
),
);
}
$output .= theme('table', array(
'header' => $header,
'rows' => $rows,
));
$output .= theme('pager', array(
'tags' => NULL,
'element' => 0,
));
return $output;
}
/**
* List of all 404s in the log
*/
function pagenotfound_reports_all() {
$oldest_item = db_select('watchdog', 'w')
->fields('w', array(
'timestamp',
))
->condition('type', 'page not found')
->range(0, 1)
->execute()
->fetchAssoc();
$item_count = db_select('watchdog', 'w')
->fields('w', array(
'wid',
))
->condition('type', 'page not found')
->execute()
->rowCount();
// Stats
$output = _pagenotfound_reports_summary_stats($oldest_item['timestamp'], $item_count);
$header = array(
array(
'data' => t('Date'),
'field' => 'timestamp',
'sort' => 'desc',
),
array(
'data' => t('Path'),
'field' => 'message',
),
array(
'data' => t('Referer'),
'field' => 'referer',
),
array(
'data' => t('Operations'),
),
);
$result = db_select('watchdog', 'w')
->fields('w', array(
'wid',
'timestamp',
'message',
'referer',
))
->condition('type', 'page not found')
->extend('PagerDefault')
->limit(30)
->extend('TableSort')
->orderByHeader($header)
->execute();
$rows = array();
foreach ($result as $dblog) {
$rows[] = array(
l(format_date($dblog->timestamp), 'admin/reports/event/' . $dblog->wid, array(
'html' => TRUE,
)),
truncate_utf8($dblog->message, 56, TRUE, TRUE),
l(truncate_utf8($dblog->referer, 56, TRUE, TRUE), $dblog->referer),
_pagenotfound_reports_add_operations($dblog),
);
}
if (empty($rows)) {
$rows[] = array(
array(
'data' => t('No log messages available.'),
'colspan' => 4,
),
);
}
$output .= theme('table', array(
'header' => $header,
'rows' => $rows,
));
$output .= theme('pager', array(
'tags' => NULL,
'element' => 0,
));
return $output;
}
/**
* Get summary stats to show above the report. Takes the $oldest_item and
* $item_count variables because different reports include different types or
* sets of log records, so they need to be figured for each report.
*
* @param $oldest_item_timestamp
* Timestamp of the oldest 404 error shown in current report
* @param $item_count
* Number of 404 errors included in this report
*
* @return
* Formatted HTML of summary stats to show at the top of the report
*/
function _pagenotfound_reports_summary_stats($oldest_item_timestamp, $item_count) {
// If there are no 404 errors, there are no stats to show
if (empty($oldest_item_timestamp) || $item_count == 0) {
return '';
}
// Stats
$rate_of_404s = round($item_count / ((REQUEST_TIME - $oldest_item_timestamp) / 60), 2);
$list_items = array();
$list_items[] = t('%oldest: Oldest "page not found" error available in log', array(
'%oldest' => format_date($oldest_item_timestamp),
));
$list_items[] = t('%count: Total 404 errors available in log', array(
'%count' => $item_count,
));
$list_items[] = t('%count_per_minute: Errors per minute', array(
'%count_per_minute' => $rate_of_404s,
));
return theme('item_list', array(
'items' => $list_items,
));
}
/**
* Page of tips to minimize 404 errors
*/
function pagenotfound_reports_tips() {
$header = array(
t('Status'),
t('Description'),
);
$rows = array();
if (module_exists('redirect')) {
$row = array(
'data' => array(
t('Done'),
t('Redirect module is installed, so that redirects can be created from the 404 reports.'),
),
'class' => array(
'ok',
),
);
}
else {
$row = array(
'data' => array(
t('Todo'),
t('Install the !redirect module so that redirects can be quickly and easily created for any item in the 404 reports.', array(
'!redirect' => l('Redirect', 'http://drupal.org/project/redirect'),
)),
),
'class' => array(
'warning',
),
);
}
$rows[] = $row;
return theme('table', array(
'header' => $header,
'rows' => $rows,
));
}
Functions
Name![]() |
Description |
---|---|
pagenotfound_reports_all | List of all 404s in the log |
pagenotfound_reports_form_redirect_edit_form_alter | Implements hook_form_FORM_ID_alter(). |
pagenotfound_reports_menu | Implements hook_menu(). |
pagenotfound_reports_referers | List of 404s with referers. |
pagenotfound_reports_tips | Page of tips to minimize 404 errors |
pagenotfound_reports_top_404s | List of all 404s sorted by most common |
_pagenotfound_reports_add_operations | Add a set of operation links to a single dblog (404) entry. |
_pagenotfound_reports_summary_stats | Get summary stats to show above the report. Takes the $oldest_item and $item_count variables because different reports include different types or sets of log records, so they need to be figured for each report. |