You are here

emaillog.module in Logging and alerts 8

Drupal Module: Email Logging and Alerts.

Sends logs and alerts to email addresses.

File

emaillog/emaillog.module
View source
<?php

/**
 * @file
 * Drupal Module: Email Logging and Alerts.
 *
 * Sends logs and alerts to email addresses.
 */
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\user\Entity\User;
use Drupal\Component\Render\FormattableMarkup;

/**
 * Implements hook_help().
 */
function emaillog_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'emaillog.configuration':
      return '<p>' . t('Sends logs and alerts to email addresses, with different severity going to different emails.') . '</p>';
  }
}

/**
 * Implements hook_theme().
 */
function emaillog_theme() {
  return [
    'emaillog' => [
      'render element' => 'elements',
      'template' => 'emaillog',
      'variables' => [
        'log' => NULL,
      ],
    ],
    'emaillog_admin_settings' => [
      'render element' => 'form',
      'function' => 'theme_emaillog_admin_settings',
    ],
  ];
}

/**
 * Themes admin settings form.
 */
function theme_emaillog_admin_settings($variables) {
  $form = $variables['form'];
  $severity_levels = RfcLogLevel::getLevels();
  foreach (Element::children($form['debug_info']['variable']) as $key) {
    $row = [];

    // Permission row.
    $row[] = [
      'data' => render($form['debug_info']['variable'][$key]),
      'class' => [
        'variable',
      ],
    ];
    foreach (array_keys($severity_levels) as $level_id) {
      $element = $form['debug_info'][$level_id];
      $form['debug_info'][$level_id][$key]['#title'] = $element['#title'] . ' : ' . $form['debug_info']['variable'][$key]['#markup'];
      $form['debug_info'][$level_id][$key]['#title_display'] = 'invisible';
      $row[] = [
        'data' => render($form['debug_info'][$level_id][$key]),
        'class' => [
          'checkbox',
        ],
        'title' => $element['#title'] . ' : ' . $form['debug_info']['variable'][$key]['#markup'],
      ];
    }
    $rows[] = $row;
  }
  $header = [
    '',
  ];
  foreach (array_keys($severity_levels) as $level_id) {
    $element = $form['debug_info'][$level_id];
    $header[] = [
      'data' => $element['#title'],
      'class' => [
        'checkbox',
      ],
    ];

    // Mark the checkboxes parent as rendered.
    $form['debug_info'][$level_id]['#printed'] = TRUE;
  }
  $table = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#attributes' => [
      'id' => 'permissions',
    ],
  ];

  // Put the table with all checkboxes inside a fieldset.
  $form['debug_info']['variables'] = [
    '#type' => 'markup',
    '#markup' => render($table),
  ];

  // Render and return all remaining elements.
  return \Drupal::service('renderer')
    ->render($form);
}

/**
 * Implements hook_mail().
 */
function emaillog_mail($key, &$message, $params) {
  if ($key == 'alert') {
    $severity_levels = RfcLogLevel::getLevels();
    $message_body = new FormattableMarkup($params['message'], $params['variables']);
    $vars = [
      '@site_name' => \Drupal::config('system.site')
        ->get('name'),
      '@severity_desc' => Unicode::ucfirst($severity_levels[$params['severity']]
        ->render()),
      '@dblog_message' => Unicode::truncate(strip_tags($message_body), 60, TRUE, TRUE),
    ];

    // Legacy email subject.
    if (\Drupal::config('emaillog.settings')
      ->get('emaillog_legacy_subject')) {
      $message['subject'] = t('[@site_name] @severity_desc: Alert from your web site', $vars);
    }
    else {
      $message['subject'] = t('[@site_name] @severity_desc: @dblog_message', $vars);
    }
    $emaillog_theme_element = [
      '#theme' => 'emaillog',
      '#log' => $params,
    ];
    $message['body'][] = render($emaillog_theme_element);
  }
}

/**
 * Process variables for emaillog.tpl.php.
 */
function template_preprocess_emaillog(&$variables) {
  global $base_url;
  $user = User::load($variables['log']['variables']['uid']);
  $variables['base_url'] = $base_url;
  $severity_list = RfcLogLevel::getLevels();
  $message_body = new FormattableMarkup($variables['log']['message'], $variables['log']['variables']);
  $variables['log']['severity_desc'] = Unicode::ucfirst($severity_list[$variables['log']['severity']]
    ->render());
  $variables['log']['datetime'] = date('Y-m-d H:i:s', $variables['log']['variables']['timestamp']);
  $variables['log']['uid'] = $user
    ->id();
  $variables['log']['name'] = $user
    ->getDisplayName();
  $variables['log']['link'] = strip_tags($variables['log']['variables']['link']);
  $variables['log']['message'] = strip_tags($message_body);
  $severity = _emaillog_system_string($severity_list[$variables['log']['severity']]
    ->render());
  $variables['theme_hook_suggestions'][] = 'emaillog__' . $severity;
  $variables['theme_hook_suggestions'][] = 'emaillog__' . _emaillog_system_string($variables['log']['variables']['channel']);
  $variables['theme_hook_suggestions'][] = 'emaillog__' . $severity . '__' . _emaillog_system_string($variables['log']['variables']['channel']);
}

/**
 * Formats string as safe system string.
 */
function _emaillog_system_string($string, $replacement = '_') {
  return preg_replace('/[^a-z0-9]+/', $replacement, mb_strtolower($string));
}

/**
 * Returns array of available additional debug information for email alerts.
 */
function _emaillog_get_debug_info_callbacks() {
  return [
    'server' => '$_SERVER',
    'env' => '$_ENV',
    'request' => '$_REQUEST',
    'cookie' => '$_COOKIE',
    'get' => '$_GET',
    'post' => '$_POST',
    'session' => '$_SESSION',
    'backtrace' => 'debug_backtrace()',
  ];
}

/**
 * Replaces backtrace argument values with their types.
 */
function emaillog_emaillog_debug_info_alter(&$debug_info) {
  if (isset($debug_info['debug_backtrace()']) && is_array($debug_info['debug_backtrace()']) && \Drupal::config('emaillog.settings')
    ->get('emaillog_backtrace_replace_args')) {
    foreach ($debug_info['debug_backtrace()'] as $trace_key => $trace) {
      $args = [];
      if (isset($trace['args']) && is_array($trace['args'])) {
        foreach ($trace['args'] as $key => $value) {
          $args[$key] = sprintf('%s(%s)', gettype($value), _emaillog_get_variable_size($value));
        }
        $debug_info['debug_backtrace()'][$trace_key]['args'] = implode(', ', $args);
      }
    }
  }
}

/**
 * Returns size of a variable.
 */
function _emaillog_get_variable_size($variable) {
  switch (gettype($variable)) {
    case 'array':
    case 'object':
      return count((array) $variable);
    case 'integer':
    case 'int':
    case 'boolean':
    case 'bool':
    case 'float':
    case 'double':
    case 'real':
    case 'string':
      return strlen((string) $variable);
    default:
      return '?';
  }
}

Functions

Namesort descending Description
emaillog_emaillog_debug_info_alter Replaces backtrace argument values with their types.
emaillog_help Implements hook_help().
emaillog_mail Implements hook_mail().
emaillog_theme Implements hook_theme().
template_preprocess_emaillog Process variables for emaillog.tpl.php.
theme_emaillog_admin_settings Themes admin settings form.
_emaillog_get_debug_info_callbacks Returns array of available additional debug information for email alerts.
_emaillog_get_variable_size Returns size of a variable.
_emaillog_system_string Formats string as safe system string.