public virtual void VersionedFieldIsChanged(IItemData targetItem, IItemVersion version, Guid fieldId, string targetValue, string sourceValue)
		{
			Assert.ArgumentNotNull(targetItem, "targetItem");
			Assert.ArgumentNotNull(version, "version");

			if (targetValue == null)
			{
				_logger.Debug("> Field {0} - {1}#{2} - Reset to standard value".FormatWith(TryResolveItemName(targetItem.DatabaseName, fieldId), version.Language, version.VersionNumber));
			}
			else if (targetValue.Length < MaxFieldLengthToDisplayValue && (sourceValue == null || sourceValue.Length < MaxFieldLengthToDisplayValue))
			{
				var encodedTarget = HttpUtility.HtmlEncode(targetValue);
				var encodedSource = sourceValue == null ? string.Empty : HttpUtility.HtmlEncode(sourceValue);
				_logger.Debug("> Field {0} - {1}#{2}: Serialized {3}, Source {4}".FormatWith(TryResolveItemName(targetItem.DatabaseName, fieldId), version.Language, version.VersionNumber, encodedTarget, encodedSource));
			}
			else
			{
				_logger.Debug("> Field {0} - {1}#{2}: Value mismatch (values too long to display)".FormatWith(TryResolveItemName(targetItem.DatabaseName, fieldId), version.Language, version.VersionNumber));
			}
		}
		protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, bool creatingNewItem, List<TemplateMissingFieldException> softErrors)
		{
			Language language = Language.Parse(serializedVersion.Language.Name);
			var targetVersion = Version.Parse(serializedVersion.VersionNumber);

			Item languageItem = item.Database.GetItem(item.ID, language);

			Item languageVersionItem = languageItem.Versions[targetVersion];

			IDictionary<Guid, IItemFieldValue> serializedVersionFieldsLookup = serializedVersion.Fields.ToDictionary(field => field.FieldId);

			// Add a new version if we need to for the serialized version we're pasting
			// NOTE: normally Sitecore will return an empty version when requested (e.g. you can ask for 'en#25' and get a blank version back)
			// so this null check is only here for legacy support
			if (languageVersionItem == null)
			{
				languageVersionItem = languageItem.Versions.AddVersion();

				if(languageVersionItem == null) throw new InvalidOperationException("Failed to add a new version: AddVersion() returned null.");

				if (!creatingNewItem)
					_logger.AddedNewVersion(languageVersionItem);
			}

			// Based on the note above, in order to detect the modern form where item.Versions[] returns a blank version no matter what,
			// we need to check again to see if the version we requested is actually currently present on the item or not, so we can correctly log version adds
			// ReSharper disable once SimplifyLinqExpression
			if (!languageVersionItem.Versions.GetVersionNumbers().Any(x => x.Number == languageVersionItem.Version.Number))
			{
				if (!creatingNewItem)
					_logger.AddedNewVersion(languageVersionItem);
			}

			// begin writing the version data
			bool commitEditContext = false;

			try
			{
				languageVersionItem.Editing.BeginEdit();

				languageVersionItem.RuntimeSettings.ReadOnlyStatistics = true;

				if (languageVersionItem.Versions.Count == 0)
					languageVersionItem.Fields.ReadAll();

				// find versioned fields that need to be reset to standard value, because they are not in serialized
				// (we do all these checks so we can back out of the edit context and avoid a DB write if we don't need one)
				foreach (Field field in languageVersionItem.Fields)
				{
					// shared/unversioned fields = ignore, those are handled in their own paste methods
					if (field.Shared || field.Unversioned) continue;

					// 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 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;

					_logger.ResetFieldThatDidNotExistInSerialized(field);

					field.Reset();

					commitEditContext = true;
				}

				bool wasOwnerFieldParsed = false;
				foreach (IItemFieldValue field in serializedVersion.Fields)
				{
					if (field.FieldId == FieldIDs.Owner.Guid)
						wasOwnerFieldParsed = true;

					try
					{
						if (PasteField(languageVersionItem, field, creatingNewItem))
							commitEditContext = true;
					}
					catch (TemplateMissingFieldException tex)
					{
						softErrors.Add(tex);
					}
				}

				if (!wasOwnerFieldParsed)
				{
					languageVersionItem.Fields[FieldIDs.Owner].Reset();
					commitEditContext = true;
				}

				// if the item came with blank statistics, and we're creating the item or have version updates already, let's set some sane defaults - update revision, set last updated, etc
				if (creatingNewItem || commitEditContext)
				{
					if (!serializedVersionFieldsLookup.ContainsKey(FieldIDs.Revision.Guid))
					{
						languageVersionItem.Fields[FieldIDs.Revision].SetValue(Guid.NewGuid().ToString(), true);
					}

					if (!serializedVersionFieldsLookup.ContainsKey(FieldIDs.Updated.Guid))
					{
						languageVersionItem[FieldIDs.Updated] = DateUtil.ToIsoDate(DateTime.UtcNow);
					}

					if (!serializedVersionFieldsLookup.ContainsKey(FieldIDs.UpdatedBy.Guid))
					{
						languageVersionItem[FieldIDs.UpdatedBy] = @"sitecore\unicorn";
					}
				}

				// we commit the edit context - and write to the DB - only if we changed something
				if (commitEditContext)
					languageVersionItem.Editing.EndEdit();
			}
			finally
			{
				if (languageVersionItem.Editing.IsEditing)
					languageVersionItem.Editing.CancelEdit();
			}

			if (commitEditContext)
			{
				ClearCaches(languageVersionItem.Database, languageVersionItem.ID);
				ResetTemplateEngineIfItemIsTemplate(languageVersionItem);
			}

			return languageVersionItem;
		}
Example #3
0
 public ProxyItemVersion(IItemVersion versionToProxy)
 {
     VersionNumber = versionToProxy.VersionNumber;
     Language = versionToProxy.Language;
     Fields = versionToProxy.Fields.Select(field => new ProxyFieldValue(field)).ToArray();
 }
        public virtual void OrphanSourceVersion(IItemData existingItemData, IItemData serializedItemData, IItemVersion[] orphanSourceVersions)
        {
            Assert.ArgumentNotNull(orphanSourceVersions, "orphanSourceVersions");

            _logger.Debug("> Orphaned version{0} {1} (source)".FormatWith(orphanSourceVersions.Length > 1 ? "s" : string.Empty, string.Join(", ", orphanSourceVersions.Select(x => x.Language + "#" + x.VersionNumber))));
        }
        public virtual void NewTargetVersion(IItemVersion newSerializedVersion, IItemData serializedItemData, IItemData existingItemData)
        {
            Assert.ArgumentNotNull(newSerializedVersion, "newSerializedVersion");

            _logger.Debug("> New version {0}#{1} (serialized)".FormatWith(newSerializedVersion.Language, newSerializedVersion.VersionNumber));
        }
        protected virtual Item PasteVersion(Item item, IItemVersion serializedVersion, bool creatingNewItem, List<TemplateMissingFieldException> softErrors)
        {
            Language language = Language.Parse(serializedVersion.Language.Name);
            var targetVersion = Version.Parse(serializedVersion.VersionNumber);
            Item languageItem = item.Database.GetItem(item.ID, language);
            Item languageVersionItem = languageItem.Versions[targetVersion];

            if (languageVersionItem == null)
            {
                languageVersionItem = languageItem.Versions.AddVersion();
                if (!creatingNewItem)
                    _logger.AddedNewVersion(languageVersionItem);
            }

            // ReSharper disable once SimplifyLinqExpression
            if (!languageVersionItem.Versions.GetVersionNumbers().Any(x => x.Number == languageVersionItem.Version.Number))
            {
                if (!creatingNewItem)
                    _logger.AddedNewVersion(languageVersionItem);
            }

            bool commitEditContext = false;

            try
            {
                languageVersionItem.Editing.BeginEdit();

                languageVersionItem.RuntimeSettings.ReadOnlyStatistics = true;

                if (languageVersionItem.Versions.Count == 0)
                    languageVersionItem.Fields.ReadAll();

                // find versioned fields that need to be reset to standard value, because they are not in serialized
                // (we do all these checks so we can back out of the edit context and avoid a DB write if we don't need one)
                foreach (Field field in languageVersionItem.Fields)
                {
                    // shared fields = ignore, those are handled in Paste
                    if (field.Shared) continue;
                    // if we have a value in the serialized item, we don't need to reset the field
                    if(serializedVersion.Fields.Any(x => x.FieldId == field.ID.Guid)) 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;
                    // if the field value is already blank - ignoring standard values - we can assume there's no need to reset it
                    if(field.GetValue(false, false) == string.Empty) continue;

                    _logger.ResetFieldThatDidNotExistInSerialized(field);
                    field.Reset();
                    commitEditContext = true;
                }

                bool wasOwnerFieldParsed = false;
                foreach (IItemFieldValue field in serializedVersion.Fields)
                {
                    if (field.FieldId == FieldIDs.Owner.Guid)
                        wasOwnerFieldParsed = true;

                    try
                    {
                        if (PasteField(languageVersionItem, field, creatingNewItem))
                            commitEditContext = true;
                    }
                    catch (TemplateMissingFieldException tex)
                    {
                        softErrors.Add(tex);
                    }
                }

                if (!wasOwnerFieldParsed)
                {
                    languageVersionItem.Fields[FieldIDs.Owner].Reset();
                    commitEditContext = true;
                }

                // if the item came with blank statistics, and we're creating the item or have version updates already, let's set some sane defaults - update revision, set last updated, etc
                if (creatingNewItem || commitEditContext)
                {
                    // ReSharper disable once SimplifyLinqExpression
                    if (!serializedVersion.Fields.Any(f => f.FieldId == FieldIDs.Revision.Guid))
                    {
                        languageVersionItem.Fields[FieldIDs.Revision].SetValue(Guid.NewGuid().ToString(), true);
                    }

                    // ReSharper disable once SimplifyLinqExpression
                    if (!serializedVersion.Fields.Any(f => f.FieldId == FieldIDs.Updated.Guid))
                    {
                        languageVersionItem[FieldIDs.Updated] = DateUtil.ToIsoDate(DateTime.UtcNow);
                    }

                    // ReSharper disable once SimplifyLinqExpression
                    if (!serializedVersion.Fields.Any(f => f.FieldId == FieldIDs.UpdatedBy.Guid))
                    {
                        languageVersionItem[FieldIDs.UpdatedBy] = @"sitecore\unicorn";
                    }
                }

                // we commit the edit context - and write to the DB - only if we changed something
                if (commitEditContext)
                    languageVersionItem.Editing.EndEdit();
            }
            finally
            {
                if (languageVersionItem.Editing.IsEditing)
                    languageVersionItem.Editing.CancelEdit();
            }

            if (commitEditContext)
            {
                ClearCaches(languageVersionItem.Database, languageVersionItem.ID);
                ResetTemplateEngineIfItemIsTemplate(languageVersionItem);
            }

            return languageVersionItem;
        }
Example #7
0
			public FilteredVersion(IItemVersion innerVersion, IFieldFilter fieldFilter) : base(innerVersion)
			{
				_innerVersion = innerVersion;
				_fieldFilter = fieldFilter;
			}
		public ItemVersionComparisonResult(IItemVersion sourceVersion, IItemVersion targetVersion, FieldComparisonResult[] changedFields)
		{
			SourceVersion = sourceVersion;
			TargetVersion = targetVersion;
			ChangedFields = changedFields ?? new FieldComparisonResult[] {};
		}
			public ItemChangeApplyingItemVersion(IItemVersion innerVersion, ItemChanges changes)
			{
				_innerVersion = innerVersion;
				_changes = changes;
			}