Beispiel #1
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }