1
|
|
|
<?php |
2
|
|
|
namespace Azine\EmailBundle\Services; |
3
|
|
|
|
4
|
|
|
use Symfony\Component\Routing\RequestContext; |
5
|
|
|
use Symfony\Component\HttpFoundation\File\Exception\FileException; |
6
|
|
|
use Doctrine\ORM\EntityManager; |
7
|
|
|
use Azine\EmailBundle\Entity\SentEmail; |
8
|
|
|
use Azine\EmailBundle\DependencyInjection\AzineEmailExtension; |
9
|
|
|
use Symfony\Bundle\FrameworkBundle\Translation\Translator; |
10
|
|
|
use Monolog\Logger; |
11
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
12
|
|
|
use FOS\UserBundle\Mailer\TwigSwiftMailer; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* This Service is used to send html-emails with embedded images |
16
|
|
|
* @author Dominik Businger |
17
|
|
|
*/ |
18
|
|
|
class AzineTwigSwiftMailer extends TwigSwiftMailer implements TemplateTwigSwiftMailerInterface |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* @var Translator |
22
|
|
|
*/ |
23
|
|
|
protected $translator; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var Logger |
27
|
|
|
*/ |
28
|
|
|
protected $logger; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var TemplateProviderInterface |
32
|
|
|
*/ |
33
|
|
|
protected $templateProvider; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var EntityManager |
37
|
|
|
*/ |
38
|
|
|
protected $entityManager; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* |
42
|
|
|
* @var RequestContext |
43
|
|
|
*/ |
44
|
|
|
protected $routerContext; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var email to use for "no-reply" |
48
|
|
|
*/ |
49
|
|
|
protected $noReplyEmail; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @var name to use for "no-reply" |
53
|
|
|
*/ |
54
|
|
|
protected $noReplyName; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* The Swift_Mailer to be used for sending emails immediately |
58
|
|
|
* @var \Swift_Mailer |
59
|
|
|
*/ |
60
|
|
|
private $immediateMailer; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @var EmailOpenTrackingCodeBuilderInterface |
64
|
|
|
*/ |
65
|
|
|
private $emailOpenTrackingCodeBuilder; |
66
|
|
|
|
67
|
|
|
private $encodedItemIdPattern; |
68
|
|
|
private $currentHost; |
69
|
|
|
private $templateCache = array(); |
70
|
|
|
private $imageCache = array(); |
71
|
|
|
|
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* |
75
|
|
|
* @param \Swift_Mailer $mailer |
76
|
|
|
* @param UrlGeneratorInterface $router |
77
|
|
|
* @param \Twig_Environment $twig |
78
|
|
|
* @param Logger $logger |
79
|
|
|
* @param Translator $translator |
80
|
|
|
* @param array $parameters |
81
|
|
|
* @param \Swift_Mailer $immediateMailer |
82
|
|
|
*/ |
83
|
7 |
|
public function __construct( \Swift_Mailer $mailer, |
84
|
|
|
UrlGeneratorInterface $router, |
85
|
|
|
\Twig_Environment $twig, |
86
|
|
|
Logger $logger, |
87
|
|
|
Translator $translator, |
88
|
|
|
TemplateProviderInterface $templateProvider, |
89
|
|
|
EntityManager $entityManager, |
|
|
|
|
90
|
|
|
EmailOpenTrackingCodeBuilderInterface $emailOpenTrackingCodeBuilder, |
91
|
|
|
array $parameters, |
92
|
|
|
\Swift_Mailer $immediateMailer = null) |
93
|
|
|
{ |
94
|
7 |
|
parent::__construct($mailer, $router, $twig, $parameters); |
95
|
7 |
|
$this->immediateMailer = $immediateMailer; |
96
|
7 |
|
$this->logger = $logger; |
97
|
7 |
|
$this->translator = $translator; |
98
|
7 |
|
$this->templateProvider = $templateProvider; |
99
|
7 |
|
$this->entityManager = $entityManager; |
100
|
7 |
|
$this->noReplyEmail = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_ADDRESS]; |
101
|
7 |
|
$this->noReplyName = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_NAME]; |
102
|
7 |
|
$this->emailOpenTrackingCodeBuilder = $emailOpenTrackingCodeBuilder; |
103
|
7 |
|
$this->routerContext = $router->getContext(); |
104
|
7 |
|
$this->currentHost = $this->routerContext->getHost(); |
105
|
7 |
|
$this->encodedItemIdPattern = "/^cid:.*@/"; |
106
|
7 |
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* (non-PHPdoc) |
110
|
|
|
* @see Azine\EmailBundle\Services.TemplateTwigSwiftMailerInterface::sendEmail() |
111
|
|
|
*/ |
112
|
7 |
|
public function sendEmail(&$failedRecipients, $subject, $from, $fromName, $to, $toName, $cc, $ccName, $bcc, $bccName, $replyTo, $replyToName, array $params, $template, $attachments = array(), $emailLocale = null, \Swift_Message &$message = null) |
113
|
|
|
{ |
114
|
|
|
// create the message |
115
|
7 |
|
if ($message == null) { |
116
|
7 |
|
$message = \Swift_Message::newInstance(); |
117
|
7 |
|
} |
118
|
|
|
|
119
|
7 |
|
$message->setSubject($subject); |
120
|
|
|
|
121
|
|
|
// set the from-Name & -Emali to the default ones if not given |
122
|
7 |
|
if ($from == null) { |
123
|
4 |
|
$from = $this->noReplyEmail; |
124
|
4 |
|
} |
125
|
7 |
|
if ($fromName == null) { |
126
|
4 |
|
$fromName = $this->noReplyName; |
127
|
4 |
|
} |
128
|
|
|
|
129
|
|
|
// add the from-email for the footer-text |
130
|
7 |
|
if (!array_key_exists('fromEmail', $params)) { |
131
|
7 |
|
$params['sendMailAccountName'] = $this->noReplyName; |
132
|
7 |
|
$params['sendMailAccountAddress'] = $this->noReplyEmail; |
133
|
7 |
|
} |
134
|
|
|
|
135
|
|
|
// get the baseTemplate. => templateId without the ending. |
136
|
7 |
|
$templateBaseId = substr($template, 0, strrpos($template, ".", -6)); |
137
|
|
|
|
138
|
|
|
// check if this email should be stored for web-view |
139
|
7 |
|
if ($this->templateProvider->saveWebViewFor($templateBaseId)) { |
140
|
|
|
// keep a copy of the vars for the web-view |
141
|
4 |
|
$webViewParams = $params; |
142
|
|
|
|
143
|
|
|
// add the web-view token |
144
|
4 |
|
$params[$this->templateProvider->getWebViewTokenId()] = SentEmail::getNewToken(); |
145
|
4 |
|
} else { |
146
|
3 |
|
$webViewParams = array(); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
// recursively add all template-variables for the wrapper-templates and contentItems |
150
|
7 |
|
$params = $this->templateProvider->addTemplateVariablesFor($templateBaseId, $params); |
151
|
|
|
|
152
|
|
|
// recursively attach all messages in the array |
153
|
7 |
|
$this->embedImages($message, $params); |
154
|
|
|
|
155
|
|
|
// change the locale for the email-recipients |
156
|
7 |
|
if ($emailLocale != null) { |
|
|
|
|
157
|
6 |
|
$currentUserLocale = $this->translator->getLocale(); |
158
|
|
|
|
159
|
|
|
// change the router-context locale |
160
|
6 |
|
$this->routerContext->setParameter("_locale", $emailLocale); |
161
|
|
|
|
162
|
|
|
// change the translator locale |
163
|
6 |
|
$this->translator->setLocale($emailLocale); |
164
|
6 |
|
} else { |
165
|
1 |
|
$emailLocale = $this->translator->getLocale(); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
// recursively add snippets for the wrapper-templates and contentItems |
169
|
7 |
|
$params = $this->templateProvider->addTemplateSnippetsWithImagesFor($templateBaseId, $params, $emailLocale); |
170
|
|
|
|
171
|
|
|
// add the emailLocale (used for web-view) |
172
|
7 |
|
$params['emailLocale'] = $emailLocale; |
173
|
|
|
|
174
|
|
|
// render the email parts |
175
|
7 |
|
$twigTemplate = $this->loadTemplate($template); |
176
|
7 |
|
$textBody = $twigTemplate->renderBlock('body_text', $params); |
177
|
7 |
|
$message->addPart($textBody, 'text/plain'); |
178
|
|
|
|
179
|
7 |
|
$htmlBody = $twigTemplate->renderBlock('body_html', $params); |
180
|
|
|
|
181
|
7 |
|
$campaignParams = $this->templateProvider->getCampaignParamsFor($templateBaseId, $params); |
182
|
|
|
|
183
|
7 |
|
if (sizeof($campaignParams) > 0) { |
184
|
5 |
|
$htmlBody = AzineEmailTwigExtension::addCampaignParamsToAllUrls($htmlBody, $campaignParams); |
185
|
5 |
|
} |
186
|
|
|
|
187
|
|
|
// if email-tracking is enabled |
188
|
7 |
|
if($this->emailOpenTrackingCodeBuilder){ |
189
|
|
|
// add an image at the end of the html tag with the tracking-params to track email-opens |
190
|
7 |
|
$imgTrackingCode = $this->emailOpenTrackingCodeBuilder->getTrackingImgCode($templateBaseId, $campaignParams, $params, $message->getId(), $to, $cc, $bcc); |
191
|
7 |
|
if($imgTrackingCode && strlen($imgTrackingCode) > 0) { |
192
|
5 |
|
$htmlCloseTagPosition = strpos($htmlBody, "</body>"); |
193
|
5 |
|
$htmlBody = substr_replace($htmlBody, $imgTrackingCode, $htmlCloseTagPosition, 0); |
194
|
5 |
|
} |
195
|
7 |
|
} |
196
|
|
|
|
197
|
7 |
|
$message->setBody($htmlBody, 'text/html'); |
198
|
|
|
|
199
|
|
|
// remove unused/unreferenced embeded items from the message |
200
|
7 |
|
$message = $this->removeUnreferecedEmbededItemsFromMessage($message, $params, $htmlBody); |
201
|
|
|
|
202
|
|
|
// change the locale back to the users locale |
203
|
7 |
|
if (isset($currentUserLocale) && $currentUserLocale != null) { |
204
|
6 |
|
$this->routerContext->setParameter("_locale", $currentUserLocale); |
205
|
6 |
|
$this->translator->setLocale($currentUserLocale); |
206
|
6 |
|
} |
207
|
|
|
|
208
|
|
|
// add attachments |
209
|
7 |
|
foreach ($attachments as $fileName => $file) { |
210
|
|
|
|
211
|
|
|
// add attachment from existing file |
212
|
2 |
|
if (is_string($file)) { |
213
|
|
|
|
214
|
|
|
// check that the file really exists! |
215
|
2 |
|
if (file_exists($file)) { |
216
|
1 |
|
$attachment = \Swift_Attachment::fromPath($file); |
217
|
1 |
|
if (strlen($fileName) >= 5 ) { |
218
|
1 |
|
$attachment->setFilename($fileName); |
219
|
1 |
|
} |
220
|
1 |
|
} else { |
221
|
1 |
|
throw new FileException("File not found: ".$file); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
// add attachment from generated data |
225
|
1 |
|
} else { |
226
|
1 |
|
$attachment = \Swift_Attachment::newInstance($file, $fileName); |
227
|
|
|
} |
228
|
|
|
|
229
|
1 |
|
$message->attach($attachment); |
230
|
6 |
|
} |
231
|
|
|
|
232
|
|
|
// set the addresses |
233
|
6 |
|
if ($from) { |
234
|
6 |
|
$message->setFrom($from, $fromName); |
235
|
6 |
|
} |
236
|
6 |
|
if ($replyTo) { |
237
|
2 |
|
$message->setReplyTo($replyTo, $replyToName); |
238
|
6 |
|
} elseif ($from) { |
239
|
4 |
|
$message->setReplyTo($from, $fromName); |
240
|
4 |
|
} |
241
|
6 |
|
if ($to) { |
242
|
6 |
|
$message->setTo($to, $toName); |
243
|
6 |
|
} |
244
|
6 |
|
if ($cc) { |
245
|
2 |
|
$message->setCc($cc, $ccName); |
246
|
2 |
|
} |
247
|
6 |
|
if ($bcc) { |
248
|
2 |
|
$message->setBcc($bcc, $bccName); |
249
|
2 |
|
} |
250
|
|
|
|
251
|
|
|
// add custom headers |
252
|
6 |
|
$this->templateProvider->addCustomHeaders($templateBaseId, $message, $params); |
253
|
|
|
|
254
|
|
|
// send the message |
255
|
6 |
|
$mailer = $this->getMailer($params); |
256
|
6 |
|
$messagesSent = $mailer->send($message, $failedRecipients); |
257
|
|
|
|
258
|
|
|
// if the message was successfully sent, |
259
|
|
|
// and it should be made available in web-view |
260
|
6 |
|
if ($messagesSent && array_key_exists($this->templateProvider->getWebViewTokenId(), $params)) { |
261
|
|
|
|
262
|
|
|
// store the email |
263
|
2 |
|
$sentEmail = new SentEmail(); |
264
|
2 |
|
$sentEmail->setToken($params[$this->templateProvider->getWebViewTokenId()]); |
265
|
2 |
|
$sentEmail->setTemplate($templateBaseId); |
266
|
2 |
|
$sentEmail->setSent(new \DateTime()); |
267
|
|
|
|
268
|
|
|
// recursively add all template-variables for the wrapper-templates and contentItems |
269
|
2 |
|
$webViewParams = $this->templateProvider->addTemplateVariablesFor($template, $webViewParams); |
270
|
|
|
|
271
|
|
|
// replace absolute image-paths with relative ones. |
272
|
2 |
|
$webViewParams = $this->templateProvider->makeImagePathsWebRelative($webViewParams, $emailLocale); |
273
|
|
|
|
274
|
|
|
// recursively add snippets for the wrapper-templates and contentItems |
275
|
2 |
|
$webViewParams = $this->templateProvider->addTemplateSnippetsWithImagesFor($template, $webViewParams, $emailLocale, true); |
276
|
|
|
|
277
|
2 |
|
$sentEmail->setVariables($webViewParams); |
278
|
|
|
|
279
|
|
|
// save only successfull recipients |
280
|
2 |
|
if (!is_array($to)) { |
281
|
2 |
|
$to = array($to); |
282
|
2 |
|
} |
283
|
2 |
|
$successfulRecipients = array_diff($to, $failedRecipients); |
284
|
2 |
|
$sentEmail->setRecipients($successfulRecipients); |
285
|
|
|
|
286
|
|
|
// write to db |
287
|
2 |
|
$this->entityManager->persist($sentEmail); |
288
|
2 |
|
$this->entityManager->flush($sentEmail); |
289
|
2 |
|
} |
290
|
|
|
|
291
|
6 |
|
return $messagesSent; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* Remove all Embeded Attachments that are not referenced in the html-body from the message |
296
|
|
|
* to avoid using unneccary bandwidth. |
297
|
|
|
* |
298
|
|
|
* @param \Swift_Message $message |
299
|
|
|
* @param array $params the parameters used to render the html |
300
|
|
|
* @param string $htmlBody |
301
|
|
|
* @return \Swift_Message |
302
|
|
|
*/ |
303
|
7 |
|
private function removeUnreferecedEmbededItemsFromMessage(\Swift_Message $message, $params, $htmlBody) |
304
|
|
|
{ |
305
|
7 |
|
foreach ($params as $key => $value) { |
306
|
|
|
// remove unreferenced attachments from contentItems too. |
307
|
7 |
|
if ($key === 'contentItems') { |
308
|
2 |
|
foreach ($value as $contentItemParams) { |
309
|
2 |
|
$message = $this->removeUnreferecedEmbededItemsFromMessage($message, $contentItemParams, $htmlBody); |
310
|
2 |
|
} |
311
|
2 |
|
} else { |
312
|
|
|
|
313
|
|
|
// check if the embeded items are referenced in the templates |
314
|
7 |
|
$isEmbededItem = is_string($value) && preg_match($this->encodedItemIdPattern, $value) == 1; |
315
|
|
|
|
316
|
7 |
|
if ($isEmbededItem && stripos($htmlBody, $value) === false) { |
317
|
|
|
// remove unreferenced items |
318
|
7 |
|
$children = array(); |
319
|
|
|
|
320
|
7 |
|
foreach ($message->getChildren() as $attachment) { |
321
|
7 |
|
if ("cid:".$attachment->getId() != $value) { |
322
|
7 |
|
$children[] = $attachment; |
323
|
7 |
|
} |
324
|
7 |
|
} |
325
|
|
|
|
326
|
7 |
|
$message->setChildren($children); |
327
|
7 |
|
} |
328
|
|
|
} |
329
|
7 |
|
} |
330
|
|
|
|
331
|
7 |
|
return $message; |
332
|
7 |
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Get the template from the cache if it was loaded already |
336
|
|
|
* @param string $template |
337
|
|
|
* @return \Twig_Template |
338
|
|
|
*/ |
339
|
7 |
|
private function loadTemplate($template) |
340
|
|
|
{ |
341
|
7 |
|
if (!array_key_exists($template, $this->templateCache)) { |
342
|
7 |
|
$this->templateCache[$template] = $this->twig->loadTemplate($template); |
343
|
7 |
|
} |
344
|
|
|
|
345
|
7 |
|
return $this->templateCache[$template]; |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* Recursively embed all images in the array into the message |
350
|
|
|
* @param \Swift_Message $message |
351
|
|
|
* @param array $params |
352
|
|
|
* @return array $params |
353
|
|
|
*/ |
354
|
7 |
|
private function embedImages(&$message, &$params) |
355
|
|
|
{ |
356
|
|
|
// loop throug the array |
357
|
7 |
|
foreach ($params as $key => $value) { |
358
|
|
|
|
359
|
|
|
// if the current value is an array |
360
|
7 |
|
if (is_array($value)) { |
361
|
|
|
// search for more images deeper in the arrays |
362
|
2 |
|
$value = $this->embedImages($message, $value); |
363
|
2 |
|
$params[$key] = $value; |
364
|
|
|
|
365
|
|
|
// if the current value is an existing file from the image-folder, embed it |
366
|
7 |
|
} elseif (is_string($value)) { |
367
|
7 |
|
if (is_file($value)) { |
368
|
|
|
|
369
|
|
|
// check if the file is from an allowed folder |
370
|
7 |
|
if ($this->templateProvider->isFileAllowed($value) !== false) { |
371
|
7 |
|
$encodedImage = $this->cachedEmbedImage($value); |
372
|
7 |
|
if ($encodedImage != null) { |
373
|
7 |
|
$id = $message->embed($encodedImage); |
374
|
7 |
|
$params[$key] = $id; |
375
|
7 |
|
} |
376
|
7 |
|
} |
377
|
|
|
|
378
|
|
|
// the $filePath isn't a regular file |
379
|
7 |
|
} else { |
380
|
|
|
// ignore the imageDir itself, but log all other directories and symlinks that were not embeded |
381
|
7 |
|
if ($value != $this->templateProvider->getTemplateImageDir() ) { |
382
|
7 |
|
$this->logger->info("'$value' is not a regular file and will not be embeded in the email."); |
383
|
7 |
|
} |
384
|
|
|
|
385
|
|
|
// add a null-value to the cache for this path, so we don't try again. |
386
|
7 |
|
$this->imageCache[$value] = null; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
//if the current value is a generated image |
390
|
7 |
|
} elseif (is_resource($value) && stripos(get_resource_type($value), "gd") == 0) { |
391
|
|
|
// get the image-data as string |
392
|
1 |
|
ob_start(); |
393
|
1 |
|
imagepng($value); |
394
|
1 |
|
$imageData = ob_get_clean(); |
395
|
|
|
|
396
|
|
|
// encode the image |
397
|
1 |
|
$encodedImage = \Swift_Image::newInstance($imageData, "generatedImage".md5($imageData)); |
398
|
1 |
|
$id = $message->embed($encodedImage); |
399
|
1 |
|
$params[$key] = $id; |
400
|
1 |
|
} else { |
401
|
|
|
// don't do anything |
402
|
|
|
} |
403
|
7 |
|
} |
404
|
|
|
|
405
|
|
|
// remove duplicate-attachments |
406
|
7 |
|
$message->setChildren(array_unique($message->getChildren())); |
407
|
|
|
|
408
|
7 |
|
return $params; |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
/** |
412
|
|
|
* Get the Swift_Image for the file. |
413
|
|
|
* @param string $filePath |
414
|
|
|
* @return \Swift_Image|null |
415
|
|
|
*/ |
416
|
7 |
|
private function cachedEmbedImage($filePath) |
417
|
|
|
{ |
418
|
7 |
|
$filePath = realpath($filePath); |
419
|
7 |
|
if (!array_key_exists($filePath, $this->imageCache)) { |
420
|
7 |
|
if (is_file($filePath)) { |
421
|
|
|
|
422
|
7 |
|
$image = \Swift_Image::fromPath($filePath); |
423
|
7 |
|
$id = $image->getId(); |
424
|
|
|
|
425
|
|
|
// log an error if the image could not be embedded properly |
426
|
7 |
|
if ($id == $filePath) { // $id and $value must not be the same => this happens if the file cannot be found/read |
427
|
|
|
// @codeCoverageIgnoreStart |
428
|
|
|
// log error |
429
|
|
|
$this->logger->error('The image $value was not correctly embedded in the email.', array('image' => $filePath, 'resulting id' => $id)); |
430
|
|
|
// add a null-value to the cache for this path, so we don't try again. |
431
|
|
|
$this->imageCache[$filePath] = null; |
432
|
|
|
|
433
|
|
|
} else { |
434
|
|
|
// @codeCoverageIgnoreEnd |
435
|
|
|
// add the image to the cache |
436
|
7 |
|
$this->imageCache[$filePath] = $image; |
437
|
|
|
} |
438
|
|
|
|
439
|
7 |
|
} |
440
|
|
|
|
441
|
7 |
|
} |
442
|
|
|
|
443
|
7 |
|
return $this->imageCache[$filePath]; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* (non-PHPdoc) |
448
|
|
|
* @see Azine\EmailBundle\Services.TemplateTwigSwiftMailerInterface::sendSingleEmail() |
449
|
|
|
*/ |
450
|
4 |
|
public function sendSingleEmail($to, $toName, $subject, array $params, $template, $emailLocale, $from = null, $fromName = null, \Swift_Message &$message = null) |
451
|
|
|
{ |
452
|
4 |
|
$failedRecipients = array(); |
453
|
4 |
|
$this->sendEmail($failedRecipients, $subject, $from, $fromName, $to, $toName, null, null, null, null, null, null, $params, $template, array(), $emailLocale, $message); |
454
|
|
|
|
455
|
4 |
|
return sizeof($failedRecipients) == 0; |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
/** |
459
|
|
|
* Override the fosuserbundles original sendMessage, to embed template variables etc. into html-emails. |
460
|
|
|
* @param string $templateName |
461
|
|
|
* @param array $context |
462
|
|
|
* @param string $fromEmail |
463
|
|
|
* @param string $toEmail |
464
|
|
|
* @return boolean true if the mail was sent successfully, else false |
465
|
|
|
*/ |
466
|
2 |
|
protected function sendMessage($templateName, $context, $fromEmail, $toEmail) |
467
|
|
|
{ |
468
|
|
|
// get the subject from the template |
469
|
|
|
// => make sure the subject block exists in your fos-templates (FOSUserBundle:Registration:email.txt.twig & FOSUserBundle:Resetting:email.txt.twig) |
470
|
2 |
|
$twigTemplate = $this->loadTemplate($templateName); |
471
|
2 |
|
$subject = $twigTemplate->renderBlock('subject', $context); |
472
|
|
|
|
473
|
2 |
|
return $this->sendSingleEmail($toEmail, null, $subject, $context, $templateName, $this->translator->getLocale()); |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
/** |
477
|
|
|
* Return the Swift_Mailer to be used for sending mails immediately (e.g. instead of spooling them) if it is configured |
478
|
|
|
* @param $params |
479
|
|
|
* @return \Swift_Mailer |
480
|
|
|
*/ |
481
|
6 |
|
private function getMailer($params){ |
482
|
|
|
// if the second mailer for immediate mail-delivery has been configured |
483
|
6 |
|
if($this->immediateMailer != null){ |
484
|
|
|
// check if this template has been configured to be sent immediately |
485
|
|
|
if(array_key_exists(AzineTemplateProvider::SEND_IMMEDIATELY_FLAG, $params) && $params[AzineTemplateProvider::SEND_IMMEDIATELY_FLAG]) { |
486
|
|
|
return $this->immediateMailer; |
487
|
|
|
} |
488
|
|
|
} |
489
|
6 |
|
return $this->mailer; |
490
|
|
|
} |
491
|
|
|
} |
492
|
|
|
|
The
EntityManager
might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManager
is closed. Any other code which depends on the same instance of theEntityManager
during this request will fail.On the other hand, if you instead inject the
ManagerRegistry
, thegetManager()
method guarantees that you will always get a usable manager instance.