Skip to content

Commit

Permalink
Merge pull request #34 from SitecoreUnicorn/develop
Browse files Browse the repository at this point in the history
2.1.0 Release
  • Loading branch information
cassidydotdk authored Jun 2, 2019
2 parents 29c6dd8 + 9afc7db commit 49e26a2
Show file tree
Hide file tree
Showing 18 changed files with 197 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void Deserialize_DeserializesNewItem()
new FakeItemVersion(1, "en", new FakeFieldValue("Hello", fieldId: _testVersionedFieldId.Guid))
});

var deserialized = deserializer.Deserialize(item);
var deserialized = deserializer.Deserialize(item, null);

Assert.NotNull(deserialized);

Expand Down Expand Up @@ -225,7 +225,7 @@ public void Deserialize_IgnoresField_ExcludedWithFieldFilter()
fields.Add(new FakeFieldValue("Changed Ignored Value", fieldId: ignoredFieldId.Guid));
((ProxyItemVersion)itemData.Versions.First()).Fields = fields;

deserializer.Deserialize(itemData);
deserializer.Deserialize(itemData, null);

var fromDb = db.GetItem(itemId);

Expand Down Expand Up @@ -263,7 +263,7 @@ public void Deserialize_IgnoresField_ExcludedWithFieldFilterNotSerialized()
((ProxyItemVersion)itemData.Versions.First()).Fields = fields;
itemData.SharedFields = fields;

deserializer.Deserialize(itemData);
deserializer.Deserialize(itemData, null);

var fromDb = db.GetItem(itemId);

Expand Down Expand Up @@ -318,7 +318,7 @@ private void RunItemChangeTest(Action<ProxyItem> setup, Action<Item> assert)

setup(itemData);

deserializer.Deserialize(itemData);
deserializer.Deserialize(itemData, null);

var fromDb = db.GetItem(itemId);

Expand Down
4 changes: 2 additions & 2 deletions src/Rainbow.Storage.Sc.Tests/SitecoreDataStoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public void Save_ShouldDeserializeItem()

var item = new FakeItem();

dataStore.Save(item);
dataStore.Save(item, null);

deserializer.Received().Deserialize(item);
deserializer.Received().Deserialize(item, null);
}

[Fact]
Expand Down
153 changes: 123 additions & 30 deletions src/Rainbow.Storage.Sc/Deserialization/DefaultDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public DefaultDeserializer(bool ignoreBranchId, IDefaultDeserializerLogger logge
_fieldFilter = fieldFilter;
}

public IItemData Deserialize(IItemData serializedItemData)
public IItemData Deserialize(IItemData serializedItemData, IFieldValueManipulator fieldValueManipulator)
{
Assert.ArgumentNotNull(serializedItemData, "serializedItem");

Expand All @@ -63,9 +63,7 @@ public IItemData Deserialize(IItemData serializedItemData)
// Updated to try and bring back Sitecore 7 compatibility for Rainbow moving forward. https://github.com/SitecoreUnicorn/Rainbow/issues/25
using (new VersionSafeEnforceVersionPresenceDisabler())
{
bool newItemWasCreated;
var targetItem = GetOrCreateTargetItem(serializedItemData, out newItemWasCreated);

var targetItem = GetOrCreateTargetItem(serializedItemData, out var newItemWasCreated);
var softErrors = new List<TemplateMissingFieldException>();

try
Expand All @@ -81,13 +79,13 @@ public IItemData Deserialize(IItemData serializedItemData)

ResetTemplateEngineIfItemIsTemplate(targetItem);

PasteSharedFields(serializedItemData, targetItem, newItemWasCreated, softErrors);
PasteSharedFields(serializedItemData, targetItem, newItemWasCreated, softErrors, fieldValueManipulator);

PasteUnversionedFields(serializedItemData, targetItem, newItemWasCreated, softErrors);
PasteUnversionedFields(serializedItemData, targetItem, newItemWasCreated, softErrors, fieldValueManipulator);

UpdateFieldSharingIfNeeded(serializedItemData, targetItem);

PasteVersions(serializedItemData, targetItem, newItemWasCreated, softErrors);
PasteVersions(serializedItemData, targetItem, newItemWasCreated, softErrors, fieldValueManipulator);

if (softErrors.Count > 0) throw TemplateMissingFieldException.Merge(softErrors);

Expand Down Expand Up @@ -347,7 +345,7 @@ protected Item CreateTargetItem(IItemData serializedItemData, Item destinationPa
return targetItem;
}

protected virtual void PasteSharedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors)
protected virtual void PasteSharedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator)
{
bool commitEdit = false;

Expand All @@ -362,7 +360,7 @@ protected virtual void PasteSharedFields(IItemData serializedItemData, Item targ

foreach (Field field in targetItem.Fields)
{
if (field.Shared && !allTargetSharedFields.Contains(field.ID.Guid) && _fieldFilter.Includes(field.ID.Guid))
if (field.Shared && fieldValueManipulator?.GetFieldValueTransformer(field.Name) == null && !allTargetSharedFields.Contains(field.ID.Guid) && _fieldFilter.Includes(field.ID.Guid))
{
_logger.ResetFieldThatDidNotExistInSerialized(field);

Expand All @@ -372,19 +370,46 @@ protected virtual void PasteSharedFields(IItemData serializedItemData, Item targ
}
}

var transformersArray = fieldValueManipulator?.GetFieldValueTransformers();
List<IFieldValueTransformer> transformersList = new List<IFieldValueTransformer>();
if (transformersArray != null)
transformersList = new List<IFieldValueTransformer>(transformersArray);

foreach (var field in serializedItemData.SharedFields)
{
try
{
if (PasteField(targetItem, field, newItemWasCreated))
if (PasteField(targetItem, field, newItemWasCreated, fieldValueManipulator))
commitEdit = true;

var t = transformersList.FirstOrDefault(x => x.FieldName.Equals(field.NameHint));
if (t != null)
transformersList.Remove(t);
}
catch (TemplateMissingFieldException tex)
{
softErrors.Add(tex);
}
}

// Whatever remains here are field transformers that are NOT represented in the serialized data
foreach (var t in transformersList)
{
var fieldMeta = targetItem.Template.GetField(t.FieldName);

// If the field doesn't exist on the target template, it's time to just skip
if (fieldMeta != null)
{
var existingField = targetItem.Fields[fieldMeta.ID];
if (t.ShouldDeployFieldValue(existingField.Value, null))
{
var fakeField = new ItemFieldValue(existingField, null);
if (PasteField(targetItem, fakeField, newItemWasCreated, fieldValueManipulator))
commitEdit = true;
}
}
}

// we commit the edit context - and write to the DB - only if we changed something
if (commitEdit)
{
Expand All @@ -404,7 +429,7 @@ protected virtual void PasteSharedFields(IItemData serializedItemData, Item targ
}
}

protected virtual void PasteVersions(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors)
protected virtual void PasteVersions(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator)
{
Hashtable versionTable = CommonUtils.CreateCIHashtable();

Expand All @@ -415,7 +440,7 @@ protected virtual void PasteVersions(IItemData serializedItemData, Item targetIt

foreach (var syncVersion in serializedItemData.Versions)
{
var version = PasteVersion(targetItem, syncVersion, newItemWasCreated, softErrors);
var version = PasteVersion(targetItem, syncVersion, newItemWasCreated, softErrors, fieldValueManipulator);
if (versionTable.ContainsKey(version.Uri))
versionTable.Remove(version.Uri);
}
Expand All @@ -430,7 +455,7 @@ protected virtual void PasteVersions(IItemData serializedItemData, Item targetIt
}
}

protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, bool creatingNewItem, List<TemplateMissingFieldException> softErrors)
protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, bool creatingNewItem, List<TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator)
{
Language language = Language.Parse(serializedVersion.Language.Name);
var targetVersion = Version.Parse(serializedVersion.VersionNumber);
Expand Down Expand Up @@ -490,6 +515,9 @@ protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, b
// if we have a value in the serialized item, we don't need to reset the field
if (serializedVersionFieldsLookup.ContainsKey(field.ID.Guid)) continue;

// If the field manipulator has something to say about the field, we won't reset it (it might not be present in the serialization data, but needs to be forced a value)
if (fieldValueManipulator?.GetFieldValueTransformer(field.Name) != null) continue;

// if the field is one of revision, updated, or updated by we can specially ignore it, because these will get set below if actual field changes occur
// so there's no need to reset them as well
if (field.ID == FieldIDs.Revision || field.ID == FieldIDs.UpdatedBy || field.ID == FieldIDs.Updated) continue;
Expand All @@ -501,6 +529,11 @@ protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, b
commitEdit = true;
}

var transformersArray = fieldValueManipulator?.GetFieldValueTransformers();
List<IFieldValueTransformer> transformersList = new List<IFieldValueTransformer>();
if(transformersArray != null)
transformersList = new List<IFieldValueTransformer>(transformersArray);

bool wasOwnerFieldParsed = false;
foreach (IItemFieldValue field in serializedVersion.Fields)
{
Expand All @@ -509,15 +542,37 @@ protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, b

try
{
if (PasteField(languageVersionItem, field, creatingNewItem))
if (PasteField(languageVersionItem, field, creatingNewItem, fieldValueManipulator))
commitEdit = true;

var t = transformersList.FirstOrDefault(x => x.FieldName.Equals(field.NameHint));
if (t != null)
transformersList.Remove(t);
}
catch (TemplateMissingFieldException tex)
{
softErrors.Add(tex);
}
}

// Whatever remains here are field transformers that are NOT represented in the serialized data
foreach (var t in transformersList)
{
var fieldMeta = languageVersionItem.Template.GetField(t.FieldName);

// If the field doesn't exist on the target template, it's time to just skip
if (fieldMeta != null)
{
var existingField = languageVersionItem.Fields[fieldMeta.ID];
if (t.ShouldDeployFieldValue(existingField.Value, null))
{
var fakeField = new ItemFieldValue(existingField, null);
if (PasteField(languageVersionItem, fakeField, creatingNewItem, fieldValueManipulator))
commitEdit = true;
}
}
}

if (!wasOwnerFieldParsed)
{
languageVersionItem.Fields[FieldIDs.Owner].Reset();
Expand Down Expand Up @@ -562,15 +617,15 @@ protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, b
return languageVersionItem;
}

protected virtual void PasteUnversionedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors)
protected virtual void PasteUnversionedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator)
{
foreach (var language in serializedItemData.UnversionedFields)
{
PasteUnversionedLanguage(targetItem, language, newItemWasCreated, softErrors);
PasteUnversionedLanguage(targetItem, language, newItemWasCreated, softErrors, fieldValueManipulator);
}
}

protected virtual void PasteUnversionedLanguage(Item item, IItemLanguage serializedLanguage, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors)
protected virtual void PasteUnversionedLanguage(Item item, IItemLanguage serializedLanguage, bool newItemWasCreated, List<TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator)
{
Language language = Language.Parse(serializedLanguage.Language.Name);

Expand Down Expand Up @@ -599,8 +654,7 @@ protected virtual void PasteUnversionedLanguage(Item item, IItemLanguage seriali
foreach (Field field in targetItem.Fields)
{
// field was not serialized. Which means the field is either blank or has its standard value, so let's reset it
if (field.Unversioned && !field.Shared && !allTargetUnversionedFields.Contains(field.ID.Guid) &&
_fieldFilter.Includes(field.ID.Guid))
if (field.Unversioned && fieldValueManipulator?.GetFieldValueTransformer(field.Name) == null && !field.Shared && !allTargetUnversionedFields.Contains(field.ID.Guid) && _fieldFilter.Includes(field.ID.Guid))
{
_logger.ResetFieldThatDidNotExistInSerialized(field);

Expand All @@ -610,19 +664,46 @@ protected virtual void PasteUnversionedLanguage(Item item, IItemLanguage seriali
}
}

var transformersArray = fieldValueManipulator?.GetFieldValueTransformers();
List<IFieldValueTransformer> transformersList = new List<IFieldValueTransformer>();
if (transformersArray != null)
transformersList = new List<IFieldValueTransformer>(transformersArray);

foreach (var field in serializedLanguage.Fields)
{
try
{
if (PasteField(targetItem, field, newItemWasCreated))
if (PasteField(targetItem, field, newItemWasCreated, fieldValueManipulator))
commitEdit = true;

var t = transformersList.FirstOrDefault(x => x.FieldName.Equals(field.NameHint));
if (t != null)
transformersList.Remove(t);
}
catch (TemplateMissingFieldException tex)
{
softErrors.Add(tex);
}
}

// Whatever remains here are field transformers that are NOT represented in the serialized data
foreach (var t in transformersList)
{
var fieldMeta = targetItem.Template.GetField(t.FieldName);

// If the field doesn't exist on the target template, it's time to just skip
if (fieldMeta != null)
{
var existingField = targetItem.Fields[fieldMeta.ID];
if (t.ShouldDeployFieldValue(existingField.Value, null))
{
var fakeField = new ItemFieldValue(existingField, null);
if (PasteField(targetItem, fakeField, newItemWasCreated, fieldValueManipulator))
commitEdit = true;
}
}
}

// we commit the edit context - and write to the DB - only if we changed something
if (commitEdit)
targetItem.Editing.EndEdit();
Expand All @@ -634,14 +715,7 @@ protected virtual void PasteUnversionedLanguage(Item item, IItemLanguage seriali
}
}

/// <summary>
/// Inserts field value into item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="field">The field.</param>
/// <param name="creatingNewItem">Whether the item under update is new or not (controls logging verbosity)</param>
/// <exception cref="T:Sitecore.Data.Serialization.Exceptions.FieldIsMissingFromTemplateException"/>
protected virtual bool PasteField(Item item, IItemFieldValue field, bool creatingNewItem)
protected virtual bool PasteField(Item item, IItemFieldValue field, bool creatingNewItem, IFieldValueManipulator fieldValueManipulator)
{
if (!_fieldFilter.Includes(field.FieldId))
{
Expand All @@ -664,8 +738,7 @@ protected virtual bool PasteField(Item item, IItemFieldValue field, bool creatin
Field itemField = item.Fields[new ID(field.FieldId)];
if (itemField.IsBlobField)
{
Guid existingBlobId;
bool hasExistingId = Guid.TryParse(itemField.Value, out existingBlobId);
bool hasExistingId = Guid.TryParse(itemField.Value, out var existingBlobId);

// serialized blob has no value (media item with detached media)
if (!field.BlobId.HasValue)
Expand Down Expand Up @@ -701,6 +774,26 @@ protected virtual bool PasteField(Item item, IItemFieldValue field, bool creatin
return true;
}

var proposedValue = field.Value;
var destinationValue = itemField.GetValue(false, false);
var fieldTransformer = fieldValueManipulator?.GetFieldValueTransformer(itemField.Name);

if (fieldTransformer != null)
{
if (fieldTransformer.ShouldDeployFieldValue(destinationValue, proposedValue))
{
var oldValue = destinationValue;
itemField.SetValue(fieldTransformer.GetFieldValue(oldValue, proposedValue), true);

if (!creatingNewItem)
_logger.UpdatedChangedFieldValue(item, field, oldValue);

return true;
}

return false;
}

if (field.Value != null && !field.Value.Equals(itemField.GetValue(false, false)))
{
var oldValue = itemField.Value;
Expand Down
2 changes: 1 addition & 1 deletion src/Rainbow.Storage.Sc/Deserialization/IDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Rainbow.Storage.Sc.Deserialization
{
public interface IDeserializer
{
IItemData Deserialize(IItemData serializedItemData);
IItemData Deserialize(IItemData serializedItemData, IFieldValueManipulator fieldValueManipulator);
IDataStore ParentDataStore { set; }
}
}
4 changes: 2 additions & 2 deletions src/Rainbow.Storage.Sc/SitecoreDataStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public virtual IEnumerable<string> GetDatabaseNames()
return Factory.GetDatabaseNames();
}

public virtual void Save(IItemData item)
public virtual void Save(IItemData item, IFieldValueManipulator fieldValueManipulator)
{
Assert.ArgumentNotNull(item, "item");

_deserializer.Deserialize(item);
_deserializer.Deserialize(item, fieldValueManipulator);
}

public virtual void MoveOrRenameItem(IItemData itemWithFinalPath, string oldPath)
Expand Down
Loading

0 comments on commit 49e26a2

Please sign in to comment.