A colleague of mine has been looking at some custom page events and reporting in Sitecore 8.1 recently. One thing which came to light during this work is that some of the personalisation rule code in the product didn't appear to work as expected. In case anyone else is looking at this aspect of the software, he's a summary of the issue we were seeing, in the hope that it can help you avoid the time we spent looking into this:
This is supposed to allow you to trigger a personalisation when a certain page event has been recorded for the current user, and it's custom data matches the criteria specified. However we found that this did not work as expected.
Cue some head-scratching, and a bit of debugging...
The rule's logic is part of the
PageEventWithCustomDataWasTriggeredDuringPastOrCurrentInteractionCondition
class (Snappy name, huh?) in the Sitecore.Analytics.Rules.Conditions namespace. So we grabbed our trusty decompiler and looked through what this code was doing when a rule is evaluated. Through inheritance, this class makes use of the same
Execute()
method as the
PageEventWasTriggeredDuringPastOrCurrentInteractionCondition
class. That code, tidied up a bit, looks like:
protected override bool Execute(T ruleContext) { // -- snip if (this.HasEventOccurredInInteraction((IInteractionData) Tracker.Current.Session.Interaction)) { return true; } // -- snip return this.FilterKeyBehaviorCacheEntries(Tracker.Current.Contact.GetKeyBehaviorCache()).Any<KeyBehaviorCacheEntry>((Func<KeyBehaviorCacheEntry, bool>) (entry => { Guid id = entry.Id; Guid? pageEventGuid = this.PageEventGuid; if (pageEventGuid.HasValue) { return id == pageEventGuid.GetValueOrDefault(); } return false; })); }
Based on that, if the event happened in the current session then only the
HasEventOccurredInInteraction()
method is called. If not, the
FilterKeyBehaviorCacheEntries()
method is called. Digging deeper
FilterKeyBehaviorCacheEntries()
‘s behaviour depends on which rule is being run (it may or may not filter based on custom event data, depending on whether you're using the "with custom data" version of the rule or not).
But
HasEventOccurredInInteraction()
does not have any code that looks at the custom data, and it makes no reference to the
FilterKeyBehaviorCacheEntries()
method which does. It looks like this:
protected override bool HasEventOccurredInInteraction(IInteractionData interaction) { // -- snip return ((IEnumerable<Page>) interaction.Pages).SelectMany<Page, PageEventData>((Func<Page, IEnumerable<PageEventData>>) (page => page.PageEvents)).Any<PageEventData>((Func<PageEventData, bool>) (pageEvent => { if (pageEvent.IsGoal) { return false; } Guid eventDefinitionId = pageEvent.PageEventDefinitionId; Guid? pageEventGuid = this.PageEventGuid; if (pageEventGuid.HasValue) { return eventDefinitionId == pageEventGuid.GetValueOrDefault(); } return false; })); }
That code seems to explain the behaviour we've been seeing – the logic is actually different depending on whether the Page Event fired in the current session or not...