How To Hook Into Episerver Commerces 8 Catalog Event Handlers

A common requirement on a commerce project is to hook into the the commerce pages events handler, for example you may need to do things like:

  • Call an additional search index when a new game/variants is published
  • Call a third party service, like a pricing service
  • Add custom validation to prevent a product being saved under certain circumstances

In today’s guide, we are going to cover the basics of doing this in Episerver Commerce 8, using the CatalogEventListenerBase.

Catalog EventListener

The Catalog Event Listener is new to Episerver Commerce 8. It provides a mechanism to listen to all the vents within your catalog. TO start hooking into events you need to extend from the CatalogEventListenerBase. You can read more about the different event available to you from CatalogEventListenerBase at EpiWorld here.

In order to override the default Episerver CatalogEventListener, you need to implement from CatalogEventListenerBase and then decorate your new class with the ServiceConfiguration attribute with the ‘typeof’ property set as a CatalogEventListenerBase, like so:

[ServiceConfiguration(typeof(CatalogEventListenerBase))]
public class CustomCatalogEventListenerBase : CatalogEventListenerBase
{
}

You can then override the events you are interested in like so:

[ServiceConfiguration(typeof(CatalogEventListenerBase))]
public class GmgCatalogEventListenerBase : CatalogEventListenerBase
{
public override void EntryUpdating(object source, EntryEventArgs args)
{
}
public override void RelationUpdating(object source, RelationEventArgs args)
{
}
}

Warning!!! After a few hours working with the API, I probably should warn you that it is definitely not the most developer friendly API I’ve worked with. Instead of working with typed objects like you do with pages and blocks in the CMS, the API works on a much lower abstraction level. When you work with the CatalogEvent entities you will be working in the DataTables and DataRows level. This can make it a bit tricky to figure out what you need to do and where you need to get your data from, but with a bit of persistence you can hopefully survive.

After you have your CustomCatalogEventListenerBase set-up, you can now think about events you want to hook into. The rest of this guide will cover a few basic example.

Hooking into commerce’s publish event

When you want to hook in the save/publish events, you need to override the EntryUpdating event. This uses the CatalogEntryDto as the source object. The below snippet always ensures the variant code is set to the first value it was published with:

public override void EntryUpdating(object source, EntryEventArgs args)
{
var variant = source as CatalogEntryDto;
var catalogEntryRow = catalogEntryDto.CatalogEntry.FirstOrDefault();
if (catalogEntryRow == null)
return;
if (catalogEntryRow.RowState == System.Data.DataRowState.Modified)
{
var workId = 0;
var referenceConverter = ServiceLocator.Current.GetInstance<ReferenceConverter>();
var variantLink = referenceConverter.GetContentLink(catalogEntryRow.CatalogEntryId, workId);
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var firstVersionOfVariant = repo.Get<VariationContent>(variantLink);
if (firstVersionOfVariant == null)
return;
catalogEntryRow.Code = firstVariant.Code;
}
}

The firs thing we do is get the actual data for the content being published, using these lines:

var variant = source as CatalogEntryDto;
var catalogEntryRow = variant.CatalogEntry.Rows[0]
as Mediachase.Commerce.Catalog.Dto.CatalogEntryDto.CatalogEntryRow;

Typing it is really important, otherwise you won’t be able to get any of the VariationContent data that you probably want to manipulate.

The next important line in this snippet is this

catalogEntryRow.RowState == System.Data.DataRowState.Modified

You can use RowState check to determine if the data being saved is new, or, if the object already exists in the database.

Hooking into the relation updating event

This event is useful if you want to add validation or similar when you move content around the page tree. When you create new associations, the location of the variant/product can change without the EntryUpdating event being triggered. When we want to hook into the relation updating events we use the RelationUpdating event. This uses CatalogRelationDto as the source object.

public override void RelationUpdating(object source, RelationEventArgs args)
{
var catalogRelationDto = source as CatalogRelationDto;
var itemsBeingUpdated = catalogRelationDto.NodeEntryRelation;
var failedValidation = false;
foreach (var itemBeingUpdated in itemsBeingUpdated)
{
if (itemBeingUpdated.RowState == System.Data.DataRowState.Added)
{
// Do Logic here
if (itemBeingUpdated.CatalogId == 9)
{
failedValidation = true;
}
}
}
if (failedValidation)
catalogRelationDto.RejectChanges();
}

Conclusion

In today’s guide, we have discussed how you can hook into Episerver commerce’s catalog events. Using the CustomCatalogEventListenerBase you can listen out for all the catalogs, node and products events. By overriding CustomCatalogEventListenerBase and creating your own implementation you can override the default event actions and add in your own custom code.

There are several ways you can hook into Episerver commerce events but if you want catalog specific events, then CustomCatalogEventListenerBase is probably your best bet.

We also covered two different examples of how you can use CustomCatalogEventListenerBase in your project, one that will prevent a value from changing after it has first been set. The other example shows how you can prevent nodes/products being dragged into certain areas within the Episerver catalog tree.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *