Commit cb112e9a authored by Dries's avatar Dries

- Patch #718662 by andypost, c960657: DBLog listings truncate messages in the middle of HTML tags.

parent 73deaa34
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
/** /**
* Menu callback; displays a listing of log messages. * Menu callback; displays a listing of log messages.
*
* Messages are truncated at 56 chars. Full-length message could be viewed at
* the message details page.
*/ */
function dblog_overview() { function dblog_overview() {
$filter = dblog_build_filter_query(); $filter = dblog_build_filter_query();
...@@ -65,7 +68,7 @@ function dblog_overview() { ...@@ -65,7 +68,7 @@ function dblog_overview() {
$icons[$dblog->severity], $icons[$dblog->severity],
t($dblog->type), t($dblog->type),
format_date($dblog->timestamp, 'short'), format_date($dblog->timestamp, 'short'),
l(truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE), 'admin/reports/event/' . $dblog->wid, array('html' => TRUE)), theme('dblog_message', array('event' => $dblog, 'link' => TRUE)),
theme('username', array('account' => $dblog)), theme('username', array('account' => $dblog)),
$dblog->link, $dblog->link,
), ),
...@@ -87,8 +90,12 @@ function dblog_overview() { ...@@ -87,8 +90,12 @@ function dblog_overview() {
} }
/** /**
* Menu callback; generic function to display a page of the most frequent * Menu callback; generic function to display a page of the most frequent events.
* dblog events of a specified type. *
* Messages are not truncated because events from this page have no detail view.
*
* @param $type
* type of dblog events to display.
*/ */
function dblog_top($type) { function dblog_top($type) {
...@@ -114,7 +121,7 @@ function dblog_top($type) { ...@@ -114,7 +121,7 @@ function dblog_top($type) {
$rows = array(); $rows = array();
foreach ($result as $dblog) { foreach ($result as $dblog) {
$rows[] = array($dblog->count, truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE)); $rows[] = array($dblog->count, theme('dblog_message', array('event' => $dblog)));
} }
$build['dblog_top_table'] = array( $build['dblog_top_table'] = array(
...@@ -158,7 +165,7 @@ function dblog_event($id) { ...@@ -158,7 +165,7 @@ function dblog_event($id) {
), ),
array( array(
array('data' => t('Message'), 'header' => TRUE), array('data' => t('Message'), 'header' => TRUE),
_dblog_format_message($dblog), theme('dblog_message', array('event' => $dblog)),
), ),
array( array(
array('data' => t('Severity'), 'header' => TRUE), array('data' => t('Severity'), 'header' => TRUE),
...@@ -246,21 +253,35 @@ function dblog_filters() { ...@@ -246,21 +253,35 @@ function dblog_filters() {
/** /**
* Formats a log message for display. * Formats a log message for display.
* *
* @param $dblog * @param $variables
* An object with at least the message and variables properties * 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.
*
* @ingroup themeable
*/ */
function _dblog_format_message($dblog) { function theme_dblog_message($variables) {
// Legacy messages and user specified text $output = '';
if ($dblog->variables === 'N;') { $event = $variables['event'];
return $dblog->message; // Check for required properties.
} if (isset($event->message) && isset($event->variables)) {
// Message to translate with injected variables // Messages without variables or user specified text.
else { if ($event->variables === 'N;') {
return t($dblog->message, unserialize($dblog->variables)); $output = $event->message;
}
// Message to translate with injected variables.
else {
$output = t($event->message, unserialize($event->variables));
}
if ($variables['link'] && isset($event->wid)) {
// Truncate message to 56 chars.
$output = truncate_utf8(filter_xss($output, array()), 56, TRUE, TRUE);
$output = l($output, 'admin/reports/event/' . $event->wid, array('html' => TRUE));
}
} }
return $output;
} }
/** /**
* Return form for dblog administration filters. * Return form for dblog administration filters.
* *
......
...@@ -144,3 +144,15 @@ function dblog_form_system_logging_settings_alter(&$form, $form_state) { ...@@ -144,3 +144,15 @@ function dblog_form_system_logging_settings_alter(&$form, $form_state) {
); );
$form['actions']['#weight'] = 1; $form['actions']['#weight'] = 1;
} }
/**
* Implements hook_theme().
*/
function dblog_theme() {
return array(
'dblog_message' => array(
'variables' => array('event' => NULL, 'link' => FALSE),
'file' => 'dblog.admin.inc',
),
);
}
...@@ -74,9 +74,7 @@ class DBLogTestCase extends DrupalWebTestCase { ...@@ -74,9 +74,7 @@ class DBLogTestCase extends DrupalWebTestCase {
$this->assertTrue($count > $row_limit, t('Dblog row count of @count exceeds row limit of @limit', array('@count' => $count, '@limit' => $row_limit))); $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 cron job.
$this->drupalGet('admin/reports/status/run-cron'); $this->cronRun();
$this->assertResponse(200);
$this->assertText(t('Cron ran successfully'), t('Cron ran successfully'));
// Verify dblog row count equals row limit plus one because cron adds a record after it runs. // Verify dblog row count equals row limit plus one because cron adds a record after it runs.
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField(); $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))); $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)));
...@@ -108,9 +106,9 @@ class DBLogTestCase extends DrupalWebTestCase { ...@@ -108,9 +106,9 @@ class DBLogTestCase extends DrupalWebTestCase {
'ip' => ip_address(), 'ip' => ip_address(),
'timestamp' => REQUEST_TIME, 'timestamp' => REQUEST_TIME,
); );
$message = 'Log entry added to test the dblog row limit.'; $message = 'Log entry added to test the dblog row limit. Entry #';
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$log['message'] = $this->randomString(); $log['message'] = $message . $i;
dblog_watchdog($log); dblog_watchdog($log);
} }
} }
...@@ -181,7 +179,7 @@ class DBLogTestCase extends DrupalWebTestCase { ...@@ -181,7 +179,7 @@ class DBLogTestCase extends DrupalWebTestCase {
*/ */
private function doUser() { private function doUser() {
// Set user variables. // Set user variables.
$name = $this->randomName(4); $name = $this->randomName();
$pass = user_password(); $pass = user_password();
// Add user using form to generate add user event (which is not triggered by drupalCreateUser). // Add user using form to generate add user event (which is not triggered by drupalCreateUser).
$edit = array(); $edit = array();
...@@ -223,11 +221,38 @@ class DBLogTestCase extends DrupalWebTestCase { ...@@ -223,11 +221,38 @@ class DBLogTestCase extends DrupalWebTestCase {
// 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 then email 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]')); $this->assertLogMessage(t('New user: %name (%email).', array('%name' => $name, '%email' => $user->mail)), t('DBLog event was recorded: [add user]'));
// Login user. // Login user.
$this->assertLogMessage(t('Session opened for %name', array('%name' => $name)), t('DBLog event was recorded: [login user]')); $this->assertLogMessage(t('Session opened for %name.', array('%name' => $name)), t('DBLog event was recorded: [login user]'));
// Logout user. // Logout user.
$this->assertLogMessage(t('Session closed for %name', array('%name' => $name)), t('DBLog event was recorded: [logout user]')); $this->assertLogMessage(t('Session closed for %name.', array('%name' => $name)), t('DBLog event was recorded: [logout user]'));
// Delete user. // Delete user.
$this->assertLogMessage(t('Deleted user: %name', array('%name' => $name)), t('DBLog event was recorded: [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.
$link = FALSE;
if ($links = $this->xpath('//a[text()="' . html_entity_decode($message_text) . '"]')) {
// Found link with the message text.
$links = array_shift($links);
foreach ($links->attributes() as $attr => $value) {
if ($attr == 'href') {
// Extract link to details page.
$link = drupal_substr($value, strpos($value, 'admin/reports/event/'));
$this->drupalGet($link);
// Check for full message text on the details page.
$this->assertRaw($message, t('DBLog event details was found: [delete user]'));
break;
}
}
}
$this->assertTrue($link, t('DBLog event was recorded: [delete user]'));
// Visit random URL (to generate page not found event).
$not_found_url = $this->randomName(60);
$this->drupalGet($not_found_url);
$this->assertResponse(404);
// View dblog page-not-found report page.
$this->drupalGet('admin/reports/page-not-found');
$this->assertResponse(200);
// Check that full-length url displayed.
$this->assertText($not_found_url, t('DBLog event was recorded: [page not found]'));
} }
/** /**
...@@ -537,15 +562,20 @@ class DBLogTestCase extends DrupalWebTestCase { ...@@ -537,15 +562,20 @@ class DBLogTestCase extends DrupalWebTestCase {
/** /**
* Assert messages appear on the log overview screen. * Assert messages appear on the log overview screen.
* *
* This function should be used only for admin/reports/dblog page, because it
* check for the message link text truncated to 56 characters. Other dblog
* pages have no detail links so contains a full message text.
*
* @param $log_message * @param $log_message
* The message to check. * The message to check.
* @param $message * @param $message
* The message to pass to simpletest. * The message to pass to simpletest.
*/ */
protected function assertLogMessage($log_message, $message) { protected function assertLogMessage($log_message, $message) {
// Truncate at 56 characters to compare with dblog's HTML output. $message_text = truncate_utf8(filter_xss($log_message, array()), 56, TRUE, TRUE);
// @todo: Check the database instead for the exact error string. // After filter_xss() HTML entities should be converted to their characters
$this->assertRaw(truncate_utf8($log_message, 56, TRUE, TRUE), $message); // because assertLink() uses this string in xpath() to query DOM.
$this->assertLink(html_entity_decode($message_text), 0, $message);
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment