Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: ~
Expand Down
167 changes: 116 additions & 51 deletions public/js/opendxp/settings/email/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,15 @@ 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
// deleted in the meantime
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 '<span onclick="opendxp.helpers.openElement(' + data.objectId + ', \'' + type + '\' , \''
+ subtype + '\'); Ext.getCmp(\'email_log_params_panel\').close();" class="x-grid-cell-inner input_drop_target" style="display: block;">'
+ data.objectPath + '</span>';
Expand All @@ -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'
Expand Down Expand Up @@ -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') ){
Expand All @@ -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),
Expand Down Expand Up @@ -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'),
Expand Down Expand Up @@ -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';
Expand All @@ -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',
Expand All @@ -534,47 +597,49 @@ 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',
height: 350,
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({
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Admin/EmailController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
58 changes: 45 additions & 13 deletions src/Handler/Email/ResendEmail/ResendEmailHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -38,14 +44,24 @@ 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);
} else {
$mail->disableLogging();
}

$skipDocumentRecipients = $isForward
|| $payload->useOriginalRecipients
|| $this->unusableRecipientDetector->hasUnusableRecipients($emailLog->getDocumentId());

if ($skipDocumentRecipients) {
$mail->clearRecipients();
}

if ($html = $emailLog->getHtmlLog()) {
$mail->html($html);
}
Expand All @@ -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);
}
}

Expand All @@ -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) {
Expand Down Expand Up @@ -104,6 +120,22 @@ public function __invoke(ResendEmailPayload $payload): void
$mail->send();
}

/**
* @return list<Address>
*/
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') {
Expand Down
Loading
Loading