Add address parser, fixes #82, #145

This commit is contained in:
Synchro 2015-05-21 17:05:57 +02:00
parent d2b8b996f3
commit 199bd9698b
3 changed files with 140 additions and 0 deletions

View File

@ -2,6 +2,7 @@
* Don't switch to quoted-printable for long lines if already using base64
* Fixed Travis-CI config when run on PHP 7
* Add address parser for RFC822-format addresses
## Version 5.2.10 (May 4th 2015)
* Add custom header getter

View File

@ -852,6 +852,61 @@ class PHPMailer
return false;
}
/**
* Parse and validate a string containing one or more RFC822-style comma-separated email addresses
* of the form "display name <address>" into an array of name/address pairs.
* Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
* Note that quotes in the name part are removed.
* @param string $addrstr The address list string
* @param bool $useimap Whether to use the IMAP extension to parse the list
* @return array
* @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
*/
public function parseAddresses($addrstr, $useimap = true)
{
$addresses = array();
if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
//Use this built-in parser if it's available
$list = imap_rfc822_parse_adrlist($addrstr, '');
foreach ($list as $address) {
if ($address->host != '.SYNTAX-ERROR.') {
if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
$addresses[] = array(
'name' => (property_exists($address, 'personal') ? $address->personal : ''),
'address' => $address->mailbox . '@' . $address->host
);
}
}
}
} else {
//Use this simpler parser
$list = explode(',', $addrstr);
foreach ($list as $address) {
$address = trim($address);
//Is there a separate name part?
if (strpos($address, '<') === false) {
//No separate name, just use the whole thing
if ($this->validateAddress($address)) {
$addresses[] = array(
'name' => '',
'address' => $address
);
}
} else {
list($name, $email) = explode('<', $address);
$email = trim(str_replace('>', '', $email));
if ($this->validateAddress($email)) {
$addresses[] = array(
'name' => trim(str_replace(array('"', "'"), '', $name)),
'address' => $email
);
}
}
}
}
return $addresses;
}
/**
* Set the From and FromName properties.
* @param string $address

View File

@ -1364,6 +1364,90 @@ EOT;
$this->Mail->clearReplyTos();
}
/**
* Test RFC822 address splitting.
*/
public function testAddressSplitting()
{
//Test built-in address parser
$this->assertCount(
2,
$this->Mail->parseAddresses(
'Joe User <joe@example.com>, Jill User <jill@example.net>'
),
'Failed to recognise address list (IMAP parser)'
);
//Test simple address parser
$this->assertCount(
2,
$this->Mail->parseAddresses(
'Joe User <joe@example.com>, Jill User <jill@example.net>',
false
),
'Failed to recognise address list'
);
//Test single address
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'Joe User <joe@example.com>',
false
),
'Failed to recognise single address'
);
//Test quoted name IMAP
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'Tim "The Book" O\'Reilly <foo@example.com>'
),
'Failed to recognise quoted name (IMAP)'
);
//Test quoted name
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'Tim "The Book" O\'Reilly <foo@example.com>',
false
),
'Failed to recognise quoted name'
);
//Test single address IMAP
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'Joe User <joe@example.com>'
),
'Failed to recognise single address (IMAP)'
);
//Test unnamed address
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'joe@example.com',
false
),
'Failed to recognise unnamed address'
);
//Test unnamed address IMAP
$this->assertNotEmpty(
$this->Mail->parseAddresses(
'joe@example.com'
),
'Failed to recognise unnamed address (IMAP)'
);
//Test invalid addresses
$this->assertEmpty(
$this->Mail->parseAddresses(
'Joe User <joe@example.com.>, Jill User <jill.@example.net>'
),
'Failed to recognise invalid addresses (IMAP)'
);
//Test invalid addresses
$this->assertEmpty(
$this->Mail->parseAddresses(
'Joe User <joe@example.com.>, Jill User <jill.@example.net>',
false
),
'Failed to recognise invalid addresses'
);
}
/**
* Test address escaping.
*/