You are here

update_detailed_email.module in Update Status Detailed Email 6

Same filename and directory in other branches
  1. 7 update_detailed_email.module

Adds detail to the email message Drupal core's Update Status sends.

The information sent in the email is based on the information seen at /admin/reports/updates.

File

update_detailed_email.module
View source
<?php

/**
 * @file
 * Adds detail to the email message Drupal core's Update Status sends.
 *
 * The information sent in the email is based on the information seen at /admin/reports/updates.
 */

/**
 * Implementation of hook_help().
 */
function update_detailed_email_help($page, $arg) {
  switch ($page) {
    case 'admin/help#update_detailed_email':
      return '<p>' . t('The Update Detailed Email module modifies the basic email that the core Update Status module sends. It includes detailed information about what modules need updating, and uses a customizable subject line. The information sent in the email is based on the information seen on the <a href="@update-report">update report</a> page. Go to <a href="@update-settings">Update status module settings page</a> to set a customized subject line.', array(
        '@update-report' => url('admin/reports/updates'),
        '@update-settings' => url('admin/reports/updates/settings'),
      )) . '</p>';
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 *
 * Add subject line text field to the update settings form.
 */
function update_detailed_email_form_update_settings_alter(&$form, &$form_state) {
  $form['update_detailed_email_subject'] = array(
    '#type' => 'textfield',
    '#title' => 'Subject',
    '#default_value' => variable_get('update_detailed_email_subject', t('Updates Available')),
    '#size' => 78,
    '#maxlength' => 78,
    '#required' => TRUE,
    '#description' => 'The subject line of the email message.',
    '#weight' => 0,
  );
  if (module_exists('token')) {
    $form['token_help'] = array(
      '#title' => t('Replacement patterns'),
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#weight' => 0,
      'help' => array(
        '#value' => theme('token_help', 'global'),
      ),
    );
  }
  $form['#submit'][] = 'update_detailed_email_subject_submit';
}

/**
 * Submit handle for the subject field.
 */
function update_detailed_email_subject_submit($form, $form_state) {
  variable_set('update_detailed_email_subject', $form['update_detailed_email_subject']['#value']);
}

/**
 * Implementation of hook_mail_alter().
 *
 * The update status email needs to be intercepted so it can be changed to HTML.
 */
function update_detailed_email_mail_alter(&$message) {
  if ($message['id'] == 'update_status_notify') {
    if (module_exists('update')) {
      module_load_include('inc', 'update', 'update.report');
      if (function_exists('update_status')) {
        $message['headers']['Content-Type'] = 'text/html';
        if (module_exists('token')) {
          $message['subject'] = token_replace(variable_get('update_detailed_email_subject', t('Updates Available')));
        }
        else {
          $message['subject'] = variable_get('update_detailed_email_subject', t('Updates Available'));
        }
        $message['body'] = array();
        $message['body'][] = update_status();
      }
    }
  }
}

/**
 * Implementation of hook_theme_registry_alter().
 *
 * The registry needs to be changed to override the update status theme function.
 * The "if" will check to see if the original theme function is in place. If not, no override.
 * This allows a theme (template.php) to still override the original function.
 */
function update_detailed_email_theme_registry_alter(&$theme_registry) {
  if (!empty($theme_registry['update_report']) && $theme_registry['update_report']['function'] == 'theme_update_report') {
    $theme_registry['update_report']['function'] = 'theme_update_detailed_email';
  }
}

/**
 * Implementation of hook_theme().
 *
 * theme_update_detailed_email_message() is being registered so a theme can override it
 * and change the HTML being sent.
 */
function update_detailed_email_theme() {
  return array(
    'update_detailed_email_message' => array(
      'arguments' => array(
        'data' => NULL,
      ),
    ),
    'update_detailed_email_message_version' => array(
      'arguments' => array(
        'version' => NULL,
        'title' => NULL,
      ),
    ),
  );
}

/**
 * Theme function to override the original update theme function.
 *
 * If on the updates page, use the original function.
 *
 * @param $data
 *   An array of update information for installed modules.
 *
 * @return
 *   Return either the orignal theme rendering of the data or the new one.
 */
function theme_update_detailed_email($data) {
  if (strpos($_GET['q'], 'admin/reports/updates') === FALSE) {
    return theme('update_detailed_email_message', $data);
  }
  else {
    return theme_update_report($data);
  }
}

/**
 * Theme the detailed update email.
 *
 * Much of the code is taken from the original theme_update_report(). The changes are primarily focused on
 * making the outputted HTML more email-friendly.
 *
 * @param $data
 *   An array of update information for installed modules.
 *
 * @return
 *   Themed output.
 */
function theme_update_detailed_email_message($data) {
  $output = '<html><head><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">';
  $output .= "<title>Update Status</title></head><body>\n";
  if (!is_array($data)) {
    $output .= '<p>' . $data . '</p>';
    return $output;
  }
  $rows = array();
  $notification_level = variable_get('update_notification_threshold', 'all');
  foreach ($data as $project) {

    // Don't include modules that are up to date.
    // If set to only notify of security updates, don't include non-security updates in the email.
    if ($notification_level == 'all' && $project['status'] != UPDATE_CURRENT || $notification_level == 'security' && $project['status'] == UPDATE_NOT_SECURE) {
      $row = '<p>';
      switch ($project['status']) {
        case UPDATE_NOT_SECURE:
          $row .= t('Security update required!');
          break;
        case UPDATE_REVOKED:
          $row .= t('Revoked!');
          break;
        case UPDATE_NOT_SUPPORTED:
          $row .= t('Not supported!');
          break;
        case UPDATE_NOT_CURRENT:
          $row .= t('Update available');
          break;
        default:
          $row .= check_plain($project['reason']);
          break;
      }
      $row .= "<br />\n";

      // Project title
      if (isset($project['title'])) {
        if (isset($project['link'])) {
          $row .= l($project['title'], $project['link']);
        }
        else {
          $row .= check_plain($project['title']);
        }
      }
      else {
        $row .= check_plain($project['name']);
      }

      // Project version
      $row .= ' ' . check_plain($project['existing_version']);

      // Project date
      if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) {
        $row .= ' (' . format_date($project['datestamp'], 'custom', 'Y-M-d') . ')';
      }

      // Versions
      if (isset($project['recommended'])) {

        // Recommended
        if ($project['existing_version'] !== $project['recommended']) {
          $row .= theme('update_detailed_email_message_version', $project['releases'][$project['recommended']], 'Recommended version:');

          // Now, print any security updates.
          if (!empty($project['security updates'])) {
            foreach ($project['security updates'] as $security_update) {
              $row .= theme('update_detailed_email_message_version', $security_update, 'Security update:');
            }
          }
        }

        // Latest
        if ($project['recommended'] !== $project['latest_version']) {
          $row .= theme('update_detailed_email_message_version', $project['releases'][$project['latest_version']], 'Latest version:');
        }

        // Development
        if ($project['install_type'] == 'dev' && isset($project['dev_version']) && $project['recommended'] !== $project['dev_version']) {
          $row .= theme('update_detailed_email_message_version', $project['releases'][$project['dev_version']], 'Development version:');
        }
      }

      // Also available
      if (isset($project['also'])) {
        foreach ($project['also'] as $also) {
          $row .= theme('update_detailed_email_message_version', $project['releases'][$also], 'Also available:');
        }
      }
      $row .= "<br />\n";

      // Extra
      if (!empty($project['extra'])) {
        foreach ($project['extra'] as $key => $value) {
          $row .= check_plain($value['label']) . ': ';
          $row .= theme('placeholder', $value['data']);
          $row .= '<br />';
        }
      }

      // Includes
      sort($project['includes']);
      $row .= t('Includes: %includes', array(
        '%includes' => implode(', ', $project['includes']),
      ));

      // Base themes
      if (!empty($project['base_themes'])) {
        sort($project['base_themes']);

        // We use !dependencies and manually call theme('placeholder') here to
        // avoid breakding the D6 string freeze. This identical string is
        // already in modules/system/system.admin.inc.
        $row .= "<br />\n";
        $row .= t('Depends on: !dependencies', array(
          '!dependencies' => theme('placeholder', implode(', ', $project['base_themes'])),
        ));
      }

      // Sub-themes
      if (!empty($project['sub_themes'])) {
        sort($project['sub_themes']);

        // We use !required and manually call theme('placeholder') here to avoid
        // breakding the D6 string freeze. This identical string is already in
        // modules/system/system.admin.inc.
        $row .= "<br />\n";
        $row .= t('Required by: !required', array(
          '!required' => theme('placeholder', implode(', ', $project['sub_themes'])),
        ));
      }
      $row .= "</p>\n";
      if (!isset($rows[$project['project_type']])) {
        $rows[$project['project_type']] = array();
      }
      $row_key = isset($project['title']) ? drupal_strtolower($project['title']) : drupal_strtolower($project['name']);
      $rows[$project['project_type']][$row_key] = array(
        'data' => array(
          $row,
        ),
      );
    }
  }
  $project_types = array(
    'core' => t('Drupal core'),
    'module' => t('Modules'),
    'theme' => t('Themes'),
    'disabled-module' => t('Disabled modules'),
    'disabled-theme' => t('Disabled themes'),
  );
  foreach ($project_types as $type_name => $type_label) {
    if (!empty($rows[$type_name])) {
      ksort($rows[$type_name]);
      $output .= '<p><strong>' . $type_label . "</strong></p>\n";
      foreach ($rows[$type_name] as $list) {
        $output .= $list['data'][0];
      }
    }
  }
  $output .= '</body></html>';
  return $output;
}

/**
 * Theme a project version.
 *
 * @param $version
 *   An array of version information to be themed.
 * @param $title
 *   A string to use as the title.
 *
 * @return $output
 *   Themed output.
 */
function theme_update_detailed_email_message_version($version, $title) {
  $output = "<br />\n";
  $output .= t($title);
  $output .= ' ' . l($version['version'], $version['release_link']);
  $output .= ' (' . format_date($version['date'], 'custom', 'Y-M-d') . ') ';
  $output .= ' ' . l(t('Download'), $version['download_link']);
  $output .= ' | ' . l(t('Release notes'), $version['release_link']);
  return $output;
}

Functions

Namesort descending Description
theme_update_detailed_email Theme function to override the original update theme function.
theme_update_detailed_email_message Theme the detailed update email.
theme_update_detailed_email_message_version Theme a project version.
update_detailed_email_form_update_settings_alter Implementation of hook_form_FORM_ID_alter().
update_detailed_email_help Implementation of hook_help().
update_detailed_email_mail_alter Implementation of hook_mail_alter().
update_detailed_email_subject_submit Submit handle for the subject field.
update_detailed_email_theme Implementation of hook_theme().
update_detailed_email_theme_registry_alter Implementation of hook_theme_registry_alter().