Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 52a2eab

Browse files
committed
bug #46963 [Mime] Fix inline parts when added via attachPart() (fabpot)
This PR was merged into the 4.4 branch. Discussion ---------- [Mime] Fix inline parts when added via attachPart() | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | Fixes #42921, Fixes #46962 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT | Doc PR | n/a Commits ------- aeab24a [Mime] Fix inline parts when added via attachPart()
2 parents a9ab336 + aeab24a commit 52a2eab

File tree

2 files changed

+108
-20
lines changed

2 files changed

+108
-20
lines changed

src/Symfony/Component/Mime/Email.php

+19-7
Original file line numberDiff line numberDiff line change
@@ -507,25 +507,37 @@ private function prepareParts(): ?array
507507
$names = array_filter(array_unique(array_merge($names[2], $names[3])));
508508
}
509509

510+
// usage of reflection is a temporary workaround for missing getters that will be added in 6.2
511+
$dispositionRef = new \ReflectionProperty(TextPart::class, 'disposition');
512+
$dispositionRef->setAccessible(true);
513+
$nameRef = new \ReflectionProperty(TextPart::class, 'name');
514+
$nameRef->setAccessible(true);
510515
$attachmentParts = $inlineParts = [];
511516
foreach ($this->attachments as $attachment) {
517+
$part = $this->createDataPart($attachment);
518+
if (isset($attachment['part'])) {
519+
$attachment['name'] = $nameRef->getValue($part);
520+
}
521+
512522
foreach ($names as $name) {
513-
if (isset($attachment['part'])) {
514-
continue;
515-
}
516523
if ($name !== $attachment['name']) {
517524
continue;
518525
}
519526
if (isset($inlineParts[$name])) {
520527
continue 2;
521528
}
522-
$attachment['inline'] = true;
523-
$inlineParts[$name] = $part = $this->createDataPart($attachment);
529+
$part->setDisposition('inline');
524530
$html = str_replace('cid:'.$name, 'cid:'.$part->getContentId(), $html);
525531
$part->setName($part->getContentId());
526-
continue 2;
532+
533+
break;
534+
}
535+
536+
if ('inline' === $dispositionRef->getValue($part)) {
537+
$inlineParts[$attachment['name']] = $part;
538+
} else {
539+
$attachmentParts[] = $part;
527540
}
528-
$attachmentParts[] = $this->createDataPart($attachment);
529541
}
530542
if (null !== $htmlPart) {
531543
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');

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

+89-13
Original file line numberDiff line numberDiff line change
@@ -246,76 +246,116 @@ public function testGetBody()
246246
$this->assertEquals($text, $e->getBody());
247247
}
248248

249-
public function testGenerateBody()
249+
public function testGenerateBodyWithTextOnly()
250250
{
251251
$text = new TextPart('text content');
252-
$html = new TextPart('html content', 'utf-8', 'html');
253-
$att = new DataPart($file = fopen(__DIR__.'/Fixtures/mimetypes/test', 'r'));
254-
$img = new DataPart($image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r'), 'test.gif');
255-
256252
$e = (new Email())->from('[email protected]')->to('[email protected]');
257253
$e->text('text content');
258254
$this->assertEquals($text, $e->getBody());
259255
$this->assertEquals('text content', $e->getTextBody());
256+
}
260257

258+
public function testGenerateBodyWithHtmlOnly()
259+
{
260+
$html = new TextPart('html content', 'utf-8', 'html');
261261
$e = (new Email())->from('[email protected]')->to('[email protected]');
262262
$e->html('html content');
263263
$this->assertEquals($html, $e->getBody());
264264
$this->assertEquals('html content', $e->getHtmlBody());
265+
}
265266

267+
public function testGenerateBodyWithTextAndHtml()
268+
{
269+
$text = new TextPart('text content');
270+
$html = new TextPart('html content', 'utf-8', 'html');
266271
$e = (new Email())->from('[email protected]')->to('[email protected]');
267272
$e->html('html content');
268273
$e->text('text content');
269274
$this->assertEquals(new AlternativePart($text, $html), $e->getBody());
275+
}
270276

277+
public function testGenerateBodyWithTextAndHtmlNotUtf8()
278+
{
271279
$e = (new Email())->from('[email protected]')->to('[email protected]');
272280
$e->html('html content', 'iso-8859-1');
273281
$e->text('text content', 'iso-8859-1');
274282
$this->assertEquals('iso-8859-1', $e->getTextCharset());
275283
$this->assertEquals('iso-8859-1', $e->getHtmlCharset());
276284
$this->assertEquals(new AlternativePart(new TextPart('text content', 'iso-8859-1'), new TextPart('html content', 'iso-8859-1', 'html')), $e->getBody());
285+
}
277286

287+
public function testGenerateBodyWithTextContentAndAttachedFile()
288+
{
289+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
278290
$e = (new Email())->from('[email protected]')->to('[email protected]');
279291
$e->attach($file);
280292
$e->text('text content');
281-
$this->assertEquals(new MixedPart($text, $att), $e->getBody());
293+
$this->assertEquals(new MixedPart($text, $filePart), $e->getBody());
294+
}
282295

296+
public function testGenerateBodyWithHtmlContentAndAttachedFile()
297+
{
298+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
283299
$e = (new Email())->from('[email protected]')->to('[email protected]');
284300
$e->attach($file);
285301
$e->html('html content');
286-
$this->assertEquals(new MixedPart($html, $att), $e->getBody());
302+
$this->assertEquals(new MixedPart($html, $filePart), $e->getBody());
303+
}
287304

305+
public function testGenerateBodyWithAttachedFileOnly()
306+
{
307+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
288308
$e = (new Email())->from('[email protected]')->to('[email protected]');
289309
$e->attach($file);
290-
$this->assertEquals(new MixedPart($att), $e->getBody());
310+
$this->assertEquals(new MixedPart($filePart), $e->getBody());
311+
}
291312

313+
public function testGenerateBodyWithTextAndHtmlContentAndAttachedFile()
314+
{
315+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
292316
$e = (new Email())->from('[email protected]')->to('[email protected]');
293317
$e->html('html content');
294318
$e->text('text content');
295319
$e->attach($file);
296-
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att), $e->getBody());
320+
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $filePart), $e->getBody());
321+
}
297322

323+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageNotReferenced()
324+
{
325+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
298326
$e = (new Email())->from('[email protected]')->to('[email protected]');
299327
$e->html('html content');
300328
$e->text('text content');
301329
$e->attach($file);
302330
$e->attach($image, 'test.gif');
303-
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $att, $img), $e->getBody());
331+
$this->assertEquals(new MixedPart(new AlternativePart($text, $html), $filePart, $imagePart), $e->getBody());
332+
}
304333

334+
public function testGenerateBodyWithTextAndAttachedFileAndAttachedImageNotReferenced()
335+
{
336+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
305337
$e = (new Email())->from('[email protected]')->to('[email protected]');
306338
$e->text('text content');
307339
$e->attach($file);
308340
$e->attach($image, 'test.gif');
309-
$this->assertEquals(new MixedPart($text, $att, $img), $e->getBody());
341+
$this->assertEquals(new MixedPart($text, $filePart, $imagePart), $e->getBody());
342+
}
310343

344+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageNotReferencedViaCid()
345+
{
346+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
311347
$e = (new Email())->from('[email protected]')->to('[email protected]');
312348
$e->html($content = 'html content <img src="test.gif">');
313349
$e->text('text content');
314350
$e->attach($file);
315351
$e->attach($image, 'test.gif');
316352
$fullhtml = new TextPart($content, 'utf-8', 'html');
317-
$this->assertEquals(new MixedPart(new AlternativePart($text, $fullhtml), $att, $img), $e->getBody());
353+
$this->assertEquals(new MixedPart(new AlternativePart($text, $fullhtml), $filePart, $imagePart), $e->getBody());
354+
}
318355

356+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImageReferencedViaCid()
357+
{
358+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
319359
$e = (new Email())->from('[email protected]')->to('[email protected]');
320360
$e->html($content = 'html content <img src="cid:test.gif">');
321361
$e->text('text content');
@@ -325,12 +365,35 @@ public function testGenerateBody()
325365
$this->assertInstanceOf(MixedPart::class, $body);
326366
$this->assertCount(2, $related = $body->getParts());
327367
$this->assertInstanceOf(RelatedPart::class, $related[0]);
328-
$this->assertEquals($att, $related[1]);
368+
$this->assertEquals($filePart, $related[1]);
329369
$this->assertCount(2, $parts = $related[0]->getParts());
330370
$this->assertInstanceOf(AlternativePart::class, $parts[0]);
331371
$generatedHtml = $parts[0]->getParts()[1];
332372
$this->assertStringContainsString('cid:'.$parts[1]->getContentId(), $generatedHtml->getBody());
373+
}
333374

375+
public function testGenerateBodyWithTextAndHtmlAndAttachedFileAndAttachedImagePartAsInlineReferencedViaCid()
376+
{
377+
[$text, $html, $filePart, $file, $imagePart, $image] = $this->generateSomeParts();
378+
$e = (new Email())->from('[email protected]')->to('[email protected]');
379+
$e->html($content = 'html content <img src="cid:test.gif">');
380+
$e->text('text content');
381+
$e->attach($file);
382+
$e->attachPart((new DataPart($image, 'test.gif'))->asInline());
383+
$body = $e->getBody();
384+
$this->assertInstanceOf(MixedPart::class, $body);
385+
$this->assertCount(2, $related = $body->getParts());
386+
$this->assertInstanceOf(RelatedPart::class, $related[0]);
387+
$this->assertEquals($filePart, $related[1]);
388+
$this->assertCount(2, $parts = $related[0]->getParts());
389+
$this->assertInstanceOf(AlternativePart::class, $parts[0]);
390+
$generatedHtml = $parts[0]->getParts()[1];
391+
$this->assertStringContainsString('cid:'.$parts[1]->getContentId(), $generatedHtml->getBody());
392+
}
393+
394+
public function testGenerateBodyWithHtmlAndInlinedImageTwiceReferencedViaCid()
395+
{
396+
// inline image (twice) referenced in the HTML content
334397
$content = 'html content <img src="cid:test.gif">';
335398
$r = fopen('php://memory', 'r+', false);
336399
fwrite($r, $content);
@@ -339,6 +402,7 @@ public function testGenerateBody()
339402
$e = (new Email())->from('[email protected]')->to('[email protected]');
340403
$e->html($r);
341404
// embedding the same image twice results in one image only in the email
405+
$image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r');
342406
$e->embed($image, 'test.gif');
343407
$e->embed($image, 'test.gif');
344408
$body = $e->getBody();
@@ -348,8 +412,19 @@ public function testGenerateBody()
348412
$this->assertStringMatchesFormat('html content <img src=3D"cid:%s@symfony">', $parts[0]->bodyToString());
349413
}
350414

415+
private function generateSomeParts(): array
416+
{
417+
$text = new TextPart('text content');
418+
$html = new TextPart('html content', 'utf-8', 'html');
419+
$filePart = new DataPart($file = fopen(__DIR__.'/Fixtures/mimetypes/test', 'r'));
420+
$imagePart = new DataPart($image = fopen(__DIR__.'/Fixtures/mimetypes/test.gif', 'r'), 'test.gif');
421+
422+
return [$text, $html, $filePart, $file, $imagePart, $image];
423+
}
424+
351425
public function testAttachments()
352426
{
427+
// inline part
353428
$contents = file_get_contents($name = __DIR__.'/Fixtures/mimetypes/test', 'r');
354429
$att = new DataPart($file = fopen($name, 'r'), 'test');
355430
$inline = (new DataPart($contents, 'test'))->asInline();
@@ -358,6 +433,7 @@ public function testAttachments()
358433
$e->embed($contents, 'test');
359434
$this->assertEquals([$att, $inline], $e->getAttachments());
360435

436+
// inline part from path
361437
$att = DataPart::fromPath($name, 'test');
362438
$inline = DataPart::fromPath($name, 'test')->asInline();
363439
$e = new Email();

0 commit comments

Comments
 (0)