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'