| 1 | | <?php |
| 2 | | // $Id: dblog.admin.inc,v 1.8 2008/07/19 07:44:45 dries Exp $ |
| 3 | | |
| 4 | | /** |
| 5 | | * @file |
| 6 | | * Administrative page callbacks for the dblog module. |
| 7 | | */ |
| 8 | | |
| 9 | | /** |
| 10 | | * dblog module settings form. |
| 11 | | * |
| 12 | | * @ingroup forms |
| 13 | | * @see system_settings_form() |
| 14 | | */ |
| 15 | 28 | function dblog_admin_settings() { |
| 16 | 3 | $form['dblog_row_limit'] = array( |
| 17 | 3 | '#type' => 'select', |
| 18 | 3 | '#title' => t('Discard log entries above the following row limit'), |
| 19 | 3 | '#default_value' => variable_get('dblog_row_limit', 1000), |
| 20 | 3 | '#options' => drupal_map_assoc(array(100, 1000, 10000, 100000,
1000000)), |
| 21 | 3 | '#description' => t('The maximum number of rows to keep in the database
log. Older entries will be automatically discarded. (Requires a correctly
configured <a href="@cron">cron maintenance task</a>.)', array('@cron' =>
url('admin/reports/status'))) |
| 22 | 3 | ); |
| 23 | | |
| 24 | 3 | return system_settings_form($form); |
| 25 | 0 | } |
| 26 | | |
| 27 | | /** |
| 28 | | * Menu callback; displays a listing of log messages. |
| 29 | | */ |
| 30 | 28 | function dblog_overview() { |
| 31 | 6 | $filter = dblog_build_filter_query(); |
| 32 | 6 | $rows = array(); |
| 33 | | $icons = array( |
| 34 | 6 | WATCHDOG_DEBUG => '', |
| 35 | 6 | WATCHDOG_INFO => '', |
| 36 | 6 | WATCHDOG_NOTICE => '', |
| 37 | 6 | WATCHDOG_WARNING => theme('image', 'misc/watchdog-warning.png',
t('warning'), t('warning')), |
| 38 | 6 | WATCHDOG_ERROR => theme('image', 'misc/watchdog-error.png',
t('error'), t('error')), |
| 39 | 6 | WATCHDOG_CRITICAL => theme('image', 'misc/watchdog-error.png',
t('critical'), t('critical')), |
| 40 | 6 | WATCHDOG_ALERT => theme('image', 'misc/watchdog-error.png',
t('alert'), t('alert')), |
| 41 | 6 | WATCHDOG_EMERG => theme('image', 'misc/watchdog-error.png',
t('emergency'), t('emergency')), |
| 42 | 6 | ); |
| 43 | | $classes = array( |
| 44 | 6 | WATCHDOG_DEBUG => 'dblog-debug', |
| 45 | 6 | WATCHDOG_INFO => 'dblog-info', |
| 46 | 6 | WATCHDOG_NOTICE => 'dblog-notice', |
| 47 | 6 | WATCHDOG_WARNING => 'dblog-warning', |
| 48 | 6 | WATCHDOG_ERROR => 'dblog-error', |
| 49 | 6 | WATCHDOG_CRITICAL => 'dblog-critical', |
| 50 | 6 | WATCHDOG_ALERT => 'dblog-alert', |
| 51 | 6 | WATCHDOG_EMERG => 'dblog-emerg', |
| 52 | 6 | ); |
| 53 | | |
| 54 | 6 | $output = drupal_get_form('dblog_filter_form'); |
| 55 | | |
| 56 | | $header = array( |
| 57 | 6 | ' ', |
| 58 | 6 | array('data' => t('Type'), 'field' => 'w.type'), |
| 59 | 6 | array('data' => t('Date'), 'field' => 'w.wid', 'sort' => 'desc'), |
| 60 | 6 | t('Message'), |
| 61 | 6 | array('data' => t('User'), 'field' => 'u.name'), |
| 62 | 6 | array('data' => t('Operations')), |
| 63 | 6 | ); |
| 64 | | |
| 65 | 6 | $sql = "SELECT w.wid, w.uid, w.severity, w.type, w.timestamp, w.message,
w.variables, w.link, u.name FROM {watchdog} w INNER JOIN {users} u ON w.uid
= u.uid"; |
| 66 | 6 | $tablesort = tablesort_sql($header); |
| 67 | 6 | if (!empty($filter['where'])) { |
| 68 | 0 | $result = pager_query($sql . " WHERE " . $filter['where'] . $tablesort,
50, 0, NULL, $filter['args']); |
| 69 | 0 | } |
| 70 | | else { |
| 71 | 6 | $result = pager_query($sql . $tablesort, 50); |
| 72 | | } |
| 73 | | |
| 74 | 6 | while ($dblog = db_fetch_object($result)) { |
| 75 | 6 | $rows[] = array('data' => |
| 76 | | array( |
| 77 | | // Cells |
| 78 | 6 | $icons[$dblog->severity], |
| 79 | 6 | t($dblog->type), |
| 80 | 6 | format_date($dblog->timestamp, 'small'), |
| 81 | 6 | l(truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE),
'admin/reports/event/' . $dblog->wid, array('html' => TRUE)), |
| 82 | 6 | theme('username', $dblog), |
| 83 | 6 | $dblog->link, |
| 84 | 6 | ), |
| 85 | | // Attributes for tr |
| 86 | 6 | 'class' => "dblog-" . preg_replace('/[^a-z]/i', '-', $dblog->type) .
' ' . $classes[$dblog->severity] |
| 87 | 6 | ); |
| 88 | 6 | } |
| 89 | | |
| 90 | 6 | if (!$rows) { |
| 91 | 0 | $rows[] = array(array('data' => t('No log messages available.'),
'colspan' => 6)); |
| 92 | 0 | } |
| 93 | | |
| 94 | 6 | $output .= theme('table', $header, $rows, array('id' => 'admin-dblog')); |
| 95 | 6 | $output .= theme('pager', NULL, 50, 0); |
| 96 | | |
| 97 | 6 | return $output; |
| 98 | 0 | } |
| 99 | | |
| 100 | | /** |
| 101 | | * Menu callback; generic function to display a page of the most frequent |
| 102 | | * dblog events of a specified type. |
| 103 | | */ |
| 104 | 28 | function dblog_top($type) { |
| 105 | | |
| 106 | | $header = array( |
| 107 | 10 | array('data' => t('Count'), 'field' => 'count', 'sort' => 'desc'), |
| 108 | 10 | array('data' => t('Message'), 'field' => 'message') |
| 109 | 10 | ); |
| 110 | | |
| 111 | 10 | $result = pager_query("SELECT COUNT(wid) AS count, message, variables
FROM {watchdog} WHERE type = '%s' GROUP BY message, variables " .
tablesort_sql($header), 30, 0, "SELECT COUNT(DISTINCT(message)) FROM
{watchdog} WHERE type = '%s'", $type); |
| 112 | | |
| 113 | 10 | $rows = array(); |
| 114 | 10 | while ($dblog = db_fetch_object($result)) { |
| 115 | 10 | $rows[] = array($dblog->count,
truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE)); |
| 116 | 10 | } |
| 117 | | |
| 118 | 10 | if (empty($rows)) { |
| 119 | 0 | $rows[] = array(array('data' => t('No log messages available.'),
'colspan' => 2)); |
| 120 | 0 | } |
| 121 | | |
| 122 | 10 | $output = theme('table', $header, $rows); |
| 123 | 10 | $output .= theme('pager', NULL, 30, 0); |
| 124 | | |
| 125 | 10 | return $output; |
| 126 | 0 | } |
| 127 | | |
| 128 | | /** |
| 129 | | * Menu callback; displays details about a log message. |
| 130 | | */ |
| 131 | 28 | function dblog_event($id) { |
| 132 | 1 | $severity = watchdog_severity_levels(); |
| 133 | 1 | $output = ''; |
| 134 | 1 | $result = db_query('SELECT w.*, u.name, u.uid FROM {watchdog} w INNER
JOIN {users} u ON w.uid = u.uid WHERE w.wid = %d', $id); |
| 135 | 1 | if ($dblog = db_fetch_object($result)) { |
| 136 | | $rows = array( |
| 137 | | array( |
| 138 | 0 | array('data' => t('Type'), 'header' => TRUE), |
| 139 | 0 | t($dblog->type), |
| 140 | 0 | ), |
| 141 | | array( |
| 142 | 0 | array('data' => t('Date'), 'header' => TRUE), |
| 143 | 0 | format_date($dblog->timestamp, 'large'), |
| 144 | 0 | ), |
| 145 | | array( |
| 146 | 0 | array('data' => t('User'), 'header' => TRUE), |
| 147 | 0 | theme('username', $dblog), |
| 148 | 0 | ), |
| 149 | | array( |
| 150 | 0 | array('data' => t('Location'), 'header' => TRUE), |
| 151 | 0 | l($dblog->location, $dblog->location), |
| 152 | 0 | ), |
| 153 | | array( |
| 154 | 0 | array('data' => t('Referrer'), 'header' => TRUE), |
| 155 | 0 | l($dblog->referer, $dblog->referer), |
| 156 | 0 | ), |
| 157 | | array( |
| 158 | 0 | array('data' => t('Message'), 'header' => TRUE), |
| 159 | 0 | _dblog_format_message($dblog), |
| 160 | 0 | ), |
| 161 | | array( |
| 162 | 0 | array('data' => t('Severity'), 'header' => TRUE), |
| 163 | 0 | $severity[$dblog->severity], |
| 164 | 0 | ), |
| 165 | | array( |
| 166 | 0 | array('data' => t('Hostname'), 'header' => TRUE), |
| 167 | 0 | check_plain($dblog->hostname), |
| 168 | 0 | ), |
| 169 | | array( |
| 170 | 0 | array('data' => t('Operations'), 'header' => TRUE), |
| 171 | 0 | $dblog->link, |
| 172 | 0 | ), |
| 173 | 0 | ); |
| 174 | 0 | $attributes = array('class' => 'dblog-event'); |
| 175 | 0 | $output = theme('table', array(), $rows, $attributes); |
| 176 | 0 | } |
| 177 | 1 | return $output; |
| 178 | 0 | } |
| 179 | | |
| 180 | | /** |
| 181 | | * Build query for dblog administration filters based on session. |
| 182 | | */ |
| 183 | 28 | function dblog_build_filter_query() { |
| 184 | 6 | if (empty($_SESSION['dblog_overview_filter'])) { |
| 185 | 6 | return; |
| 186 | 0 | } |
| 187 | | |
| 188 | 0 | $filters = dblog_filters(); |
| 189 | | |
| 190 | | // Build query |
| 191 | 0 | $where = $args = array(); |
| 192 | 0 | foreach ($_SESSION['dblog_overview_filter'] as $key => $filter) { |
| 193 | 0 | $filter_where = array(); |
| 194 | 0 | foreach ($filter as $value) { |
| 195 | 0 | $filter_where[] = $filters[$key]['where']; |
| 196 | 0 | $args[] = $value; |
| 197 | 0 | } |
| 198 | 0 | if (!empty($filter_where)) { |
| 199 | 0 | $where[] = '(' . implode(' OR ', $filter_where) . ')'; |
| 200 | 0 | } |
| 201 | 0 | } |
| 202 | 0 | $where = !empty($where) ? implode(' AND ', $where) : ''; |
| 203 | | |
| 204 | | return array( |
| 205 | 0 | 'where' => $where, |
| 206 | 0 | 'args' => $args, |
| 207 | 0 | ); |
| 208 | 0 | } |
| 209 | | |
| 210 | | |
| 211 | | /** |
| 212 | | * List dblog administration filters that can be applied. |
| 213 | | */ |
| 214 | 28 | function dblog_filters() { |
| 215 | 6 | $filters = array(); |
| 216 | | |
| 217 | 6 | foreach (_dblog_get_message_types() as $type) { |
| 218 | 6 | $types[$type] = $type; |
| 219 | 6 | } |
| 220 | | |
| 221 | 6 | if (!empty($types)) { |
| 222 | 6 | $filters['type'] = array( |
| 223 | 6 | 'title' => t('Type'), |
| 224 | 6 | 'where' => "w.type = '%s'", |
| 225 | 6 | 'options' => $types, |
| 226 | | ); |
| 227 | 6 | } |
| 228 | | |
| 229 | 6 | $filters['severity'] = array( |
| 230 | 6 | 'title' => t('Severity'), |
| 231 | 6 | 'where' => 'w.severity = %d', |
| 232 | 6 | 'options' => watchdog_severity_levels(), |
| 233 | | ); |
| 234 | | |
| 235 | 6 | return $filters; |
| 236 | 0 | } |
| 237 | | |
| 238 | | /** |
| 239 | | * Formats a log message for display. |
| 240 | | * |
| 241 | | * @param $dblog |
| 242 | | * An object with at least the message and variables properties |
| 243 | | */ |
| 244 | 28 | function _dblog_format_message($dblog) { |
| 245 | | // Legacy messages and user specified text |
| 246 | 16 | if ($dblog->variables === 'N;') { |
| 247 | 15 | return $dblog->message; |
| 248 | 0 | } |
| 249 | | // Message to translate with injected variables |
| 250 | | else { |
| 251 | 6 | return t($dblog->message, unserialize($dblog->variables)); |
| 252 | | } |
| 253 | 0 | } |
| 254 | | |
| 255 | | |
| 256 | | /** |
| 257 | | * Return form for dblog administration filters. |
| 258 | | * |
| 259 | | * @ingroup forms |
| 260 | | * @see dblog_filter_form_submit() |
| 261 | | * @see dblog_filter_form_validate() |
| 262 | | */ |
| 263 | 28 | function dblog_filter_form() { |
| 264 | 6 | $session = &$_SESSION['dblog_overview_filter']; |
| 265 | 6 | $session = is_array($session) ? $session : array(); |
| 266 | 6 | $filters = dblog_filters(); |
| 267 | | |
| 268 | 6 | $form['filters'] = array( |
| 269 | 6 | '#type' => 'fieldset', |
| 270 | 6 | '#title' => t('Filter log messages'), |
| 271 | 6 | '#theme' => 'dblog_filters', |
| 272 | 6 | '#collapsible' => TRUE, |
| 273 | 6 | '#collapsed' => empty($session), |
| 274 | | ); |
| 275 | 6 | foreach ($filters as $key => $filter) { |
| 276 | 6 | $form['filters']['status'][$key] = array( |
| 277 | 6 | '#title' => $filter['title'], |
| 278 | 6 | '#type' => 'select', |
| 279 | 6 | '#multiple' => TRUE, |
| 280 | 6 | '#size' => 8, |
| 281 | 6 | '#options' => $filter['options'], |
| 282 | | ); |
| 283 | 6 | if (!empty($session[$key])) { |
| 284 | 0 | $form['filters']['status'][$key]['#default_value'] = $session[$key]; |
| 285 | 0 | } |
| 286 | 6 | } |
| 287 | | |
| 288 | 6 | $form['filters']['buttons']['submit'] = array( |
| 289 | 6 | '#type' => 'submit', |
| 290 | 6 | '#value' => t('Filter'), |
| 291 | | ); |
| 292 | 6 | if (!empty($session)) { |
| 293 | 0 | $form['filters']['buttons']['reset'] = array( |
| 294 | 0 | '#type' => 'submit', |
| 295 | 0 | '#value' => t('Reset') |
| 296 | 0 | ); |
| 297 | 0 | } |
| 298 | | |
| 299 | 6 | return $form; |
| 300 | 0 | } |
| 301 | | |
| 302 | | /** |
| 303 | | * Validate result from dblog administration filter form. |
| 304 | | */ |
| 305 | 28 | function dblog_filter_form_validate($form, &$form_state) { |
| 306 | 0 | if ($form_state['values']['op'] == t('Filter') &&
empty($form_state['values']['type']) &&
empty($form_state['values']['severity'])) { |
| 307 | 0 | form_set_error('type', t('You must select something to filter by.')); |
| 308 | 0 | } |
| 309 | 0 | } |
| 310 | | |
| 311 | | /** |
| 312 | | * Process result from dblog administration filter form. |
| 313 | | */ |
| 314 | 28 | function dblog_filter_form_submit($form, &$form_state) { |
| 315 | 0 | $op = $form_state['values']['op']; |
| 316 | 0 | $filters = dblog_filters(); |
| 317 | | switch ($op) { |
| 318 | 0 | case t('Filter'): |
| 319 | 0 | foreach ($filters as $name => $filter) { |
| 320 | 0 | if (isset($form_state['values'][$name])) { |
| 321 | 0 | $_SESSION['dblog_overview_filter'][$name] =
$form_state['values'][$name]; |
| 322 | 0 | } |
| 323 | 0 | } |
| 324 | 0 | break; |
| 325 | 0 | case t('Reset'): |
| 326 | 0 | $_SESSION['dblog_overview_filter'] = array(); |
| 327 | 0 | break; |
| 328 | 0 | } |
| 329 | 0 | return 'admin/reports/dblog'; |
| 330 | 0 | } |
| 331 | 28 | |