Skip to content

Commit 8c2e128

Browse files
committed
feature #33091 [Mime] Add Address::fromString (gisostallenberg)
This PR was merged into the 4.4 branch. Discussion ---------- [Mime] Add Address::fromString | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #33086 | License | MIT | Doc PR | symfony/symfony-docs#12128 This will allow to create a Address from a string such as 'Name <name@example.com>' Example: ```php $address = Address::fromString("Name <name@example.com>"); ``` Commits ------- 75ea8d0 Add Address::fromString
2 parents a77e326 + 75ea8d0 commit 8c2e128

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/Symfony/Component/Mime/Address.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
*/
2424
final class Address
2525
{
26+
/**
27+
* A regex that matches a structure like 'Name <email@address.com>'.
28+
* It matches anything between the first < and last > as email address.
29+
* This allows to use a single string to construct an Address, which can be convenient to use in
30+
* config, and allows to have more readable config.
31+
* This does not try to cover all edge cases for address.
32+
*/
33+
private const FROM_STRING_PATTERN = '~(?<displayName>[^<]*)<(?<addrSpec>.*)>[^>]*~';
34+
2635
private static $validator;
2736
private static $encoder;
2837

@@ -100,4 +109,15 @@ public static function createArray(array $addresses): array
100109

101110
return $addrs;
102111
}
112+
113+
public static function fromString(string $string): self
114+
{
115+
if (false === strpos($string, '<')) {
116+
return new self($string, '');
117+
}
118+
if (!preg_match(self::FROM_STRING_PATTERN, $string, $matches)) {
119+
throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, static::class));
120+
}
121+
return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
122+
}
103123
}

src/Symfony/Component/Mime/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* [BC BREAK] Removed `NamedAddress` (`Address` now supports a name)
88
* Added PHPUnit constraints
99
* Added `AbstractPart::asDebugString()`
10+
* Added `Address::fromString()`
1011

1112
4.3.3
1213
-----

src/Symfony/Component/Mime/Tests/AddressTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Mime\Address;
16+
use Symfony\Component\Mime\Exception\InvalidArgumentException;
1617

1718
class AddressTest extends TestCase
1819
{
@@ -77,4 +78,79 @@ public function nameEmptyDataProvider(): array
7778
{
7879
return [[''], [' '], [" \r\n "]];
7980
}
81+
82+
/**
83+
* @dataProvider fromStringProvider
84+
*/
85+
public function testFromString($string, $displayName, $addrSpec)
86+
{
87+
$address = Address::fromString($string);
88+
$this->assertEquals($displayName, $address->getName());
89+
$this->assertEquals($addrSpec, $address->getAddress());
90+
$fromToStringAddress = Address::fromString($address->toString());
91+
$this->assertEquals($displayName, $fromToStringAddress->getName());
92+
$this->assertEquals($addrSpec, $fromToStringAddress->getAddress());
93+
}
94+
95+
public function testFromStringFailure()
96+
{
97+
$this->expectException(InvalidArgumentException::class);
98+
Address::fromString('Jane Doe <example@example.com');
99+
}
100+
101+
public function fromStringProvider()
102+
{
103+
return [
104+
[
105+
'example@example.com',
106+
'',
107+
'example@example.com',
108+
],
109+
[
110+
'<example@example.com>',
111+
'',
112+
'example@example.com',
113+
],
114+
[
115+
'Jane Doe <example@example.com>',
116+
'Jane Doe',
117+
'example@example.com',
118+
],
119+
[
120+
'Jane Doe<example@example.com>',
121+
'Jane Doe',
122+
'example@example.com',
123+
],
124+
[
125+
'\'Jane Doe\' <example@example.com>',
126+
'Jane Doe',
127+
'example@example.com',
128+
],
129+
[
130+
'"Jane Doe" <example@example.com>',
131+
'Jane Doe',
132+
'example@example.com',
133+
],
134+
[
135+
'Jane Doe <"ex<ample"@example.com>',
136+
'Jane Doe',
137+
'"ex<ample"@example.com',
138+
],
139+
[
140+
'Jane Doe <"ex<amp>le"@example.com>',
141+
'Jane Doe',
142+
'"ex<amp>le"@example.com',
143+
],
144+
[
145+
'Jane Doe > <"ex<am p>le"@example.com>',
146+
'Jane Doe >',
147+
'"ex<am p>le"@example.com',
148+
],
149+
[
150+
'Jane Doe <example@example.com>discarded',
151+
'Jane Doe',
152+
'example@example.com',
153+
],
154+
];
155+
}
80156
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy