Skip to content

Instantly share code, notes, and snippets.

@agehlot
Created March 14, 2021 00:43
Show Gist options
  • Save agehlot/ea7550eaae341654ee4f15965b9791d5 to your computer and use it in GitHub Desktop.
Save agehlot/ea7550eaae341654ee4f15965b9791d5 to your computer and use it in GitHub Desktop.
Collection of helper methods for Sitecore Tracking field
using Sitecore.Analytics.Data;
using Sitecore.Analytics.Data.Items;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Core.Foundation.SitecoreExtensions.Helpers
{
/// <summary>
/// Class TrackingFieldHelper.
/// </summary>
public class TrackingFieldHelper
{
/// <summary>
/// Gets the profile keys.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IEnumerable&lt;System.String&gt;.</returns>
public static IEnumerable<string> GetProfileKeys(Item item)
{
return TrackingFieldHelper.GetProfileDetail(item).Select(p => p.Value).ToList();
}
/// <summary>
/// Gets the profile detail.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IEnumerable&lt;KeyValuePair&lt;System.String, System.String&gt;&gt;.</returns>
public static IEnumerable<KeyValuePair<string, string>> GetProfileDetail(Item item)
{
if (item != null && item["__Tracking"] != string.Empty)
{
return TrackingFieldHelper.GetProfileDetail(item["__Tracking"]).ToList();
}
return new List<KeyValuePair<string, string>>();
}
/// <summary>
/// Gets the profile detail.
/// </summary>
/// <param name="xml">The XML.</param>
/// <returns>IEnumerable&lt;KeyValuePair&lt;System.String, System.String&gt;&gt;.</returns>
public static IEnumerable<KeyValuePair<string, string>> GetProfileDetail(string xml)
{
var doc = XElement.Parse(xml);
var elements =
from el in doc.Elements()
select el;
var profileData = ProfileExtensions.GetProfileData();
foreach (XElement c in elements)
{
foreach (XElement profileEl in c.Elements())
{
if (int.TryParse(profileEl.Attribute("value").Value, out int profileValue))
{
if (profileValue > 0)
{
//yield return new KeyValuePair<string, string>(c.Attribute("name").Value, profileEl.Attribute("name").Value);
yield return new KeyValuePair<string, string>(c.Attribute("name").Value, ProfileExtensions.GetProfileKeyTitle(profileEl.Attribute("name").Value, profileData));
}
}
}
}
}
/// <summary>
/// https://sitecore.stackexchange.com/questions/19786/how-to-update-profile-card-to-content-item-programmatically
/// </summary>
/// <param name="contentItem">The content item.</param>
/// <param name="tags">The tags.</param>
/// <param name="tagValue">The tag value.</param>
/// <param name="errors">The errors.</param>
/// <param name="isItemInEditMode">if set to <c>true</c> [is item in edit mode].</param>
public static void UpdateTrackingField(Item contentItem, string[] tags, double tagValue, out string errors, bool isItemInEditMode = false)
{
// retrieve tracking information
errors = string.Empty;
ProfileUtil.GetProfiles(contentItem, out TrackingField trackingField);
var trackingValue = contentItem.Fields["__Tracking"].Value;
List<string> processedTags = new List<string>();
if (tags.Length > 0)
{
Database master = Factory.GetDatabase("master", false);
Item profileContainer = master.GetItem(AnalyticsProfile.ContainerItemID);
var allRelevantProfiles = profileContainer.Axes.GetDescendants().Where(p => p.TemplateID == Constants.AnalyticsProfile.ProfileTemplateID);
foreach (var item in allRelevantProfiles)
{
var currentTagValue = tagValue;
if (item.Name.ToLower() == "premium level tags") currentTagValue = 1;
// get needed profile
var profile = trackingField.Profiles.FirstOrDefault(p => p.ProfileID.Guid.Equals(item.ID.Guid));
if (profile != null)
{
var profileItem = new ProfileItem(profile.GetProfileItem());
// iterate through profile cards and add NEEDED key/values to presets dictionary
foreach (var profileCard in profileItem.ProfileCards)
{
bool isFound = false;
if (tags.Any(p => p.Trim().ToLower() == profileCard.InnerItem.Key.Trim().ToLower()))
{
processedTags.Add(profileCard.InnerItem.Key.Trim().ToLower());
isFound = true;
}
if (tags.Any(p => p.Trim().ToLower() == profileCard.InnerItem["name"].ToLower()))
{
processedTags.Add(profileCard.InnerItem["name"].ToLower());
isFound = true;
}
if(isFound)
profile.Keys.FirstOrDefault(key => key.Key.ToLower() == profileCard.InnerItem.Key
|| key.Key.ToLower() == profileCard.InnerItem["name"]).Value = currentTagValue;
}
profile.SaveToField = true;
SetProfileKeys(profile, profileItem);
if (profile.Any(p => p.Value > 0))
TrackingField.UpdateKeyValues(profile);
}
}
var notFoundList = tags.Except(processedTags, StringComparer.OrdinalIgnoreCase);
errors = string.Join(",", notFoundList);
}
// update "Tracking" field raw-value of contentItem
XDocument document = string.IsNullOrEmpty(trackingValue) ? new XDocument(new XElement("tracking")) : XDocument.Parse(trackingValue);
XElement xelement1 = document.Element("tracking");
if (xelement1 == null)
{
xelement1 = new XElement("tracking");
document.Add(xelement1);
}
List<XElement> list = xelement1.Elements("profile").ToList();
foreach (XElement t in list)
{
t.Remove();
}
foreach (XElement xelement2 in trackingField.Profiles.Where(x => x.SaveToField && x.Any(y => y.Value > 0)).Select(x => x.ToXElement()))
xelement1.Add(xelement2);
// save
using (new SecurityDisabler())
{
if (!isItemInEditMode)
{
contentItem.Editing.BeginEdit();
contentItem.Fields["__Tracking"].Value = document.ToString();
contentItem.Editing.EndEdit();
}
else
contentItem.Fields["__Tracking"].Value = document.ToString();
}
}
/// <summary>
/// Sets the profile keys.
/// </summary>
/// <param name="profile">The profile.</param>
/// <param name="profileItem">The profile item.</param>
public static void SetProfileKeys(ContentProfile profile, ProfileItem profileItem)
{
foreach (ProfileKeyItem profileKeyItem in profileItem.Keys.ToList())
{
ProfileKeyItem keyItem = profileKeyItem;
if (profile.Keys.FirstOrDefault(k => string.Compare(k.Key, keyItem.Name, StringComparison.InvariantCultureIgnoreCase) == 0) == null)
{
ContentProfileKeyData key = new ContentProfileKeyData(keyItem.KeyName)
{
Value = keyItem.GetDefaultValue()
};
profile.AddKey(key);
}
}
foreach (ContentProfileKeyData key in profile.Keys.Where(key => key.ProfileKeyDefinitionId == Guid.Empty))
{
profile.RemoveKey(key);
}
if (profile.Any(p => p.Value > 0))
TrackingField.UpdateKeyValues(profile);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment