7

I am trying to use the Eventsystem to update some (Metadata) Fields when a Component is copied (using copy+paste).

I do NOT get any content (or metadata) saved this way. However, I do get my new Title saved.... Any idea how I can get my Content/Metadata saved?

We do use Tridion 2011 SP1 (no HR!), could it be we need a hotfix here?

subscriptions.Add(EventSystem.Subscribe<Component, CopyEventArgs>(ComponentCopy, EventPhases.Processed)); 

        private void ComponentCopy(Component component, CopyEventArgs args, EventPhases phase)
    {
        Component newComp = (Component) args.CopiedObject;
        ItemFields content = new ItemFields(newComp.Content, newComp.Schema);
        XhtmlField body = (XhtmlField) content["body"];
        body.Value = "Er waren eens een heleboel kamelen " + DateTime.Now.ToLongDateString();
        newComp.Content = content.ToXml();

        ItemFields fields = new ItemFields(newComp.Metadata, newComp.Schema);
        EmbeddedSchemaField embeddedField = (EmbeddedSchemaField)fields["portal"];
        if (embeddedField != null)
        {
            ItemFields embeddedFields = embeddedField.Value;
            if (embeddedFields != null)
            {
                TextField bla = (TextField)embeddedFields["bla"];
                bla.Value = DateTime.Now.ToLongDateString();
                newComp.Metadata = embeddedFields.ToXml();
            }
        }


        // now SAVE the Component, as changes are NOT saved in this phase
        try
        {
            if (!newComp.IsCheckedOut)
            {
                newComp.CheckOut();
            }
            newComp.Title = "TEST-" + DateTime.Now;
            newComp.Save(true);
            if (newComp.IsCheckedOut) newComp.CheckIn();
        }
        catch (Exception ex)
        {
            warn(string.Format("Could not save modified Component after Copy/Paste: {0}", ex.Message));
        }

    }

2 Answers 2

7

So you set the title after making sure your Component is checked out, but you tried to sync back the changes of the content before ensuring it is checked out:

...
// sync content back to Component
newComp.Content = content.ToXml();
...
// sync metadata back to Component
newComp.Metadata = embeddedFields.ToXml();
...
if (!newComp.IsCheckedOut)
{
    newComp.CheckOut();
}
newComp.Title = "TEST-" + DateTime.Now;
newComp.Save(true);

Now if you would first check if your Component needs to be checked out before syncing back its content, then I think you will get a better result on your save. Because I expect that when you call newComp.CheckOut(); all your previous actions on newComp will be reset.

So change it into something like this:

...
if (!newComp.IsCheckedOut)
{
    newComp.CheckOut();
}
newComp.Title = "TEST-" + DateTime.Now;
newComp.Content = content.ToXml();
newComp.Metadata = embeddedFields.ToXml();
newComp.Save(true);

Note that the line if (newComp.IsCheckedOut) newComp.CheckIn(); after calling newComp.Save(true); might undo a "permanent" lock that was set on the Component. Although that might be intentional of course.

1
7

Bart already pointed out the proper order to do this check-out/modify/check-in cycle after the copy operation is performed. Do note that this approach leads to a version 2 on the copy: version 1 is the unmodified copy and your post-processing creates a version 2. This may be exactly what you want, but note that it is also possible to modify the copy without creating an additional version: you can also subscribe to the Initiated phase and modify the state of the subject (without check-out, save, or check-in).

2
  • 1
    It seems not possible to edit the Component while copying it. Copy/Paste will not trigger the save & checkin events, so it must be dealt with in (the initialized phase of the) copy-event. In this phase the copiedObject is still null. In order to modify the copied component, I must checkout & save the component in the processed phase of the copy event Commented Nov 21, 2014 at 15:58
  • 1
    What I meant is that you can change the in-memory state of the event subject (the component parameter in your example code) in the Initiated phase; you should not check-out/save/check-in that parameter (because it represents the source of the copy operation), but its state will be used as source of the copy operation (so will be reflected in version 1 of the copied object). Unfortunately, I have to add that this trick only works for the Title property. Commented Nov 21, 2014 at 18:18

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.