Aleksander Machniak
2013-11-04 a8b004e8d8f040d868e4b19da9527c177be9959d
Improve identity selection based on From: header (#1489378)
3 files modified
91 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 42 ●●●●● patch | view | raw | blame | history
tests/MailFunc.php 48 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Improve identity selection based on From: header (#1489378)
- Fix issue where mails with inline images of the same name contained only the first image multiple times (#1489406)
- Use left/right arrow keys to collapse/expand thread and spacebar to select a row, change Ctrl key behavior (#1489392)
- Fix an issue where using arrow keys to go up a list can result in selected message being under headers (#1489403)
program/steps/mail/func.inc
@@ -1776,28 +1776,34 @@
        }
    }
    $from_idx         = null;
    $found_idx        = null;
    $default_identity = 0; // default identity is always first on the list
    // decode From: address
    $from = rcube_mime::decode_address_list($MESSAGE->headers->from, null, true, $MESSAGE->headers->charset);
    $from = array_shift($from);
    $from['mailto'] = strtolower($from['mailto']);
    $from_idx   = null;
    $found_idx  = array('to' => null, 'from' => null);
    $check_from = in_array($compose_mode, array('draft', 'edit', 'reply'));
    // Select identity
    foreach ($identities as $idx => $ident) {
        // use From header
        if (in_array($compose_mode, array('draft', 'edit'))) {
            if ($MESSAGE->headers->from == $ident['ident']) {
        // use From: header when in edit/draft or reply-to-self
        if ($check_from && $from['mailto'] == strtolower($ident['email_ascii'])) {
            // remember first matching identity address
            if ($found_idx['from'] === null) {
                $found_idx['from'] = $idx;
            }
            // match identity name
            if ($from['name'] && $ident['name'] && $from['name'] == $ident['name']) {
                $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
        // use replied/forwarded message recipients
        else if (($found = array_search(strtolower($ident['email_ascii']), $a_recipients)) !== false) {
            if ($found_idx === null) {
                $found_idx = $idx;
            // remember first matching identity address
            if ($found_idx['to'] === null) {
                $found_idx['to'] = $idx;
            }
            // match identity name
            if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
@@ -1807,9 +1813,10 @@
        }
    }
    // If matching by name+address doesn't found any matches, get first found address (identity)
    // If matching by name+address didn't find any matches,
    // get first found identity (address) if any
    if ($from_idx === null) {
        $from_idx = $found_idx;
        $from_idx = $found_idx['from'] !== null ? $found_idx['from'] : $found_idx['to'];
    }
    // Try Return-Path
@@ -1840,7 +1847,8 @@
    $selected = $plugin['selected'];
    return $identities[$selected !== null ? $selected : $default_identity];
    // default identity is always first on the list
    return $identities[$selected !== null ? $selected : 0];
}
// Fixes some content-type names
tests/MailFunc.php
@@ -217,4 +217,52 @@
        $this->assertSame($identities[1], $res);
    }
    /**
     * Test identities selection (#1489378)
     */
    function test_rcmail_identity_select2()
    {
        $identities = array(
            array(
                'name' => 'Test 1',
                'email_ascii' => 'addr1@domain.tld',
                'ident' => 'Test 1 <addr1@domain.tld>',
            ),
            array(
                'name' => 'Test 2',
                'email_ascii' => 'addr2@domain.tld',
                'ident' => 'Test 2 <addr2@domain.tld>',
            ),
            array(
                'name' => 'Test 3',
                'email_ascii' => 'addr3@domain.tld',
                'ident' => 'Test 3 <addr3@domain.tld>',
            ),
            array(
                'name' => 'Test 4',
                'email_ascii' => 'addr2@domain.tld',
                'ident' => 'Test 4 <addr2@domain.tld>',
            ),
        );
        $message = new stdClass;
        $message->headers = new rcube_message_header;
        $message->headers->set('From', '<addr2@domain.tld>');
        $res = rcmail_identity_select($message, $identities);
        $this->assertSame($identities[1], $res);
        $message->headers->set('From', 'Test 2 <addr2@domain.tld>');
        $res = rcmail_identity_select($message, $identities);
        $this->assertSame($identities[1], $res);
        $message->headers->set('From', 'Other <addr2@domain.tld>');
        $res = rcmail_identity_select($message, $identities);
        $this->assertSame($identities[1], $res);
        $message->headers->set('From', 'Test 4 <addr2@domain.tld>');
        $res = rcmail_identity_select($message, $identities);
        $this->assertSame($identities[3], $res);
    }
}