2

I'm trying to capture the resolved items using the Publish Context of my current Publish Transaction.

My code works in case of Publish of a Bundle and all the resolved items for the respective Identifiable object are fetched. But same code fails to capture when it is Unpublish.

This is the code I'm using

List<PublicationTarget> pubTargets = new List<PublicationTarget> { pubTrans.PublishContexts.First().PublicationTarget };

// Gets theTridion ResolvedItems for the Current Component from ResolveInstruction
var resolvedItems = default(Tridion.Collections.ISet<ResolvedItem>);
if (isBundleItem)
{
    var pubContext = ResolveEngine.ResolvePublishContext(publishedObject, pubTrans.Instruction.ResolveInstruction, pubTargets);
    resolvedItems = ResolveEngine.ResolveItem(publishedObject, pubTrans.Instruction.ResolveInstruction, pubContext.First());
}

I'm passing the Publish Transaction through an event.

EventSystem.Subscribe<PublishTransaction, SaveEventArgs>(PublishOnTransactionSaveFinished, EventPhases.TransactionCommitted);

This is what I found in CHM file for TOM.NET API.

ResolveItem Gets a list of ResolvedItem to be (un-/re-)published to given PublishContext if an (un-/re-)publish action is performed on this item.

This suggests that the method should work for both Publish and Unpublish. Please let me know what I'm missing here.

2
  • Can you explain what you are trying to achieve with this code? Have you checked what pubTrans.Instruction.ResolveInstruction looks like? Commented Nov 27, 2014 at 20:10
  • I'm trying to capture the resolved items for a component in a Bundle during unpublish. pubTrans give me a complete set of resolved Items that include Resolved Items for all the componens in the Bundle. What I needed was resolved Items per component. Commented Dec 1, 2014 at 7:12

2 Answers 2

2

What do you mean by "code fails"? Do you get exception? Is your handler executed? Do you get empty list?

First of all you shouldn't call Resolve yourself as there already are ResolvedItems on PublishTransaction and you definitley shouldn't be doing anything like this in synchronous handler, you should use SubscribeAsync for it. If you do it with Subscribe you are blocking the execution thread, it means that all other processes will wait for your event handler to complete. So your publish transaction will not actually be saved until your event handler is done. As you are doing resolving inside, which is quite heavy operation, you will get quite big performance hit. If you do it asynchronously - you will get a snapshot of publish transaction and eventArgs in your event handler and unpublish process will proceed on its own without waiting for your handler. There's also remote possibility that by the time you will start resolving, the items will already be unpublished, but I doubt it as it's gonna take way longer then execution time of your event handler.

So your code will look like:

var resolvedItems = pubTrans.PublishContexts.First().ResolvedItems;

Resolved items on unpublish transaction might be empty if non of the items are published for this context. If you get 0 items it means that there are no relevant items to be unpublished in this context

3
  • Please note that I'm facing the problem when I unpublish a Bundle and the code does not fail. It gives me 0 resolved items. pubTrans.ResolvedItems.First().ResolvedItems; works perfectly fine for one single Item, but it returns list of all items when it's a Bundle. What I need is resolved items for each component in a Bundle from the list of pubTrans.ResolvedItems.First().ResolvedItems; Could you please elaborate as to Why it should be SunscribeAsync. Commented Nov 27, 2014 at 9:06
  • Updated my answer Commented Nov 27, 2014 at 10:45
  • I'm going into event system at publishTransaction.State == PublishTransactionState.Success.. Will Async call do any good in this case? Commented Nov 28, 2014 at 8:37
1

The issue was that my event was capturing details after there is a SUCCESS message from deployer. In case of UnPublish, the code

var pubContext = ResolveEngine.ResolvePublishContext(publishedObject, pubTrans.Instruction.ResolveInstruction, pubTargets);
resolvedItems = ResolveEngine.ResolveItem(publishedObject, pubTrans.Instruction.ResolveInstruction, pubContext.First());

does not work because ResolveEngine recalculates the Resolved Items and since the pages have already been unpublished, there are no items to Reolve too. Hence I was getting 0 Count in case of unpublish.

I used the WhereUsed concept to fetch the Resolved Items in case of Unpublish. Below is the code for same.

// Resolved Item will not return any pages after publishing success, Hence, pages are fetched using Where Used functionality
                            var allResolvedPagesInBundle = pubTrans.PublishContexts.First().ResolvedItems.Where(x =>x.Item.Id.ItemType == ItemType.Page);
                            IEnumerable<Page> resolvedPages = GetResolvedPages(currentComponent);
                            resolvedItems = allResolvedPagesInBundle.Where(x => resolvedPages.Contains(x.Item as Page)); 

/// <summary>
    /// Gets the List of Resolved Page upto 3 Levels of Component Linking
    /// </summary>
    /// <param name="item">Component</param>
    /// <param name="level">Current Level of Component Linking</param>
    /// <returns>List of Resolved Pages</returns>
    private List<Page> GetResolvedPages(Component item, int level = 0)
    {
        List<Page> resolvedPages = new List<Page>();
        try
        {
            //TO-DO - Get Value from Configuration Component
            if (level < 3)
            {
                UsingItemsFilter usingFilter = new UsingItemsFilter(item.Session)
                {
                    ItemTypes = new ItemType[] { ItemType.Component, ItemType.Page },
                    IncludedVersions = VersionCondition.OnlyLatestVersions,
                    BaseColumns = ListBaseColumns.Id,
                };

                IEnumerable<IdentifiableObject> usingItems = item.GetUsingItems(usingFilter);
                //Adds Pages to Page List
                resolvedPages.AddRange(usingItems.Where(it => it.Id.ItemType == ItemType.Page).Cast<Page>());

                IEnumerable<Component> resolvedComponents = usingItems.Where(it => it.Id.ItemType == ItemType.Component).Cast<Component>();
                if (resolvedComponents != null && resolvedComponents.Count() > 0)
                {                        
                    foreach (IdentifiableObject localObject in resolvedComponents)
                    {
                        resolvedPages.AddRange(GetResolvedPages(localObject as Component, level + 1));

                    }
                }
            }
        }
        catch(Exception ex)
        {
            throw new Exception("Error Occured GetResolvedPages While Fetching the Where Used Item for Component ID =\"" + item.Id + "\" Error:" + ex.Message);
        }

        return resolvedPages.Distinct().ToList();
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.