diff --git a/src/Umbraco.Core/Components/UpdateContentOnVariantChangesComponent.cs b/src/Umbraco.Core/Components/UpdateContentOnVariantChangesComponent.cs index 06d2b86166..71fe4d46bd 100644 --- a/src/Umbraco.Core/Components/UpdateContentOnVariantChangesComponent.cs +++ b/src/Umbraco.Core/Components/UpdateContentOnVariantChangesComponent.cs @@ -12,6 +12,7 @@ namespace Umbraco.Core.Components /// Manages data changes for when content/property types have variation changes /// [RuntimeLevel(MinLevel = RuntimeLevel.Run)] + //fixme: this one MUST fire before any of the content cache ones public sealed class UpdateContentOnVariantChangesComponent : UmbracoComponentBase, IUmbracoCoreComponent { private IContentService _contentService; @@ -40,7 +41,9 @@ namespace Umbraco.Core.Components { var propType = c.Item.PropertyTypes.First(x => x.Alias == a); - switch(propType.Variations) + //fixme: this does not take into account segments, but how can we since we don't know what it changed from? + + switch (propType.Variations) { case ContentVariation.Culture: //if the current variation is culture it means that the previous was nothing @@ -50,7 +53,7 @@ namespace Umbraco.Core.Components try { content.Properties[a].PropertyType.Variations = ContentVariation.Nothing; - //now get the culture val + //now get the invariant val invariantVal = content.GetValue(a); } finally diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index 05b9bc8631..743b7c858e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -402,10 +402,19 @@ AND umbracoNode.id <> @id", propertyType.PropertyGroupId = new Lazy(() => groupId); } + //check if the content type variation has been changed to Nothing since we will need to update + //all property types to Nothing as well if they aren't already + //fixme: this does not take into account segments, but how can we since we don't know what it changed from? + var ctVariationChangedToNothing = entity.IsPropertyDirty("Variations") && entity.Variations == ContentVariation.Nothing; + // insert or update properties // all of them, no-group and in-groups foreach (var propertyType in entity.PropertyTypes) { + //fixme: this does not take into account segments, but how can we since we don't know what it changed from? + if (ctVariationChangedToNothing && propertyType.Variations != ContentVariation.Nothing) + propertyType.Variations = ContentVariation.Nothing; + var groupId = propertyType.PropertyGroupId?.Value ?? default(int); // if the Id of the DataType is not set, we resolve it from the db by its PropertyEditorAlias if (propertyType.DataTypeId == 0 || propertyType.DataTypeId == default(int)) diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index 8ece9621ce..ad16f4228a 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -24,6 +24,105 @@ namespace Umbraco.Tests.Services [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)] public class ContentTypeServiceTests : TestWithSomeContentBase { + + //TODO: Then write the ones for content type changes + + [Test] + public void Change_Content_Type_From_Variant_Invariant() + { + //initialize the listener which is responsible for updating content based on variant/invariant changes + var listener = new UpdateContentOnVariantChangesComponent(); + listener.Initialize(ServiceContext.ContentService, ServiceContext.LocalizationService); + + //create content type with a property type that varies by culture + var contentType = MockedContentTypes.CreateBasicContentType(); + contentType.Variations = ContentVariation.Culture; + var contentCollection = new PropertyTypeCollection(true); + contentCollection.Add(new PropertyType("test", ValueStorageType.Ntext) + { + Alias = "title", + Name = "Title", + Description = "", + Mandatory = false, + SortOrder = 1, + DataTypeId = -88, + Variations = ContentVariation.Culture + }); + contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); + contentType.ResetDirtyProperties(false); + ServiceContext.ContentTypeService.Save(contentType); + + //create some content of this content type + IContent doc = MockedContent.CreateBasicContent(contentType); + doc.SetCultureName("Home", "en-US"); + doc.SetValue("title", "hello world", "en-US"); + ServiceContext.ContentService.Save(doc); + + Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); + + //change the content type to be invariant + contentType.Variations = ContentVariation.Nothing; + ServiceContext.ContentTypeService.Save(contentType); + doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + + Assert.AreEqual("hello world", doc.GetValue("title")); + + //change back property type to be variant + contentType.Variations = ContentVariation.Culture; + ServiceContext.ContentTypeService.Save(contentType); + doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + + Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); + } + + [Test] + public void Change_Property_Type_From_Invariant_Variant() + { + //initialize the listener which is responsible for updating content based on variant/invariant changes + var listener = new UpdateContentOnVariantChangesComponent(); + listener.Initialize(ServiceContext.ContentService, ServiceContext.LocalizationService); + + //create content type with a property type that varies by culture + var contentType = MockedContentTypes.CreateBasicContentType(); + contentType.Variations = ContentVariation.Culture; + var contentCollection = new PropertyTypeCollection(true); + contentCollection.Add(new PropertyType("test", ValueStorageType.Ntext) + { + Alias = "title", + Name = "Title", + Description = "", + Mandatory = false, + SortOrder = 1, + DataTypeId = -88, + Variations = ContentVariation.Nothing + }); + contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); + contentType.ResetDirtyProperties(false); + ServiceContext.ContentTypeService.Save(contentType); + + //create some content of this content type + IContent doc = MockedContent.CreateBasicContent(contentType); + doc.SetCultureName("Home", "en-US"); + doc.SetValue("title", "hello world"); + ServiceContext.ContentService.Save(doc); + + Assert.AreEqual("hello world", doc.GetValue("title")); + + //change the property type to be variant + contentType.PropertyTypes.First().Variations = ContentVariation.Culture; + ServiceContext.ContentTypeService.Save(contentType); + doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + + Assert.AreEqual("hello world", doc.GetValue("title", "en-US")); + + //change back property type to be invariant + contentType.PropertyTypes.First().Variations = ContentVariation.Nothing; + ServiceContext.ContentTypeService.Save(contentType); + doc = ServiceContext.ContentService.GetById(doc.Id); //re-get + + Assert.AreEqual("hello world", doc.GetValue("title")); + } + [Test] public void Change_Property_Type_From_Variant_Invariant() {