Skip to content

Commit c3558ff

Browse files
committed
Replace neos/swiftmailer by neos/symfonymailer
1 parent 1f8fcea commit c3558ff

File tree

2 files changed

+56
-96
lines changed

2 files changed

+56
-96
lines changed

Classes/Channel/EmailChannel.php

Lines changed: 55 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@
1010
use Neos\Flow\ResourceManagement\Exception as ResourceException;
1111
use Neos\Flow\ResourceManagement\PersistentResource;
1212
use Neos\Flow\ResourceManagement\ResourceManager;
13-
use Neos\SwiftMailer\Message;
14-
use Swift_Attachment;
15-
use Swift_Image;
16-
use Swift_Message;
13+
use Neos\SymfonyMailer\Exception\InvalidMailerConfigurationException;
14+
use Neos\SymfonyMailer\Service\MailerService;
1715
use Swisscom\CommunicationDispatcher\Domain\Model\Dto\Recipient;
1816
use Swisscom\CommunicationDispatcher\Exception;
17+
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
18+
use Symfony\Component\Mime\Address;
19+
use Symfony\Component\Mime\Email;
1920

2021
/**
2122
* @Flow\Scope("prototype")
2223
*/
2324
class EmailChannel implements ChannelInterface
2425
{
26+
/**
27+
* @Flow\Inject
28+
* @var MailerService
29+
*/
30+
protected $mailerService;
2531

2632
/**
2733
* @Flow\Inject
@@ -30,17 +36,17 @@ class EmailChannel implements ChannelInterface
3036
protected $resourceManager;
3137

3238
/**
33-
* @var string
39+
* @var array<string, string>
3440
*/
3541
protected $from;
3642

3743
/**
38-
* @var string
44+
* @var array<string, string>
3945
*/
4046
protected $replyTo;
4147

4248
/**
43-
* @var string
49+
* @var array<string, string>
4450
*/
4551
protected $cc;
4652

@@ -49,9 +55,9 @@ class EmailChannel implements ChannelInterface
4955
*/
5056
function __construct(array $options = [])
5157
{
52-
$this->from = isset($options['from']) ? $options['from'] : '';
53-
$this->replyTo = isset($options['replyTo']) ? $options['replyTo'] : '';
54-
$this->cc = isset($options['cc']) ? $options['cc'] : '';
58+
$this->from = $options['from'] ?? '';
59+
$this->replyTo = $options['replyTo'] ?? '';
60+
$this->cc = $options['cc'] ?? '';
5561
}
5662

5763
/**
@@ -61,105 +67,54 @@ function __construct(array $options = [])
6167
* @param array $options
6268
* @return void
6369
* @throws Exception
70+
* @throws ResourceException
71+
* @throws InvalidMailerConfigurationException
72+
* @throws TransportExceptionInterface
6473
*/
6574
public function send(Recipient $recipient, string $subject, string $text, array $options = [])
6675
{
6776
$toEmail = $recipient->getEmail();
6877
$toName = $recipient->getName();
69-
$attachedResources = $options['attachedResources'] ?? [];
78+
$attachedResources = isset($options['attachedResources']) && is_array($options['attachedResources'])
79+
? $options['attachedResources']
80+
: [];
7081

7182
if (empty($toEmail)) {
7283
throw new Exception('Recipient has no email address', 1570541186);
7384
}
74-
$mail = new Message();
75-
$mail->setFrom($this->from);
85+
86+
$email = new Email();
87+
$email
88+
->from($this->arrayToAddress($this->from))
89+
->subject($subject);
90+
7691
if (!empty($this->replyTo)) {
77-
$mail->setReplyTo($this->replyTo);
92+
$email->replyTo($this->arrayToAddress($this->replyTo));
7893
}
79-
$mail->setTo($toEmail, $toName);
94+
$email->to(new Address($toEmail, $toName));
8095
if (!empty($this->cc)) {
81-
$mail->setCc($this->cc);
96+
$email->cc($this->arrayToAddress($this->cc));
8297
}
83-
$mail->setSubject(htmlspecialchars_decode($subject));
84-
$plaintext = preg_replace(array('/\s{2,}/', '/[\t]/', '/###IMAGE:(.+?)###/', '/###PLAIN:(.+?)###/'), ' ', strip_tags($text));
85-
$text = $this->embedResources($text, $mail);
98+
$email->subject(htmlspecialchars_decode($subject));
99+
100+
$html = $this->formatInternetMessage($text);
101+
$text = $this->formatInternetMessage(strip_tags($text));
86102

87-
$text = $this->formatInternetMessage($text);
88-
$plaintext = $this->formatInternetMessage($plaintext);
103+
$email->html($html);
104+
$email->text($text);
89105

90-
$mail->setBody($text, 'text/html', 'utf-8');
91-
$mail->addPart($plaintext, 'text/plain', 'utf-8');
92-
foreach ($attachedResources as $resource) {
106+
foreach ($attachedResources as $name => $resource) {
93107
if ($resource instanceof PersistentResource) {
94-
if ($swiftAttachment = $this->createSwiftAttachmentFromPersistentResource($resource)) {
95-
$mail->attach($swiftAttachment);
108+
if ($path = $this->getPathFromPersistentResource($resource)) {
109+
$email->attachFromPath($path, $resource->getFilename(), $resource->getMediaType());
96110
}
97-
} elseif ($resource instanceof Swift_Attachment) {
98-
$mail->attach($resource);
111+
} elseif (is_string($resource) && is_string($name)) {
112+
$email->attach($resource, $name, 'text/plain');
99113
}
100114
}
101115

102-
$acceptedRecipients = $mail->send();
103-
if ($acceptedRecipients <= 0) {
104-
throw new Exception('Sending SwiftMessage failed', 1570541189);
105-
}
106-
}
107-
108-
/**
109-
* Embed images. I.e:
110-
* <img height="40px" src="###IMAGE:'{template.logo}'###" alt="Logo"/>
111-
*
112-
* @param string $html
113-
* @param Swift_Message $mail
114-
* @return string $html
115-
*/
116-
private function embedResources(string $html, Swift_Message &$mail): string
117-
{
118-
$html = preg_replace_callback('/###IMAGE:(.+?)###/', function ($matches) use ($mail) {
119-
return $this->embedImageResourceCallback($matches, $mail);
120-
}, $html);
121-
$html = preg_replace_callback('/###PLAIN:(.+?)###/', function ($matches) use ($mail) {
122-
return $this->embedPlainResourceCallback($matches);
123-
}, $html);
124-
125-
return $html;
126-
}
127-
128-
/**
129-
* @param array $matches
130-
* @param \Swift_Message $mail
131-
* @return string
132-
*/
133-
private function embedImageResourceCallback(array $matches, Swift_Message &$mail): string
134-
{
135-
$cid = '';
136-
if (isset($matches[1])) {
137-
$source = trim($matches[1], '\'');
138-
try {
139-
$cid = $mail->embed(Swift_Image::fromPath($source));
140-
} catch (\Exception $e) {
141-
// Nothing to do here
142-
}
143-
}
144-
return $cid;
145-
}
146-
147-
/**
148-
* @param array $matches
149-
* @return string
150-
*/
151-
private function embedPlainResourceCallback(array $matches): string
152-
{
153-
$plain = '';
154-
if (isset($matches[1])) {
155-
$source = trim($matches[1], '\'');
156-
try {
157-
$plain = file_get_contents($source);
158-
} catch (\Exception $e) {
159-
// Nothing to do here
160-
}
161-
}
162-
return $plain;
116+
$mailer = $this->mailerService->getMailer();
117+
$mailer->send($email);
163118
}
164119

165120
/**
@@ -180,18 +135,24 @@ private function formatInternetMessage(string $text): string
180135
return implode(PHP_EOL, $lines);
181136
}
182137

183-
public function createSwiftAttachmentFromPersistentResource(PersistentResource $resource): ?Swift_Attachment
138+
public function getPathFromPersistentResource(PersistentResource $resource): ?string
184139
{
185140
if (!is_string($resource->getSha1())) {
186141
// Throw exception to prevent type error on getCacheEntryIdentifier(): "Return value must be of type string, null returned"
187142
throw new ResourceException('No sha1 set in persistent resource', 1733826832);
188143
}
189144

190145
// No exception handling here. This provides flexibility to handle it outside or by aspects
191-
$path = $resource->createTemporaryLocalCopy();
192-
$attachment = Swift_Attachment::fromPath($path, $resource->getMediaType());
193-
$attachment->setFilename($resource->getFilename());
146+
return $resource->createTemporaryLocalCopy();
147+
}
148+
149+
/**
150+
* @param array<string, string> $array
151+
*/
152+
protected function arrayToAddress(array $array): Address
153+
{
154+
$email = (string)array_key_first($array);
194155

195-
return $attachment;
156+
return new Address($email, $array[$email]);
196157
}
197158
}

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
],
1515
"require": {
1616
"neos/flow": "^7.0 || ^8.0",
17-
"neos/swiftmailer": "~7.0"
17+
"neos/symfonymailer": "^0.1"
1818
},
1919
"name": "swisscom/communicationdispatcher",
2020
"autoload": {
@@ -60,7 +60,6 @@
6060
"Neos.Media-20161219094126",
6161
"Neos.Flow-20170125103800",
6262
"Neos.Flow-20170127183102",
63-
"Neos.SwiftMailer-20161130105617",
6463
"TYPO3.TYPO3CR-130523180140",
6564
"TYPO3.TYPO3CR-140911160326",
6665
"TYPO3.TYPO3CR-141101082142",

0 commit comments

Comments
 (0)