Aleksander Machniak
2012-12-14 a0e3dcf170502bd74f74c5ac5952cd7ad6de3863
Use matching identity in MDN response (#1488864)
3 files modified
211 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/steps/mail/compose.inc 107 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 103 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Use matching identity in MDN response (#1488864)
- Fix unwanted horizontal scrollbar in message preview header (#1488866)
- Fix handling of signatures on draft edit (#1488798)
- Fix so compacting of non-empty folder is possible also when messages list is empty (#1488858)
program/steps/mail/compose.inc
@@ -20,10 +20,10 @@
*/
// define constants for message compose mode
define('RCUBE_COMPOSE_REPLY', 0x0106);
define('RCUBE_COMPOSE_FORWARD', 0x0107);
define('RCUBE_COMPOSE_DRAFT', 0x0108);
define('RCUBE_COMPOSE_EDIT', 0x0109);
define('RCUBE_COMPOSE_REPLY', 'reply');
define('RCUBE_COMPOSE_FORWARD', 'forward');
define('RCUBE_COMPOSE_DRAFT', 'draft');
define('RCUBE_COMPOSE_EDIT', 'edit');
$MESSAGE_FORM = null;
$COMPOSE_ID   = get_input_value('_id', RCUBE_INPUT_GET);
@@ -156,17 +156,16 @@
}
else if ($msg_uid = $COMPOSE['param']['reply_uid']) {
  $compose_mode = RCUBE_COMPOSE_REPLY;
  $OUTPUT->set_env('compose_mode', 'reply');
}
else if ($msg_uid = $COMPOSE['param']['forward_uid']) {
  $compose_mode = RCUBE_COMPOSE_FORWARD;
  $OUTPUT->set_env('compose_mode', 'forward');
  $COMPOSE['forward_uid']   = $msg_uid;
  $COMPOSE['as_attachment'] = !empty($COMPOSE['param']['attachment']);
}
else if ($msg_uid = $COMPOSE['param']['uid']) {
  $compose_mode = RCUBE_COMPOSE_EDIT;
}
$OUTPUT->set_env('compose_mode', $compose_mode);
$config_show_sig = $RCMAIL->config->get('show_sig', 1);
if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) {
@@ -373,102 +372,6 @@
/****** compose mode functions ********/
function rcmail_identity_select($MESSAGE, $identities, $compose_mode)
{
  $a_recipients = array();
  $a_names      = array();
  // extract all recipients of the reply-message
  if (is_object($MESSAGE->headers) && in_array($compose_mode, array(RCUBE_COMPOSE_REPLY, RCUBE_COMPOSE_FORWARD))) {
    $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset);
    foreach ($a_to as $addr) {
      if (!empty($addr['mailto'])) {
        $a_recipients[] = format_email($addr['mailto']);
        $a_names[]      = $addr['name'];
      }
    }
    if (!empty($MESSAGE->headers->cc)) {
      $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset);
      foreach ($a_cc as $addr) {
        if (!empty($addr['mailto'])) {
          $a_recipients[] = format_email($addr['mailto']);
          $a_names[]      = $addr['name'];
        }
      }
    }
  }
  $from_idx         = null;
  $found_idx        = null;
  $default_identity = 0; // default identity is always first on the list
  // Select identity
  foreach ($identities as $idx => $ident) {
    // use From header
    if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) {
      if ($MESSAGE->headers->from == $ident['ident']) {
        $from_idx = $idx;
        break;
      }
    }
    // reply to yourself
    else if ($compose_mode == RCUBE_COMPOSE_REPLY && $MESSAGE->headers->from == $ident['ident']) {
      $from_idx = $idx;
      break;
    }
    // use replied message recipients
    else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) {
      if ($found_idx === null) {
        $found_idx = $idx;
      }
      // match identity name
      if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
        $from_idx = $idx;
        break;
      }
    }
  }
  // If matching by name+address doesn't found any amtches, get first found address (identity)
  if ($from_idx === null) {
    $from_idx = $found_idx;
  }
  // Try Return-Path
  if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
    foreach ($identities as $idx => $ident) {
      if (strpos($return_path, str_replace('@', '=', $ident['email_ascii']).'@') !== false) {
        $from_idx = $idx;
        break;
      }
    }
  }
  // Fallback using Delivered-To
  if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
    foreach ($identities as $idx => $ident) {
      if (in_array($ident['email_ascii'], (array)$delivered_to)) {
        $from_idx = $idx;
        break;
      }
    }
  }
  // Fallback using Envelope-To
  if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
    foreach ($identities as $idx => $ident) {
      if (in_array($ident['email_ascii'], (array)$envelope_to)) {
        $from_idx = $idx;
        break;
      }
    }
  }
  return $identities[$from_idx !== null ? $from_idx : $default_identity];
}
function rcmail_compose_headers($attrib)
{
program/steps/mail/func.inc
@@ -1720,7 +1720,7 @@
  if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) &&
    ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')))
  {
    $identity = $RCMAIL->user->get_identity();
    $identity  = rcmail_identity_select($message);
    $sender = format_email_recipient($identity['email'], $identity['name']);
    $recipient = array_shift(rcube_mime::decode_address_list(
      $message->headers->mdn_to, 1, true, $message->headers->charset));
@@ -1782,6 +1782,107 @@
  return false;
}
/**
 * Detect recipient identity from specified message
 */
function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'reply')
{
    $a_recipients = array();
    $a_names      = array();
    if ($identities === null) {
        $identities = rcmail::get_instance()->user->list_identities(null, true);
    }
    // extract all recipients of the reply-message
    if (is_object($MESSAGE->headers) && in_array($compose_mode, array('reply', 'forward'))) {
        $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset);
        foreach ($a_to as $addr) {
            if (!empty($addr['mailto'])) {
                $a_recipients[] = format_email($addr['mailto']);
                $a_names[]      = $addr['name'];
            }
        }
        if (!empty($MESSAGE->headers->cc)) {
            $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset);
            foreach ($a_cc as $addr) {
                if (!empty($addr['mailto'])) {
                    $a_recipients[] = format_email($addr['mailto']);
                    $a_names[]      = $addr['name'];
                }
            }
        }
    }
    $from_idx         = null;
    $found_idx        = null;
    $default_identity = 0; // default identity is always first on the list
    // Select identity
    foreach ($identities as $idx => $ident) {
        // use From header
        if (in_array($compose_mode, array('draft', 'edit'))) {
            if ($MESSAGE->headers->from == $ident['ident']) {
                $from_idx = $idx;
                break;
            }
        }
        // reply to yourself
        else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) {
            $from_idx = $idx;
            break;
        }
        // use replied message recipients
        else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) {
            if ($found_idx === null) {
                $found_idx = $idx;
            }
            // match identity name
            if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
                $from_idx = $idx;
                break;
            }
        }
    }
    // If matching by name+address doesn't found any matches, get first found address (identity)
    if ($from_idx === null) {
        $from_idx = $found_idx;
    }
    // Try Return-Path
    if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
        foreach ($identities as $idx => $ident) {
            if (strpos($return_path, str_replace('@', '=', $ident['email_ascii']).'@') !== false) {
                $from_idx = $idx;
                break;
            }
        }
    }
    // Fallback using Delivered-To
    if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
        foreach ($identities as $idx => $ident) {
            if (in_array($ident['email_ascii'], (array)$delivered_to)) {
                $from_idx = $idx;
                break;
            }
        }
    }
    // Fallback using Envelope-To
    if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
        foreach ($identities as $idx => $ident) {
            if (in_array($ident['email_ascii'], (array)$envelope_to)) {
                $from_idx = $idx;
                break;
            }
        }
    }
    return $identities[$from_idx !== null ? $from_idx : $default_identity];
}
// Fixes some content-type names
function rcmail_fix_mimetype($name)