protected virtual void PasteSharedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List <TemplateMissingFieldException> softErrors) { bool commitEdit = false; try { targetItem.Editing.BeginEdit(); targetItem.RuntimeSettings.ReadOnlyStatistics = true; targetItem.RuntimeSettings.SaveAll = true; var allTargetSharedFields = serializedItemData.SharedFields.ToLookup(field => field.FieldId); foreach (Field field in targetItem.Fields) { if (field.Shared && !allTargetSharedFields.Contains(field.ID.Guid) && _fieldFilter.Includes(field.ID.Guid)) { _logger.ResetFieldThatDidNotExistInSerialized(field); field.Reset(); commitEdit = true; } } foreach (var field in serializedItemData.SharedFields) { try { if (PasteField(targetItem, field, newItemWasCreated)) { commitEdit = true; } } catch (TemplateMissingFieldException tex) { softErrors.Add(tex); } } // we commit the edit context - and write to the DB - only if we changed something if (commitEdit) { targetItem.Editing.EndEdit(); ClearCaches(targetItem.Database, new ID(serializedItemData.Id)); targetItem.Reload(); ResetTemplateEngineIfItemIsTemplate(targetItem); } } finally { if (targetItem.Editing.IsEditing) { targetItem.Editing.CancelEdit(); } } }
// TODO private UnicornDataProvider CreateTestProvider(Database db, ITargetDataStore targetDataStore = null, ISourceDataStore sourceDataStore = null, IPredicate predicate = null, IFieldFilter filter = null, IUnicornDataProviderLogger logger = null, bool enableTransparentSync = false) { if (predicate == null) { predicate = CreateInclusiveTestPredicate(); } if (filter == null) { filter = Substitute.For<IFieldFilter>(); filter.Includes(Arg.Any<Guid>()).Returns(true); } targetDataStore = targetDataStore ?? Substitute.For<ITargetDataStore>(); sourceDataStore = sourceDataStore ?? Substitute.For<ISourceDataStore>(); var dp = new UnicornDataProvider(targetDataStore, sourceDataStore, predicate, filter, logger ?? Substitute.For<IUnicornDataProviderLogger>(), new DefaultUnicornDataProviderConfiguration(enableTransparentSync), new PredicateRootPathResolver(predicate, targetDataStore, sourceDataStore, Substitute.For<ILogger>())); dp.ParentDataProvider = db.GetDataProviders().First(); return dp; }
// TODO private UnicornDataProvider CreateTestProvider(Database db, ITargetDataStore targetDataStore = null, ISourceDataStore sourceDataStore = null, IPredicate predicate = null, IFieldFilter filter = null, IUnicornDataProviderLogger logger = null, ISyncConfiguration syncConfiguration = null, bool enableTransparentSync = false) { if (predicate == null) { predicate = CreateInclusiveTestPredicate(); } if (filter == null) { filter = Substitute.For <IFieldFilter>(); filter.Includes(Arg.Any <Guid>()).Returns(true); } targetDataStore = targetDataStore ?? Substitute.For <ITargetDataStore>(); sourceDataStore = sourceDataStore ?? Substitute.For <ISourceDataStore>(); syncConfiguration = syncConfiguration ?? Substitute.For <ISyncConfiguration>(); var dp = new UnicornDataProvider(targetDataStore, sourceDataStore, predicate, filter, logger ?? Substitute.For <IUnicornDataProviderLogger>(), new DefaultUnicornDataProviderConfiguration(enableTransparentSync), syncConfiguration, new PredicateRootPathResolver(predicate, targetDataStore, sourceDataStore, Substitute.For <ILogger>())); dp.ParentDataProvider = db.GetDataProviders().First(); return(dp); }
protected virtual bool HasConsequentialChanges(ItemChanges changes) { // properties, e.g. template, etc are always consequential // NOTE: sometimes you can get spurious 'changes' where the old and new value are the same. We reject those. if (changes.HasPropertiesChanged && changes.Properties.Any(x => !x.Value.OriginalValue.Equals(x.Value.Value))) { return(true); } foreach (FieldChange change in changes.FieldChanges) { if (change.OriginalValue == change.Value) { continue; } if (change.FieldID == FieldIDs.Revision) { continue; } if (change.FieldID == FieldIDs.Updated) { continue; } if (change.FieldID == FieldIDs.UpdatedBy) { continue; } if (change.FieldID == FieldIDs.Originator) { continue; } if (!_fieldFilter.Includes(change.FieldID.Guid)) { continue; } return(true); } _logger.SaveRejectedAsInconsequential(_targetDataStore.FriendlyName, changes); return(false); }
protected virtual bool HasConsequentialChanges(ItemChanges changes) { // properties, e.g. template, etc are always consequential // NOTE: sometimes you can get spurious 'changes' where the old and new value are the same. We reject those. if (changes.HasPropertiesChanged && changes.Properties.Any(x => !x.Value.OriginalValue.Equals(x.Value.Value))) { return(true); } foreach (FieldChange change in changes.FieldChanges) { // NOTE: we do not check for old and new value equality here // because during package installation Sitecore will set item fields using // identical old and new values in the changes - for fields that have never been set before. if (change.FieldID == FieldIDs.Revision) { continue; } if (change.FieldID == FieldIDs.Updated) { continue; } if (change.FieldID == FieldIDs.UpdatedBy) { continue; } if (change.FieldID == FieldIDs.Originator) { continue; } if (!_fieldFilter.Includes(change.FieldID.Guid)) { continue; } return(true); } _logger.SaveRejectedAsInconsequential(_targetDataStore.FriendlyName, changes); return(false); }
protected virtual bool PasteSharedFields(IItemData serializedItemData, Item targetItem, bool newItemWasCreated, List <TemplateMissingFieldException> softErrors, IFieldValueManipulator fieldValueManipulator) { bool commitEdit = false; try { targetItem.Editing.BeginEdit(); targetItem.RuntimeSettings.ReadOnlyStatistics = true; targetItem.RuntimeSettings.SaveAll = true; var allTargetSharedFields = serializedItemData.SharedFields.ToLookup(field => field.FieldId); foreach (Field field in targetItem.Fields) { if (field.Shared && fieldValueManipulator?.GetFieldValueTransformer(field.Name) == null && !allTargetSharedFields.Contains(field.ID.Guid) && _fieldFilter.Includes(field.ID.Guid)) { _logger.ResetFieldThatDidNotExistInSerialized(field); field.Reset(); commitEdit = true; } } 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, 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 shared fields 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) { // We're only dealing with Shared Fields in this method if (!fieldMeta.IsShared) { continue; } 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(); ClearCaches(targetItem.Database, new ID(serializedItemData.Id)); targetItem.Reload(); ResetTemplateEngineIfItemIsTemplate(targetItem); return(true); } } finally { if (targetItem.Editing.IsEditing) { targetItem.Editing.CancelEdit(); } } return(false); }
/// <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) { if (!_fieldFilter.Includes(field.FieldId)) { _logger.SkippedPastingIgnoredField(item, field); return(false); } Template template = AssertTemplate(item.Database, item.TemplateID, item.Paths.Path); if (template.GetField(new ID(field.FieldId)) == null) { item.Database.Engines.TemplateEngine.Reset(); template = AssertTemplate(item.Database, item.TemplateID, item.Paths.Path); } if (template.GetField(new ID(field.FieldId)) == null) { throw new TemplateMissingFieldException(item.TemplateName, item.Database.Name + ":" + item.Paths.FullPath, field); } Field itemField = item.Fields[new ID(field.FieldId)]; if (itemField.IsBlobField) { if (!field.BlobId.HasValue) { throw new InvalidOperationException("Field " + field.FieldId + " is a blob field, but it had no blob ID."); } // check if existing blob is here with the same ID; abort if so Guid existingBlobId; if (Guid.TryParse(itemField.Value, out existingBlobId) && existingBlobId == field.BlobId.Value) { return(false); } byte[] buffer = Convert.FromBase64String(field.Value); // if an existing blob of a different ID exists, drop it from the database if (existingBlobId != default(Guid)) { ItemManager.RemoveBlobStream(existingBlobId, item.Database); } // write the new blob to the database ItemManager.SetBlobStream(new MemoryStream(buffer, false), field.BlobId.Value, item.Database); // set the value of the blob field to the correct blob ID itemField.SetValue(MainUtil.GuidToString(field.BlobId.Value), true); if (!creatingNewItem) { _logger.WroteBlobStream(item, field); } return(true); } if (field.Value != null && !field.Value.Equals(itemField.GetValue(false, false))) { var oldValue = itemField.Value; itemField.SetValue(field.Value, true); if (!creatingNewItem) { _logger.UpdatedChangedFieldValue(item, field, oldValue); } return(true); } return(false); }
/// <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) { if (!_fieldFilter.Includes(field.FieldId)) { _logger.SkippedPastingIgnoredField(item, field); return(false); } Template template = AssertTemplate(item.Database, item.TemplateID, item.Paths.Path); if (template.GetField(new ID(field.FieldId)) == null) { item.Database.Engines.TemplateEngine.Reset(); template = AssertTemplate(item.Database, item.TemplateID, item.Paths.Path); } if (template.GetField(new ID(field.FieldId)) == null) { throw new TemplateMissingFieldException(item.TemplateName, item.Database.Name + ":" + item.Paths.FullPath, field); } Field itemField = item.Fields[new ID(field.FieldId)]; if (itemField.IsBlobField) { Guid existingBlobId; bool hasExistingId = Guid.TryParse(itemField.Value, out existingBlobId); // serialized blob has no value (media item with detached media) if (!field.BlobId.HasValue) { if (!hasExistingId || existingBlobId == Guid.Empty) { return(false); // no blob ID and none in DB either, so we're cool } // existing blob in DB but none in serialized // so clear the blob and field value ItemManager.RemoveBlobStream(existingBlobId, item.Database); itemField.SetValue(string.Empty, true); _logger.WroteBlobStream(item, field); return(true); } // check if existing blob is here with the same ID; abort if so if (hasExistingId && existingBlobId == field.BlobId.Value) { return(false); } byte[] buffer = Convert.FromBase64String(field.Value); // if an existing blob of a different ID exists, drop it from the database if (existingBlobId != default(Guid)) { ItemManager.RemoveBlobStream(existingBlobId, item.Database); } // write the new blob to the database ItemManager.SetBlobStream(new MemoryStream(buffer, false), field.BlobId.Value, item.Database); // set the value of the blob field to the correct blob ID itemField.SetValue(MainUtil.GuidToString(field.BlobId.Value), true); if (!creatingNewItem) { _logger.WroteBlobStream(item, field); } return(true); } if (field.Value != null && !field.Value.Equals(itemField.GetValue(false, false))) { var oldValue = itemField.Value; itemField.SetValue(field.Value, true); if (!creatingNewItem) { _logger.UpdatedChangedFieldValue(item, field, oldValue); } return(true); } return(false); }