Quick question, we have 2 workflows on a form. The first one is standard workflow sends email out to someone. The second workflow also sends email that is run through razor template all works fine. What i want to do is for the second workflow only fire when record in backend is approved. What do i need todo to get this to work?
Hmm that was easy. So in answer to my question on the form check manual approval then move the custom work flow to approval status and bingo!! I have said it before will say it again if you are doing forms in umbraco without contour you are doing it wrong!!!!
i dont suppose you have an example of your second workflow do you? I'd like to be able to send an email after the form is submitted but using a razor template and pull through certain items from the form submission, i only see an XSLT Transform Email in the options and i'd love to be able to do the same with Razor instead of XSLT.
I understand if its for a client and you cant share the code but i dont suppose you have an example you could point me to otherwise?
The way i have done it is anything i need to do i do in the workflow and pass through to the model so i dont need to access httpcontext in razor see below:
using RazorEngine;
using RazorEngine.Templating;
using SSE.Common.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Attributes;
using Umbraco.Forms.Core.Enums;
using Umbraco.Web;
using File = System.IO.File;
namespace SSE.BusinessLogic.Contour
{
public class SendRazorTransformedEmailWorkflow : WorkflowType
{
public static int pageID = -1;
[Setting("Email", control = "Umbraco.Forms.Core.FieldSetting.TextField", description = "Enter the receiver email")]
public string Email { get; set; }
[Setting("Subject", control = "Umbraco.Forms.Core.FieldSetting.TextField", description = "Enter the subject")]
public string Subject { get; set; }
[Setting("RazorFile", control = "Umbraco.Forms.Core.FieldSetting.File", description = "The .cshtml file to transform the record. (<a href='/umbraco/plugins/pandemicode/razor/sendRazorEmailSample.cshtml.txt' target='_blank'>Sample File</a>)")]
public string RazorFile { get; set; }
static SendRazorTransformedEmailWorkflow()
{
}
public SendRazorTransformedEmailWorkflow()
{
this.Name = "Send Razor Transformed Email";
this.Id = new Guid("fcdcb88b-24d6-4a53-800d-cf9e46ce91ee");
this.Description = "Send the result of the form to an email address";
}
public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
{
try
{
var message = new MailMessage
{
From = new MailAddress(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress),
Subject = this.Subject,
IsBodyHtml = true
};
if (Email.Contains(";"))
{
AddMultiRecipients(message);
}
else
{
message.To.Add(Email);
}
string emailBody = string.Empty;
if (!string.IsNullOrEmpty(this.RazorFile))
{
emailBody = GetEmailBody(emailBody);
}
message.Body = emailBody;
try
{
new SmtpClient().Send(message);
}
catch (SmtpException ex)
{
LogHelper.Error(typeof(SendRazorTransformedEmailWorkflow), "WorkflowExecutionStatus error sending email ", ex);
}
catch (Exception ex)
{
LogHelper.Error(typeof(SendRazorTransformedEmailWorkflow), "WorkflowExecutionStatus error processing record ", ex);
}
}
catch (TemplateCompilationException ex)
{
var errors = new StringBuilder();
ex.Errors.ToList().ForEach(p => errors.AppendLine(p.ErrorText));
LogHelper.Error(typeof(SendRazorTransformedEmailWorkflow), "WorkflowExecutionStatus template compile error " + errors.ToString(), ex);
}
catch (Exception ex)
{
LogHelper.Error(typeof(SendRazorTransformedEmailWorkflow), "WorkflowExecutionStatus error ", ex);
}
return (WorkflowExecutionStatus)3;
}
private string GetEmailBody(string emailBody)
{
using (StreamReader streamReader = File.OpenText(HttpContext.Current.Request.MapPath(this.RazorFile)))
{
string razor = streamReader.ReadToEnd();
IPublishedContent homePage = UmbracoContext.Current.ContentCache.GetByXPath("//Home").FirstOrDefault();
var razorModel = new RazorTemplateModel
{
DateOfEvent = homePage.GetPropertyValue<DateTime>("dateOfEvent"),
EventLocation = HttpUtility.HtmlDecode(homePage.GetPropertyValue<string>("location")),
BaseUrl = "http://" + HttpContext.Current.Request.ServerVariables["HTTP_HOST"] + "/images/"
};
emailBody = Razor.Parse<RazorTemplateModel>(razor, razorModel);
}
return emailBody;
}
private void AddMultiRecipients(MailMessage message)
{
string email = this.Email;
var chArray = new char[1] { ';' };
foreach (string str in email.Split(chArray))
{
message.To.Add(str.Trim());
}
}
public override List<Exception> ValidateSettings()
{
List<Exception> list = new List<Exception>();
if (string.IsNullOrEmpty(this.Email))
list.Add(new Exception("'Email' setting not filled out"));
if (string.IsNullOrEmpty(this.Subject))
list.Add(new Exception("'Subject' setting not filled out"));
return list;
}
}
Where do you create this class? Do you create a Class Library and add it to your solution, or a stand alone Class Library and build and drop the DLL into your sites bin folder? Or even create a folder within the site and drop a class into there?
The problem i think im having is refrencing all the required references, especially the RazorEngine and Umbraco.Forms. If i add a class to my website and add the refrences it breaks the site.
Whats the standard way of adding it? if i create it in a stand alone class library i need to refrence a lot of DLLs and one is still HTTPContext.
I have separate class project and the class is in there i also add all references there. I could have also added it to the site this is becuase when starting new projects i have blank solution and i add website then nuget down umbraco. If you are doing similar it should work for you as well. However try it with separate project class library and then reference that in your website.
Approval workflow
Hello,
Quick question, we have 2 workflows on a form. The first one is standard workflow sends email out to someone. The second workflow also sends email that is run through razor template all works fine. What i want to do is for the second workflow only fire when record in backend is approved. What do i need todo to get this to work?
Regards
Ismail
Hmm that was easy. So in answer to my question on the form check manual approval then move the custom work flow to approval status and bingo!! I have said it before will say it again if you are doing forms in umbraco without contour you are doing it wrong!!!!
Ismail
Hi Ismail
i dont suppose you have an example of your second workflow do you? I'd like to be able to send an email after the form is submitted but using a razor template and pull through certain items from the form submission, i only see an XSLT Transform Email in the options and i'd love to be able to do the same with Razor instead of XSLT.
I understand if its for a client and you cant share the code but i dont suppose you have an example you could point me to otherwise?
Cheers
Neil.
Ah just found this - http://our.umbraco.org/projects/backoffice-extensions/send-razor-transformed-email-contour-workflow
Should do what i need it to :)
I should of done a bit more digging before asking, sorry.
Neil,
Yup thats the one i did with a few mods if you need the code let me know.
Hi Ismail
Dont suppose you could email me that code could you?
Seems to not be working for me and think id be better stepping through the code.
Ive used the one from bitbucket but cant reference HTTPContext for the RazorFile.
Could you email it to [email protected]
Cheers
Neil.
Neil,
The way i have done it is anything i need to do i do in the workflow and pass through to the model so i dont need to access httpcontext in razor see below:
using RazorEngine.Templating; using SSE.Common.Model; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Mail; using System.Text; using System.Web; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Forms.Core; using Umbraco.Forms.Core.Attributes; using Umbraco.Forms.Core.Enums; using Umbraco.Web; using File = System.IO.File;
namespace SSE.BusinessLogic.Contour { public class SendRazorTransformedEmailWorkflow : WorkflowType { public static int pageID = -1;
}
Regards
Ismail
Cheers Ismail
Where do you create this class? Do you create a Class Library and add it to your solution, or a stand alone Class Library and build and drop the DLL into your sites bin folder? Or even create a folder within the site and drop a class into there?
The problem i think im having is refrencing all the required references, especially the RazorEngine and Umbraco.Forms. If i add a class to my website and add the refrences it breaks the site.
Whats the standard way of adding it? if i create it in a stand alone class library i need to refrence a lot of DLLs and one is still HTTPContext.
Just a little unsure of the mechanics of it all.
Neil,
I have separate class project and the class is in there i also add all references there. I could have also added it to the site this is becuase when starting new projects i have blank solution and i add website then nuget down umbraco. If you are doing similar it should work for you as well. However try it with separate project class library and then reference that in your website.
Regards
Ismail
Cheers Ismail, i'll have a go at it and see if i can get it to work.
Cheers
Neil.
is working on a reply...