Skip to content

Commit a4ecec2

Browse files
committed
[FEATURE] Use FluidEmail instead of MailMessage for the email4link mails to improve mail styling possibilities
1 parent 15f8439 commit a4ecec2

9 files changed

Lines changed: 153 additions & 146 deletions

File tree

Classes/Domain/Service/Email/SendAssetEmail4LinkService.php

Lines changed: 35 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212
use In2code\Lux\Utility\StringUtility;
1313
use In2code\Lux\Utility\UrlUtility;
1414
use Psr\EventDispatcher\EventDispatcherInterface;
15-
use TYPO3\CMS\Core\Mail\MailMessage;
15+
use Symfony\Component\Mime\Address;
16+
use TYPO3\CMS\Core\Http\ServerRequest;
17+
use TYPO3\CMS\Core\Mail\FluidEmail;
18+
use TYPO3\CMS\Core\Mail\MailerInterface;
1619
use TYPO3\CMS\Core\Resource\File;
1720
use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
1821
use TYPO3\CMS\Core\Resource\StorageRepository;
1922
use TYPO3\CMS\Core\Utility\GeneralUtility;
2023
use TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException;
21-
use TYPO3\CMS\Fluid\View\StandaloneView;
2224

2325
class SendAssetEmail4LinkService
2426
{
@@ -44,57 +46,46 @@ public function __construct(Visitor $visitor, array $settings)
4446
$this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
4547
}
4648

47-
/**
48-
* @param string $href
49-
* @param File|null $file
50-
* @return void
51-
* @throws InvalidConfigurationTypeException
52-
*/
5349
public function sendMail(string $href, ?File $file): void
5450
{
5551
$this->href = $href;
5652
$this->file = $file;
5753
if ($this->visitor->isNotBlacklisted()) {
5854
if ($this->isActivatedAndAllowed()) {
5955
$this->send();
60-
$this->eventDispatcher->dispatch(
61-
GeneralUtility::makeInstance(LogEmail4linkSendEmailEvent::class, $this->visitor, $this->href)
62-
);
56+
$this->eventDispatcher->dispatch(new LogEmail4linkSendEmailEvent($this->visitor, $this->href));
6357
} else {
64-
$this->eventDispatcher->dispatch(
65-
GeneralUtility::makeInstance(LogEmail4linkSendEmailFailedEvent::class, $this->visitor, $this->href)
66-
);
58+
$this->eventDispatcher->dispatch(new LogEmail4linkSendEmailFailedEvent($this->visitor, $this->href));
6759
}
6860
}
6961
}
7062

71-
/**
72-
* @return void
73-
* @throws InvalidConfigurationTypeException
74-
*/
7563
protected function send(): void
7664
{
77-
$message = GeneralUtility::makeInstance(MailMessage::class);
78-
$message
79-
->setTo([$this->visitor->getEmail() => 'Receiver'])
80-
->setFrom($this->getSender())
81-
->setSubject($this->getSubject())
82-
->attachFromPath(GeneralUtility::getFileAbsFileName(UrlUtility::convertToRelative($this->href)))
83-
->html($this->getMailTemplate());
84-
$this->setBcc($message);
85-
$this->eventDispatcher->dispatch(
86-
GeneralUtility::makeInstance(SetAssetEmail4LinkEvent::class, $this->visitor, $message, $this->href)
65+
/** @var SetAssetEmail4LinkEvent $event */
66+
$event = $this->eventDispatcher->dispatch(
67+
new SetAssetEmail4LinkEvent($this->visitor, $this->href, $this->file)
8768
);
88-
$message->send();
69+
$mail = GeneralUtility::makeInstance(FluidEmail::class);
70+
$mail
71+
->to($this->visitor->getEmail())
72+
->from($this->getSender())
73+
->format(FluidEmail::FORMAT_BOTH)
74+
->setTemplate('Email4Link')
75+
->assignMultiple([
76+
'href' => $event->getHref(),
77+
'visitor' => $event->getVisitor(),
78+
'file' => $event->getFile(),
79+
'request' => $this->getRequest(),
80+
])
81+
->attachFromPath(GeneralUtility::getFileAbsFileName(UrlUtility::convertToRelative($event->getHref())));
82+
$this->setBcc($mail);
83+
GeneralUtility::makeInstance(MailerInterface::class)->send($mail);
8984
}
9085

91-
/**
92-
* @param MailMessage $message
93-
* @return void
94-
*/
95-
protected function setBcc(MailMessage $message): void
86+
protected function setBcc(FluidEmail $mail): void
9687
{
97-
if (!empty($this->settings['identification']['email4link']['mail']['bccEmail'])) {
88+
if (($this->settings['identification']['email4link']['mail']['bccEmail'] ?? '') !== '') {
9889
$bcc = [];
9990
$emails = GeneralUtility::trimExplode(
10091
',',
@@ -103,55 +94,19 @@ protected function setBcc(MailMessage $message): void
10394
);
10495
foreach ($emails as $email) {
10596
if (GeneralUtility::validEmail($email)) {
106-
$bcc = array_merge($bcc, [$email => 'Receiver']);
97+
$bcc[] = new Address($email);
10798
}
10899
}
109-
$message->setBcc($bcc);
100+
$mail->bcc(...$bcc);
110101
}
111102
}
112103

113-
/**
114-
* @return string
115-
* @throws InvalidConfigurationTypeException
116-
*/
117-
protected function getMailTemplate(): string
118-
{
119-
$mailTemplatePath = $this->configurationService->getTypoScriptSettingsByPath(
120-
'identification.email4link.mail.mailTemplate'
121-
);
122-
$standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
123-
$standaloneView->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($mailTemplatePath));
124-
$standaloneView->assignMultiple([
125-
'href' => $this->href,
126-
'visitor' => $this->visitor,
127-
'file' => $this->file,
128-
]);
129-
return $standaloneView->render();
130-
}
131-
132-
/**
133-
* @return array
134-
* @throws InvalidConfigurationTypeException
135-
*/
136-
protected function getSender(): array
104+
protected function getSender(): Address
137105
{
138106
$configuration = $this->configurationService->getTypoScriptSettingsByPath('identification.email4link.mail');
139-
return [$configuration['fromEmail'] => $configuration['fromName']];
107+
return new Address($configuration['fromEmail'], $configuration['fromName']);
140108
}
141109

142-
/**
143-
* @return string
144-
* @throws InvalidConfigurationTypeException
145-
*/
146-
protected function getSubject(): string
147-
{
148-
return $this->configurationService->getTypoScriptSettingsByPath('identification.email4link.mail.subject');
149-
}
150-
151-
/**
152-
* @return bool
153-
* @throws InvalidConfigurationTypeException
154-
*/
155110
protected function isActivatedAndAllowed(): bool
156111
{
157112
return $this->isEnabled()
@@ -162,20 +117,12 @@ protected function isActivatedAndAllowed(): bool
162117
&& $this->visitor->isIdentified();
163118
}
164119

165-
/**
166-
* @return bool
167-
* @throws InvalidConfigurationTypeException
168-
*/
169120
protected function isEnabled(): bool
170121
{
171122
$path = 'identification.email4link.mail._enable';
172123
return $this->configurationService->getTypoScriptSettingsByPath($path) === '1';
173124
}
174125

175-
/**
176-
* @return bool
177-
* @throws InvalidConfigurationTypeException
178-
*/
179126
protected function isAllowedFileExtension(): bool
180127
{
181128
$allowed = false;
@@ -221,4 +168,9 @@ protected function isFileExisting(): bool
221168
{
222169
return file_exists(GeneralUtility::getFileAbsFileName(UrlUtility::convertToRelative($this->href)));
223170
}
171+
172+
protected function getRequest(): ?ServerRequest
173+
{
174+
return $GLOBALS['TYPO3_REQUEST'] ?? null;
175+
}
224176
}

Classes/Events/SetAssetEmail4LinkEvent.php

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,41 @@
44
namespace In2code\Lux\Events;
55

66
use In2code\Lux\Domain\Model\Visitor;
7-
use TYPO3\CMS\Core\Mail\MailMessage;
7+
use TYPO3\CMS\Core\Resource\File;
88

99
final class SetAssetEmail4LinkEvent
1010
{
11-
protected Visitor $visitor;
12-
protected MailMessage $mailMessage;
11+
public function __construct(
12+
private readonly Visitor $visitor,
13+
private string $href,
14+
private File $file
15+
) {
16+
}
1317

14-
protected string $href = '';
18+
public function getVisitor(): Visitor
19+
{
20+
return $this->visitor;
21+
}
1522

16-
public function __construct(Visitor $visitor, MailMessage $mailMessage, string $href)
23+
public function getHref(): string
1724
{
18-
$this->visitor = $visitor;
19-
$this->mailMessage = $mailMessage;
20-
$this->href = $href;
25+
return $this->href;
2126
}
2227

23-
public function getVisitor(): Visitor
28+
public function setHref(string $href): self
2429
{
25-
return $this->visitor;
30+
$this->href = $href;
31+
return $this;
2632
}
2733

28-
public function getMailMessage(): MailMessage
34+
public function getFile(): File
2935
{
30-
return $this->mailMessage;
36+
return $this->file;
3137
}
3238

33-
public function getHref(): string
39+
public function setFile(File $file): self
3440
{
35-
return $this->href;
41+
$this->file = $file;
42+
return $this;
3643
}
3744
}

Configuration/TypoScript/Lux/02_IdentificationConfiguration.typoscript

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,14 @@ lib.lux.settings {
129129
# Enable/Disable
130130
_enable = 1
131131

132-
# Template file for mail with asset attachment
133-
mailTemplate = EXT:lux/Resources/Private/Templates/Mail/Email4LinkMail.html
134-
135-
# Mail subject
136-
subject = Your requested asset
137-
138132
# From name for mail to visitor
139133
fromName = {$plugin.tx_lux.settings.email.defaultSenderName}
140134

141135
# From email for mail to visitor
142136
fromEmail = {$plugin.tx_lux.settings.email.defaultSenderEmail}
143137

144138
# Send a blind copy to any receivers (can be a commaseparated email list)
145-
bccEmail =
139+
bccEmail = sandra@in2code.de
146140

147141
# Allow only files with this extensions
148142
allowedFileExtensions = pdf,txt,doc,docx,xls,xlsx,ppt,pptx,jpg,png,zip

Documentation/Technical/FAQ/Index.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ lib.lux.settings {
6565
# Define your own email4link configuration
6666
email4link.mail {
6767
_enable = 1
68-
mailTemplate = EXT:sitepackage/Resources/Private/Templates/Extensions/Lux/Mail/Email4LinkMail.html
69-
subject = Email from your company
7068
fromName = Service
7169
fromEmail = service@yourcompany.com
7270
bccEmail = bcc@yourcompany.com

Documentation/Technical/Identification/Index.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,6 @@ lib.lux.settings {
342342
# Enable/Disable
343343
_enable = 1
344344
345-
# Template file for mail with asset attachment
346-
mailTemplate = EXT:lux/Resources/Private/Templates/Mail/Email4LinkMail.html
347-
348-
# Mail subject
349-
subject = Your requested asset
350-
351345
# From name for mail to visitor
352346
fromName = {$plugin.tx_lux.settings.email.defaultSenderName}
353347
@@ -411,6 +405,24 @@ After that, you can copy the original file from `EXT:lux/Resources/Private/Templ
411405
to the template and can be re-used there with `{download.arguments.foo}`
412406

413407

408+
##### Change templates of the mail
409+
410+
Since email4link is using FluidEmail class, mails are styled TYPO3-wide automatically. If you want to overrule the
411+
template, add such a line to your ext_localconf.php of your sitepackage:
412+
413+
```
414+
// Number must be higher then 1762935800
415+
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths'][1762935801] = 'EXT:sitepackage/Resources/Private/Templates/Mail/';
416+
```
417+
418+
After that you can copy the exixting files `Email4Link.html` and `Email4Link.txt` from
419+
`EXT:lux/Resources/Private/Templates/Mail/` to the new path of your sitepackage and modify it to your needs.
420+
421+
If you also want to change the wrapping layout of your mails, you could do it like:
422+
`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['layoutRootPaths'][1762935801] = 'EXT:sitepackage/Resources/Private/Layouts/Mail/';`
423+
After that you need to copy files `SystemEmail.*` from TYPO3 to the new path and update the files.
424+
425+
414426
#### 4. Frontend login of a frontend user
415427

416428
If a frontend user logs in into TYPO3, lux automatically creates a relation to this user. If the field
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<f:layout name="SystemEmail" />
2+
3+
Available variables:
4+
- {href} like "fileadmin/file.pdf"
5+
- {file} File object: {file.publicUrl} for complete URL, {file.name} for filename, etc...
6+
- {visitor} Visitor object
7+
- {request.attributes.site} Get site configuration object
8+
- {request.attributes.language} Get site language object ({request.attributes.language.typo3Language} for "de")
9+
10+
<f:section name="Subject">
11+
Your requested whitepaper
12+
</f:section>
13+
14+
<f:section name="Main">
15+
<h2>Your requested whitepaper</h2>
16+
17+
<p>
18+
We’ve attached the requested whitepaper to this message.
19+
<f:if condition="{file}">
20+
Alternatively, you can <f:link.typolink parameter="{file.publicUrl}" absolute="1">download it directly</f:link.typolink>.
21+
</f:if>
22+
</p>
23+
<p>
24+
If you have any questions or need further information, please don’t hesitate to contact us.
25+
</p>
26+
27+
<p>
28+
--<br /><br />
29+
30+
Firstname Lastname<br />
31+
Marketing<br /><br /><br />
32+
33+
34+
company name<br /><br />
35+
36+
Street 12a · D-ZIPCODE City<br />
37+
Email: firstname.lastname@company.org<br />
38+
Telefon: +49(0) 1234 56789<br />
39+
Mobil: +49(0) 1234 56789<br />
40+
Fax: +49(0) 1234 56789<br />
41+
Website: https://www.company.org
42+
</p>
43+
</f:section>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<f:layout name="SystemEmail" />
2+
3+
<f:section name="Subject">
4+
Your requested whitepaper
5+
</f:section>
6+
7+
<f:section name="Main">
8+
Your requested whitepaper
9+
10+
We’ve attached the requested whitepaper to this message.
11+
<f:if condition="{file}">Alternatively, you can download it directly via the following link: <f:uri.typolink parameter="{file.publicUrl}" absolute="1" /></f:if>
12+
13+
If you have any questions or need further information, please don’t hesitate to contact us.
14+
15+
--
16+
17+
Firstname Lastname
18+
Marketing
19+
20+
21+
company name
22+
23+
Street 12a · D-ZIPCODE City
24+
Email: firstname.lastname@company.org
25+
Telefon: +49(0) 1234 56789
26+
Mobil: +49(0) 1234 56789
27+
Fax: +49(0) 1234 56789
28+
Website: https://www.company.org
29+
</f:section>

0 commit comments

Comments
 (0)