Commit 17914705 authored by jhodgdon's avatar jhodgdon
Browse files

Issue #1326600 by batigolix, kid_icarus, Lars Toomre: Fix up API docs for dblog module

parent 2d4c3c65
/**
* @file
* RTL styling for the Database Logging module.
*/
.form-item-type,
.form-item-severity {
......
......@@ -2,14 +2,17 @@
/**
* @file
* Administrative page callbacks for the dblog module.
* Administrative page callbacks for the Database Logging module.
*/
/**
* Menu callback; displays a listing of log messages.
* Page callback: Displays a listing of database log messages.
*
* Messages are truncated at 56 chars. Full-length message could be viewed at
* Messages are truncated at 56 chars. Full-length messages can be viewed on
* the message details page.
*
* @see dblog_menu()
* @see dblog_event()
*/
function dblog_overview() {
$filter = dblog_build_filter_query();
......@@ -81,12 +84,15 @@ function dblog_overview() {
}
/**
* Menu callback; generic function to display a page of the most frequent events.
* Page callback: Shows the most frequent log messages of a given event type.
*
* Messages are not truncated on this page because events detailed herein do not
* have links to a detailed view.
*
* Messages are not truncated because events from this page have no detail view.
* @param string $type
* Type of database log events to display (e.g., 'search').
*
* @param $type
* type of dblog events to display.
* @see dblog_menu()
*/
function dblog_top($type) {
......@@ -129,7 +135,12 @@ function dblog_top($type) {
}
/**
* Menu callback; displays details about a log message.
* Page callback: Displays details about a specific database log message.
*
* @param int $id
* Unique ID of the database log message.
*
* @see dblog_menu()
*/
function dblog_event($id) {
$severity = watchdog_severity_levels();
......@@ -186,7 +197,10 @@ function dblog_event($id) {
}
/**
* Build query for dblog administration filters based on session.
* Builds a query for database log administration filters based on session.
*
* @return array
* An associative array with keys 'where' and 'args'.
*/
function dblog_build_filter_query() {
if (empty($_SESSION['dblog_overview_filter'])) {
......@@ -215,9 +229,16 @@ function dblog_build_filter_query() {
);
}
/**
* List dblog administration filters that can be applied.
* Creates a list of database log administration filters that can be applied.
*
* @return array
* Associative array of filters. The top-level keys are used as the form
* element names for the filters, and the values are arrays with the following
* elements:
* - title: Title of the filter.
* - where: The filter condition.
* - options: Array of options for the select list for the filter.
*/
function dblog_filters() {
$filters = array();
......@@ -246,7 +267,7 @@ function dblog_filters() {
/**
* Returns HTML for a log message.
*
* @param $variables
* @param array $variables
* An associative array containing:
* - event: An object with at least the message and variables properties.
* - link: (optional) Format message as link, event->wid is required.
......@@ -276,11 +297,11 @@ function theme_dblog_message($variables) {
}
/**
* Return form for dblog administration filters.
* Form constructor for the database logging filter form.
*
* @ingroup forms
* @see dblog_filter_form_submit()
* @see dblog_filter_form_validate()
* @see dblog_filter_form_submit()
* @ingroup forms
*/
function dblog_filter_form($form) {
$filters = dblog_filters();
......@@ -318,12 +339,13 @@ function dblog_filter_form($form) {
'#value' => t('Reset')
);
}
return $form;
}
/**
* Validate result from dblog administration filter form.
* Form validation handler for dblog_filter_form().
*
* @see dblog_filter_form_submit()
*/
function dblog_filter_form_validate($form, &$form_state) {
if ($form_state['values']['op'] == t('Filter') && empty($form_state['values']['type']) && empty($form_state['values']['severity'])) {
......@@ -332,7 +354,9 @@ function dblog_filter_form_validate($form, &$form_state) {
}
/**
* Process result from dblog administration filter form.
* Form submission handler for dblog_filter_form().
*
* @see dblog_filter_form_validate()
*/
function dblog_filter_form_submit($form, &$form_state) {
$op = $form_state['values']['op'];
......@@ -353,10 +377,10 @@ function dblog_filter_form_submit($form, &$form_state) {
}
/**
* Return form for dblog clear button.
* Form constructor for the form that clears out the log.
*
* @ingroup forms
* @see dblog_clear_log_submit()
* @ingroup forms
*/
function dblog_clear_log_form($form) {
$form['dblog_clear'] = array(
......@@ -371,12 +395,11 @@ function dblog_clear_log_form($form) {
'#value' => t('Clear log messages'),
'#submit' => array('dblog_clear_log_submit'),
);
return $form;
}
/**
* Submit callback: clear database with log messages.
* Form submission handler for dblog_clear_log_form().
*/
function dblog_clear_log_submit() {
$_SESSION['dblog_overview_filter'] = array();
......
/**
* @file
* Admin styles for the Database Logging module.
*/
.form-item-type,
.form-item-severity {
float: left; /* LTR */
......
......@@ -6,9 +6,9 @@
* @file
* System monitoring and logging for administrators.
*
* The dblog module monitors your site and keeps a list of
* recorded events containing usage and performance data, errors,
* warnings, and similar operational information.
* The Database Logging module monitors your site and keeps a list of recorded
* events containing usage and performance data, errors, warnings, and similar
* operational information.
*
* @see watchdog()
*/
......@@ -98,7 +98,7 @@ function dblog_init() {
/**
* Implements hook_cron().
*
* Remove expired log messages and flood control events.
* Controls the size of the log table, paring it to 'dblog_row_limit' messages.
*/
function dblog_cron() {
// Cleanup the watchdog table.
......@@ -123,6 +123,12 @@ function dblog_cron() {
}
}
/**
* Gathers a list of uniquely defined database log message types.
*
* @return array
* List of uniquely defined database log message types.
*/
function _dblog_get_message_types() {
$types = array();
......@@ -137,7 +143,7 @@ function _dblog_get_message_types() {
/**
* Implements hook_watchdog().
*
* Note some values may be truncated for database column size restrictions.
* Note: Some values may be truncated to meet database column size restrictions.
*/
function dblog_watchdog(array $log_entry) {
Database::getConnection('default', 'default')->insert('watchdog')
......@@ -157,7 +163,7 @@ function dblog_watchdog(array $log_entry) {
}
/**
* Implements hook_form_FORM_ID_alter().
* Implements hook_form_FORM_ID_alter() for system_logging_settings().
*/
function dblog_form_system_logging_settings_alter(&$form, $form_state) {
$form['dblog_row_limit'] = array(
......
......@@ -41,7 +41,11 @@ function setUp() {
}
/**
* Login users, create dblog events, and test dblog functionality through the admin and user interfaces.
* Tests Database Logging module functionality through interfaces.
*
* First logs in users, then creates database log events, and finally tests
* Database Logging module functionality through both the admin and user
* interfaces.
*/
function testDBLog() {
// Login the admin user.
......@@ -59,12 +63,13 @@ function testDBLog() {
}
/**
* Verify setting of the dblog row limit.
* Verifies setting of the database log row limit.
*
* @param integer $count Log row limit.
* @param int $row_limit
* The row limit.
*/
private function verifyRowLimit($row_limit) {
// Change the dblog row limit.
// Change the database log row limit.
$edit = array();
$edit['dblog_row_limit'] = $row_limit;
$this->drupalPost('admin/config/development/logging', $edit, t('Save configuration'));
......@@ -76,32 +81,34 @@ private function verifyRowLimit($row_limit) {
}
/**
* Verify cron applies the dblog row limit.
* Verifies that cron correctly applies the database log row limit.
*
* @param integer $count Log row limit.
* @param int $row_limit
* The row limit.
*/
private function verifyCron($row_limit) {
// Generate additional log entries.
$this->generateLogEntries($row_limit + 10);
// Verify dblog row count exceeds row limit.
// Verify that the database log row count exceeds the row limit.
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
$this->assertTrue($count > $row_limit, t('Dblog row count of @count exceeds row limit of @limit', array('@count' => $count, '@limit' => $row_limit)));
// Run cron job.
// Run a cron job.
$this->cronRun();
// Verify dblog row count equals row limit plus one because cron adds a record after it runs.
// Verify that the database log row count equals the row limit plus one
// because cron adds a record after it runs.
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
$this->assertTrue($count == $row_limit + 1, t('Dblog row count of @count equals row limit of @limit plus one', array('@count' => $count, '@limit' => $row_limit)));
}
/**
* Generate dblog entries.
* Generates a number of random database log events.
*
* @param integer $count
* Number of log entries to generate.
* @param $type
* @param int $count
* Number of watchdog entries to generate.
* @param string $type
* The type of watchdog entry.
* @param $severity
* @param int $severity
* The severity of the watchdog entry.
*/
private function generateLogEntries($count, $type = 'custom', $severity = WATCHDOG_NOTICE) {
......@@ -129,42 +136,43 @@ private function generateLogEntries($count, $type = 'custom', $severity = WATCHD
}
/**
* Verify the logged in user has the desired access to the various dblog nodes.
* Confirms that database log reports are displayed at the correct paths.
*
* @param integer $response HTTP response code.
* @param int $response
* HTTP response code.
*/
private function verifyReports($response = 200) {
$quote = ''';
// View dblog help node.
// View the database log help page.
$this->drupalGet('admin/help/dblog');
$this->assertResponse($response);
if ($response == 200) {
$this->assertText(t('Database Logging'), t('DBLog help was displayed'));
}
// View dblog report node.
// View the database log report page.
$this->drupalGet('admin/reports/dblog');
$this->assertResponse($response);
if ($response == 200) {
$this->assertText(t('Recent log messages'), t('DBLog report was displayed'));
}
// View dblog page-not-found report node.
// View the database log page-not-found report page.
$this->drupalGet('admin/reports/page-not-found');
$this->assertResponse($response);
if ($response == 200) {
$this->assertText(t('Top ' . $quote . 'page not found' . $quote . ' errors'), t('DBLog page-not-found report was displayed'));
}
// View dblog access-denied report node.
// View the database log access-denied report page.
$this->drupalGet('admin/reports/access-denied');
$this->assertResponse($response);
if ($response == 200) {
$this->assertText(t('Top ' . $quote . 'access denied' . $quote . ' errors'), t('DBLog access-denied report was displayed'));
}
// View dblog event node.
// View the database log event page.
$this->drupalGet('admin/reports/event/1');
$this->assertResponse($response);
if ($response == 200) {
......@@ -173,7 +181,7 @@ private function verifyReports($response = 200) {
}
/**
* Verify events.
* Generates and then verifies various types of events.
*/
private function verifyEvents() {
// Invoke events.
......@@ -188,14 +196,14 @@ private function verifyEvents() {
}
/**
* Generate and verify user events.
*
* Generates and then verifies some user events.
*/
private function doUser() {
// Set user variables.
$name = $this->randomName();
$pass = user_password();
// Add user using form to generate add user event (which is not triggered by drupalCreateUser).
// Add a user using the form to generate an add user event (which is not
// triggered by drupalCreateUser).
$edit = array();
$edit['name'] = $name;
$edit['mail'] = $name . '@example.com';
......@@ -204,15 +212,16 @@ private function doUser() {
$edit['status'] = 1;
$this->drupalPost('admin/people/create', $edit, t('Create new account'));
$this->assertResponse(200);
// Retrieve user object.
// Retrieve the user object.
$user = user_load_by_name($name);
$this->assertTrue($user != NULL, t('User @name was loaded', array('@name' => $name)));
$user->pass_raw = $pass; // Needed by drupalLogin.
// pass_raw property is needed by drupalLogin.
$user->pass_raw = $pass;
// Login user.
$this->drupalLogin($user);
// Logout user.
$this->drupalLogout();
// Fetch row ids in watchdog that relate to the user.
// Fetch the row IDs in watchdog that relate to the user.
$result = db_query('SELECT wid FROM {watchdog} WHERE uid = :uid', array(':uid' => $user->uid));
foreach ($result as $row) {
$ids[] = $row->wid;
......@@ -222,17 +231,18 @@ private function doUser() {
// Login the admin user.
$this->drupalLogin($this->big_user);
// Delete user.
// Delete the user created at the start of this test.
// We need to POST here to invoke batch_process() in the internal browser.
$this->drupalPost('user/' . $user->uid . '/cancel', array('user_cancel_method' => 'user_cancel_reassign'), t('Cancel account'));
// View the dblog report.
// View the database log report.
$this->drupalGet('admin/reports/dblog');
$this->assertResponse(200);
// Verify events were recorded.
// Verify that the expected events were recorded.
// Add user.
// Default display includes name and email address; if too long then email is replaced by three periods.
// Default display includes name and email address; if too long, the email
// address is replaced by three periods.
$this->assertLogMessage(t('New user: %name (%email).', array('%name' => $name, '%email' => $user->mail)), t('DBLog event was recorded: [add user]'));
// Login user.
$this->assertLogMessage(t('Session opened for %name.', array('%name' => $name)), t('DBLog event was recorded: [login user]'));
......@@ -241,7 +251,7 @@ private function doUser() {
// Delete user.
$message = t('Deleted user: %name %email.', array('%name' => $name, '%email' => '<' . $user->mail . '>'));
$message_text = truncate_utf8(filter_xss($message, array()), 56, TRUE, TRUE);
// Verify full message on details page.
// Verify that the full message displays on the details page.
$link = FALSE;
if ($links = $this->xpath('//a[text()="' . html_entity_decode($message_text) . '"]')) {
// Found link with the message text.
......@@ -262,7 +272,7 @@ private function doUser() {
$not_found_url = $this->randomName(60);
$this->drupalGet($not_found_url);
$this->assertResponse(404);
// View dblog page-not-found report page.
// View the database log page-not-found report page.
$this->drupalGet('admin/reports/page-not-found');
$this->assertResponse(200);
// Check that full-length url displayed.
......@@ -270,9 +280,10 @@ private function doUser() {
}
/**
* Generate and verify node events.
* Generates and then verifies some node events.
*
* @param string $type Content type.
* @param string $type
* A node type (e.g., 'article', 'page' or 'poll').
*/
private function doNode($type) {
// Create user.
......@@ -281,61 +292,65 @@ private function doNode($type) {
// Login user.
$this->drupalLogin($user);
// Create node using form to generate add content event (which is not triggered by drupalCreateNode).
// Create a node using the form in order to generate an add content event
// (which is not triggered by drupalCreateNode).
$edit = $this->getContent($type);
$langcode = LANGUAGE_NOT_SPECIFIED;
$title = $edit["title"];
$this->drupalPost('node/add/' . $type, $edit, t('Save'));
$this->assertResponse(200);
// Retrieve node object.
// Retrieve the node object.
$node = $this->drupalGetNodeByTitle($title);
$this->assertTrue($node != NULL, t('Node @title was loaded', array('@title' => $title)));
// Edit node.
// Edit the node.
$edit = $this->getContentUpdate($type);
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertResponse(200);
// Delete node.
// Delete the node.
$this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
$this->assertResponse(200);
// View node (to generate page not found event).
// View the node (to generate page not found event).
$this->drupalGet('node/' . $node->nid);
$this->assertResponse(404);
// View the dblog report (to generate access denied event).
// View the database log report (to generate access denied event).
$this->drupalGet('admin/reports/dblog');
$this->assertResponse(403);
// Login the admin user.
$this->drupalLogin($this->big_user);
// View the dblog report.
// View the database log report.
$this->drupalGet('admin/reports/dblog');
$this->assertResponse(200);
// Verify events were recorded.
// Content added.
// Verify that node events were recorded.
// Was node content added?
$this->assertLogMessage(t('@type: added %title.', array('@type' => $type, '%title' => $title)), t('DBLog event was recorded: [content added]'));
// Content updated.
// Was node content updated?
$this->assertLogMessage(t('@type: updated %title.', array('@type' => $type, '%title' => $title)), t('DBLog event was recorded: [content updated]'));
// Content deleted.
// Was node content deleted?
$this->assertLogMessage(t('@type: deleted %title.', array('@type' => $type, '%title' => $title)), t('DBLog event was recorded: [content deleted]'));
// View dblog access-denied report node.
// View the database log access-denied report page.
$this->drupalGet('admin/reports/access-denied');
$this->assertResponse(200);
// Access denied.
// Verify that the 'access denied' event was recorded.
$this->assertText(t('admin/reports/dblog'), t('DBLog event was recorded: [access denied]'));
// View dblog page-not-found report node.
// View the database log page-not-found report page.
$this->drupalGet('admin/reports/page-not-found');
$this->assertResponse(200);
// Page not found.
// Verify that the 'page not found' event was recorded.
$this->assertText(t('node/@nid', array('@nid' => $node->nid)), t('DBLog event was recorded: [page not found]'));
}
/**
* Create content based on content type.
* Creates random content based on node content type.
*
* @param string $type Content type.
* @return array Content.
* @param string $type
* Node content type (e.g., 'article').
*
* @return array
* Random content needed by various node types.
*/
private function getContent($type) {
$langcode = LANGUAGE_NOT_SPECIFIED;
......@@ -359,10 +374,13 @@ private function getContent($type) {
}
/**
* Create content update based on content type.
* Creates random content as an update based on node content type.
*
* @param string $type
* Node content type (e.g., 'article').
*
* @param string $type Content type.
* @return array Content.
* @return array
* Random content needed by various node types.
*/
private function getContentUpdate($type) {
switch ($type) {
......@@ -384,11 +402,14 @@ private function getContentUpdate($type) {
}
/**
* Login an admin user, create dblog event, and test clearing dblog functionality through the admin interface.
* Tests the addition and clearing of log events through the admin interface.
*
* Logs in the admin user, creates a database log event, and tests the
* functionality of clearing the database log through the admin interface.
*/
protected function testDBLogAddAndClear() {
global $base_root;
// Get a count of how many watchdog entries there are.
// Get a count of how many watchdog entries already exist.
$count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
$log = array(
'type' => 'custom',
......@@ -405,27 +426,27 @@ protected function testDBLogAddAndClear() {
);
// Add a watchdog entry.
dblog_watchdog($log);
// Make sure the table count has actually incremented.
// Make sure the table count has actually been incremented.
$this->assertEqual($count + 1, db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), t('dblog_watchdog() added an entry to the dblog :count', array(':count' => $count)));
// Login the admin user.
$this->drupalLogin($this->big_user);
// Now post to clear the db table.
// Post in order to clear the database table.
$this->drupalPost('admin/reports/dblog', array(), t('Clear log messages'));
// Count rows in watchdog that previously related to the deleted user.
// Count the rows in watchdog that previously related to the deleted user.
$count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
$this->assertEqual($count, 0, t('DBLog contains :count records after a clear.', array(':count' => $count)));
}
/**
* Test the dblog filter on admin/reports/dblog.
* Tests the database log filter functionality at admin/reports/dblog.
*/
protected function testFilter() {
$this->drupalLogin($this->big_user);
// Clear log to ensure that only generated entries are found.
// Clear the log to ensure that only generated entries will be found.
db_delete('watchdog')->execute();
// Generate watchdog entries.
// Generate 9 random watchdog entries.
$type_names = array();
$types = array();
for ($i = 0; $i < 3; $i++) {
......@@ -441,10 +462,10 @@ protected function testFilter() {
}
}
// View the dblog.
// View the database log page.
$this->drupalGet('admin/reports/dblog');
// Confirm all the entries are displayed.
// Confirm that all the entries are displayed.
$count = $this->getTypeCount($types);
foreach ($types as $key => $type) {
$this->assertEqual($count[$key], $type['count'], 'Count matched');
......@@ -470,8 +491,8 @@ protected function testFilter() {
$this->assertEqual(array_sum($count), $type_count, 'Count matched');
}
// Set filter to match each of the three type attributes and confirm the
// number of entries displayed.
// Set the filter to match each of the two filter-type attributes and
// confirm the correct number of entries are displayed.
foreach ($types as $key => $type) {