<?php

/**
 * @file
 * Reroute Email module
 */

define('REROUTE_EMAIL_ADDRESS', 'reroute_email_address');
define('REROUTE_EMAIL_ENABLE_MESSAGE', 'reroute_email_enable_message');
define('REROUTE_EMAIL_ENABLE',  'reroute_email_enable');

// Regular expression used to split email addresses provided in form.
// This allows the use of any number of spaces, commas, or semicolons
// between email addresses.
define('EMAIL_SPLIT_RE', '/[\s,;]+/');


/**
 * Implements of hook_permission().
 */
function reroute_email_permission() {
  return array(
    'administer reroute email' =>  array(
      'title' => t('Administer Reroute Email'),
      'description' => t('Administer the Reroute Email module.'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function reroute_email_menu() {
  $items = array();

  $items['admin/config/development/reroute_email'] = array(
    'title'              => 'Reroute Email',
    'description'        => 'Reroute emails to a test address.',
    'page callback'      => 'drupal_get_form',
    'page arguments'     => array('reroute_email_settings'),
    'access arguments'   => array('administer reroute email'),
  );

  return $items;
}

/**
 * Settings form.
 */
function reroute_email_settings() {
  $form[REROUTE_EMAIL_ENABLE] = array(
    '#type'          => 'checkbox',
    '#title'         => t('Enable rerouting'),
    '#default_value' => variable_get(REROUTE_EMAIL_ENABLE, 0),
    '#description'   => t('Check this box if you want to enable email rerouting. Uncheck to disable rerouting.'),
  );
  $form[REROUTE_EMAIL_ADDRESS] = array(
    '#type'          => 'textfield',
    '#title'         => t('Email addresses'),
    '#default_value' => variable_get(REROUTE_EMAIL_ADDRESS, ini_get('sendmail_from')),
    '#description'   => t('Provide a space, comma, or semicolon-delimited list of email addresses to pass through. Every destination email address which is not on this list will be rerouted to the first address on the list.'),
    '#states' => array(
      'visible' => array(':input[name=reroute_email_enable]' => array('checked' => TRUE)),
    ),
  );
  $form[REROUTE_EMAIL_ENABLE_MESSAGE] = array(
    '#type' => 'checkbox',
    '#title' => t('Show rerouting description in mail body'),
    '#default_value' => variable_get(REROUTE_EMAIL_ENABLE_MESSAGE, 1),
    '#description' => t('Check this box if you want a message to be inserted into the email body when the mail is being rerouted. Otherwise, SMTP headers will be used to describe the rerouting. If sending rich-text email, leave this unchecked so that the body of the email will not be disturbed.'),
    '#states' => array(
      'visible' => array(':input[name=reroute_email_enable]' => array('checked' => TRUE)),
    ),
  );

  return system_settings_form($form);
}

/**
 * Validation callback for reroute_email_settings() form.
 */
function reroute_email_settings_validate($form, $form_state) {
  if ($form_state['values']['reroute_email_enable'] == TRUE) {
    // Allow splitting emails by space, comma, semicolon.
    $addresslist = preg_split(EMAIL_SPLIT_RE, $form_state['values']['reroute_email_address'], -1, PREG_SPLIT_NO_EMPTY);
    foreach ($addresslist as $address) {
      if(!valid_email_address($address)) {
        form_set_error('reroute_email_address', t('@address is not a valid email address', array('@address' => $address)));
      }
    }
  }
}

/**
 * Implements hook_mail_alter() to change the destination of outgoing emails.
 * @param array $message
 *   An array containing message with keys like 'to', 'from', 'body'.
 */
function reroute_email_mail_alter(&$message) {
  if (variable_get(REROUTE_EMAIL_ENABLE, 0)) {
    global $base_url;

    if (!variable_get(REROUTE_EMAIL_ADDRESS, '')) {
      // If email address not in settings, then do nothing.
      return;
    }

    if (empty($message)) {
      return;
    }

    if (!is_array($message)) {
      return;
    }

    $mailkey = isset($message['id']) ? $message['id'] : t('<mail id> is missing');
    $to = isset($message['to']) ? $message['to'] : t('<to> is missing');

    $message['headers']['X-Rerouted-Mail-Key'] = $mailkey;
    $message['headers']['X-Rerouted-Website'] = $base_url;

    // Suppress Bcc and Cc fields otherwise email will still go out to those addresses
    if (isset($message['headers']) && is_array($message['headers'])) {
      if (isset($message['headers']['Bcc'])) {
        $message['headers']['X-Rerouted-Original-Bcc'] = $message['headers']['Bcc'];
        unset($message['headers']['Bcc']);
      }
      if (isset($message['headers']['Cc'])) {
        $message['headers']['X-Rerouted-Original-Cc'] = $message['headers']['Cc'];
        unset($message['headers']['Cc']);
      }
    }

    // Split the address string on whitespace, ignoring any empty results
    $addresslist = preg_split(EMAIL_SPLIT_RE, variable_get(REROUTE_EMAIL_ADDRESS, ini_get('sendmail_from')), -1, PREG_SPLIT_NO_EMPTY);

    if (!in_array($to, $addresslist)) {
      // Not on the list, so reroute to the first address in the list
      $message['headers']['X-Rerouted-Original-To'] = $to;
      $message['to'] = $addresslist[0];

      if (variable_get(REROUTE_EMAIL_ENABLE_MESSAGE, 1)) {
        // Format a message to show at the top
        $msg = t("This email was rerouted.") . "\n";
        $msg .= t("Web site: @site", array('@site' => $base_url)) . "\n";
        $msg .= t("Mail key: @key", array('@key' => $mailkey)) . "\n";
        $msg .= t("Originally to: @to", array('@to' => $to)) . "\n";
        $msg .= "-----------------------" . "\n";

        // Prepend explanation message to the body of the email. This must be
        // handled differently depending on whether the body came in as a
        // string or an array. If it came in as a string (despite the fact it
        // should be an array) we'll respect that and leave it as a string.
        if (is_string($message['body'])) {
          $message['body'] = $msg . $message['body'];
        }
        else {
          array_unshift($message['body'], $msg);
        }
      }
    }
  }
}

