mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-06-28 05:30:05 +08:00
Add FromName and ReplyTo properties to SmtpSettingsPart (#8420)
This commit is contained in:
parent
70c04a9a5f
commit
1c93e4a501
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Email.Models;
|
||||
@ -29,8 +28,7 @@ namespace Orchard.Email.Controllers {
|
||||
ILogger logger = null;
|
||||
try {
|
||||
var fakeLogger = new FakeLogger();
|
||||
var smtpChannelComponent = _smtpChannel as Component;
|
||||
if (smtpChannelComponent != null) {
|
||||
if (_smtpChannel is Component smtpChannelComponent) {
|
||||
logger = smtpChannelComponent.Logger;
|
||||
smtpChannelComponent.Logger = fakeLogger;
|
||||
}
|
||||
@ -38,7 +36,9 @@ namespace Orchard.Email.Controllers {
|
||||
// Temporarily update settings so that the test will actually use the specified host, port, etc.
|
||||
var smtpSettings = _orchardServices.WorkContext.CurrentSite.As<SmtpSettingsPart>();
|
||||
|
||||
smtpSettings.Address = testSettings.From;
|
||||
smtpSettings.FromAddress = testSettings.FromAddress;
|
||||
smtpSettings.FromName = testSettings.FromName;
|
||||
smtpSettings.ReplyTo = testSettings.ReplyTo;
|
||||
smtpSettings.Host = testSettings.Host;
|
||||
smtpSettings.Port = testSettings.Port;
|
||||
smtpSettings.EnableSsl = testSettings.EnableSsl;
|
||||
@ -46,6 +46,7 @@ namespace Orchard.Email.Controllers {
|
||||
smtpSettings.UseDefaultCredentials = testSettings.UseDefaultCredentials;
|
||||
smtpSettings.UserName = testSettings.UserName;
|
||||
smtpSettings.Password = testSettings.Password;
|
||||
smtpSettings.ListUnsubscribe = testSettings.ListUnsubscribe;
|
||||
|
||||
if (!smtpSettings.IsValid()) {
|
||||
fakeLogger.Error("Invalid settings.");
|
||||
@ -57,7 +58,7 @@ namespace Orchard.Email.Controllers {
|
||||
});
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(fakeLogger.Message)) {
|
||||
if (!string.IsNullOrEmpty(fakeLogger.Message)) {
|
||||
return Json(new { error = fakeLogger.Message });
|
||||
}
|
||||
|
||||
@ -67,12 +68,11 @@ namespace Orchard.Email.Controllers {
|
||||
return Json(new { error = e.Message });
|
||||
}
|
||||
finally {
|
||||
var smtpChannelComponent = _smtpChannel as Component;
|
||||
if (smtpChannelComponent != null) {
|
||||
if (_smtpChannel is Component smtpChannelComponent) {
|
||||
smtpChannelComponent.Logger = logger;
|
||||
}
|
||||
|
||||
// Undo the temporarily changed smtp settings.
|
||||
// Undo the temporarily changed SMTP settings.
|
||||
_orchardServices.TransactionManager.Cancel();
|
||||
}
|
||||
}
|
||||
@ -80,17 +80,16 @@ namespace Orchard.Email.Controllers {
|
||||
private class FakeLogger : ILogger {
|
||||
public string Message { get; set; }
|
||||
|
||||
public bool IsEnabled(LogLevel level) {
|
||||
return true;
|
||||
}
|
||||
public bool IsEnabled(LogLevel level) => true;
|
||||
|
||||
public void Log(LogLevel level, Exception exception, string format, params object[] args) {
|
||||
public void Log(LogLevel level, Exception exception, string format, params object[] args) =>
|
||||
Message = exception == null ? format : exception.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestSmtpSettings {
|
||||
public string From { get; set; }
|
||||
public string FromAddress { get; set; }
|
||||
public string FromName { get; set; }
|
||||
public string ReplyTo { get; set; }
|
||||
public string Host { get; set; }
|
||||
public int Port { get; set; }
|
||||
public bool EnableSsl { get; set; }
|
||||
@ -99,6 +98,7 @@ namespace Orchard.Email.Controllers {
|
||||
public string UserName { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string To { get; set; }
|
||||
public string ListUnsubscribe { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,39 @@
|
||||
using Orchard.Data.Migration;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Data.Migration;
|
||||
using Orchard.Email.Models;
|
||||
|
||||
namespace Orchard.Email {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public int Create() {
|
||||
public Migrations(IContentManager contentManager) => _contentManager = contentManager;
|
||||
|
||||
return 1;
|
||||
// The first migration without any content should not exist but it has been deployed so we need to keep it.
|
||||
public int Create() => 1;
|
||||
|
||||
public int UpdateFrom1() {
|
||||
// Migrate existing SmtpSettingPart.Address because we rename it to FromAddress.
|
||||
var siteSettingsItem = _contentManager.Query(contentTypeNames: "Site")
|
||||
.Slice(1)
|
||||
.SingleOrDefault();
|
||||
|
||||
var siteSettingsRecord = siteSettingsItem?.Record;
|
||||
|
||||
if (siteSettingsRecord != null) {
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(siteSettingsRecord.Data);
|
||||
|
||||
var smtpSettingNode = xmlDoc.SelectSingleNode("//SmtpSettingsPart");
|
||||
if (smtpSettingNode != null) {
|
||||
var smtpSettingsPart = siteSettingsItem.As<SmtpSettingsPart>();
|
||||
smtpSettingsPart.FromAddress = smtpSettingNode.Attributes["Address"]?.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,8 @@ namespace Orchard.Email.Models {
|
||||
public string Body { get; set; }
|
||||
public string Recipients { get; set; }
|
||||
public string ReplyTo { get; set; }
|
||||
public string From { get; set; }
|
||||
public string FromAddress { get; set; }
|
||||
public string FromName { get; set; }
|
||||
public string Bcc { get; set; }
|
||||
public string Cc { get; set; }
|
||||
/// <summary>
|
||||
|
@ -1,72 +1,90 @@
|
||||
using System.Configuration;
|
||||
using System.Net.Configuration;
|
||||
using Orchard.ContentManagement;
|
||||
using System;
|
||||
using Orchard.ContentManagement.Utilities;
|
||||
|
||||
namespace Orchard.Email.Models {
|
||||
public class SmtpSettingsPart : ContentPart {
|
||||
private readonly ComputedField<string> _password = new ComputedField<string>();
|
||||
|
||||
public ComputedField<string> PasswordField {
|
||||
get { return _password; }
|
||||
public ComputedField<string> PasswordField => _password;
|
||||
|
||||
public string FromAddress {
|
||||
get => this.Retrieve(x => x.FromAddress);
|
||||
set => this.Store(x => x.FromAddress, value);
|
||||
}
|
||||
|
||||
public string Address {
|
||||
get { return this.Retrieve(x => x.Address); }
|
||||
set { this.Store(x => x.Address, value); }
|
||||
public string FromName {
|
||||
get => this.Retrieve(x => x.FromName);
|
||||
set => this.Store(x => x.FromName, value);
|
||||
}
|
||||
|
||||
public string ReplyTo {
|
||||
get => this.Retrieve(x => x.ReplyTo);
|
||||
set => this.Store(x => x.ReplyTo, value);
|
||||
}
|
||||
|
||||
private readonly LazyField<string> _addressPlaceholder = new LazyField<string>();
|
||||
internal LazyField<string> AddressPlaceholderField { get { return _addressPlaceholder; } }
|
||||
public string AddressPlaceholder { get { return _addressPlaceholder.Value; } }
|
||||
internal LazyField<string> AddressPlaceholderField => _addressPlaceholder;
|
||||
public string AddressPlaceholder => _addressPlaceholder.Value;
|
||||
|
||||
public string Host {
|
||||
get { return this.Retrieve(x => x.Host); }
|
||||
set { this.Store(x => x.Host, value); }
|
||||
get => this.Retrieve(x => x.Host);
|
||||
set => this.Store(x => x.Host, value);
|
||||
}
|
||||
|
||||
public int Port {
|
||||
get { return this.Retrieve(x => x.Port, 25); }
|
||||
set { this.Store(x => x.Port, value); }
|
||||
get => this.Retrieve(x => x.Port, 25);
|
||||
set => this.Store(x => x.Port, value);
|
||||
}
|
||||
|
||||
public bool EnableSsl {
|
||||
get { return this.Retrieve(x => x.EnableSsl); }
|
||||
set { this.Store(x => x.EnableSsl, value); }
|
||||
get => this.Retrieve(x => x.EnableSsl);
|
||||
set => this.Store(x => x.EnableSsl, value);
|
||||
}
|
||||
|
||||
public bool RequireCredentials {
|
||||
get { return this.Retrieve(x => x.RequireCredentials); }
|
||||
set { this.Store(x => x.RequireCredentials, value); }
|
||||
get => this.Retrieve(x => x.RequireCredentials);
|
||||
set => this.Store(x => x.RequireCredentials, value);
|
||||
}
|
||||
|
||||
public bool UseDefaultCredentials {
|
||||
get { return this.Retrieve(x => x.UseDefaultCredentials); }
|
||||
set { this.Store(x => x.UseDefaultCredentials, value); }
|
||||
get => this.Retrieve(x => x.UseDefaultCredentials);
|
||||
set => this.Store(x => x.UseDefaultCredentials, value);
|
||||
}
|
||||
|
||||
public string UserName {
|
||||
get { return this.Retrieve(x => x.UserName); }
|
||||
set { this.Store(x => x.UserName, value); }
|
||||
get => this.Retrieve(x => x.UserName);
|
||||
set => this.Store(x => x.UserName, value);
|
||||
}
|
||||
|
||||
public string Password {
|
||||
get { return _password.Value; }
|
||||
set { _password.Value = value; }
|
||||
get => _password.Value;
|
||||
set => _password.Value = value;
|
||||
}
|
||||
|
||||
// Hotmail only supports the mailto:link. When a user clicks on the 'unsubscribe' option in Hotmail.
|
||||
// Hotmail tries to read the mailto:link in the List-Unsubscribe header.
|
||||
// If the mailto:link is missing, it moves all the messages to the Junk folder.
|
||||
// The mailto:link is supported by Gmail, Hotmail, Yahoo, AOL, ATT, Time Warner and Comcast;
|
||||
// European ISPs such as GMX, Libero, Ziggo, Orange, BTInternet; Russian ISPs such as mail.ru and Yandex;
|
||||
// and the Chinese domains qq.com, naver.com etc. So most ISPs support (and prefer) mailto:link.
|
||||
public string ListUnsubscribe {
|
||||
get => this.Retrieve(x => x.ListUnsubscribe);
|
||||
set => this.Store(x => x.ListUnsubscribe, value);
|
||||
}
|
||||
|
||||
public bool IsValid() {
|
||||
var section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
|
||||
if (section != null && !String.IsNullOrWhiteSpace(section.Network.Host)) {
|
||||
if (section != null && !string.IsNullOrWhiteSpace(section.Network.Host)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(Address)) {
|
||||
if (string.IsNullOrWhiteSpace(FromAddress)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Host) && Port == 0) {
|
||||
if (!string.IsNullOrWhiteSpace(Host) && Port == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,9 @@
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
<Reference Include="System.Web.Entity" />
|
||||
@ -98,6 +101,7 @@
|
||||
<HintPath>..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -53,7 +53,7 @@ namespace Orchard.Email.Services {
|
||||
smtpClient.EnableSsl = smtpSettings.EnableSsl;
|
||||
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
|
||||
|
||||
context.MailMessage.From = new MailAddress(smtpSettings.Address);
|
||||
context.MailMessage.From = new MailAddress(smtpSettings.FromAddress);
|
||||
context.MailMessage.IsBodyHtml = !String.IsNullOrWhiteSpace(context.MailMessage.Body) && context.MailMessage.Body.Contains("<") && context.MailMessage.Body.Contains(">");
|
||||
|
||||
try {
|
||||
|
@ -9,7 +9,6 @@ using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Email.Models;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace Orchard.Email.Services {
|
||||
@ -41,7 +40,6 @@ namespace Orchard.Email.Services {
|
||||
}
|
||||
|
||||
public void Process(IDictionary<string, object> parameters) {
|
||||
|
||||
if (!_smtpSettings.IsValid()) {
|
||||
return;
|
||||
}
|
||||
@ -51,10 +49,15 @@ namespace Orchard.Email.Services {
|
||||
Subject = Read(parameters, "Subject"),
|
||||
Recipients = Read(parameters, "Recipients"),
|
||||
ReplyTo = Read(parameters, "ReplyTo"),
|
||||
From = Read(parameters, "From"),
|
||||
FromAddress = Read(parameters, "FromAddress"),
|
||||
FromName = Read(parameters, "FromName"),
|
||||
Bcc = Read(parameters, "Bcc"),
|
||||
Cc = Read(parameters, "CC"),
|
||||
Attachments = (IEnumerable<string>)(parameters.ContainsKey("Attachments") ? parameters["Attachments"] : new List<string>())
|
||||
Attachments = (IEnumerable<string>)(
|
||||
parameters.ContainsKey("Attachments")
|
||||
? parameters["Attachments"]
|
||||
: new List<string>()
|
||||
)
|
||||
};
|
||||
|
||||
if (string.IsNullOrWhiteSpace(emailMessage.Recipients)) {
|
||||
@ -62,6 +65,18 @@ namespace Orchard.Email.Services {
|
||||
return;
|
||||
}
|
||||
|
||||
var mailMessage = CreteMailMessage(parameters, emailMessage);
|
||||
|
||||
try {
|
||||
_smtpClientField.Value.Send(mailMessage);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Logger.Error(e, "Could not send email");
|
||||
}
|
||||
}
|
||||
|
||||
private MailMessage CreteMailMessage(IDictionary<string, object> parameters, EmailMessage emailMessage) {
|
||||
|
||||
// Apply default Body alteration for SmtpChannel.
|
||||
var template = _shapeFactory.Create("Template_Smtp_Wrapper", Arguments.From(new {
|
||||
Content = new MvcHtmlString(emailMessage.Body)
|
||||
@ -75,79 +90,88 @@ namespace Orchard.Email.Services {
|
||||
|
||||
if (parameters.ContainsKey("Message")) {
|
||||
// A full message object is provided by the sender.
|
||||
|
||||
var oldMessage = mailMessage;
|
||||
mailMessage = (MailMessage)parameters["Message"];
|
||||
|
||||
if (String.IsNullOrWhiteSpace(mailMessage.Subject))
|
||||
if (string.IsNullOrWhiteSpace(mailMessage.Subject))
|
||||
mailMessage.Subject = oldMessage.Subject;
|
||||
|
||||
if (String.IsNullOrWhiteSpace(mailMessage.Body)) {
|
||||
if (string.IsNullOrWhiteSpace(mailMessage.Body)) {
|
||||
mailMessage.Body = oldMessage.Body;
|
||||
mailMessage.IsBodyHtml = oldMessage.IsBodyHtml;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Recipients)) {
|
||||
mailMessage.To.Add(new MailAddress(recipient));
|
||||
}
|
||||
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Recipients)) {
|
||||
mailMessage.To.Add(new MailAddress(recipient));
|
||||
if (!string.IsNullOrWhiteSpace(emailMessage.Cc)) {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Cc)) {
|
||||
mailMessage.CC.Add(new MailAddress(recipient));
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(emailMessage.Cc)) {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Cc)) {
|
||||
mailMessage.CC.Add(new MailAddress(recipient));
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(emailMessage.Bcc)) {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Bcc)) {
|
||||
mailMessage.Bcc.Add(new MailAddress(recipient));
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(emailMessage.Bcc)) {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.Bcc)) {
|
||||
mailMessage.Bcc.Add(new MailAddress(recipient));
|
||||
}
|
||||
}
|
||||
var senderAddress =
|
||||
!string.IsNullOrWhiteSpace(emailMessage.FromAddress) ? emailMessage.FromAddress :
|
||||
!string.IsNullOrWhiteSpace(_smtpSettings.FromAddress) ? _smtpSettings.FromAddress :
|
||||
// Take 'From' address from site settings or web.config.
|
||||
((SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp")).From;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(emailMessage.From)) {
|
||||
mailMessage.From = new MailAddress(emailMessage.From);
|
||||
var senderName = !string.IsNullOrWhiteSpace(emailMessage.FromName)
|
||||
? emailMessage.FromName
|
||||
: _smtpSettings.FromName;
|
||||
|
||||
var sender = (senderAddress, senderName) switch
|
||||
{
|
||||
(string address, string name) => new MailAddress(address, name),
|
||||
(string address, null) => new MailAddress(address),
|
||||
_ => throw new InvalidOperationException("No sender email address")
|
||||
};
|
||||
mailMessage.From = sender;
|
||||
|
||||
var replyTo =
|
||||
!string.IsNullOrWhiteSpace(emailMessage.ReplyTo) ? ParseRecipients(emailMessage.ReplyTo) :
|
||||
!string.IsNullOrWhiteSpace(_smtpSettings.ReplyTo) ? new[] { _smtpSettings.ReplyTo } :
|
||||
Array.Empty<string>();
|
||||
|
||||
foreach (var recipient in replyTo) {
|
||||
mailMessage.ReplyToList.Add(new MailAddress(recipient));
|
||||
}
|
||||
|
||||
foreach (var attachmentPath in emailMessage.Attachments) {
|
||||
if (File.Exists(attachmentPath)) {
|
||||
mailMessage.Attachments.Add(new Attachment(attachmentPath));
|
||||
}
|
||||
else {
|
||||
// Take 'From' address from site settings or web.config.
|
||||
mailMessage.From = !String.IsNullOrWhiteSpace(_smtpSettings.Address)
|
||||
? new MailAddress(_smtpSettings.Address)
|
||||
: new MailAddress(((SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp")).From);
|
||||
throw new FileNotFoundException(T("One or more attachments not found.").Text);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(emailMessage.ReplyTo)) {
|
||||
foreach (var recipient in ParseRecipients(emailMessage.ReplyTo)) {
|
||||
mailMessage.ReplyToList.Add(new MailAddress(recipient));
|
||||
}
|
||||
}
|
||||
foreach (var attachmentPath in emailMessage.Attachments) {
|
||||
if (File.Exists(attachmentPath)) {
|
||||
mailMessage.Attachments.Add(new Attachment(attachmentPath));
|
||||
}
|
||||
else {
|
||||
throw new FileNotFoundException(T("One or more attachments not found.").Text);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.ContainsKey("NotifyReadEmail")) {
|
||||
if (parameters["NotifyReadEmail"] is bool) {
|
||||
if ((bool)(parameters["NotifyReadEmail"])) {
|
||||
mailMessage.Headers.Add("Disposition-Notification-To", mailMessage.From.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_smtpClientField.Value.Send(mailMessage);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Logger.Error(e, "Could not send email");
|
||||
|
||||
if (parameters.ContainsKey("NotifyReadEmail")) {
|
||||
if (parameters["NotifyReadEmail"] is bool) {
|
||||
if ((bool)(parameters["NotifyReadEmail"])) {
|
||||
mailMessage.Headers.Add("Disposition-Notification-To", mailMessage.From.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_smtpSettings.ListUnsubscribe)){
|
||||
mailMessage.Headers.Add("List-Unsubscribe", _smtpSettings.ListUnsubscribe);
|
||||
}
|
||||
|
||||
return mailMessage;
|
||||
}
|
||||
|
||||
private SmtpClient CreateSmtpClient() {
|
||||
// If no properties are set in the dashboard, use the web.config value.
|
||||
if (String.IsNullOrWhiteSpace(_smtpSettings.Host)) {
|
||||
if (string.IsNullOrWhiteSpace(_smtpSettings.Host)) {
|
||||
return new SmtpClient();
|
||||
}
|
||||
|
||||
@ -155,7 +179,7 @@ namespace Orchard.Email.Services {
|
||||
UseDefaultCredentials = _smtpSettings.RequireCredentials && _smtpSettings.UseDefaultCredentials
|
||||
};
|
||||
|
||||
if (!smtpClient.UseDefaultCredentials && !String.IsNullOrWhiteSpace(_smtpSettings.UserName)) {
|
||||
if (!smtpClient.UseDefaultCredentials && !string.IsNullOrWhiteSpace(_smtpSettings.UserName)) {
|
||||
smtpClient.Credentials = new NetworkCredential(_smtpSettings.UserName, _smtpSettings.Password);
|
||||
}
|
||||
|
||||
@ -169,12 +193,10 @@ namespace Orchard.Email.Services {
|
||||
return smtpClient;
|
||||
}
|
||||
|
||||
private string Read(IDictionary<string, object> dictionary, string key) {
|
||||
return dictionary.ContainsKey(key) ? dictionary[key] as string : null;
|
||||
}
|
||||
private string Read(IDictionary<string, object> dictionary, string key) =>
|
||||
dictionary.ContainsKey(key) ? dictionary[key] as string : null;
|
||||
|
||||
private IEnumerable<string> ParseRecipients(string recipients) {
|
||||
return recipients.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
private IEnumerable<string> ParseRecipients(string recipients) =>
|
||||
recipients.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,24 @@
|
||||
@{
|
||||
var smtpClient = new SmtpClient();
|
||||
}
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Email")</legend>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.Address)">@T("Sender email address")</label>
|
||||
@Html.TextBoxFor(m => m.Address, new { @class = "text medium", placeholder = Model.AddressPlaceholder })
|
||||
@Html.ValidationMessage("Address", "*")
|
||||
<label for="@Html.FieldIdFor(m => m.FromAddress)">@T("Sender email address")</label>
|
||||
@Html.TextBoxFor(m => m.FromAddress, new { @class = "text medium", placeholder = Model.AddressPlaceholder })
|
||||
@Html.ValidationMessage("FromAddress", "*")
|
||||
<span class="hint">@T("The default email address to use as a sender.")</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.FromName)">@T("Sender name")</label>
|
||||
@Html.TextBoxFor(m => m.FromName, new { @class = "text medium" })
|
||||
<span class="hint">@T("The default value to use as a sender name.")</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.ReplyTo)">@T("Reply to address")</label>
|
||||
@Html.TextBoxFor(m => m.ReplyTo, new { @class = "text medium" })
|
||||
<span class="hint">@T("The default email address to use for reply to")</span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.Host)">@T("Host name")</label>
|
||||
@Html.TextBoxFor(m => m.Host, new { placeholder = smtpClient.Host, @class = "text medium" })
|
||||
@ -35,9 +44,7 @@
|
||||
<label for="@Html.FieldIdFor(m => m.RequireCredentials)" class="forcheckbox">@T("Require credentials")</label>
|
||||
@Html.ValidationMessage("RequireCredentials", "*")
|
||||
</div>
|
||||
|
||||
<div data-controllerid="@Html.FieldIdFor(m => m.RequireCredentials)">
|
||||
|
||||
<div>
|
||||
@Html.RadioButtonFor(m => m.UseDefaultCredentials, false, new { id = "customCredentialsOption", name = "UseDefaultCredentials" })
|
||||
<label for="customCredentialsOption" class="forcheckbox">@T("Specify username/password")</label>
|
||||
@ -65,6 +72,11 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="@Html.FieldIdFor(m => m.ListUnsubscribe)">@T("List-Unsubscribe header")</label>
|
||||
@Html.TextBoxFor(m => m.ListUnsubscribe, new { @class = "text medium" })
|
||||
<span class="hint">@T("A mailto:link to unsubscribe a user when clicking unsubscribe option")</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>@T("Test those settings:")</legend>
|
||||
@ -84,7 +96,9 @@
|
||||
var url = "@Url.Action("TestSettings", "EmailAdmin", new {area = "Orchard.Email"})",
|
||||
error = $("#emailtesterror"),
|
||||
info = $("#emailtestinfo"),
|
||||
from = $("#@Html.FieldIdFor(m => m.Address)"),
|
||||
fromAddress = $("#@Html.FieldIdFor(m => m.FromAddress)"),
|
||||
fromName = $("#@Html.FieldIdFor(m => m.FromName)"),
|
||||
replyTo = $("#@Html.FieldIdFor(m => m.ReplyTo)"),
|
||||
host = $("#@Html.FieldIdFor(m => m.Host)"),
|
||||
port = $("#@Html.FieldIdFor(m => m.Port)"),
|
||||
enableSsl = $("#@Html.FieldIdFor(m => m.EnableSsl)"),
|
||||
@ -92,11 +106,14 @@
|
||||
useDefaultCredentials = $("input[name='@Html.NameFor(m => m.UseDefaultCredentials)']"),
|
||||
userName = $("#@Html.FieldIdFor(m => m.UserName)"),
|
||||
password = $("#@Html.FieldIdFor(m => m.Password)"),
|
||||
listUnsubscribe = $("#@Html.FieldIdFor(m => m.ListUnsubscribe)"),
|
||||
to = $("#emailtestto");
|
||||
|
||||
$("#emailtestsend").click(function () {
|
||||
$.post(url, {
|
||||
from: from.val(),
|
||||
fromAddress: fromAddress.val(),
|
||||
fromName: fromName.val(),
|
||||
replyTo: replyTo.val(),
|
||||
host: host.val(),
|
||||
port: port.val(),
|
||||
enableSsl: enableSsl.prop("checked"),
|
||||
@ -104,6 +121,7 @@
|
||||
useDefaultCredentials: useDefaultCredentials.filter(':checked').val(),
|
||||
userName: userName.val(),
|
||||
password: password.val(),
|
||||
listUnsubscribe: listUnsubscribe.val(),
|
||||
to: to.val(),
|
||||
__RequestVerificationToken: to.closest("form").find("input[name=__RequestVerificationToken]").val()
|
||||
})
|
||||
|
@ -6,4 +6,5 @@
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net452" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user