Skip to content

Commit 4a6259c

Browse files
committed
Merge branch '6.0' into 6.1
* 6.0: Fix CS Fix CS quote address names if they contain parentheses [FrameworkBundle] Fail gracefully when forms use disabled CSRF [Mime] Fix inline parts when added via attachPart() Fail gracefully when attempting to autowire composite types [VarDumper] Add a test case for nesting intersection and union types Fix #46592 - Ignore getter with required parameters [Serializer] Fix inconsistent behaviour of nullable objects in key/value arrays
2 parents a2d5684 + e96131a commit 4a6259c

File tree

4 files changed

+119
-20
lines changed

4 files changed

+119
-20
lines changed

Email.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,25 +501,37 @@ private function prepareParts(): ?array
501501
$names = array_filter(array_unique($names));
502502
}
503503

504+
// usage of reflection is a temporary workaround for missing getters that will be added in 6.2
505+
$dispositionRef = new \ReflectionProperty(TextPart::class, 'disposition');
506+
$dispositionRef->setAccessible(true);
507+
$nameRef = new \ReflectionProperty(TextPart::class, 'name');
508+
$nameRef->setAccessible(true);
504509
$attachmentParts = $inlineParts = [];
505510
foreach ($this->attachments as $attachment) {
511+
$part = $this->createDataPart($attachment);
512+
if (isset($attachment['part'])) {
513+
$attachment['name'] = $nameRef->getValue($part);
514+
}
515+
506516
foreach ($names as $name) {
507-
if (isset($attachment['part'])) {
508-
continue;
509-
}
510517
if ($name !== $attachment['name']) {
511518
continue;
512519
}
513520
if (isset($inlineParts[$name])) {
514521
continue 2;
515522
}
516-
$attachment['inline'] = true;
517-
$inlineParts[$name] = $part = $this->createDataPart($attachment);
523+
$part->setDisposition('inline');
518524
$html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html);
519525
$part->setName($part->getContentId());
520-
continue 2;
526+
527+
break;
528+
}
529+
530+
if ('inline' === $dispositionRef->getValue($part)) {
531+
$inlineParts[$attachment['name']] = $part;
532+
} else {
533+
$attachmentParts[] = $part;
521534
}
522-
$attachmentParts[] = $this->createDataPart($attachment);
523535
}
524536
if (null !== $htmlPart) {
525537
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');

Header/AbstractHeader.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ protected function createPhrase(HeaderInterface $header, string $string, string
109109
}
110110
$phraseStr = $this->encodeWords($header, $string, $usedLength);
111111
}
112+
} elseif (str_contains($phraseStr, '(')) {
113+
foreach (['\\', '"'] as $char) {
114+
$phraseStr = str_replace($char, '\\'.$char, $phraseStr);
115+
}
116+
$phraseStr = '"'.$phraseStr.'"';
112117
}
113118

114119
return $phraseStr;

Tests/EmailTest.php

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,76 +253,116 @@ public function testGetBody()
253253
$this->assertEquals($text, $e->getBody());
254254
}
255255

256-
public function testGenerateBody()
256+
public function testGenerateBodyWithTextOnly()
257257
{
258258
$text = new TextPart('text content');
259-
$html = new TextPart('html content', 'utf-8', 'html');
260-
$att = new DataPart($file = fopen(__DIR__.'/Fixtures/mimetypes/test', 'r'));
261-
$img = new DataPart($image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r'), 'test.gif');
262-
263259
$e = (new Email())->from('[email protected]')->to('[email protected]');
264260
$e->text('text content');
265261
$this->assertEquals($text, $e->getBody());
266262
$this->assertEquals('text content', $e->getTextBody());
263+
}
267264

265+
public function testGenerateBodyWithHtmlOnly()
266+
{
267+
$html = new TextPart('html content', 'utf-8', 'html');
268268
$e = (new Email())->from('[email protected]')->to('[email protected]');
269269
$e->html('html content');
270270
$this->assertEquals($html, $e->getBody());
271271
$this->assertEquals('html content', $e->getHtmlBody());
272+
}
272273

274+
public function testGenerateBodyWithTextAndHtml()
275+
{
276+
$text = new TextPart('text content');
277+
$html = new TextPart('html content', 'utf-8', 'html');
273278
$e = (new Email())->from('[email protected]')->to('[email protected]');
274279
$e->html('html content');
275280
$e->text('text content');
276281
$this->assertEquals(new AlternativePart($text, $html), $e->getBody());
282+
}
277283

284+
public function testGenerateBodyWithTextAndHtmlNotUtf8()
285+
{
278286
$e = (new Email())->from('[email protected]')->to('[email protected]');
279287
$e->html('html content', 'iso-8859-1');
280288
$e->text('text content', 'iso-8859-1');
281289
$this->assertEquals('iso-8859-1', $e->getTextCharset());
282290
$this->assertEquals('iso-8859-1', $e->getHtmlCharset());
283291
$this->assertEquals(new AlternativePart(new TextPart('text content', 'iso-8859-1'), new TextPart('html content', 'iso-8859-1', 'html')), $e->getBody());
292+
}
284293

294+
public function testGenerateBodyWithTextContentAndAttachedFile()
295+
{
296+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
285297
$e = (new Email())->from('[email protected]')->to('[email protected]');
286298
$e->attach($file);
287299
$e->text('text content');
288-
$this->assertEquals(new MixedPart($text, $att), $e->getBody());
300+
$this->assertEquals(new MixedPart($text, $filePart), $e->getBody());
301+
}
289302

303+
public function testGenerateBodyWithHtmlContentAndAttachedFile()
304+
{
305+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
290306
$e = (new Email())->from('[email protected]')->to('[email protected]');
291307
$e->attach($file);
292308
$e->html('html content');
293-
$this->assertEquals(new MixedPart($html, $att), $e->getBody());
309+
$this->assertEquals(new MixedPart($html, $filePart), $e->getBody());
310+
}
294311

312+
public function testGenerateBodyWithAttachedFileOnly()
313+
{
314+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
295315
$e = (new Email())->from('[email protected]')->to('[email protected]');
296316
$e->attach($file);
297-
$this->assertEquals(new MixedPart($att), $e->getBody());
317+
$this->assertEquals(new MixedPart($filePart), $e->getBody());
318+
}
298319

320+
public function testGenerateBodyWithTextAndHtmlContentAndAttachedFile()
321+
{
322+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
299323
$e = (new Email())->from('[email protected]')->to('[email protected]');
300324
$e->html('html content');
301325
$e->text('text content');
302326
$e->attach($file);
303-
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att), $e->getBody());
327+
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $filePart), $e->getBody());
328+
}
304329

330+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageNotReferenced()
331+
{
332+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
305333
$e = (new Email())->from('[email protected]')->to('[email protected]');
306334
$e->html('html content');
307335
$e->text('text content');
308336
$e->attach($file);
309337
$e->attach($image, 'test.gif');
310-
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att, $img), $e->getBody());
338+
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $filePart, $imagePart), $e->getBody());
339+
}
311340

341+
public function testGenerateBodyWithTextAndAttachedFileAndAttachedImageNotReferenced()
342+
{
343+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
312344
$e = (new Email())->from('[email protected]')->to('[email protected]');
313345
$e->text('text content');
314346
$e->attach($file);
315347
$e->attach($image, 'test.gif');
316-
$this->assertEquals(new MixedPart($text, $att, $img), $e->getBody());
348+
$this->assertEquals(new MixedPart($text, $filePart, $imagePart), $e->getBody());
349+
}
317350

351+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageNotReferencedViaCid()
352+
{
353+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
318354
$e = (new Email())->from('[email protected]')->to('[email protected]');
319355
$e->html($content = 'html content <img src="test.gif">');
320356
$e->text('text content');
321357
$e->attach($file);
322358
$e->attach($image, 'test.gif');
323359
$fullhtml = new TextPart($content, 'utf-8', 'html');
324-
$this->assertEquals(new MixedPart(new AlternativePart($text, $fullhtml), $att, $img), $e->getBody());
360+
$this->assertEquals(new MixedPart(new AlternativePart($text, $fullhtml), $filePart, $imagePart), $e->getBody());
361+
}
325362

363+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageReferencedViaCid()
364+
{
365+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
326366
$e = (new Email())->from('[email protected]')->to('[email protected]');
327367
$e->html($content = 'html content <img src="cid:test.gif">');
328368
$e->text('text content');
@@ -332,12 +372,35 @@ public function testGenerateBody()
332372
$this->assertInstanceOf(MixedPart::class, $body);
333373
$this->assertCount(2, $related = $body->getParts());
334374
$this->assertInstanceOf(RelatedPart::class, $related[0]);
335-
$this->assertEquals($att, $related[1]);
375+
$this->assertEquals($filePart, $related[1]);
336376
$this->assertCount(2, $parts = $related[0]->getParts());
337377
$this->assertInstanceOf(AlternativePart::class, $parts[0]);
338378
$generatedHtml = $parts[0]->getParts()[1];
339379
$this->assertStringContainsString('cid:'.$parts[1]->getContentId(), $generatedHtml->getBody());
380+
}
340381

382+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImagePartAsInlineReferencedViaCid()
383+
{
384+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
385+
$e = (new Email())->from('[email protected]')->to('[email protected]');
386+
$e->html($content = 'html content <img src="cid:test.gif">');
387+
$e->text('text content');
388+
$e->attach($file);
389+
$e->attachPart((new DataPart($image, 'test.gif'))->asInline());
390+
$body = $e->getBody();
391+
$this->assertInstanceOf(MixedPart::class, $body);
392+
$this->assertCount(2, $related = $body->getParts());
393+
$this->assertInstanceOf(RelatedPart::class, $related[0]);
394+
$this->assertEquals($filePart, $related[1]);
395+
$this->assertCount(2, $parts = $related[0]->getParts());
396+
$this->assertInstanceOf(AlternativePart::class, $parts[0]);
397+
$generatedHtml = $parts[0]->getParts()[1];
398+
$this->assertStringContainsString('cid:'.$parts[1]->getContentId(), $generatedHtml->getBody());
399+
}
400+
401+
public function testGenerateBodyWithHtmlAndInlinedImageTwiceReferencedViaCid()
402+
{
403+
// inline image (twice) referenced in the HTML content
341404
$content = 'html content <img src="cid:test.gif">';
342405
$r = fopen('php://memory', 'r+', false);
343406
fwrite($r, $content);
@@ -346,6 +409,7 @@ public function testGenerateBody()
346409
$e = (new Email())->from('[email protected]')->to('[email protected]');
347410
$e->html($r);
348411
// embedding the same image twice results in one image only in the email
412+
$image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r');
349413
$e->embed($image, 'test.gif');
350414
$e->embed($image, 'test.gif');
351415
$body = $e->getBody();
@@ -363,8 +427,19 @@ public function testGenerateBody()
363427
$this->assertStringMatchesFormat('<div background=3D"cid:%s@symfony"></div>', $parts[0]->bodyToString());
364428
}
365429

430+
private function generateSomeParts(): array
431+
{
432+
$text = new TextPart('text content');
433+
$html = new TextPart('html content', 'utf-8', 'html');
434+
$filePart = new DataPart($file = fopen(__DIR__.'/Fixtures/mimetypes/test', 'r'));
435+
$imagePart = new DataPart($image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r'), 'test.gif');
436+
437+
return [$text, $html, $filePart, $file, $imagePart, $image];
438+
}
439+
366440
public function testAttachments()
367441
{
442+
// inline part
368443
$contents = file_get_contents($name = __DIR__.'/Fixtures/mimetypes/test', 'r');
369444
$att = new DataPart($file = fopen($name, 'r'), 'test');
370445
$inline = (new DataPart($contents, 'test'))->asInline();
@@ -373,6 +448,7 @@ public function testAttachments()
373448
$e->embed($contents, 'test');
374449
$this->assertEquals([$att, $inline], $e->getAttachments());
375450

451+
// inline part from path
376452
$att = DataPart::fromPath($name, 'test');
377453
$inline = DataPart::fromPath($name, 'test')->asInline();
378454
$e = new Email();

Tests/Header/MailboxListHeaderTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public function testEscapeCharsInNameAreQuoted()
4949
$this->assertEquals(['"Chris Corbyn, \\\\escaped\\\\" <[email protected]>'], $header->getAddressStrings());
5050
}
5151

52+
public function testParenthesesInNameAreQuoted()
53+
{
54+
$header = new MailboxListHeader('From', [new Address('[email protected]', 'J Doe (ACME)')]);
55+
$this->assertEquals(['"J Doe (ACME)" <[email protected]>'], $header->getAddressStrings());
56+
}
57+
5258
public function testUtf8CharsInDomainAreIdnEncoded()
5359
{
5460
$header = new MailboxListHeader('From', [new Address('chris@swïftmailer.org', 'Chris Corbyn')]);

0 commit comments

Comments
 (0)