Mail action now can send to arbitrary lists of addresses, with token support.

Code also more resilient to dynamically created recipients.

--HG--
branch : 1.x
This commit is contained in:
Bertrand@Nutella
2011-12-06 17:11:24 -08:00
parent 728911a3c0
commit 7388df97b0
4 changed files with 80 additions and 36 deletions
@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.ContentManagement.Records;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Events; using Orchard.Events;
@@ -41,7 +40,9 @@ namespace Orchard.Email.Rules {
Func<dynamic, LocalizedString> display = context => T("Send an e-mail"); Func<dynamic, LocalizedString> display = context => T("Send an e-mail");
describe.For("Messaging", T("Messaging"), T("Messages")) describe.For("Messaging", T("Messaging"), T("Messages"))
.Element("SendEmail", T("Send e-mail"), T("Sends an e-mail to a specific user."), (Func<dynamic, bool>)Send, display, "ActionEmail"); .Element(
"SendEmail", T("Send e-mail"), T("Sends an e-mail to a specific user."), (Func<dynamic, bool>)Send,
display, "ActionEmail");
} }
private bool Send(dynamic context) { private bool Send(dynamic context) {
@@ -55,6 +56,8 @@ namespace Orchard.Email.Rules {
if (owner != null && owner.Record != null) { if (owner != null && owner.Record != null) {
_messageManager.Send(owner.Record, MessageType, "email", properties); _messageManager.Send(owner.Record, MessageType, "email", properties);
} }
_messageManager.Send(
SplitEmail(owner.As<IUser>().Email), MessageType, "email", properties);
} }
} }
else if (recipient == "author") { else if (recipient == "author") {
@@ -74,15 +77,20 @@ namespace Orchard.Email.Rules {
_messageManager.Send(user.ContentItem.Record, MessageType, "email", properties); _messageManager.Send(user.ContentItem.Record, MessageType, "email", properties);
} }
} }
else if (recipient == "other") {
var email = properties["RecipientOther"];
_messageManager.Send(SplitEmail(email), MessageType, "email", properties);
}
return true; return true;
} }
private static IEnumerable<string> SplitEmail(string commaSeparated) {
return commaSeparated.Split(new[] { ',', ';' });
}
} }
public class MailActionsHandler : IMessageEventHandler { public class MailActionsHandler : IMessageEventHandler {
private readonly IContentManager _contentManager; public MailActionsHandler() {
public MailActionsHandler(IContentManager contentManager) {
_contentManager = contentManager;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -92,7 +100,8 @@ namespace Orchard.Email.Rules {
if (context.MessagePrepared) if (context.MessagePrepared)
return; return;
if (!context.Recipients.Any()) { if ((context.Recipients == null || !context.Recipients.Any()) &&
(context.Addresses == null || !context.Addresses.Any())) {
return; return;
} }
@@ -107,12 +116,10 @@ namespace Orchard.Email.Rules {
} }
private static void FormatEmailBody(MessageContext context) { private static void FormatEmailBody(MessageContext context) {
context.MailMessage.Body = "<p style=\"font-family:Arial, Helvetica; font-size:10pt;\">" + context.MailMessage.Body; context.MailMessage.Body = "<p style=\"font-family:Arial, Helvetica; font-size:10pt;\">" + context.MailMessage.Body + "</p>";
context.MailMessage.Body += "</p>";
} }
public void Sent(MessageContext context) { public void Sent(MessageContext context) {
} }
} }
} }
@@ -1,5 +1,4 @@
using System; using System;
using System.Web.Mvc;
using Orchard.DisplayManagement; using Orchard.DisplayManagement;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Events; using Orchard.Events;
@@ -21,16 +20,46 @@ namespace Orchard.Email.Rules {
} }
public void Describe(dynamic context) { public void Describe(dynamic context) {
Func<IShapeFactory, dynamic> form = Func<IShapeFactory, dynamic> form =
shape => Shape.Form( shape => Shape.Form(
Id: "ActionEmail", Id: "ActionEmail",
_Type: Shape.SelectList( _Type: Shape.FieldSet(
Id: "Recipient", Name: "Recipient",
Title: T("Send to"), Title: T("Send to"),
Description: T("Select who should be the recipient of this e-mail.")) _RecipientOwner: Shape.Radio(
.Add(new SelectListItem { Value = "owner", Text = T("Owner").Text }) Id: "recipient-owner",
.Add(new SelectListItem { Value = "author", Text = T("Author").Text }) Name: "Recipient",
.Add(new SelectListItem { Value = "admin", Text = T("Site Admin").Text }), Value: "owner",
Title: T("Owner"),
Description: T("The owner of the content item in context, such as a blog post's author.")
),
_RecipientAuthor: Shape.Radio(
Id: "recipient-author",
Name: "Recipient",
Value: "author",
Title: T("Author"),
Description: T("The current user when this action executes.")
),
_RecipientAdmin: Shape.Radio(
Id: "recipient-admin",
Name: "Recipient",
Value: "admin",
Title: T("Site Admin"),
Description: T("The site administrator.")
),
_RecipientOther: Shape.Radio(
Id: "recipient-other",
Name: "Recipient",
Value: "other",
Title: T("Other:")
),
_OtherEmails: Shape.Textbox(
Id: "recipient-other-email",
Name: "RecipientOther",
Title: T("E-mail"),
Description: T("Specify a comma-separated list of e-mail recipients."),
Classes: new[] { "large", "text", "tokenized" }
)
),
_Subject: Shape.Textbox( _Subject: Shape.Textbox(
Id: "Subject", Name: "Subject", Id: "Subject", Name: "Subject",
Title: T("Subject"), Title: T("Subject"),
@@ -68,6 +97,11 @@ namespace Orchard.Email.Rules {
if (context.ValueProvider.GetValue("Body").AttemptedValue == String.Empty) { if (context.ValueProvider.GetValue("Body").AttemptedValue == String.Empty) {
context.ModelState.AddModelError("Body", T("You must provide a Body").Text); context.ModelState.AddModelError("Body", T("You must provide a Body").Text);
} }
if (context.ValueProvider.GetValue("RecipientOther").AttemptedValue == String.Empty &&
context.ValueProvider.GetValue("Recipient").AttemptedValue == "other") {
context.ModelState.AddModelError("Recipient", T("You must provide an e-mail address").Text);
}
} }
} }
} }
@@ -12,19 +12,21 @@ namespace Orchard.Email.Services {
} }
public void Sending(MessageContext context) { public void Sending(MessageContext context) {
foreach(var rec in context.Recipients) { if (context.Recipients != null) {
var contentItem = _contentManager.Get(rec.Id); foreach (var rec in context.Recipients) {
if (contentItem == null) var contentItem = _contentManager.Get(rec.Id);
return; if (contentItem == null)
return;
var recipient = contentItem.As<IUser>(); var recipient = contentItem.As<IUser>();
if (recipient == null) if (recipient == null)
return; return;
context.MailMessage.To.Add(recipient.Email); context.MailMessage.To.Add(recipient.Email);
}
} }
foreach(var address in context.Addresses) { foreach (var address in context.Addresses) {
context.MailMessage.To.Add(address); context.MailMessage.To.Add(address);
} }
} }
@@ -24,15 +24,6 @@ namespace Orchard.Users.Handlers {
if (context.MessagePrepared) if (context.MessagePrepared)
return; return;
// we expect a single account to be created
var contentItem = _contentManager.Get(context.Recipients.Single().Id);
if ( contentItem == null )
return;
var recipient = contentItem.As<UserPart>();
if ( recipient == null )
return;
switch (context.Type) { switch (context.Type) {
case MessageTypes.Moderation: case MessageTypes.Moderation:
context.MailMessage.Subject = T("New account").Text; context.MailMessage.Subject = T("New account").Text;
@@ -61,6 +52,7 @@ namespace Orchard.Users.Handlers {
break; break;
case MessageTypes.LostPassword: case MessageTypes.LostPassword:
var recipient = GetRecipient(context);
context.MailMessage.Subject = T("Lost password").Text; context.MailMessage.Subject = T("Lost password").Text;
context.MailMessage.Body = context.MailMessage.Body =
T("Dear {0}, please <a href=\"{1}\">click here</a> to change your password.", recipient.UserName, T("Dear {0}, please <a href=\"{1}\">click here</a> to change your password.", recipient.UserName,
@@ -71,6 +63,15 @@ namespace Orchard.Users.Handlers {
} }
} }
private UserPart GetRecipient(MessageContext context) {
// we expect a single account to be created
var contentItem = _contentManager.Get(context.Recipients.Single().Id);
if (contentItem == null) {
return null;
}
return contentItem.As<UserPart>();
}
private static void FormatEmailBody(MessageContext context) { private static void FormatEmailBody(MessageContext context) {
context.MailMessage.Body = "<p style=\"font-family:Arial, Helvetica; font-size:10pt;\">" + context.MailMessage.Body; context.MailMessage.Body = "<p style=\"font-family:Arial, Helvetica; font-size:10pt;\">" + context.MailMessage.Body;
context.MailMessage.Body += "</p>"; context.MailMessage.Body += "</p>";