即使在 InDesign 中编辑,Sitecore PXM/APS 中使用的内容能否受工作流控制?

Can content used in Sitecore PXM/APS be controlled by workflow even when edited in InDesign?

背景

我在 Sitecore Print Experience Manager (PXM*) 项目中使用由工作流控制的内容。 PXM 的一项重要功能是能够在从 InDesign 查看流式内容时将内容更改保存回 Sitecore。

问题

不幸的是,当将内容项保存回 Sitecore 时,它​​保存了数据,但没有参与该项目的工作流程。

问题

有没有办法将工作流程与 Sitecore PXM InDesign 连接器结合起来?

*以前称为 Adaptive Print Studio,或 APS

PXM 不支持开箱即用。但是,在 Mark Demeny at Sitecore, I was able to create a workable solution. I made a video demonstrating how it works.

的帮助下

item:saving 事件

我向 Sitecore 的 item:saving 事件添加了一个事件处理程序,该事件处理程序拦截来自 InDesign 的对处于最终工作流状态的内容项的保存,添加新版本,将更改应用到该版本,保存该版本, 并取消原来的存档。

SaveProcessor.cs

public class SaveProcessor
{
    private Template _StandardTemplate;
    private const string PRINT_STUDIO_SITE_NAME = "printstudio";
    private static readonly List<Guid> _ActiveItemIds = new List<Guid>();

    public void OnItemSaving(object sender, EventArgs args)
    {
        // Only intercept updates from PXM
        if (Context.Site.Name.Equals(PRINT_STUDIO_SITE_NAME))
        {
            var sitecoreEventArgs = args as SitecoreEventArgs;
            var updatedItem = sitecoreEventArgs?.Parameters[0] as Item;

            if (updatedItem != null)
            {
                // If we're already working with this item, allow this save to continue normally (prevents infinite recursion)
                if (!_ActiveItemIds.Contains(updatedItem.ID.Guid))
                {
                    var originalItem = Context.Database.GetItem(updatedItem.ID);
                    if (originalItem != null)
                    {
                        var workflow = Context.Database.WorkflowProvider.GetWorkflow(originalItem);
                        var workflowState = workflow?.GetState(originalItem);

                        // If the current item is not in workflow, or it is in workflow but the current state is not final, allow the save to continue normally
                        if (workflowState != null && workflowState.FinalState)
                        {
                            var differences = new Dictionary<string, string>();
                            foreach (Field field in updatedItem.Fields)
                            {
                                var updatedItemField = updatedItem.Fields[field.ID];
                                var originalItemField = originalItem.Fields[field.ID];

                                // Find all the differences that are not standard fields
                                if (updatedItemField != null &&
                                    !IsStandardField(updatedItemField) &&
                                    originalItemField != null &&
                                    !updatedItemField.Value.Equals(originalItemField.Value))
                                {
                                    differences.Add(field.Name, updatedItemField.Value);
                                }
                            }

                            // If there are no differences, allow the save to continue normally
                            if (differences.Count > 0)
                            {
                                // Add this item ID to the list of currently-processing item IDs
                                _ActiveItemIds.Add(updatedItem.ID.Guid);

                                try
                                {
                                    originalItem.Editing.BeginEdit();
                                    var newVersion = originalItem.Versions.AddVersion();
                                    newVersion.Editing.BeginEdit();
                                    foreach (var difference in differences)
                                    {
                                        newVersion[difference.Key] = difference.Value;
                                    }
                                    newVersion.Editing.EndEdit();
                                    originalItem.Editing.EndEdit();
                                }
                                finally
                                {
                                    // Remove this item ID from the list of currently-processing item IDs
                                    _ActiveItemIds.Remove(updatedItem.ID.Guid);
                                }

                                sitecoreEventArgs.Result.Cancel = true;
                            }
                        }
                    }
                }
            }
        }
    }

    public bool IsStandardField(Field field)
    {
        if (_StandardTemplate == null)
            _StandardTemplate = TemplateManager.GetTemplate(Sitecore.Configuration.Settings.DefaultBaseTemplate, field.Database);

        return _StandardTemplate.ContainsField(field.ID);
    }
}

您还需要修补 web.config 文件才能使用新的事件处理程序。

App_Config\Include\SaveProcessor.config

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
    <events>
        <event name="item:saving">
            <handler type="TestPxm.Pxm.SaveProcessor,TestPxm" method="OnItemSaving" patch:before="handler[@type='Sitecore.Tasks.ItemEventHandler, Sitecore.Kernel']"/>
        </event>
    </events>
</sitecore>
</configuration>