Created
August 31, 2012 09:43
-
-
Save janhebnes/3550920 to your computer and use it in GitHub Desktop.
Sitecore CMS - Handling Item copying where DataSources are referenced inside the copied structure, to inserted in the Item:Copied event queue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Class used to update Spot Context Data, when copying trees in Sitecore. | |
/// </summary> | |
public class LayoutDataSourceReferenceUpdater | |
{ | |
#region Properties | |
/// <summary> | |
/// Gets or sets the new root Item (source item). | |
/// </summary> | |
/// <value>The new root Item.</value> | |
public Item NewRoot | |
{ | |
get; | |
set; | |
} | |
/// <summary> | |
/// Gets or sets the original root Item (destination item). | |
/// </summary> | |
/// <value>The original root Item.</value> | |
public Item OriginalRoot | |
{ | |
get; | |
set; | |
} | |
#endregion Properties | |
#region Methods | |
/// <summary> | |
/// Updates the references using <see cref="OriginalRoot"/> and <see cref="NewRoot"/>. | |
/// </summary> | |
/// <param name="parameters">The parameters.</param> | |
public void UpdateReferences(object[] parameters) | |
{ | |
Assert.IsNotNull(OriginalRoot, "OriginalRoot cannot be null"); | |
Assert.IsNotNull(NewRoot, "NewRoot cannot be null"); | |
UpdateTree(OriginalRoot); | |
} | |
/// <summary> | |
/// Finds the corresponding item using <see cref="OriginalRoot"/> and <see cref="NewRoot"/>. | |
/// </summary> | |
/// <param name="itemBeingCopied">The item being copied.</param> | |
/// <returns></returns> | |
private Item FindCorrespondingItem(Item itemBeingCopied) | |
{ | |
if (!itemBeingCopied.Axes.IsDescendantOf(OriginalRoot)) | |
{ | |
return null; | |
} | |
string relativePath = itemBeingCopied.Paths.FullPath.Substring(OriginalRoot.Paths.FullPath.Length); | |
string newItemPath = String.Concat(NewRoot.Paths.FullPath, relativePath); | |
return NewRoot.Database.GetItem(newItemPath, itemBeingCopied.Language, itemBeingCopied.Version); | |
} | |
/// <summary> | |
/// Updates the items Context fields to point to correct references. | |
/// </summary> | |
/// <param name="itemBeingCopied">The item being copied.</param> | |
private void UpdateItemFields(Item itemBeingCopied) | |
{ | |
LayoutField layoutField = new LayoutField(itemBeingCopied.Fields[Sitecore.FieldIDs.LayoutField]); | |
if (layoutField.InnerField.HasValue && itemBeingCopied.Languages.Count() > 0) | |
{ | |
Item newItem = FindCorrespondingItem(itemBeingCopied); | |
if (newItem == null) | |
{ | |
Log.Warn(String.Format("Unable to find corresponding item for copied item {0} - root {1}.", itemBeingCopied.Paths.FullPath, OriginalRoot.Paths.FullPath), this); | |
return; | |
} | |
foreach (Language language in itemBeingCopied.Languages) | |
{ | |
Item versionedItem = itemBeingCopied.Database.GetItem(itemBeingCopied.ID, language, | |
itemBeingCopied.Version); | |
if (versionedItem != null && versionedItem.Versions.Count > 0) | |
{ | |
foreach (var itemVersion in versionedItem.Versions.GetVersions()) | |
{ | |
if (itemVersion != null) | |
{ | |
// Loop all datasources, if sources is child tree FindCorrespondingItem and replace | |
layoutField = new LayoutField(itemVersion.Fields[Sitecore.FieldIDs.LayoutField]); | |
if (!layoutField.InnerField.HasValue) | |
{ | |
continue; | |
} | |
var rawLayout = itemVersion.Fields[Sitecore.FieldIDs.LayoutField].Value; | |
if (string.IsNullOrWhiteSpace(layoutField.Value)) | |
{ | |
continue; | |
} | |
LayoutDefinition layout = LayoutDefinition.Parse(layoutField.Value); | |
for (int i = 0; i < layout.Devices.Count; i++) | |
{ | |
DeviceDefinition device = layout.Devices[i] as DeviceDefinition; | |
for (int j = 0; j < device.Renderings.Count; j++) | |
{ | |
RenderingDefinition rendering = device.Renderings[j] as RenderingDefinition; | |
if (!string.IsNullOrEmpty(rendering.Datasource)) | |
{ | |
Item datasourceItem = itemVersion.Database.GetItem(rendering.Datasource); | |
if (datasourceItem == null) | |
{ | |
Log.Warn(string.Format("Could not find datasource item {0} while copying item {1}", rendering.Datasource, itemVersion.ID), this); | |
continue; | |
} | |
// Exit if datasource is not a descendend of the item being copied | |
if (!datasourceItem.Axes.IsDescendantOf(itemBeingCopied)) | |
{ | |
continue; | |
} | |
// Find new datasource if it is not under path of parent | |
Item correspondingItem = FindCorrespondingItem(datasourceItem); | |
if (correspondingItem == null) | |
{ | |
Log.Warn(string.Format("Could not find datasource target item {0} while copying item {1}", rendering.Datasource, itemVersion.ID), this); | |
continue; | |
} | |
rawLayout = rawLayout.Replace(datasourceItem.ID.ToString(), | |
correspondingItem.ID.ToString()); | |
} | |
} | |
} | |
// Replace Layout field on new item | |
newItem = itemVersion.Database.GetItem(newItem.ID, itemVersion.Language, | |
itemVersion.Version); | |
if (rawLayout != newItem.Fields[Sitecore.FieldIDs.LayoutField].Value) | |
{ | |
// Save updated layout information | |
newItem.Editing.BeginEdit(); | |
newItem.Fields[Sitecore.FieldIDs.LayoutField].Value = rawLayout; | |
newItem.Editing.EndEdit(); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Updates a tree in Sitecore (fixes all references in the tree). | |
/// </summary> | |
/// <param name="root">The root Item.</param> | |
private void UpdateTree(Item root) | |
{ | |
UpdateItemFields(root); | |
foreach (Item child in root.GetChildren(ChildListOptions.None)) | |
{ | |
UpdateTree(child); | |
} | |
} | |
/// <summary> | |
/// Called when the item copied event runs. Will update the Context references contained in the copied tree structure. | |
/// </summary> | |
/// <param name="sender">The sender.</param> | |
/// <param name="args">The <see cref="System.EventArgs"/> instance containing the event data.</param> | |
protected void OnItemCopied(object sender, EventArgs args) | |
{ | |
Item itemThatWasCopied = Event.ExtractParameter(args, 0) as Item; | |
Item itemRootCreatedByCopy = Event.ExtractParameter(args, 1) as Item; | |
Error.AssertNotNull(itemThatWasCopied, "No sourceItem in parameters"); | |
Error.AssertNotNull(itemRootCreatedByCopy, "No targetItem in parameters"); | |
LayoutDataSourceReferenceUpdater updater = new LayoutDataSourceReferenceUpdater | |
{ | |
NewRoot = itemRootCreatedByCopy, | |
OriginalRoot = itemThatWasCopied | |
}; | |
ProgressBox.Execute( | |
Sitecore.Globalization.Translate.Text("Updating context references"), | |
Sitecore.Globalization.Translate.Text("Updating context references"), | |
"Applications/16x16/form_blue.png", | |
new ProgressBoxMethod(updater.UpdateReferences), | |
new object[] | |
{ | |
Event.ExtractParameter(args, 0), | |
Event.ExtractParameter(args, 1) | |
}); | |
} | |
#endregion Methods | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment