Although this post is quite trivial, EPiServer Content Approvals are a large step forward from the old functionality and as it’s relatively recent, there’s not a lot of posts out there on customising the engine. Most importantly i would have found this post useful had i found it last week!
My requirement is simple in that customers can upload images via an interface on the website product details page. On successful upload, these images are saved as a media asset in a Draft state. These assets contain properties associating it with both the product and customer who uploaded it.
The image will go through a content approval workflow before eventually being either published on the web site or rejected in which case we need to send an email to the customer to notify them of the rejection. Comments are mandatory in the Content Approval workflow on declining an Image so this comment will be included in the email.
There are Approval Engine Events that we can easily hook into and it is well documented in the EPiServer World:
Our image content type has properties linking it to the customer and product so we need to extract the media content reference from the event to do just about whatever we want. Getting that content reference should be the trivial bit…and it is…once you know what to do!
As detailed in the link above, each Approval Engine event provides us with an ApprovalEventArgs object providing us with the context.
Within this object we have the ApprovalId and ApprovalReference properties which we can use to query the approval repository to get us more details:
private void OnRejected(ApprovalEventArgs e) { var approvalRepo = ServiceLocator.Current.GetInstance(); IEnumerable approvalIds = new List() {e.ApprovalID}; var approvalItems = approvalRepo.GetItemsAsync(approvalIds);
The next bit is the bit that got me initially…
Approval Items Results contain an “Approval” object….However this Approval object does not contain the content reference of the item which the event is triggered for. To retrieve the ContentReference you need to cast the Approval to a “ContentApproval” which is derived from Approval.
var contentApproval = (approvalItems.Result.FirstOrDefault() as ContentApproval);
We can now use our contentApproval object to do just about whatever we want. See the code sample below:
using System.Collections.Generic; using System.Linq; using EPiServer; using EPiServer.Approvals; using EPiServer.Approvals.ContentApprovals; using EPiServer.Framework; using EPiServer.Framework.Initialization; using EPiServer.ServiceLocation; using EPiServer.WebApplication.Core.ContentTypes.Media; namespace EPiServer.WebApplication.Infrastructure { [InitializableModule] public class ApprovalEngineEvents : IInitializableModule { private IApprovalEngineEvents _approvalEngineEvents; public void Initialize(InitializationEngine context) { _approvalEngineEvents = context.Locate.Advanced.GetInstance(); _approvalEngineEvents.Rejected += OnRejected; } private void OnRejected(ApprovalEventArgs e) { var contentLoader = ServiceLocator.Current.GetInstance(); var approvalRepo = ServiceLocator.Current.GetInstance(); IEnumerable approvalIds = new List() {e.ApprovalID}; var approvalItems = approvalRepo.GetItemsAsync(approvalIds); var contentApproval = (approvalItems.Result.FirstOrDefault() as ContentApproval); if (contentApproval != null) { var rejectedContent = contentLoader.Get(contentApproval.ContentLink); if (rejectedContent != null) { string comment = e.Comment; // get customer id from page data // get product from page data // send email to customer } } } public void Uninitialize(InitializationEngine context) => _approvalEngineEvents.Rejected -= OnRejected; } }
Nice article, helped me alot.
LikeLiked by 1 person