Created
September 1, 2017 16:49
-
-
Save davidknipe/734dc1f6e1ad78de4fa36c865e9a8cfd to your computer and use it in GitHub Desktop.
A submitted form KPI for Episerver A/B testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Runtime.Serialization; | |
using System.Text; | |
using EPiServer; | |
using EPiServer.Core; | |
using EPiServer.Forms.Core; | |
using EPiServer.Forms.Core.Events; | |
using EPiServer.Framework.Localization; | |
using EPiServer.Marketing.KPI.Exceptions; | |
using EPiServer.Marketing.KPI.Manager.DataClass; | |
using EPiServer.Marketing.KPI.Results; | |
namespace AlloyDemoKit.Business.FormKPI | |
{ | |
[DataContract] | |
public class FilledInFormKpi : Kpi | |
{ | |
private readonly IContentRepository _contentRepository; | |
private readonly IEPiServerFormsCoreConfig _formsConfig; | |
private readonly IFormRepository _formRepository; | |
private readonly LocalizationService _localization; | |
public FilledInFormKpi() | |
{ | |
_formRepository = _servicelocator.GetInstance<IFormRepository>(); | |
_contentRepository = _servicelocator.GetInstance<IContentRepository>(); | |
_formsConfig = _servicelocator.GetInstance<IEPiServerFormsCoreConfig>(); | |
_localization = _servicelocator.GetInstance<LocalizationService>(); | |
} | |
[DataMember] | |
public override string UiMarkup | |
{ | |
get | |
{ | |
// This is used when setting up the custom Kpi in the UI | |
StringBuilder sb = new StringBuilder(); | |
sb.Append("<p>"); | |
sb.Append("<select data-dojo-type=\"dijit/form/ComboBox\" id=\"FormKPIFormId\" name=\"FormKPIFormId\">"); | |
foreach (var form in this.GetAllFormNamesandIds()) | |
{ | |
sb.Append("<option value=\"" + form.Item1 + "\">" + WebUtility.HtmlEncode(form.Item2) + "</option>"); | |
} | |
sb.Append("</select>"); | |
sb.Append("</p>"); | |
return sb.ToString(); | |
} | |
} | |
[DataMember] | |
public override string UiReadOnlyMarkup | |
{ | |
get | |
{ | |
string content = _localization.GetString( | |
"/formkpi/readonlytext", | |
"Has submitted the form"); | |
var foundFormId = GetAllFormNamesandIds() | |
.FirstOrDefault(x => x.Item1 == FormGuid.ToString()); | |
if (foundFormId == null) | |
return "<div>" + content + "</div>"; | |
return "<div>" + content + ": <strong>\"" + foundFormId.Item2 + "\"</strong></div>"; | |
} | |
} | |
[DataMember] | |
public override string Description => _localization.GetString( | |
"/formkpi/description", | |
"Conversion goal is activated when a user submits a completed (finalised) form"); | |
[DataMember] | |
public new string FriendlyName => _localization.GetString( | |
"/formkpi/friendlyname", | |
"Submits form"); | |
[DataMember] | |
public Guid FormGuid; | |
private EventHandler<FormsEventArgs> _eventHander; | |
/// <summary> | |
/// Attach to the form submission finalised event | |
/// </summary> | |
public override event EventHandler EvaluateProxyEvent | |
{ | |
add | |
{ | |
_eventHander = value.Invoke; | |
_servicelocator.GetInstance<FormsEvents>().FormsSubmissionFinalized += _eventHander; | |
} | |
remove | |
{ | |
_servicelocator.GetInstance<FormsEvents>().FormsSubmissionFinalized -= _eventHander; | |
} | |
} | |
public override IKpiResult Evaluate(object sender, EventArgs e) | |
{ | |
var conversionResult = new KpiConversionResult() {KpiId = Id, HasConverted = false}; | |
try | |
{ | |
var formSubmission = (e as FormsSubmittedEventArgs); | |
if (formSubmission != null) | |
conversionResult.HasConverted = formSubmission.FormsContent.ContentGuid == FormGuid; | |
} | |
catch | |
{ | |
// ignored | |
} | |
return conversionResult; | |
} | |
public override void Validate(Dictionary<string, string> responseData) | |
{ | |
// For some unknown reason the Combobox Dojo dijit only supplies us with the | |
// selected text and not the value of the selected item, so we need to | |
// do a reverse look up based on the text to get the actual form id | |
var foundFormId = GetAllFormNamesandIds() | |
.FirstOrDefault(x => x.Item2 == responseData["FormKPIFormId"]); | |
if (foundFormId == null) | |
throw new KpiValidationException( | |
_localization.GetString( | |
"/formkpi/errors/couldnotfindformid", | |
"Could not look up form id, check it hasn't been deleted and select again")); | |
Guid formGuid; | |
var formId = foundFormId.Item1; | |
if (!string.IsNullOrEmpty(formId) && Guid.TryParse(formId, out formGuid)) | |
{ | |
FormGuid = formGuid; | |
} | |
else | |
{ | |
throw new KpiValidationException(_localization.GetString( | |
"/formkpi/errors/selectaform", | |
"Please select a form")); | |
} | |
} | |
private List<Tuple<string, string>> GetAllFormNamesandIds() | |
{ | |
var allForms = new List<Tuple<string, string>>(); | |
foreach (var form in _formRepository.GetFormsInfo(null)) | |
{ | |
allForms.Add(new Tuple<string, string>( | |
form.FormGuid.ToString(), | |
GetFormsPath(form.FormGuid, form.Name) | |
)); | |
} | |
return allForms; | |
} | |
private string GetFormsPath(Guid contentGuid, string formPath) | |
{ | |
var currentItem = _contentRepository.Get<IContent>(contentGuid); | |
var currentParent = _contentRepository.Get<IContent>(currentItem.ParentLink); | |
if (currentItem.ParentLink == _formsConfig.RootFolder) | |
{ | |
return formPath; | |
} | |
formPath = currentParent.Name + " > " + formPath; | |
return GetFormsPath(currentParent.ContentGuid, formPath); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment