M.PCM.Product - Product Gallery - Create public links for added assets, store asset sort order

Use the following code to create an action to create public links for added assets and store asset sort order.

RequestResponse
using System;
using System.Linq;
using System.Threading.Tasks;
using Stylelabs.M.Sdk;
using System.Globalization;
using System.Text;
using System.Collections.Generic;

LogScriptCalled(Context, MClient);

//Get the Product ID
var productId = Context.TargetId.Value;

string changedAssetIds, strExecutionId;

//Get the newly added assets from the Property Bag
Context.PropertyBag.TryGetValue($"{productId}-executionId", out strExecutionId);
Context.PropertyBag.TryGetValue($"{productId}-{strExecutionId}", out changedAssetIds);

LogInfo(Context, MClient, $"Changed Asset Ids are { changedAssetIds }");

var productLoadConfiguration = new EntityLoadConfiguration(CultureLoadOption.Default,
    new PropertyLoadOption("ProductGalleryAssetsInSortedOrder"),
    new RelationLoadOption("ProductToGalleryAsset"));

var productEntity =
    await MClient.Entities.GetAsync(productId, productLoadConfiguration).ConfigureAwait(false);

if (productEntity == null)
{
    LogInfo(Context, MClient, "Product entity is null");
    return;
}

var productGalleryAssetsInSortedOrderProp = productEntity.GetProperty<ICultureInsensitiveProperty>("ProductGalleryAssetsInSortedOrder");

if (productGalleryAssetsInSortedOrderProp ==  null)
{
    LogInfo(Context, MClient, "ProductGalleryAssetsInSortedOrder property does not exist");
    return;
}

var changedAssetIdsList = changedAssetIds.Split(',').Select(c => long.Parse(c));

var assetLoadConfig = new EntityLoadConfiguration(
    CultureLoadOption.Default,
    PropertyLoadOption.None,
    RelationLoadOption.None
);

var changedAssetEntities = await MClient.Entities.GetManyAsync(changedAssetIdsList, assetLoadConfig);

if (changedAssetEntities.Count <= 0)
{
    LogInfo(Context, MClient, "Changed Asset entities for this product does not exist");
    return;
}

var changedAssetEntityIdentifiersString = string.Join(",",changedAssetEntities.Select(c => c.Identifier).ToArray());
LogInfo(Context, MClient, $"Changed Asset entities identifiers {changedAssetEntityIdentifiersString}");

var productGalleryAssetsInSortedOrderVal = productGalleryAssetsInSortedOrderProp.GetValue<string>();
LogInfo(Context, MClient, $"ProductGalleryAssetsInSortedOrder property value {productGalleryAssetsInSortedOrderVal}");

if (!string.IsNullOrWhiteSpace(productGalleryAssetsInSortedOrderVal))
{
    //var productGalleryStoredSortOrderIds = new HashSet<string>(productGalleryAssetsInSortedOrderVal.Split(','));

    //changedAssetEntityIdentifiersList.RemoveAll(a =>
    //                productGalleryStoredSortOrderIds.Any(
    //                    a2 => a2.Equals(a, StringComparison.CurrentCultureIgnoreCase)));

    var changedAssetEntityIdentifiersArray = changedAssetEntityIdentifiersString.Split(',');

    foreach (var changedAssetEntityIdentifier in changedAssetEntityIdentifiersArray)
    {
        if (productGalleryAssetsInSortedOrderVal.Trim().Contains(changedAssetEntityIdentifier, StringComparison.CurrentCultureIgnoreCase))
        {
            LogInfo(Context, MClient, $"ProductGalleryAssetsInSortedOrder property contains asset identifier {changedAssetEntityIdentifier}");
            changedAssetEntityIdentifiersString = changedAssetEntityIdentifiersString.Replace(changedAssetEntityIdentifier, "");
        }
        else
        {
            LogInfo(Context, MClient, $"ProductGalleryAssetsInSortedOrder property does not contain asset identifier {changedAssetEntityIdentifier}");
        }
    }

    if (!string.IsNullOrWhiteSpace(changedAssetEntityIdentifiersString))
    {
        changedAssetEntityIdentifiersString = changedAssetEntityIdentifiersString.Replace(",,", ",");

        if (changedAssetEntityIdentifiersString.StartsWith(","))
            changedAssetEntityIdentifiersString = changedAssetEntityIdentifiersString.Substring(1);

        if (changedAssetEntityIdentifiersString.EndsWith(","))
            changedAssetEntityIdentifiersString = changedAssetEntityIdentifiersString.Substring(0, changedAssetEntityIdentifiersString.Length - 1);
    }

    LogInfo(Context, MClient, $"Changed Asset entities identifiers after match {changedAssetEntityIdentifiersString}");
}

//Check and create public links if new assets are added to Product Gallery
if (!string.IsNullOrWhiteSpace(changedAssetEntityIdentifiersString))
{
    //Loop though the assets
    foreach (var changedAssetIdentifier in changedAssetEntityIdentifiersString.Split(','))
    {
        var changedAssetEntity = changedAssetEntities.FirstOrDefault(a => a.Identifier == changedAssetIdentifier);

        if (changedAssetEntity == null)
        {
            LogInfo(Context, MClient, $"Asset with identifier '{changedAssetIdentifier}' does not exist");
            continue;
        }

        var assetId = changedAssetEntity.Id.Value;

        // Check if public links don't exist yet
        var query = Query.CreateQuery(entities => from e in entities
            where e.DefinitionName == "M.PublicLink"
                    && e.Parent("AssetToPublicLink") == assetId
                    && (e.Property("Resource") == "productgallery")
                    && e.Property("IsDisabled") == false
            select e);
        query.Take = 1;

        var result = await MClient.Querying.QueryIdsAsync(query);
        if (result.TotalNumberOfResults > 0)
        {
            LogInfo(Context, MClient, $"Public links already exist for asset with id '{assetId}'");
            continue;
        }

        // Create public links
        await CreateForRendition("productgallery", assetId);
        LogInfo(Context, MClient, $"Created public link 'productgallery' for asset with id '{assetId}'");
    }
}

//Update the Product property with assets identified in sorted order
await UpdateProduct(productEntity, productGalleryAssetsInSortedOrderProp).ConfigureAwait(false);

private async Task UpdateProduct(IEntity productEntity, ICultureInsensitiveProperty productGalleryAssetsInSortedOrderProp)
{
    var productToGalleryAssetRelation =
        productEntity.GetRelation<IParentToManyChildrenRelation>("ProductToGalleryAsset");

    var entityLoadConfiguration = new EntityLoadConfiguration(CultureLoadOption.Default,
        PropertyLoadOption.None, RelationLoadOption.None);

    var productGalleryAssetEntities =
        await MClient.Entities.GetManyAsync(productToGalleryAssetRelation.GetIds(), entityLoadConfiguration).ConfigureAwait(false);

    var sbProductGalleryAssetEntityIdentifiers = new StringBuilder();
    foreach (var assetId in productToGalleryAssetRelation.GetIds())
    {
        var productGalleryAssetEntity =
            productGalleryAssetEntities.FirstOrDefault(asset => asset.Id == assetId);

        if (productGalleryAssetEntity != null)
            sbProductGalleryAssetEntityIdentifiers.Append($"{productGalleryAssetEntity.Identifier},");
    }

    var productGalleryAssetEntityIdentifiers = string.Empty;

    if (sbProductGalleryAssetEntityIdentifiers.Length > 0 && sbProductGalleryAssetEntityIdentifiers.ToString().EndsWith(","))
        productGalleryAssetEntityIdentifiers = sbProductGalleryAssetEntityIdentifiers.ToString()
            .Substring(0, sbProductGalleryAssetEntityIdentifiers.Length - 1);

    LogInfo(Context, MClient, $"Product Gallery Assets Identifiers in sorted order {productGalleryAssetEntityIdentifiers}");
    productGalleryAssetsInSortedOrderProp.SetValue(productGalleryAssetEntityIdentifiers);

    await MClient.Entities.SaveAsync(productEntity).ConfigureAwait(false);
}

private async Task CreateForRendition(string rendition, long assetId)
{
    var publicLink = await MClient.EntityFactory.CreateAsync("M.PublicLink");

    if (publicLink.CanDoLazyLoading())
    {
        await publicLink.LoadMembersAsync(new PropertyLoadOption("Resource"), new RelationLoadOption("AssetToPublicLink")).ConfigureAwait(false);
    }

    publicLink.SetPropertyValue("Resource", rendition);

    var relation = publicLink.GetRelation<IChildToManyParentsRelation>("AssetToPublicLink");
    if (relation == null)
    {
        LogError(Context, MClient, "Unable to create public link: no AssetToPublicLink relation found.");
        return;
    }

    relation.Parents.Add(assetId);

    await MClient.Entities.SaveAsync(publicLink).ConfigureAwait(false);
    return;
}

#region Helpers

void LogScriptCalled(IActionScriptContext context, IMClient client)
{
    var executionId = Guid.NewGuid().ToString("N").Substring(0, 6);
    LogInfo(context, client, $"{executionId}: Execution started. Context: {context}");
}

void LogDebug(IActionScriptContext context, IMClient client, string message)
{
    client.Logger.Debug(LogPrefix(context) + message);
}

void LogInfo(IActionScriptContext context, IMClient client, string message)
{
    client.Logger.Info(LogPrefix(context) + message);
}

void LogError(IActionScriptContext context, IMClient client, string message)
{
    client.Logger.Error(LogPrefix(context) + message);
}

string LogPrefix(IActionScriptContext context)
{
    return $"{ (context?.TargetId != null ? context.TargetId.Value.ToString() : string.Empty)} | ";
}

#endregion

Do you have some feedback for us?

If you have suggestions for improving this article,