private IList <FieldDesynchronization> GetFieldSyncStatus(SitecoreSourceItem item, ISerializedItem serializedItem, IFieldPredicate fieldPredicate) { var desyncs = new List <FieldDesynchronization>(); var serializedVersion = serializedItem.Versions.FirstOrDefault(x => x.VersionNumber == item.InnerItem.Version.Number && x.Language == item.InnerItem.Language.Name); if (serializedVersion == null) { desyncs.Add(new FieldDesynchronization("Version")); return(desyncs); } item.InnerItem.Fields.ReadAll(); foreach (Field field in item.InnerItem.Fields) { if (field.ID == FieldIDs.Revision || field.ID == FieldIDs.Updated || field.ID == FieldIDs.Created || field.ID == FieldIDs.CreatedBy || field.ID == FieldIDs.UpdatedBy || field.Type.Equals("attachment", StringComparison.OrdinalIgnoreCase) || !fieldPredicate.Includes(field.ID).IsIncluded) { continue; } // we're doing a data comparison here - revision, created (by), updated (by) don't matter // skipping these fields allows us to ignore spurious saves the template builder makes to unchanged items being conflicts // find the field in the serialized item in either versioned or shared fields string serializedField; if (!serializedVersion.Fields.TryGetValue(field.ID.ToString(), out serializedField)) { serializedItem.SharedFields.TryGetValue(field.ID.ToString(), out serializedField); } // we ignore if the field doesn't exist in the serialized item. This is because if you added a field to a template, // that does not immediately re-serialize all items based on that template so it's likely innocuous - we're not overwriting anything. if (serializedField == null) { continue; } if (!serializedField.Equals(field.Value, StringComparison.Ordinal)) { desyncs.Add(new FieldDesynchronization(field.Name)); } } return(desyncs); }
public void CopyItem(ItemDefinition source, ItemDefinition destination, string copyName, ID copyId, CallContext context) { if (DisableSerialization) { return; } // copying is easy - all we have to do is serialize the copyID. Copied children will all result in multiple calls to CopyItem so we don't even need to worry about them. var copiedItem = new SitecoreSourceItem(Database.GetItem(copyId)); if (!_predicate.Includes(copiedItem).IsIncluded) { return; // destination parent is not in a path that we are serializing, so skip out } _serializationProvider.SerializeItem(copiedItem); _logger.CopiedItem(_serializationProvider.LogName, () => GetSourceFromDefinition(source), copiedItem); }
private string GetErrorValue(SaveArgs args) { var results = new Dictionary <Item, IList <FieldDesynchronization> >(); try { foreach (var item in args.Items) { Item existingItem = Client.ContentDatabase.GetItem(item.ID, item.Language, item.Version); Assert.IsNotNull(existingItem, "Existing item {0} did not exist! This should never occur.", item.ID); var existingSitecoreItem = new SitecoreSourceItem(existingItem); foreach (var configuration in _configurations) { // ignore conflicts on items that Unicorn is not managing if (!configuration.Resolve <IPredicate>().Includes(existingSitecoreItem).IsIncluded) { continue; } ISerializedReference serializedReference = configuration.Resolve <ISerializationProvider>().GetReference(existingSitecoreItem); if (serializedReference == null) { continue; } // not having an existing serialized version means no possibility of conflict here ISerializedItem serializedItem = serializedReference.GetItem(); if (serializedItem == null) { continue; } var fieldPredicate = configuration.Resolve <IFieldPredicate>(); var fieldIssues = GetFieldSyncStatus(existingSitecoreItem, serializedItem, fieldPredicate); if (fieldIssues.Count == 0) { continue; } results.Add(existingItem, fieldIssues); } } // no problems if (results.Count == 0) { return(null); } var sb = new StringBuilder(); sb.Append("CRITICAL MESSAGE FROM UNICORN:\n"); sb.Append("You need to run a Unicorn sync. The following fields did not match the serialized version:\n"); foreach (var item in results) { if (results.Count > 1) { sb.AppendFormat("\n{0}: {1}", item.Key.DisplayName, string.Join(", ", item.Value.Select(x => x.FieldName))); } else { sb.AppendFormat("\n{0}", string.Join(", ", item.Value.Select(x => x.FieldName))); } } sb.Append("\n\nDo you want to overwrite anyway?\nTHIS MAY CAUSE LOST WORK."); return(sb.ToString()); } catch (Exception ex) { Log.Error("Exception occurred while performing serialization conflict check!", ex, this); return("Exception occurred: " + ex.Message); // this will cause a few retries } }