Skip to content

Instantly share code, notes, and snippets.

@dsolovay
Created December 21, 2021 22:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsolovay/4e497b2b5607346cb6009ea4971df273 to your computer and use it in GitHub Desktop.
Save dsolovay/4e497b2b5607346cb6009ea4971df273 to your computer and use it in GitHub Desktop.
How to modify Campaign Creator to not embed IDs in campaign names
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:env="http://www.sitecore.net/xmlconfig/env/">
<sitecore >
<services>
<configurator type="CustomCampaignRepository.ServicesConfigurator, CustomCampaignRepository" />
</services>
</sitecore>
</configuration>
using System;
using System.Globalization;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Marketing.Campaigns.Services.Data;
using Sitecore.Marketing.Campaigns.Services.Model;
using Sitecore.Marketing.Definitions;
using Sitecore.Marketing.Definitions.Campaigns;
using Sitecore.Marketing.Taxonomy.Model;
using Sitecore.Nexus.Consumption;
using Sitecore.Services.Core;
namespace CustomCampaignRepository
{
public class CustomCampaignRepository: Sitecore.Marketing.Campaigns.Services.Data.CampaignRepository, IFilteredRepository<CampaignEntity>, IRepository<CampaignEntity>
{
private readonly CultureInfo _cultureInfo;
private readonly IDefinitionManager<ICampaignActivityDefinition> _campaignActivityDefinitionManager;
public CustomCampaignRepository(IDefinitionManager<ICampaignActivityDefinition> campaignActivityDefinitionManager) : base(campaignActivityDefinitionManager)
{
this._cultureInfo = CultureInfo.GetCultureInfo("en");
_campaignActivityDefinitionManager = campaignActivityDefinitionManager;
}
public new void Add(CampaignEntity entity)
{
AssertEntityConditions(entity);
DateTime? nullable1 = string.IsNullOrEmpty(entity.StartDate) ? new DateTime?() : new DateTime?(DateUtil.ToUniversalTime(DateUtil.ParseDateTime(entity.StartDate, DateTime.MinValue)));
DateTime? nullable2 = string.IsNullOrEmpty(entity.EndDate) ? new DateTime?() : new DateTime?(DateUtil.ToUniversalTime(DateUtil.ParseDateTime(entity.EndDate, DateTime.MaxValue)));
// Begin modified behavior.
// The Campaign Creator default behavior is to embed the item ID into the name,
// which prevents using externally created query string codes.
string alias = ItemUtil.ProposeValidItemName(entity.Name);
// string alias = ItemUtil.ProposeValidItemName(FormattableString.Invariant(FormattableStringFactory.Create("{0}-{1}", (object) entity.Name, (object) entity.Id)));
// End modified behavior. Other code is reflected.
CampaignActivityDefinition activityDefinition = new CampaignActivityDefinition(Guid.Parse(entity.Id), alias, this._cultureInfo, entity.Name, DateTime.UtcNow, Context.User.Name)
{
StartDate = nullable1,
EndDate = nullable2
};
this.MapClassificationsFromCampaignEntityToCampaignDefinition(entity, (ICampaignActivityDefinition) activityDefinition);
this._campaignActivityDefinitionManager.SaveAsync((ICampaignActivityDefinition) activityDefinition, true).ConfigureAwait(false).GetAwaiter().GetResult();
Track("CM.Tracker.SUM.NewCampaign|SUM|sVj8qr7en1C2fjdVc+xsH4mOdEBwAA7iHDJnAoNPx27BAnASsPBXeQz7o5YLHtValc/n139VklvTiQ8yhIpK8w==");
}
#region Reflected private methods
private void Track(string metricToTrack)
{
var client = TelemetryFactory.CreateClient();
try
{
client.Track(metricToTrack, 1UL);
}
catch (Exception ex)
{
Log.Error("Telemetry Error.", ex, ex.GetType());
}
}
private static void AssertEntityConditions(CampaignEntity entity)
{
Assert.ArgumentNotNull((object) entity, nameof (entity));
Assert.IsTrue(ID.IsID(entity.Id), "Id");
Assert.ArgumentCondition(string.IsNullOrEmpty(entity.StartDate) || DateUtil.IsIsoDate(entity.StartDate), nameof (entity), "Start date must be represented by ISO date.");
Assert.ArgumentCondition(string.IsNullOrEmpty(entity.EndDate) || DateUtil.IsIsoDate(entity.EndDate), nameof (entity), "End date must be represented by ISO date.");
}
private void MapClassificationsFromCampaignEntityToCampaignDefinition(
CampaignEntity entity,
ICampaignActivityDefinition definition)
{
Assert.ArgumentNotNull((object)entity, nameof(entity));
Assert.ArgumentNotNull((object)definition, nameof(definition));
if (entity.Classifications == null)
return;
foreach (CampaignClassificationEntity classification in entity.Classifications)
{
Guid key = Guid.Parse(classification.FieldId);
definition.Classifications[key] = new TaxonUri(this._cultureInfo, classification.Value);
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Sitecore.DependencyInjection;
using Sitecore.Marketing.Campaigns.Services.Data;
using Sitecore.Marketing.Campaigns.Services.Model;
namespace CustomCampaignRepository
{
public class ServicesConfigurator:IServicesConfigurator
{
// "[Replace] removes the first service in IServiceCollection with the same service type as descriptor and adds descriptor to the collection."
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.extensions.servicecollectiondescriptorextensions.replace?view=dotnet-plat-ext-6.0&viewFallbackFrom=netframework-4.8
public void Configure(IServiceCollection serviceCollection)
{
Type serviceType = typeof(IFilteredRepository<CampaignEntity>);
Type implementationType = typeof(CustomCampaignRepository);
serviceCollection.Replace(new ServiceDescriptor(serviceType, implementationType, ServiceLifetime.Transient));
}
}
}
@dsolovay
Copy link
Author

Did some digging into how to make CampaignCreator not embed the campaign ID. Some reflected private methods because CampaignRepository was not designed for extensiblity.

Request in to Sitecore to make this behavior changeable by configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment