7

I am working on Event System code and am trying to retrieve the PublicationTarget(s) for the current item being published. The PublishEventArgs has a property called Targets which you would think is a list of PublicationTarget(s) but is a list of TargetTypes.

I need the PublicationTarget(s) for the current item so I can test and make sure the item isn’t already scheduled for that given target and the date as well.

Any assistance would be greatly appreciated.

I currently have the following block of code:

           private void ProcessComponent(Component component, String processEvent, PublishEventArgs pubArgs, UnPublishEventArgs unPubArgs)
    {
        if (!IsEventSystemActive())
        {
            return;
        }

        if (IsBundle(component))
        {
            Session session = component.Session;
            Publication publication = component.ContextRepository as Publication;
            //Component configComponent = session.GetObject(publication.WebDavUrl + "/Building%20Blocks/Content/System/System%20Configuration.xml") as Component;

            ItemFields cmpFields = new ItemFields(component.Content, component.Schema);
            ComponentLinkField cmpLinkField = cmpFields["Items"] as ComponentLinkField;

            DateField pubDate = cmpFields["PublishDate"] as DateField;
            DateTime date = new DateTime();
            date = pubDate.Value;

            foreach (Component linkedComp in cmpLinkField.Values)
            {
                switch (processEvent)
                {
                    case "Publish":
                        foreach (PublicationTarget pTarg in pubArgs.Targets)
                        {
                            if (!IsInPublishingQueue(session, linkedComp.Id, 0, 0, pubArgs.PublishInstruction.StartAt, pTarg))
                            {
                                Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pTarg);
                            }
                        }
                        break;
                    case "UnPublish":
                        foreach (PublicationTarget pTarg in unPubArgs.Targets)
                        {
                            if (!IsInPublishingQueue(session, linkedComp.Id, 0, 1, unPubArgs.UnPublishInstruction.StartAt, pTarg))
                            {
                                Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pTarg);
                            }
                        }
                        break;
                }
            }
        }
        else
        {
            Component bundleComponent = GetBundleComponent(component);
            if (bundleComponent != null)
            {
                ActivityInstance activity = GetActivityInstance(bundleComponent);
                if (activity != null)
                {
                    string message = string.Format("Component is part of Bundle \"{0}\", which is in Workflow \"{1}\". Publishing the item individually not allowed.",
                        bundleComponent.Title, activity.ActivityDefinition.Title);
                    throw new Exception(message);
                }
            }
        }
    }

This code is giving me a cast error due to the fact that the PublishEventArgs.Targets contains TargetType(s) and not PublicationTarget(s).

5

This should sort you out:

        PublicationTargetsFilter filter = new PublicationTargetsFilter(component.Session);
        SystemManager systemManager = component.Session.SystemManager;
        systemManager.GetPublicationTargets(filter);
  • This just gets a list of all Publication Targets. How does it help determining the current target you're publishing to? – Nuno Linhares Mar 27 '13 at 8:38
6

With some assistance I was able to get the PublicationTarget(s). Turns out I needed to do a little bit of extra lifting to get it working, but here is the Function again with the new code changes:

    private void ProcessComponent(Component component, String processEvent, PublishEventArgs pubArgs, UnPublishEventArgs unPubArgs)
    {
        if (!IsEventSystemActive())
        {
            return;
        }

        if (IsBundle(component))
        {
            Session session = component.Session;
            Publication publication = component.ContextRepository as Publication;
            //Component configComponent = session.GetObject(publication.WebDavUrl + "/Building%20Blocks/Content/System/System%20Configuration.xml") as Component;

            ItemFields cmpFields = new ItemFields(component.Content, component.Schema);
            ComponentLinkField cmpLinkField = cmpFields["Items"] as ComponentLinkField;

            DateField pubDate = cmpFields["PublishDate"] as DateField;
            DateTime date = new DateTime();
            date = pubDate.Value;

            PublicationTargetsFilter filter = new PublicationTargetsFilter(session);
            SystemManager systemManager = session.SystemManager;
            List<PublicationTarget> pubTargets = new List<PublicationTarget>(systemManager.GetPublicationTargets(filter));

            foreach (Component linkedComp in cmpLinkField.Values)
            {
                switch (processEvent)
                {
                    case "Publish":
                        foreach (TargetType pTarg in pubArgs.Targets)
                        {
                            foreach (PublicationTarget pubTarg in pubTargets)
                            {
                                if (pubTarg.TargetTypes.Contains(pTarg))
                                {
                                    if (!IsInPublishingQueue(session, linkedComp.Id, 0, 0, pubArgs.PublishInstruction.StartAt, pubTarg))
                                    {
                                        Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pubTarg);
                                    }
                                }
                            }
                        }
                        break;
                    case "UnPublish":
                        foreach (TargetType pTarg in unPubArgs.Targets)
                        {
                            foreach (PublicationTarget pubTarg in pubTargets)
                            {
                                if (pubTarg.TargetTypes.Contains(pTarg))
                                {
                                    if (!IsInPublishingQueue(session, linkedComp.Id, 0, 1, unPubArgs.UnPublishInstruction.StartAt, pubTarg))
                                    {
                                        Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pubTarg);
                                    }
                                }
                            }
                        }
                        break;
                }
            }
        }
        else
        {
            Component bundleComponent = GetBundleComponent(component);
            if (bundleComponent != null)
            {
                ActivityInstance activity = GetActivityInstance(bundleComponent);
                if (activity != null)
                {
                    string message = string.Format("Component is part of Bundle \"{0}\", which is in Workflow \"{1}\". Publishing the item individually not allowed.",
                        bundleComponent.Title, activity.ActivityDefinition.Title);
                    throw new Exception(message);
                }
            }
        }
    }

Added the following right before the ForEach that handles the Linked components:

            PublicationTargetsFilter filter = new PublicationTargetsFilter(session);
            SystemManager systemManager = session.SystemManager;
            List<PublicationTarget> pubTargets = new List<PublicationTarget>(systemManager.GetPublicationTargets(filter));

Then added the following ForEach statments:

                switch (processEvent)
                {
                    case "Publish":
                        foreach (TargetType pTarg in pubArgs.Targets)
                        {
                            foreach (PublicationTarget pubTarg in pubTargets)
                            {
                                if (pubTarg.TargetTypes.Contains(pTarg))
                                {
                                    if (!IsInPublishingQueue(session, linkedComp.Id, 0, 0, pubArgs.PublishInstruction.StartAt, pubTarg))
                                    {
                                        Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pubTarg);
                                    }
                                }
                            }
                        }
                        break;
                    case "UnPublish":
                        foreach (TargetType pTarg in unPubArgs.Targets)
                        {
                            foreach (PublicationTarget pubTarg in pubTargets)
                            {
                                if (pubTarg.TargetTypes.Contains(pTarg))
                                {
                                    if (!IsInPublishingQueue(session, linkedComp.Id, 0, 1, unPubArgs.UnPublishInstruction.StartAt, pubTarg))
                                    {
                                        Publish_UnPublish(linkedComp, unPubArgs, pubArgs, pubTarg);
                                    }
                                }
                            }
                        }
                        break;
                }
3

I recently did something like this:

if (args.Targets is IEnumerable<PublicationTarget>)
{
    PublishEngine.Publish(somePages, instruction, args.Targets.Cast<PublicationTarget>());
}
else
{
    PublishEngine.Publish(somePages, instruction, args.Targets.Cast<TargetType>());
}

I have to say, as I wrote it, I was wishing for a tidier way. Frankly, the API should allow you to pass in the collection it handed you.

  • I agree about a tidier way. The API should allow you to pass in the collection it returns. – TridionNut Mar 26 '13 at 19:41
  • The thing is, that the API needs to support both, because publishing supports both. If you call a Publish method and pass in Publication Targets, that's what the event will have to deal with. – Dominic Cronin Mar 26 '13 at 23:13
2

If all you want is to know the current Publication Target(s) you're publishing to, this simple LINQ should get you going:

List<PublicationTarget> publicationTargets = (from XmlNode node in session.GetList(filter) 
                        select (PublicationTarget)session.GetObject(node.Attributes["ID"].Value) into target 
                        where target.TargetTypes.Contains(targetType) 
                        where target.Publications.Contains(context) 
                        select target).ToList();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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