Search code examples
sitecoresitecore8web-forms-for-marketerssitecore-mvcsitecore-xdb

Sitecore WFFM: Issues Submitting form programmatically


I have been trying to submit a my own form to WFFM. The form I created is identical to the one created with WFFM, that way all fields map correctly.

I began following the following steps: https://jermdavis.wordpress.com/2015/05/18/programmatic-wffm-submissions/

I had to make minor changes to the code in order to get the SubmitActionManager to work

The members of Sitecore.Form.Core.Submit.SubmitActionManager class have been moved to the IActionExecutor interface.To obtain the instance of this interface use the (IActionExecutor)Factory.CreateObject ("wffm/wffmActionExecutor", false) call.

Below is the code I have so far:

public void SubmitData(ContactUsFormModel data)
    {
        var results = new List<ControlResult>();
        results.Add(makeControlResult(Models.Constants._cufFirstNameID, "First Name", data.FirstName));
        results.Add(makeControlResult(Models.Constants._cufLastNameID, "Last Name", data.LastName));
        results.Add(makeControlResult(Models.Constants._cufEmailID, "Email", data.Email));
        results.Add(makeControlResult(Models.Constants._cufCompanyID, "Company", data.Company));
        results.Add(makeControlResult(Models.Constants._cufSubjectID, "Subject", data.Subject));
        results.Add(makeControlResult(Models.Constants._cufMessageID, "Message", data.Message));

        var formItem = Sitecore.Context.Database.GetItem(Models.Constants._contactUsFormID);
        var simpleForm = new SitecoreSimpleForm(formItem);
        var saveActionXml = simpleForm.FormItem.SaveActions;
        var actionList = Sitecore.Form.Core.ContentEditor.Data.ListDefinition.Parse(saveActionXml);

        var actionDefinitions = new List<ActionDefinition>();
        actionDefinitions.AddRange(actionList.Groups.SelectMany(x => x.ListItems).Select(li => new ActionDefinition(li.ItemID, li.Parameters) { UniqueKey = li.Unicid }));

        var SubmitActionManager = (IActionExecutor)Factory.CreateObject("wffm/wffmActionExecutor", false);
        Sitecore.Form.Core.WffmActionEvent sessionID = new Sitecore.Form.Core.WffmActionEvent();// SessionIDGuid

        var result = SubmitActionManager.ExecuteSaving(ID.Parse(Models.Constants._contactUsFormID), results.ToArray(), actionDefinitions.ToArray(), true, ID.Parse( sessionID.SessionIDGuid ));
    }

    private ControlResult makeControlResult(string fieldID, string fieldName, string fieldValue)
    {
        return new ControlResult(fieldName, fieldValue, string.Empty)
        {
            FieldID = fieldID,
            FieldName = fieldName,
            Value = fieldValue,
            Parameters = string.Empty
        };
    }

I wasnt sure where to get Sitecore.Form.Core.Analytics.AnalyticsTracker.SessionId from to use it inside ExecuteSaving, so I used WffmActionEvent. Also the guide I followed uses Execute, which is now deprecated, so I had to go with ExecureSaving (my best guess).

This however doesn't seem to be posting the submitted data into the databse. I am unable to see any of my submissions inside WFFM Form Reports or inside mongoDB. The logs however state that the form is being saved to the database, not sure what the other warnings mean.

24688 17:20:39 WARN  [WFFM] Tracker.Current  is not initialized
24688 17:20:39 INFO  AUDIT (sitecore\admin): [WFFM] Form {978DBF4C-0F56-45A8-A9AC-52EF8D995DDF} is saving to db
24688 17:20:39 WARN  [WFFM] Tracker.Current.Contact  is not initialized
24688 17:20:39 WARN  [WFFM]  Tracker.Current.Interaction  is not initialized
24688 17:20:39 WARN  [WFFM] CurrentSession  is not initialized

Solution

  • As you are using Sitecore 8 the form submission is stored in MongoDB. Sitecore's implementation of MongoDB, xDB mostly relies on tracking users, calling them Contacts.

    Most data stored in xDB is linked to a Contact via a ContactId. The error messages you are finding in the log are stating that tracking is currently not enabled, therefore no Contact is present and there is no Interaction between the site and user.

    Therefore you need to start Sitecore.Tracker I recommend using the following code

    if (!Tracker.IsActive)
        Tracker.StartTracking();
    
    if (!Tracker.IsActive || Tracker.Current.Contact == null)
    {
        // handle no tracker and contact
    }
    

    Now that you have tracking working you need to use the correct ID for your sessionID variable.

    The blog you are following is based on Sitecore 7, in Sitecore 8 Sitecore.Form.Core.Analytics.AnalyticsTracker.SessionId is removed. I decompiled the Sitecore 7 code and Sitecore.Form.Core.Analytics.AnalyticsTracker.SessionId ultimately uses Tracker.CurrentVisit.VisitId.

    However this namespace has changed in Sitecore 8, Visits are now called interactions so instead of your variable SessionID you will want to use

    Tracker.Current.Interaction.InteractionId;
    

    That should resolve the issue you are currently having but you may need a bit more development to finish it off.