From 06924ed0f4590a8202c19604e43e974233d639b0 Mon Sep 17 00:00:00 2001 From: Mole Date: Mon, 28 Nov 2022 12:49:14 +0100 Subject: [PATCH] Ensure that all automatic relation types are updated (#13470) --- src/Umbraco.Core/Constants-Conventions.cs | 1 - .../PropertyEditors/IDataValueReference.cs | 6 ++++ .../Implement/ContentRepositoryBase.cs | 30 ++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 09942ff495..7047e16437 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -282,7 +282,6 @@ public static partial class Constants /// Developers should not manually use these relation types since they will all be cleared whenever an entity /// (content, media or member) is saved since they are auto-populated based on property values. /// - [Obsolete("This is no longer used, and will be removed in v12")] public static string[] AutomaticRelationTypes { get; } = { RelatedMediaAlias, RelatedDocumentAlias }; // TODO: return a list of built in types so we can use that to prevent deletion in the UI diff --git a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs index 39d7d7e130..6c863d66ff 100644 --- a/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs +++ b/src/Umbraco.Core/PropertyEditors/IDataValueReference.cs @@ -14,4 +14,10 @@ public interface IDataValueReference /// /// IEnumerable GetReferences(object? value); + + /// + /// Returns all reference types that are automatically tracked. + /// + /// + IEnumerable GetAutomaticRelationTypesAliases() => Enumerable.Empty(); } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs index ded99bf8bf..4632dc568a 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -1042,10 +1042,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement var trackedRelations = new List(); trackedRelations.AddRange(_dataValueReferenceFactories.GetAllReferences(entity.Properties, PropertyEditors)); - var relationTypeAliases = trackedRelations - .Select(x => x.RelationTypeAlias) - .Distinct() - .ToArray(); + var relationTypeAliases = GetAutomaticRelationTypesAliases(entity.Properties, PropertyEditors).ToArray(); // First delete all auto-relations for this entity RelationRepository.DeleteByParent(entity.Id, relationTypeAliases); @@ -1093,6 +1090,31 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement RelationRepository.SaveBulk(toSave); } + private IEnumerable GetAutomaticRelationTypesAliases( + IPropertyCollection properties, + PropertyEditorCollection propertyEditors) + { + var automaticRelationTypesAliases = new HashSet(Constants.Conventions.RelationTypes.AutomaticRelationTypes); + + foreach (IProperty property in properties) + { + if (propertyEditors.TryGet(property.PropertyType.PropertyEditorAlias, out IDataEditor? editor) is false ) + { + continue; + } + + if (editor.GetValueEditor() is IDataValueReference reference) + { + foreach (var alias in reference.GetAutomaticRelationTypesAliases()) + { + automaticRelationTypesAliases.Add(alias); + } + } + } + + return automaticRelationTypesAliases; + } + /// /// Inserts property values for the content entity ///