diff --git a/config/services.yaml b/config/services.yaml
index e95ee04e..11dafd66 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -122,6 +122,8 @@ services:
OpenDxp\Bundle\AdminBundle\Service\Element\ElementDraftService: ~
OpenDxp\Bundle\AdminBundle\Service\Element\EditLockService: ~
+ OpenDxp\Bundle\AdminBundle\Service\Email\UnusableRecipientDetector: ~
+
OpenDxp\Bundle\AdminBundle\Service\Login\LoginPageService: ~
OpenDxp\Bundle\AdminBundle\Service\Notification\NotificationFilterParser: ~
diff --git a/public/js/opendxp/settings/email/log.js b/public/js/opendxp/settings/email/log.js
index 40cbd894..bd501666 100644
--- a/public/js/opendxp/settings/email/log.js
+++ b/public/js/opendxp/settings/email/log.js
@@ -275,7 +275,7 @@ opendxp.settings.email.log = Class.create({
renderer: function(value, metadata, record) {
var data = record.data.data;
- if (data.type == 'simple') {
+ if (data.type === 'simple') {
return data.value;
} else {
//when the objectPath is set -> the object is still available otherwise it was
@@ -283,7 +283,7 @@ opendxp.settings.email.log = Class.create({
if (data.objectPath) {
var type = data.type;
var subtype = data.objectClassSubType.toLowerCase();
- metadata.tdAttr = 'data-qtip="' + t("open") + '"';
+ metadata.tdAttr = 'data-qtip="' + t('open') + '"';
return ''
+ data.objectPath + '';
@@ -297,10 +297,10 @@ opendxp.settings.email.log = Class.create({
});
this.window = new Ext.Window({
- id: "email_log_params_panel",
+ id: 'email_log_params_panel',
modal: true,
width: 620,
- height: "90%",
+ height: '90%',
title: t('parameters'),
items: [this.tree],
layout: 'fit'
@@ -347,30 +347,21 @@ opendxp.settings.email.log = Class.create({
icon: '/bundles/opendxpadmin/img/flat-color-icons/email.svg',
handler: function (grid, rowIndex) {
var rec = grid.getStore().getAt(rowIndex);
- Ext.Msg.confirm(t('email_log_resend'), t('email_log_resend_window_msg'),
- function(btn){
- if (btn == 'yes'){
- Ext.Ajax.request({
- url: Routing.generate('opendxp_admin_email_resendemail'),
- method: 'POST',
- success: function(response){
- var data = Ext.decode( response.responseText );
- if(data.success){
- Ext.Msg.alert(t('email_log_resend'),
- t('email_log_resend_window_success_message'));
- }else{
- Ext.Msg.alert(t('email_log_resend'),
- t('email_log_resend_window_error_message'));
- }
- },
- failure: function () {
- Ext.Msg.alert(t('email_log_resend'),
- t('email_log_resend_window_error_message'));
- },
- params: { id : rec.get('id') }
- });
- }
- });
+
+ Ext.Ajax.request({
+ url: Routing.generate('opendxp_admin_email_showemaillog', {id: rec.get('id'), type: 'details'}),
+ success: function(response){
+
+ var data = Ext.decode( response.responseText ),
+ win = this.getResendEmailWindow(rec.get('id'), data.documentHasUnusableRecipients);
+
+ win.show();
+
+ }.bind(this),
+ failure: function () {
+ Ext.Msg.alert(t('email_log_resend'), t('email_log_resend_window_error_message'));
+ },
+ });
}.bind(this),
getClass: function(v, meta, rec) {
if(!rec.get('emailLogExistsHtml') && !rec.get('emailLogExistsText') ){
@@ -394,13 +385,15 @@ opendxp.settings.email.log = Class.create({
Ext.Ajax.request({
url: Routing.generate('opendxp_admin_email_showemaillog', {id: rec.get('id'), type: 'details'}),
success: function(response){
- var data = Ext.decode( response.responseText );
- var win = this.getForwardEmailWindow(data);
+
+ var data = Ext.decode( response.responseText ),
+ win = this.getForwardEmailWindow(data.objectVars);
+
win.show();
+
}.bind(this),
failure: function () {
- Ext.Msg.alert(t('email_log_forward'),
- t('email_log_resend_window_error_message'));
+ Ext.Msg.alert(t('email_log_forward'), t('email_log_resend_window_error_message'));
},
});
}.bind(this),
@@ -449,9 +442,11 @@ opendxp.settings.email.log = Class.create({
}
];
- var storeFields = ["id","documentId","subject","emailLogExistsHtml","params","sentDate","params",
- "modificationDate","requestUri","from","to","cc","bcc","emailLogExistsHtml",
- "emailLogExistsText", 'error'];
+ var storeFields = [
+ 'id', 'documentId', 'subject', 'emailLogExistsHtml', 'params', 'sentDate', 'params',
+ 'modificationDate', 'requestUri', 'from', 'to', 'cc', 'bcc', 'emailLogExistsHtml',
+ 'emailLogExistsText', 'error'
+ ];
this.store = opendxp.helpers.grid.buildDefaultStore(
Routing.generate('opendxp_admin_email_emaillogs'),
@@ -508,6 +503,74 @@ opendxp.settings.email.log = Class.create({
},
+ getResendEmailWindow: function (id, documentHasUnusableRecipients) {
+ var win = new Ext.Window({
+ width: 600,
+ modal: true,
+ title: t('email_log_resend'),
+ layout: 'fit',
+ closeAction: 'close',
+ items: [{
+ xtype: 'form',
+ bodyStyle: 'padding:10px;',
+ itemId: 'form',
+ items: [
+ {
+ xtype: 'hiddenfield',
+ name: 'id',
+ value: id
+ },
+ {
+ xtype: 'displayfield',
+ value: t('email_log_resend_window_msg')
+ },
+ {
+ xtype: 'checkbox',
+ name: 'useOriginalRecipients',
+ fieldLabel: t('email_log_resend_use_original_recipients'),
+ checked: documentHasUnusableRecipients,
+ readOnly: documentHasUnusableRecipients
+ },
+ {
+ xtype: 'displayfield',
+ hidden: !documentHasUnusableRecipients,
+ value: t('email_log_resend_use_original_recipients_forced')
+ }
+ ],
+ defaults: {
+ width: 580,
+ labelWidth: 250
+ }
+ }],
+ buttons: [{
+ text: t('send'),
+ iconCls: 'opendxp_icon_email',
+ handler: function () {
+ var params = win.getComponent('form').getForm().getFieldValues();
+ Ext.Ajax.request({
+ url: Routing.generate('opendxp_admin_email_resendemail'),
+ method: 'POST',
+ success: function (response) {
+ var data = Ext.decode(response.responseText);
+ if (data.success) {
+ Ext.Msg.alert(t('email_log_resend'), t('email_log_resend_window_success_message'));
+ win.close();
+ } else {
+ Ext.Msg.alert(t('email_log_resend'), t('email_log_resend_window_error_message'));
+ }
+ },
+ failure: function () {
+ Ext.Msg.alert(t('email_log_resend'), t('email_log_resend_window_error_message'));
+ },
+ params: params
+ });
+ }
+ }]
+ });
+
+ return win;
+ },
+
getForwardEmailWindow: function (data) {
if (data) {
var emailType = data.emailLogExistsHtml ? 'html' : 'text';
@@ -517,13 +580,13 @@ opendxp.settings.email.log = Class.create({
width: 800,
height: 600,
modal: true,
- title: t("email_log_forward"),
- layout: "fit",
- closeAction: "close",
+ title: t('email_log_forward'),
+ layout: 'fit',
+ closeAction: 'close',
items: [{
- xtype: "form",
- bodyStyle: "padding:10px;",
- itemId: "form",
+ xtype: 'form',
+ bodyStyle: 'padding:10px;',
+ itemId: 'form',
items: [
{
xtype: 'hiddenfield',
@@ -534,26 +597,26 @@ opendxp.settings.email.log = Class.create({
xtype: 'textfield',
value: data.subject,
readOnly: true,
- fieldLabel: t("subject"),
+ fieldLabel: t('subject'),
},
{
xtype: 'textfield',
value: data.from,
readOnly: true,
- fieldLabel: t("from"),
+ fieldLabel: t('from'),
},
{
xtype: 'textfield',
value: data.replyTo,
hidden: empty(data.replyTo),
readOnly: true,
- fieldLabel: t("replyTo"),
+ fieldLabel: t('replyTo'),
},
{
xtype: 'textfield',
- name: "to",
+ name: 'to',
allowBlank: false,
- fieldLabel: t("to"),
+ fieldLabel: t('to'),
},
{
xtype: 'panel',
@@ -561,20 +624,22 @@ opendxp.settings.email.log = Class.create({
layout: 'fit',
items : [{
xtype : 'box',
- autoEl: {tag: 'iframe', src: emailPreviewUrl}
+ autoEl: {
+ tag: 'iframe',
+ src: emailPreviewUrl
+ }
}]
}
-
],
defaults: {
width: 780
}
}],
buttons: [{
- text: t("send"),
- iconCls: "opendxp_icon_email",
+ text: t('send'),
+ iconCls: 'opendxp_icon_email',
handler: function () {
- var form = win.getComponent("form").getForm();
+ var form = win.getComponent('form').getForm();
var params = form.getFieldValues();
if (form.isValid()) {
Ext.Ajax.request({
diff --git a/src/Controller/Admin/EmailController.php b/src/Controller/Admin/EmailController.php
index 2067e99e..d7d19c22 100644
--- a/src/Controller/Admin/EmailController.php
+++ b/src/Controller/Admin/EmailController.php
@@ -118,7 +118,7 @@ public function showEmailLogDetailsAction(
GetEmailLogDetailsHandler $handler,
IdQueryPayload $payload,
): JsonResponse {
- return $this->apiJson($handler($payload), rootProperty: 'objectVars');
+ return $this->apiJson($handler($payload), envelope: false);
}
#[IsGranted(CorePermission::Emails->value)]
diff --git a/src/Handler/Email/ResendEmail/ResendEmailHandler.php b/src/Handler/Email/ResendEmail/ResendEmailHandler.php
index 9cbbe21a..5e00f3f7 100644
--- a/src/Handler/Email/ResendEmail/ResendEmailHandler.php
+++ b/src/Handler/Email/ResendEmail/ResendEmailHandler.php
@@ -18,6 +18,8 @@
use Exception;
use OpenDxp\Bundle\AdminBundle\Exception\AdminOperationFailedException;
+use OpenDxp\Bundle\AdminBundle\Service\Email\UnusableRecipientDetector;
+use OpenDxp\Helper\Mail as MailHelper;
use OpenDxp\Logger;
use OpenDxp\Mail;
use OpenDxp\Model\Element\ElementInterface;
@@ -27,6 +29,10 @@
final class ResendEmailHandler
{
+ public function __construct(private readonly UnusableRecipientDetector $unusableRecipientDetector)
+ {
+ }
+
public function __invoke(ResendEmailPayload $payload): void
{
$emailLog = Tool\Email\Log::getById($payload->id);
@@ -38,7 +44,9 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->preventDebugInformationAppending();
$mail->setIgnoreDebugMode(true);
- if (!empty($payload->fieldOverrides['to'])) {
+ $isForward = !empty($payload->fieldOverrides['to']);
+
+ if ($isForward) {
$emailLog->setTo(null);
$emailLog->setCc(null);
$emailLog->setBcc(null);
@@ -46,6 +54,14 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->disableLogging();
}
+ $skipDocumentRecipients = $isForward
+ || $payload->useOriginalRecipients
+ || $this->unusableRecipientDetector->hasUnusableRecipients($emailLog->getDocumentId());
+
+ if ($skipDocumentRecipients) {
+ $mail->clearRecipients();
+ }
+
if ($html = $emailLog->getHtmlLog()) {
$mail->html($html);
}
@@ -54,20 +70,14 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->text($text);
}
- foreach (['From', 'To', 'Cc', 'Bcc', 'ReplyTo'] as $field) {
- $overrideKey = strtolower($field);
- if (!empty($payload->fieldOverrides[$overrideKey])) {
- $values = $payload->fieldOverrides[$overrideKey];
- } else {
- $getter = 'get' . $field;
- $values = $emailLog->{$getter}();
- }
+ // an email has a single sender, same as Mail::setDocumentSettings() picks it
+ $sender = $this->resolveAddresses($payload, $emailLog, 'From')[0] ?? null;
- $values = \OpenDxp\Helper\Mail::parseEmailAddressField($values);
+ foreach (['To', 'Cc', 'Bcc', 'ReplyTo'] as $field) {
+ $addresses = $this->resolveAddresses($payload, $emailLog, $field);
- if ($values) {
- [$value] = $values;
- $mail->{'add' . $field}(new Address($value['email'], $value['name']));
+ if ($addresses) {
+ $mail->{'add' . $field}(...$addresses);
}
}
@@ -77,6 +87,12 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->setDocument($emailLog->getDocumentId());
}
+ // Mail::setDocumentSettings() replaces the sender with the document's one
+ // and clearRecipients() does not guard that block
+ if ($sender instanceof Address && ($skipDocumentRecipients || $mail->getFrom() === [])) {
+ $mail->from($sender);
+ }
+
try {
$params = $emailLog->getParams();
} catch (Exception) {
@@ -104,6 +120,22 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->send();
}
+ /**
+ * @return list
+ */
+ private function resolveAddresses(ResendEmailPayload $payload, Tool\Email\Log $emailLog, string $field): array
+ {
+ $override = $payload->fieldOverrides[strtolower($field)] ?? null;
+ $values = empty($override) ? $emailLog->{'get' . $field}() : $override;
+
+ $addresses = [];
+ foreach (MailHelper::parseEmailAddressField($values) as $value) {
+ $addresses[] = new Address($value['email'], $value['name']);
+ }
+
+ return $addresses;
+ }
+
private function parseLoggingParamObject(array $params): mixed
{
if ($params['data']['type'] === 'object') {
diff --git a/src/Handler/Email/ResendEmail/ResendEmailPayload.php b/src/Handler/Email/ResendEmail/ResendEmailPayload.php
index 0db4bce9..948df3c1 100644
--- a/src/Handler/Email/ResendEmail/ResendEmailPayload.php
+++ b/src/Handler/Email/ResendEmail/ResendEmailPayload.php
@@ -21,14 +21,12 @@
final readonly class ResendEmailPayload implements ExtJsPayloadInterface
{
- /** @var array */
- public readonly array $fieldOverrides;
-
+ /** @param array $fieldOverrides */
public function __construct(
public readonly int $id,
- ?array $fieldOverrides,
+ public readonly array $fieldOverrides = [],
+ public readonly bool $useOriginalRecipients = false,
) {
- $this->fieldOverrides = $fieldOverrides ?? [];
}
public static function fromRequest(Request $request): static
@@ -42,6 +40,7 @@ public static function fromRequest(Request $request): static
'bcc' => $request->request->get('bcc') ?: null,
'replyto' => $request->request->get('replyto') ?: null,
],
+ useOriginalRecipients: $request->request->getBoolean('useOriginalRecipients'),
);
}
}
diff --git a/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsHandler.php b/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsHandler.php
index 6ac02f45..97aadf28 100644
--- a/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsHandler.php
+++ b/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsHandler.php
@@ -17,11 +17,16 @@
namespace OpenDxp\Bundle\AdminBundle\Handler\Email\ShowEmailLog\GetEmailLogDetails;
use OpenDxp\Bundle\AdminBundle\Payload\Common\IdQueryPayload;
+use OpenDxp\Bundle\AdminBundle\Service\Email\UnusableRecipientDetector;
use OpenDxp\Model\Tool\Email\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
final class GetEmailLogDetailsHandler
{
+ public function __construct(private readonly UnusableRecipientDetector $unusableRecipientDetector)
+ {
+ }
+
public function __invoke(IdQueryPayload $payload): GetEmailLogDetailsResult
{
$log = Log::getById($payload->id);
@@ -30,6 +35,9 @@ public function __invoke(IdQueryPayload $payload): GetEmailLogDetailsResult
throw new NotFoundHttpException(sprintf('Email log with id %d not found', $payload->id));
}
- return new GetEmailLogDetailsResult(objectVars: $log->getObjectVars());
+ return new GetEmailLogDetailsResult(
+ objectVars: $log->getObjectVars(),
+ documentHasUnusableRecipients: $this->unusableRecipientDetector->hasUnusableRecipients($log->getDocumentId()),
+ );
}
}
diff --git a/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsResult.php b/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsResult.php
index b00baeba..f1fc613c 100644
--- a/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsResult.php
+++ b/src/Handler/Email/ShowEmailLog/GetEmailLogDetails/GetEmailLogDetailsResult.php
@@ -20,7 +20,9 @@
final readonly class GetEmailLogDetailsResult implements ResultInterface
{
- public function __construct(public readonly array $objectVars)
- {
+ public function __construct(
+ public readonly array $objectVars,
+ public readonly bool $documentHasUnusableRecipients,
+ ) {
}
}
diff --git a/src/Service/Email/UnusableRecipientDetector.php b/src/Service/Email/UnusableRecipientDetector.php
new file mode 100644
index 00000000..0c27ce20
--- /dev/null
+++ b/src/Service/Email/UnusableRecipientDetector.php
@@ -0,0 +1,66 @@
+getFrom(),
+ $document->getTo(),
+ $document->getCc(),
+ $document->getBcc(),
+ $document->getReplyTo(),
+ ];
+
+ foreach ($addressFields as $addressField) {
+ if (!$this->isUsableAddressField($addressField)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function isUsableAddressField(?string $addressField): bool
+ {
+ foreach (MailHelper::parseEmailAddressField($addressField) as $entry) {
+ try {
+ new Address($entry['email'], $entry['name']);
+ } catch (MimeException) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/tests/Unit/Service/Email/UnusableRecipientDetectorTest.php b/tests/Unit/Service/Email/UnusableRecipientDetectorTest.php
new file mode 100644
index 00000000..25d61c8e
--- /dev/null
+++ b/tests/Unit/Service/Email/UnusableRecipientDetectorTest.php
@@ -0,0 +1,69 @@
+ '',
+ 'plain address' => 'office@example.com',
+ 'address with display name' => 'Max Muster ',
+ 'address with parenthesised name' => 'max@example.com (Max Muster)',
+ 'comma separated list' => 'a@example.com, b@example.com',
+ 'semicolon separated list' => 'a@example.com; b@example.com',
+ ];
+
+ foreach ($addressFields as $case => $addressField) {
+ self::assertTrue($detector->isUsableAddressField($addressField), $case);
+ }
+ }
+
+ public function testUnusableAddressFields(): void
+ {
+ $detector = new UnusableRecipientDetector();
+
+ $addressFields = [
+ 'simple placeholder' => '%email%',
+ 'placeholder inside display name syntax' => 'Max Muster <%email%>',
+ 'twig style placeholder' => '{{ email }}',
+ 'bracket style placeholder' => '[email]',
+ 'one valid address plus one placeholder' => 'office@example.com, %email%',
+ 'missing domain' => 'office@',
+ ];
+
+ foreach ($addressFields as $case => $addressField) {
+ self::assertFalse($detector->isUsableAddressField($addressField), $case);
+ }
+ }
+
+ public function testNullFieldIsUsable(): void
+ {
+ self::assertTrue((new UnusableRecipientDetector())->isUsableAddressField(null));
+ }
+
+ public function testDocumentIdIsOptional(): void
+ {
+ self::assertFalse((new UnusableRecipientDetector())->hasUnusableRecipients(null));
+ }
+}
diff --git a/translations/admin_ext.ca.yaml b/translations/admin_ext.ca.yaml
index e3e17fdb..24060931 100644
--- a/translations/admin_ext.ca.yaml
+++ b/translations/admin_ext.ca.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Elements to Export'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Enable'
diff --git a/translations/admin_ext.cs.yaml b/translations/admin_ext.cs.yaml
index c3f2d466..fd35d9b1 100644
--- a/translations/admin_ext.cs.yaml
+++ b/translations/admin_ext.cs.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS selector)'
elements_to_export: 'Elementy k exportu'
email_debug_addresses: 'E-mailové adresy pro debug e-maily'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'E-maily'
empty_label: 'Empty Display Name'
enable: 'Povolit'
diff --git a/translations/admin_ext.de.yaml b/translations/admin_ext.de.yaml
index a358f46e..614b66f1 100644
--- a/translations/admin_ext.de.yaml
+++ b/translations/admin_ext.de.yaml
@@ -222,6 +222,8 @@ effect: 'Effekt'
element_css_selector: 'Element (CSS-Selektor)'
elements_to_export: 'Elemente zum Exportieren'
email_debug_addresses: 'E-Mail-Adressen für Debug-Modus'
+email_log_resend_use_original_recipients: 'Empfänger des ursprünglichen Versands verwenden'
+email_log_resend_use_original_recipients_forced: 'Mindestens ein Adressfeld des Mail-Dokuments enthält eine ungültige E-Mail-Adresse. Es werden die Empfänger aus dem ursprünglichen Versand verwendet.'
emails: 'E-Mails'
empty_label: 'Leerer Anzeigename'
enable: 'Einschalten'
diff --git a/translations/admin_ext.en.yaml b/translations/admin_ext.en.yaml
index 27dc587a..d3c38417 100644
--- a/translations/admin_ext.en.yaml
+++ b/translations/admin_ext.en.yaml
@@ -222,6 +222,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Elements to Export'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Enable'
diff --git a/translations/admin_ext.es.yaml b/translations/admin_ext.es.yaml
index 6550f494..cb756145 100644
--- a/translations/admin_ext.es.yaml
+++ b/translations/admin_ext.es.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Elemento (selector CSS)'
elements_to_export: 'Elementos a Exportar'
email_debug_addresses: 'Direcciones de email para depuración'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Activado'
diff --git a/translations/admin_ext.fr.yaml b/translations/admin_ext.fr.yaml
index 472d646c..8d402a38 100644
--- a/translations/admin_ext.fr.yaml
+++ b/translations/admin_ext.fr.yaml
@@ -220,6 +220,8 @@ effect: 'Effet'
element_css_selector: 'Élément (sélecteur CSS)'
elements_to_export: 'Éléments à exporter'
email_debug_addresses: 'Adresses e-mail de debug'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'E-mails'
empty_label: 'Vide (nom d''affichage)'
enable: 'Activé'
diff --git a/translations/admin_ext.hu.yaml b/translations/admin_ext.hu.yaml
index 2687af43..99428c6d 100644
--- a/translations/admin_ext.hu.yaml
+++ b/translations/admin_ext.hu.yaml
@@ -220,6 +220,8 @@ effect: 'Effekt'
element_css_selector: 'Elem (CSS selector)'
elements_to_export: 'Elemek exportálása'
email_debug_addresses: 'Debug email címek'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emailek'
empty_label: 'Üres - megjelenített név'
enable: 'Engedélyez'
diff --git a/translations/admin_ext.it.yaml b/translations/admin_ext.it.yaml
index 5e5e8878..423ca352 100644
--- a/translations/admin_ext.it.yaml
+++ b/translations/admin_ext.it.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Elemento (CSS Selector)'
elements_to_export: 'Elementi da esportare'
email_debug_addresses: 'Indirizzi email per i messaggi di debug'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Email'
empty_label: 'Nome mostrato per Vuoto'
enable: 'Abilita'
diff --git a/translations/admin_ext.nl.yaml b/translations/admin_ext.nl.yaml
index 60ffff49..e305bfe2 100644
--- a/translations/admin_ext.nl.yaml
+++ b/translations/admin_ext.nl.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS selector)'
elements_to_export: 'Elementen om te exporteren'
email_debug_addresses: 'Debug e-mailadressen'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'E-mails'
empty_label: 'Benaming indien leeg'
enable: 'Inschakelen'
diff --git a/translations/admin_ext.pl.yaml b/translations/admin_ext.pl.yaml
index 6bef69b0..920973e8 100644
--- a/translations/admin_ext.pl.yaml
+++ b/translations/admin_ext.pl.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (Selektor CSS)'
elements_to_export: 'Elementy do eksportu'
email_debug_addresses: 'Debuguj adresy e-mail'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'E-maile'
empty_label: 'Labelka dla pustej wartości'
enable: 'Włącz'
diff --git a/translations/admin_ext.pt_br.yaml b/translations/admin_ext.pt_br.yaml
index b4432c92..5f03a6f1 100644
--- a/translations/admin_ext.pt_br.yaml
+++ b/translations/admin_ext.pt_br.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Elements to Export'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Enable'
diff --git a/translations/admin_ext.ro.yaml b/translations/admin_ext.ro.yaml
index e3e17fdb..24060931 100644
--- a/translations/admin_ext.ro.yaml
+++ b/translations/admin_ext.ro.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Elements to Export'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Enable'
diff --git a/translations/admin_ext.sk.yaml b/translations/admin_ext.sk.yaml
index 42512fce..2fbe4a41 100644
--- a/translations/admin_ext.sk.yaml
+++ b/translations/admin_ext.sk.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS selektor)'
elements_to_export: 'Elementy k exportu'
email_debug_addresses: 'E-mailová adresa pre debug e-maily'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'E-maily'
empty_label: 'Empty Display Name'
enable: 'Povoliť'
diff --git a/translations/admin_ext.sv.yaml b/translations/admin_ext.sv.yaml
index 31cca577..2f202c60 100644
--- a/translations/admin_ext.sv.yaml
+++ b/translations/admin_ext.sv.yaml
@@ -220,6 +220,8 @@ effect: 'Effekt'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Element att exportera'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Slå på'
diff --git a/translations/admin_ext.th.yaml b/translations/admin_ext.th.yaml
index 5bd1d272..31580256 100644
--- a/translations/admin_ext.th.yaml
+++ b/translations/admin_ext.th.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'องค์ประกอบ (ตัวเลือก CSS)'
elements_to_export: 'องค์ประกอบที่จะส่งออก'
email_debug_addresses: 'แก้ไขที่อยู่อีเมล'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'อีเมล์'
empty_label: 'ชื่อที่แสดงว่างเปล่า'
enable: 'ทำให้สามารถ'
diff --git a/translations/admin_ext.zh_Hans.yaml b/translations/admin_ext.zh_Hans.yaml
index 764704d0..763f99b1 100644
--- a/translations/admin_ext.zh_Hans.yaml
+++ b/translations/admin_ext.zh_Hans.yaml
@@ -220,6 +220,8 @@ effect: 'Effect'
element_css_selector: 'Element (CSS Selector)'
elements_to_export: 'Elements to Export'
email_debug_addresses: 'Debug Email Addresses'
+email_log_resend_use_original_recipients: 'Use the recipients of the original send'
+email_log_resend_use_original_recipients_forced: 'At least one address field of the mail document contains an invalid email address. The recipients of the original send are used.'
emails: 'Emails'
empty_label: 'Empty Display Name'
enable: 'Enable'