I'm not sure it's possible to attach a file to an e-mail using XSLT to send the content of the Contour form unless you create your own "SendMail" extension, which also takes the file path as a parameter I guess.
I'm using this custom workflow which adds emails as attachments.
public class CustomSendEmailWorkflow : WorkflowType
{
[Setting("Email from", description = "Enter the from email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string EmailFrom
{
get;
set;
}
[Setting("Email to", description = "Enter the to email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string EmailTo
{
get;
set;
}
[Setting("Email cc", description = "Enter the cc email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string EmailCc
{
get;
set;
}
[Setting("Email bcc", description = "Enter the bcc email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string EmailBcc
{
get;
set;
}
[Setting("Subject", description = "Enter the subject", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string Subject
{
get;
set;
}
[Setting("Message", description = "Enter the message", control = "Umbraco.Forms.Core.FieldSetting.TextArea")]
public string Message
{
get;
set;
}
public CustomSendEmailWorkflow()
{
base.Id = new Guid("c8a976da-0ced-4680-9296-53afb9b41df4");
base.Name = "Custom send email";
base.Description = "Send a message from a specific email address to a specific email address";
}
public override List<Exception> ValidateSettings()
{
List<Exception> i = new List<Exception>();
if (string.IsNullOrEmpty(this.EmailFrom))
{
i.Add(new Exception("'Email From' setting has not been set"));
}
if (string.IsNullOrEmpty(this.EmailTo))
{
i.Add(new Exception("'Email To' setting has not been set"));
}
if (string.IsNullOrEmpty(this.Subject))
{
i.Add(new Exception("'Subject' setting has not been set'"));
}
if (string.IsNullOrEmpty(this.Message))
{
i.Add(new Exception("'Message' setting has not been set'"));
}
return i;
}
public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
{
var pageTitle = Node.GetCurrent().Name;
MailMessage i = new MailMessage();
i.From = new MailAddress(EmailFrom);
if (!string.IsNullOrEmpty(EmailTo))
{
foreach (string email in EmailTo.Split(','))
{
i.To.Add(new MailAddress(email));
}
}
if (!string.IsNullOrEmpty(EmailCc))
{
foreach (string email in EmailCc.Split(','))
{
i.CC.Add(new MailAddress(email));
}
}
if (!string.IsNullOrEmpty(EmailBcc))
{
foreach (string email in EmailBcc.Split(','))
{
i.Bcc.Add(new MailAddress(email));
}
}
i.Subject = this.Subject.Replace("{pageTitle}", pageTitle);
i.IsBodyHtml = true;
string body = this.Message.Replace("\n", "<br/>");
string fieldHtml = @"
<table>";
foreach (RecordField rf in record.RecordFields.Values.OrderBy(x => x.Field.SortOrder))
{
if (rf.Field.FieldType.GetType().ToString() == "Umbraco.Forms.Core.Providers.FieldTypes.FileUpload")
{
if (!string.IsNullOrEmpty(rf.ValuesAsString()))
{
//If it's a FileUpload add the file as an attachment.
i.Attachments.Add(new Attachment(HttpContext.Current.Server.MapPath(rf.ValuesAsString())));
}
}
else
{
//Add the info into the table.
fieldHtml += @"
<tr>
<td>" + rf.Field.Caption + @" </td>
<td>" + rf.ValuesAsString() + @" </td>
</tr>
";
}
}
fieldHtml += @"
</table>";
i.Body = body.Replace("{velden}", fieldHtml).Replace("{pageTitle}", pageTitle);
SmtpClient smtpClient = new SmtpClient();
smtpClient.Send(i);
return WorkflowExecutionStatus.Completed;
}
}
But when i try to send a mail from the website nothing sends.
Any suggestions?
Here are the sendMailWorkflow with atatched pdf
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SendEmailExtended.cs" company="Open Source">
// MIT License
// </copyright>
// <summary>
// The Extended "send email" workflow type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Contour_workflow
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Configuration;
using System.Xml;
using System.Xml.XPath;
using System.Text;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.web;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Enums;
using Umbraco.Forms.Data.Storage;
/// <summary>
/// The send email extended.
/// </summary>
public class IDCWorkflow : WorkflowType
{
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="SendEmailExtended"/> class.
/// </summary>
public IDCWorkflow()
{
this.Id = new Guid("{26f5d74f-50ca-4b52-871d-1b41628da9f8}");
this.Name = "IDC Workflow";
this.Description = "Send the result of the form to 1 or multiple email address (separated with a semi-colon: ';'). For multi-lingual mails you can use the dash notation. For the Message field you can use multiple dictionary items (without spaces only) and newlines can be obtained using \n. To reference a field from your form use a lower-cased, spaceless version of your field name inside curly brackets like: {emailaddress}.";
}
#endregion
#region Properties
/// <summary>
/// Gets or sets Email.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("Email", description = "Enter the receiver email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string Email { get; set; }
/// <summary>
/// Gets or sets From Email.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("From Email", description = "Enter the from email (optional)", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string FromEmail { get; set; }
/// <summary>
/// Gets or sets From Name.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("From Name", description = "Enter the from name (optional)", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string FromName { get; set; }
/// <summary>
/// Gets or sets ReplyTo.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("ReplyTo", description = "Enter the reply-to email", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string ReplyTo { get; set; }
/// <summary>
/// Gets or sets Subject.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("Subject", description = "Enter the subject", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
public string Subject { get; set; }
/// <summary>
/// Gets or sets Message.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("Message", description = "Enter the intro message", control = "Umbraco.Forms.Core.FieldSetting.TextArea")]
public string Message { get; set; }
/// <summary>
/// Gets or sets SendFields.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("SendFields", description = "Send the content of the form fields in the email", control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
public string SendFields { get; set; }
/// <summary>
/// Gets or sets Attachment.
/// </summary>
[Umbraco.Forms.Core.Attributes.Setting("Attachment", description = "Attach file uploads to email", control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
public string Attachment { get; set; }
#endregion
#region Public Methods
/// <summary>
/// The execute.
/// </summary>
/// <param name="record">
/// The record.
/// </param>
/// <param name="e">
/// The Record event arguments.
/// </param>
/// <returns>
/// The Workflow execution status
/// </returns>
public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
{
try
{
MailAddress FromMailAddress;
if (string.IsNullOrEmpty(this.FromEmail))
{
FromMailAddress = new MailAddress(UmbracoSettings.NotificationEmailSender);
}
else
{
if (string.IsNullOrEmpty(this.FromName))
{
FromMailAddress = new MailAddress(this.FromEmail);
}
else
{
FromMailAddress = new MailAddress(this.FromEmail, this.FromName);
}
}
var mailMessage = new MailMessage
{
From = FromMailAddress,
Subject = this.Subject,
ReplyTo = new MailAddress(this.ReplyTo),
IsBodyHtml = true,
BodyEncoding = Encoding.UTF8
};
if (this.Email.Contains(';'))
{
foreach (string email in this.Email.Split(';'))
{
mailMessage.To.Add(email.Trim());
}
}
else
{
mailMessage.To.Add(this.Email);
}
int lang = GetLanguageIdFromNodeId(record.UmbracoPageId);
mailMessage.Body = "<p>" + ReplaceDictionaryItems(this.Message, lang).Replace(@"\n", "<br/>") + "</p>";
if (this.SendFields == true.ToString())
{
mailMessage.Body += this.CreateList(record, mailMessage, lang);
}
var smtpClient = new SmtpClient { EnableSsl = false };
if (WebConfigurationManager.AppSettings.AllKeys.Contains("contourContribUseSsl") && WebConfigurationManager.AppSettings["contourContribUseSsl"].ToLower() == true.ToString().ToLower())
{
smtpClient.EnableSsl = true;
}
smtpClient.Send(mailMessage);
}
catch (Exception ex)
{
Log.Add(LogTypes.Debug, -1, ex.Message);
}
return WorkflowExecutionStatus.Completed;
}
/// <summary>
/// The validate settings.
/// </summary>
/// <returns>
/// An exception list.
/// </returns>
public override List<Exception> ValidateSettings()
{
var exceptions = new List<Exception>();
if (string.IsNullOrEmpty(this.ReplyTo))
{
exceptions.Add(new Exception("'Reply-to' setting not filled out'"));
}
if (string.IsNullOrEmpty(this.Email))
{
exceptions.Add(new Exception("'Email' setting not filled out'"));
}
if (string.IsNullOrEmpty(this.Message))
{
exceptions.Add(new Exception("'Message' setting not filled out'"));
}
return exceptions;
}
#endregion
#region Methods
/// <summary>
/// The get dictionary item.
/// </summary>
/// <param name="item">
/// The dictionary key
/// </param>
/// <param name="lang">
/// The language
/// </param>
/// <returns>
/// The returned dictionary item
/// </returns>
private static string GetDictionaryItem(string item, int lang)
{
// multi word dictionary items are enclosed in square brackets
string translation = new Dictionary.DictionaryItem(item).Value(lang);
// need to check for empty string to show keyname when item not translated
if (string.IsNullOrEmpty(translation))
{
translation = item;
}
return translation;
}
/// <summary>
/// The get language id from node id.
/// </summary>
/// <param name="nodeId">
/// The node id.
/// </param>
/// <returns>
/// The language id from node id.
/// </returns>
private static int GetLanguageIdFromNodeId(int nodeId)
{
Domain[] domains = library.GetCurrentDomains(nodeId);
if (domains != null && domains.Length > 0)
{
return domains[0].Language.id;
}
return 0;
}
/// <summary>
/// The replace dictionary items.
/// </summary>
/// <param name="content">
/// The content.
/// </param>
/// <param name="lang">
/// The language
/// </param>
/// <returns>
/// The replace dictionary items
/// </returns>
private static string ReplaceDictionaryItems(string content, int lang)
{
const string regexPattern = @"(?<!\w)#(?<dic>\w+)";
MatchCollection tagMatches = Regex.Matches(content, regexPattern);
foreach (Match match in tagMatches)
{
string tagName = match.Groups["dic"].Value;
string replacement = GetDictionaryItem(tagName, lang);
content = content.Replace(match.Value, replacement);
}
return content;
}
/// <summary>
/// The create list.
/// </summary>
/// <param name="record">
/// The record.
/// </param>
/// <param name="mailMessage">
/// The mail message.
/// </param>
/// <param name="lang">
/// The language
/// </param>
/// <returns>
/// An HTML list
/// </returns>
private string CreateList(Record record, MailMessage mailMessage, int lang)
{
var viewer = new RecordsViewer();
XmlNode xml = viewer.GetSingleXmlRecord(record, new XmlDocument());
XPathNavigator navigator = xml.CreateNavigator();
XPathExpression selectExpression = navigator.Compile("//fields/child::*");
selectExpression.AddSort("@pageindex", XmlSortOrder.Ascending, XmlCaseOrder.None, string.Empty, XmlDataType.Number);
selectExpression.AddSort(
"@fieldsetindex", XmlSortOrder.Ascending, XmlCaseOrder.None, string.Empty, XmlDataType.Number);
selectExpression.AddSort("@sortorder", XmlSortOrder.Ascending, XmlCaseOrder.None, string.Empty, XmlDataType.Number);
XPathNodeIterator nodeIterator = navigator.Select(selectExpression);
string list = "<dl>";
XPathNavigator node = nodeIterator.Current.SelectSingleNode(".//value");
if (this.Attachment == true.ToString() && node != null)
{
// add attachment
string filelocation = HttpContext.Current.Server.MapPath("/idc/IDCAC01W(3)-1.pdf");
mailMessage.Attachments.Add(new Attachment(filelocation));
}
else
{
XPathNavigator captionNode = nodeIterator.Current.SelectSingleNode("caption");
if (captionNode != null)
{
string caption = captionNode.Value;
if (caption.StartsWith("#"))
{
caption = GetDictionaryItem(caption.TrimStart('#'), lang);
}
list += "<dt><strong>" + caption + ": </strong><dt><dd>";
}
while (nodeIterator.MoveNext())
{
if (nodeIterator.Current == null)
{
continue;
}
XPathNodeIterator values = nodeIterator.Current.Select(".//value");
while (values.MoveNext())
{
if (values.Current != null)
{
list += values.Current.Value.Replace(Environment.NewLine, "<br />").Trim() + "<br />";
}
}
list += "</dd>";
}
}
list += "</dl>";
return list;
}
#endregion
}
}
Send attachment PDF - XSLT Send email, extended
Hi
I need to send a pdf file as attached to an email.
I have umbraco 4.11.8 and umbraco contour 3.0.6
When a user submit the form i need to attache a file to the email the user get as confirmation.
I have installed conrour contrieb, but it only attache the file from the upload field.
I´m a bit stucked here... any ideas hov to attatche a pdf through the XSLT transformed email?
A little help would be great :-)
René
Hi René
I'm not sure it's possible to attach a file to an e-mail using XSLT to send the content of the Contour form unless you create your own "SendMail" extension, which also takes the file path as a parameter I guess.
If you would be okay with just sending a link to the file then have a look at the answer by Dan Evans in this post http://our.umbraco.org/forum/umbraco-pro/contour/6174-Attach-File-To-Email-Form
Hope this helps.
/Jan
Hi
I´m on my way to get it to work :-)
I have used the "Send mail, extended" from Contour Contrib, Umbraco package Repository.
But i´m a bit stucked here.
I have tryed with this "Umbraco.Forms.Core.FieldSetting.Pickers.Content", but of cource i´m only allowed to choose content nodes, instead of media.
Im trying to modify this code to choose a pdf file from a media picker. (From the SendEmailExtended.cs) http://contourcontrib.codeplex.com/SourceControl/latest#Contour.Contrib/Contour.Contrib/WorkflowTypes/SendEmailExtended.cs
Alternative it would be fine to have a textfield to enter the media id.
I can´t figure out how. Is there anyone who could come up with an ideea, tanks in advance.. :-)
René
-
Hello,
I'm using this custom workflow which adds emails as attachments.
Jeroen
Hi
Now i got this working.
I can test the form local with this settings.
But when i try to send a mail from the website nothing sends.
Any suggestions?
Here are the sendMailWorkflow with atatched pdf
Hello,
Are the smtp settings for the website ok? Do you have another form that does work?
Jeroen
HI
Yes i have other forms working
I can see in your previous post you have this in the end.
I think i miss this SmtpClient....
I don't understand. In your code there is also an SmtpClient.
Jeroen
Hi
if any on is in the same situation .
After trying different version of the xslt Send email, extended. Testing and trying to get it to work..
I rearranged the order for sending mails, not for any specifik reason and then it worked.
Rene´
is working on a reply...