Skip to content

Commit 01c26aa

Browse files
feature #60163 [TwigBridge] Allow attachment name to be set for inline images (aleho)
This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [TwigBridge] Allow attachment name to be set for inline images | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | License | MIT Using a recommended setup attaching images from Twig would normally result in attachment names like ``@assets`/img/file.png` which might not be a good file name to expose to email clients. This allows the name to be specified, analogous to `attach` in the same wrapper. Commits ------- 7e29f05 [TwigBridge] Allow attachment name to be set for inline images
2 parents 1088f53 + 7e29f05 commit 01c26aa

File tree

7 files changed

+115
-3
lines changed

7 files changed

+115
-3
lines changed

src/Symfony/Bridge/Twig/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* Add `field_id()` Twig form helper function
99
* Add a `Twig` constraint that validates Twig templates
1010
* Make `lint:twig` collect all deprecations instead of stopping at the first one
11+
* Add `name` argument to `email.image` to override the attachment file name being set as the file path
1112

1213
7.2
1314
---

src/Symfony/Bridge/Twig/Mime/WrappedTemplatedEmail.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@ public function toName(): string
3939
* some Twig namespace for email images (e.g. '@email/images/logo.png').
4040
* @param string|null $contentType The media type (i.e. MIME type) of the image file (e.g. 'image/png').
4141
* Some email clients require this to display embedded images.
42+
* @param string|null $name A custom file name that overrides the original name (filepath) of the image
4243
*/
43-
public function image(string $image, ?string $contentType = null): string
44+
public function image(string $image, ?string $contentType = null, ?string $name = null): string
4445
{
4546
$file = $this->twig->getLoader()->getSourceContext($image);
4647
$body = $file->getPath() ? new File($file->getPath()) : $file->getCode();
47-
$this->message->addPart((new DataPart($body, $image, $contentType))->asInline());
48+
$name = $name ?: $image;
49+
$this->message->addPart((new DataPart($body, $name, $contentType))->asInline());
4850

49-
return 'cid:'.$image;
51+
return 'cid:'.$name;
5052
}
5153

5254
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
logo1.png
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<h1>Attachments</h1>
2+
{{ email.attach('@assets/images/logo1.png') }}
3+
{{ email.attach('@assets/images/logo2.png', name='image.png') }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<img src="{{ email.image('@assets/images/logo1.png') }}">
2+
<img src="{{ email.image('@assets/images/logo2.png', name='image.png') }}">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Twig\Tests\Mime;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\Twig\Mime\BodyRenderer;
16+
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
17+
use Twig\Environment;
18+
use Twig\Error\LoaderError;
19+
use Twig\Loader\FilesystemLoader;
20+
21+
/**
22+
* @author Alexander Hofbauer <a.hofbauer@fify.at
23+
*/
24+
class WrappedTemplatedEmailTest extends TestCase
25+
{
26+
public function testEmailImage()
27+
{
28+
$email = $this->buildEmail('email/image.html.twig');
29+
$body = $email->toString();
30+
$contentId1 = $email->getAttachments()[0]->getContentId();
31+
$contentId2 = $email->getAttachments()[1]->getContentId();
32+
33+
$part1 = str_replace("\n", "\r\n",
34+
<<<PART
35+
Content-ID: <$contentId1>
36+
Content-Type: image/png; name="$contentId1"
37+
Content-Transfer-Encoding: base64
38+
Content-Disposition: inline;
39+
name="$contentId1";
40+
filename="@assets/images/logo1.png"
41+
42+
PART
43+
);
44+
45+
$part2 = str_replace("\n", "\r\n",
46+
<<<PART
47+
Content-ID: <$contentId2>
48+
Content-Type: image/png; name="$contentId2"
49+
Content-Transfer-Encoding: base64
50+
Content-Disposition: inline;
51+
name="$contentId2"; filename=image.png
52+
53+
PART
54+
);
55+
56+
self::assertStringContainsString('![](cid:@assets/images/logo1.png)![](cid:image.png)', $body);
57+
self::assertStringContainsString($part1, $body);
58+
self::assertStringContainsString($part2, $body);
59+
}
60+
61+
public function testEmailAttach()
62+
{
63+
$email = $this->buildEmail('email/attach.html.twig');
64+
$body = $email->toString();
65+
66+
$part1 = str_replace("\n", "\r\n",
67+
<<<PART
68+
Content-Type: image/png; name=logo1.png
69+
Content-Transfer-Encoding: base64
70+
Content-Disposition: attachment; name=logo1.png; filename=logo1.png
71+
72+
PART
73+
);
74+
75+
$part2 = str_replace("\n", "\r\n",
76+
<<<PART
77+
Content-Type: image/png; name=image.png
78+
Content-Transfer-Encoding: base64
79+
Content-Disposition: attachment; name=image.png; filename=image.png
80+
81+
PART
82+
);
83+
84+
self::assertStringContainsString($part1, $body);
85+
self::assertStringContainsString($part2, $body);
86+
}
87+
88+
private function buildEmail(string $template): TemplatedEmail
89+
{
90+
$email = (new TemplatedEmail())
91+
->from('a.hofbauer@fify.at')
92+
->htmlTemplate($template);
93+
94+
$loader = new FilesystemLoader(\dirname(__DIR__).'/Fixtures/templates/');
95+
$loader->addPath(\dirname(__DIR__).'/Fixtures/assets', 'assets');
96+
97+
$environment = new Environment($loader);
98+
$renderer = new BodyRenderer($environment);
99+
$renderer->render($email);
100+
101+
return $email;
102+
}
103+
}

0 commit comments

Comments
 (0)