From 9704c124eda16a4c2ffff869007c54b1ec498802 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 15:20:28 +1100 Subject: [PATCH 1/9] Removes all old deprecated drop down editors, we only have one drop down editor now and it doesn't store IDs either in the db or in the cache, it just stores what is selected --- src/Umbraco.Core/Constants-PropertyEditors.cs | 20 --- .../Migrations/Install/DatabaseDataCreator.cs | 2 +- .../Migrations/Upgrade/UmbracoPlan.cs | 2 + .../Upgrade/V_8_0_0/DataTypeMigration.cs | 7 +- .../DropDownPropertyEditorsMigration.cs | 145 ++++++++++++++++++ .../Upgrade/V_8_0_0/DropPreValueTable.cs | 15 ++ .../DropdownListMultipleValueConverter.cs | 33 ---- ...pdownListMultipleWithKeysValueConverter.cs | 34 ---- .../DropdownListValueConverter.cs | 23 --- .../DropdownListWithKeysValueConverter.cs | 27 ---- src/Umbraco.Core/Umbraco.Core.csproj | 6 +- .../MultiValuePropertyEditorTests.cs | 27 +--- .../PropertyEditorValueConverterTests.cs | 41 ++--- .../Entities/MockedContentTypes.cs | 11 +- .../CheckBoxListPropertyEditor.cs | 2 +- .../DropDownFlexiblePropertyEditor.cs | 2 +- .../DropDownMultipleConfigurationEditor.cs | 73 --------- .../DropDownMultiplePropertyEditor.cs | 30 ---- .../DropDownMultipleWithKeysPropertyEditor.cs | 37 ----- .../PropertyEditors/DropDownPropertyEditor.cs | 37 ----- .../DropDownWithKeysPropertyEditor.cs | 36 ----- .../PublishValueValueEditor.cs | 57 ------- .../PublishValuesMultipleValueEditor.cs | 55 +------ .../RadioButtonsPropertyEditor.cs | 21 ++- .../FlexibleDropdownPropertyValueConverter.cs | 4 +- src/Umbraco.Web/Umbraco.Web.csproj | 6 - 26 files changed, 225 insertions(+), 528 deletions(-) create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs delete mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs delete mode 100644 src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 126613cdb3..b09987ad90 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -44,26 +44,6 @@ namespace Umbraco.Core /// public const string DateTime = "Umbraco.DateTime"; - /// - /// DropDown List. - /// - public const string DropDownList = "Umbraco.DropDown"; - - /// - /// DropDown List, Publish Keys. - /// - public const string DropdownlistPublishKeys = "Umbraco.DropdownlistPublishingKeys"; - - /// - /// DropDown List Multiple. - /// - public const string DropDownListMultiple = "Umbraco.DropDownMultiple"; - - /// - /// DropDown List Multiple, Publish Keys. - /// - public const string DropdownlistMultiplePublishKeys = "Umbraco.DropdownlistMultiplePublishKeys"; - /// /// DropDown List. /// diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index c4ebfb664b..eb7cafcb01 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); - _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -39, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-39", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); + _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now }); diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index 5b0838573e..9ad7ccb48e 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -138,6 +138,8 @@ namespace Umbraco.Core.Migrations.Upgrade Chain("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}"); Chain("{77874C77-93E5-4488-A404-A630907CEEF0}"); + Chain("{23275462-446E-44C7-8C2C-3B8C1127B07D}"); + Chain("{6B251841-3069-4AD5-8AE9-861F9523E8DA}"); //FINAL diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs index eb39f37112..d7180385f0 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs @@ -7,10 +7,11 @@ using NPoco; using Umbraco.Core.Migrations.Install; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 { + public class DataTypeMigration : MigrationBase { public DataTypeMigration(IMigrationContext context) @@ -79,10 +80,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 Database.Update(dataType); } - - // drop preValues table - // FIXME keep it around for now - //Delete.Table("cmsDataTypePreValues"); } [TableName("cmsDataTypePreValues")] diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs new file mode 100644 index 0000000000..c9eba205e8 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Dtos; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Logging; + +namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 +{ + public class DropDownPropertyEditorsMigration : MigrationBase + { + public DropDownPropertyEditorsMigration(IMigrationContext context) : base(context) + { + } + + public override void Migrate() + { + //need to convert the old drop down data types to use the new one + var oldDropDowns = Database.Fetch(Sql().Select().Where(x => x.EditorAlias.Contains(".DropDown"))); + foreach(var dd in oldDropDowns) + { + //nothing to change if there is no config + if (dd.Configuration.IsNullOrWhiteSpace()) continue; + + ValueListConfiguration config; + try + { + config = JsonConvert.DeserializeObject(dd.Configuration); + } + catch (Exception ex) + { + Logger.Error(ex, $"Invalid drop down configuration detected: \"{dd.Configuration}\", cannot convert editor, values will be cleared"); + dd.Configuration = null; + Database.Update(dd); + continue; + } + + var propDataSql = Sql().Select("*").From() + .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) + .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) + .Where(x => x.EditorAlias == dd.EditorAlias); + + var propDatas = Database.Query(propDataSql); + var toUpdate = new List(); + foreach (var propData in propDatas) + { + if (UpdatePropertyDataDto(propData, config)) + { + //update later, we are iterating all values right now so no SQL can be run inside of this iteration (i.e. Query) + toUpdate.Add(propData); + } + } + + //run the property data updates + foreach(var propData in toUpdate) + { + Database.Update(propData); + } + + var requiresCacheRebuild = false; + switch (dd.EditorAlias) + { + case "Umbraco.DropDown": + UpdateDataType(dd, config, false); + break; + case "Umbraco.DropdownlistPublishingKeys": + UpdateDataType(dd, config, false); + requiresCacheRebuild = true; + break; + case "Umbraco.DropDownMultiple": + UpdateDataType(dd, config, false); + break; + case "Umbraco.DropdownlistMultiplePublishKeys": + UpdateDataType(dd, config, true); + requiresCacheRebuild = true; + break; + } + + if (requiresCacheRebuild) + { + //TODO: How to force rebuild the cache? + } + } + } + + private void UpdateDataType(DataTypeDto dataType, ValueListConfiguration config, bool isMultiple) + { + dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible; + var flexConfig = new + { + multiple = isMultiple, + items = config.Items + }; + dataType.Configuration = JsonConvert.SerializeObject(flexConfig); + } + + private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config) + { + //Get the INT ids stored for this property/drop down + IEnumerable ids = null; + if (!propData.VarcharValue.IsNullOrWhiteSpace()) + { + ids = ConvertStringValues(propData.VarcharValue); + } + else if (!propData.TextValue.IsNullOrWhiteSpace()) + { + ids = ConvertStringValues(propData.TextValue); + } + else if (propData.IntegerValue.HasValue) + { + ids = new[] { propData.IntegerValue.Value }; + } + + //if there are INT ids, convert them to values based on the configured pre-values + if (ids != null) + { + //map the ids to values + var vals = new List(); + foreach (var id in ids) + { + var val = config.Items.FirstOrDefault(x => x.Id == id); + if (val != null) + vals.Add(val.Value); + } + + propData.VarcharValue = string.Join(",", vals); + propData.TextValue = null; + propData.IntegerValue = null; + return true; + } + + return false; + } + + private IEnumerable ConvertStringValues(string val) + { + return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) + .Where(x => x != int.MinValue); + } + + } +} diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs new file mode 100644 index 0000000000..26402cc477 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs @@ -0,0 +1,15 @@ +namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 +{ + public class DropPreValueTable : MigrationBase + { + public DropPreValueTable(IMigrationContext context) : base(context) + { + } + + public override void Migrate() + { + // drop preValues table + Delete.Table("cmsDataTypePreValues").Do(); + } + } +} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs deleted file mode 100644 index d91f45292c..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleValueConverter.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListMultipleValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownListMultiple); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (IEnumerable); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel cacheLevel, object source, bool preview) - { - var sourceString = (source ?? "").ToString(); - - if (string.IsNullOrEmpty(sourceString)) - return Enumerable.Empty(); - - var values = - sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()); - - return values; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs deleted file mode 100644 index bceebc232b..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListMultipleWithKeysValueConverter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListMultipleWithKeysValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (IEnumerable); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - if (source == null) - return new int[] { }; - - var prevalueIds = source.ToString() - .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(p => p.Trim()) - .Select(int.Parse) - .ToArray(); - - return prevalueIds; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs deleted file mode 100644 index 5fe1967f32..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListValueConverter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropDownList); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (string); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - return source?.ToString() ?? string.Empty; - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs deleted file mode 100644 index 960cd4afa6..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/DropdownListWithKeysValueConverter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Umbraco.Core.Models.PublishedContent; - -namespace Umbraco.Core.PropertyEditors.ValueConverters -{ - [DefaultPropertyValueConverter] - public class DropdownListWithKeysValueConverter : PropertyValueConverterBase - { - public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys); - - public override Type GetPropertyValueType(PublishedPropertyType propertyType) - => typeof (int); - - public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType) - => PropertyCacheLevel.Element; - - public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) - { - var intAttempt = source.TryConvertTo(); - if (intAttempt.Success) - return intAttempt.Result; - - return null; - } - } -} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 6951a9e17a..4d4bbb32e2 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -356,6 +356,8 @@ + + @@ -1239,10 +1241,6 @@ - - - - diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 9ba5ccf6f2..129116bf61 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -21,28 +21,15 @@ namespace Umbraco.Tests.PropertyEditors /// Tests for the base classes of ValueEditors and PreValueEditors that are used for Property Editors that edit /// multiple values such as the drop down list, check box list, color picker, etc.... /// + /// + /// Mostly this used to test the we'd store INT Ids in the Db but publish STRING values or sometimes the INT values + /// to cache. Now we always just deal with strings and we'll keep the tests that show that. + /// [TestFixture] public class MultiValuePropertyEditorTests { - //TODO: Test the other formatting methods for the drop down classes - [Test] - public void DropDownMultipleValueEditor_With_Keys_Format_Data_For_Cache() - { - var dataTypeServiceMock = new Mock(); - var editor = new PublishValuesMultipleValueEditor(true, Mock.Of(), new DataEditorAttribute("key", "nam", "view")); - - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())); - var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234,4567,8910"); - - var result = editor.ConvertDbToString(prop.PropertyType, prop.GetValue(), new Mock().Object); - - Assert.AreEqual("1234,4567,8910", result); - } - - [Test] - public void DropDownMultipleValueEditor_No_Keys_Format_Data_For_Cache() + public void DropDownMultipleValueEditor_Format_Data_For_Cache() { var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) { @@ -61,7 +48,7 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234,4567,8910"); + prop.SetValue("Value 1,Value 2,Value 3"); var valueEditor = dataType.Editor.GetValueEditor(); ((DataValueEditor) valueEditor).Configuration = dataType.Configuration; @@ -90,7 +77,7 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); - prop.SetValue("1234"); + prop.SetValue("Value 2"); var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs index 2c3a2d1583..7ec23158f6 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs @@ -1,8 +1,14 @@ using System; using System.Collections.Generic; +using System.Linq; +using Moq; using NUnit.Framework; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Web.PropertyEditors; +using Umbraco.Web.PropertyEditors.ValueConverters; namespace Umbraco.Tests.PropertyEditors { @@ -79,27 +85,26 @@ namespace Umbraco.Tests.PropertyEditors [TestCase(null, new string[] { })] public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable expected) { - var converter = new DropdownListMultipleValueConverter(); - var inter = converter.ConvertSourceToIntermediate(null, null, value, false); - var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false); + var mockPublishedContentTypeFactory = new Mock(); + mockPublishedContentTypeFactory.Setup(x => x.GetDataType(123)) + .Returns(new PublishedDataType(123, "test", new Lazy(() => new DropDownFlexibleConfiguration + { + Multiple = true + }))); + + var publishedPropType = new PublishedPropertyType( + new PublishedContentType(1234, "test", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing), + new PropertyType("test", ValueStorageType.Nvarchar) { DataTypeId = 123 }, + new PropertyValueConverterCollection(Enumerable.Empty()), + Mock.Of(), mockPublishedContentTypeFactory.Object); + + var converter = new FlexibleDropdownPropertyValueConverter(); + var inter = converter.ConvertSourceToIntermediate(null, publishedPropType, value, false); + var result = converter.ConvertIntermediateToObject(null, publishedPropType, PropertyCacheLevel.Unknown, inter, false); Assert.AreEqual(expected, result); } - - [TestCase("100", new[] { 100 })] - [TestCase("100,200", new[] { 100, 200 })] - [TestCase("100 , 200, 300 ", new[] { 100, 200, 300 })] - [TestCase("", new int[] { })] - [TestCase(null, new int[] { })] - public void CanConvertDropdownListMultipleWithKeysPropertyEditor(object value, IEnumerable expected) - { - var converter = new DropdownListMultipleWithKeysValueConverter(); - var inter = converter.ConvertSourceToIntermediate(null, null, value, false); - var result = converter.ConvertIntermediateToObject(null, null, PropertyCacheLevel.Unknown, inter, false); - - Assert.AreEqual(expected, result); - } - + [TestCase("1", 1)] [TestCase("1", 1)] [TestCase("0", 0)] diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 752d0ac97e..42beea7df3 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -362,12 +362,10 @@ namespace Umbraco.Tests.TestHelpers.Entities contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.NoEdit, ValueStorageType.Nvarchar) { Alias = "label", Name = "Label", Mandatory = false, SortOrder = 7, DataTypeId = -92 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DateTime, ValueStorageType.Date) { Alias = "dateTime", Name = "Date Time", Mandatory = false, SortOrder = 8, DataTypeId = -36 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ColorPicker, ValueStorageType.Nvarchar) { Alias = "colorPicker", Name = "Color Picker", Mandatory = false, SortOrder = 9, DataTypeId = -37 }); - //that one is gone in 7.4 - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.FolderBrowserAlias, DataTypeDatabaseType.Nvarchar) { Alias = "folderBrowser", Name = "Folder Browser", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -38 }); - contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListMultiple, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeId = -39 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RadioButtonList, ValueStorageType.Nvarchar) { Alias = "rbList", Name = "Radio Button List", Mandatory = false, SortOrder = 12, DataTypeId = -40 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Date, ValueStorageType.Date) { Alias = "date", Name = "Date", Mandatory = false, SortOrder = 13, DataTypeId = -41 }); - contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownList, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.DropDownListFlexible, ValueStorageType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeId = -42 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.CheckBoxList, ValueStorageType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeId = -43 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ContentPicker, ValueStorageType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeId = 1046 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker, ValueStorageType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1048 }); @@ -375,11 +373,6 @@ namespace Umbraco.Tests.TestHelpers.Entities contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RelatedLinks, ValueStorageType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeId = 1050 }); contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Tags, ValueStorageType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeId = 1041 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltraSimpleEditorAlias, DataTypeDatabaseType.Ntext) { Alias = "simpleEditor", Name = "Ultra Simple Editor", Mandatory = false, SortOrder = 19, DataTypeDefinitionId = 1038 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.UltimatePickerAlias, DataTypeDatabaseType.Ntext) { Alias = "ultimatePicker", Name = "Ultimate Picker", Mandatory = false, SortOrder = 20, DataTypeDefinitionId = 1039 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.MacroContainerAlias, DataTypeDatabaseType.Ntext) { Alias = "macroContainer", Name = "Macro Container", Mandatory = false, SortOrder = 23, DataTypeDefinitionId = 1042 }); - //contentCollection.Add(new PropertyType(Constants.PropertyEditors.ImageCropperAlias, DataTypeDatabaseType.Ntext) { Alias = "imgCropper", Name = "Image Cropper", Mandatory = false, SortOrder = 24, DataTypeDefinitionId = 1043 }); - contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); return contentType; diff --git a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs index 53de8460f2..7f8dc3f03a 100644 --- a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -31,6 +31,6 @@ namespace Umbraco.Web.PropertyEditors protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); + protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(Logger, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs index 6acbedef63..4424e1d245 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors protected override IDataValueEditor CreateValueEditor() { - return new PublishValuesMultipleValueEditor(false, Attribute); + return new PublishValuesMultipleValueEditor(Logger, Attribute); } protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService); diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs deleted file mode 100644 index a8956f9c4f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleConfigurationEditor.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// Represents a configuration editor for the "drop down list multiple" property editor. - /// - /// - /// Ensures that 'multiple' is saved for the config in the db but is not a configuration field. - /// This is mostly to maintain backwards compatibility with old property editors. Devs can now simply - /// use the "drop down" property editor and check the "multiple" configuration checkbox - /// fixme what is multiple exactly?! - /// - internal class DropDownMultipleConfigurationEditor : ValueListConfigurationEditor - { - public DropDownMultipleConfigurationEditor(ILocalizedTextService textService) - : base(textService) - { - Fields.Add(new ConfigurationField - { - Key = "multiple", - Name = "multiple", - View = "hidden", // so it does not show in the configuration editor - HideLabel = true - }); - } - - // editor... - // - // receives: - // "preValues":[ - // { - // "label":"Add prevalue", - // "description":"Add and remove values for the list", - // "hideLabel":false, - // "view":"multivalues", - // "config":{}, - // "key":"items", - // "value":{"169":{"value":"a","sortOrder":1},"170":{"value":"b","sortOrder":2},"171":{"value":"c","sortOrder":3}} - // }, - // { - // "label":"multiple", - // "description":null, - // "hideLabel":true, - // "view":"hidden", - // "config":{}, - // "key":"multiple", - // "value":"1" - // }] - // - // posts ('d' being a new value): - // [{key: "items", value: [{value: "a", sortOrder: 1, id: "169"}, {value: "c", sortOrder: 3, id: "171"}, {value: "d"}]}, {key: "multiple", value: "1"}] - // - // the 'multiple' thing never goes to DB - // values go to DB with alias 0, 1, 2 + their ID + value - // the sort order that comes back makes no sense - // - // FromEditor can totally ignore 'multiple' - - /// - public override Dictionary ToConfigurationEditor(ValueListConfiguration configuration) - { - var dictionary = base.ToConfigurationEditor(configuration); - - // always add the multiple field, as 'true' - dictionary["multiple"] = 1; - - return dictionary; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs deleted file mode 100644 index 5992090a62..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow multiple selection of pre-defined items - /// - /// - /// Due to maintaining backwards compatibility this data type stores the value as a string which is a comma separated value of the - /// ids of the individual items so we have logic in here to deal with that. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownListMultiple, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list", IsDeprecated = true)] - public class DropDownMultiplePropertyEditor : DropDownMultipleWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownMultiplePropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(false, Attribute); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs deleted file mode 100644 index 0b882c6b8d..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// Represents a property editor that allows multiple selection of pre-defined items. - /// - /// - /// Due to backwards compatibility, this editor stores the value as a CSV string listing - /// the ids of individual items. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropdownlistMultiplePublishKeys, "Dropdown list multiple, publish keys", "dropdown", Group = "lists", Icon = "icon-bulleted-list", IsDeprecated = true)] - public class DropDownMultipleWithKeysPropertyEditor : DropDownPropertyEditor - { - private readonly ILocalizedTextService _textService; - - /// - /// Initializes a new instance of the class. - /// - public DropDownMultipleWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { - _textService = textService; - } - - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValuesMultipleValueEditor(true, Attribute); - - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownMultipleConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs deleted file mode 100644 index f4736ab63f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using umbraco; -using ClientDependency.Core; -using Umbraco.Core.Services; -using Constants = Umbraco.Core.Constants; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published - /// in cache and not the int ID. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropDownList, "Dropdown list", "dropdown", ValueType = ValueTypes.String, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] - public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor - { - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } - - /// - /// We need to override the value editor so that we can ensure the string value is published in cache and not the integer ID value. - /// - /// - protected override IDataValueEditor CreateValueEditor() => new PublishValueValueEditor(Attribute, Logger); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs deleted file mode 100644 index 72d4b8c95f..0000000000 --- a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A property editor to allow the individual selection of pre-defined items. - /// - /// - /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published - /// in cache and not the string value. - /// - [DataEditor(Constants.PropertyEditors.Aliases.DropdownlistPublishKeys, "Dropdown list, publishing keys", "dropdown", ValueType = ValueTypes.Integer, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] - public class DropDownWithKeysPropertyEditor : DataEditor - { - private readonly ILocalizedTextService _textService; - - /// - /// The constructor will setup the property editor based on the attribute if one is found - /// - public DropDownWithKeysPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger) - { - _textService = textService; - } - - /// - /// Return a custom pre-value editor - /// - /// - protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs deleted file mode 100644 index 49ed34ffef..0000000000 --- a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.PropertyEditors -{ - /// - /// A custom value editor for any property editor that stores a pre-value int id so that we can ensure that the 'value' not the ID get's put into cache - /// - /// - /// This is required for legacy/backwards compatibility, otherwise we'd just store the string version and cache the string version without - /// needing additional lookups. - /// - internal class PublishValueValueEditor : DataValueEditor - { - private readonly ILogger _logger; - - internal PublishValueValueEditor(DataEditorAttribute attribute, ILogger logger) - : base(attribute) - { - _logger = logger; - } - - /// - public override string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) - { - if (value == null) - return null; - - // get the configuration items - // if none, fallback to base - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); - if (configuration == null) - return base.ConvertDbToString(propertyType, value, dataTypeService); - - var items = configuration.Items; - - var idAttempt = value.TryConvertTo(); - if (idAttempt.Success) - { - var itemId = idAttempt.Result; - var item = items.FirstOrDefault(x => x.Id == itemId); - if (item != null) return item.Value; - - _logger.Warn("Could not find a configuration item with ID " + itemId + " for property alias " + propertyType.Alias); - } - - // fallback to default - return base.ConvertDbToString(propertyType, value, dataTypeService); - } - } -} diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index 0276bdc0a4..6aea6edba5 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -11,60 +11,21 @@ using Umbraco.Web.Composing; namespace Umbraco.Web.PropertyEditors { /// - /// Custom value editor to handle posted json data and to return json data for the multiple selected items as well as ensuring - /// that the multiple selected int IDs are published to cache as a delimited string (values) + /// Custom value editor to handle posted json data and to return json data for the multiple selected items /// /// /// This is re-used by editors such as the multiple drop down list or check box list /// - internal class PublishValuesMultipleValueEditor : PublishValueValueEditor + internal class PublishValuesMultipleValueEditor : DataValueEditor { - private readonly bool _publishIds; + private readonly ILogger _logger; - internal PublishValuesMultipleValueEditor(bool publishIds, ILogger logger, DataEditorAttribute attribute) - : base(attribute, logger) + internal PublishValuesMultipleValueEditor(ILogger logger, DataEditorAttribute attribute) + : base(attribute) { - _publishIds = publishIds; + _logger = logger; } - - public PublishValuesMultipleValueEditor(bool publishIds, DataEditorAttribute attribute) - : this(publishIds, Current.Logger, attribute) - { } - - /// - /// If publishing ids, we don't need to do anything, otherwise we need to look up the pre-values and get the string values - /// - /// - /// - /// - /// - public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) - { - if (propertyValue == null) - return null; - - //publishing ids, so just need to return the value as-is - if (_publishIds) - { - return propertyValue.ToString(); - } - - // get the multiple ids - // if none, fallback to base - var selectedIds = propertyValue.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); - if (selectedIds.Any() == false) - return base.ConvertDbToString(propertyType, propertyValue, dataTypeService); - - // get the configuration items - // if none, fallback to base - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); - if (configuration == null) - return base.ConvertDbToString(propertyType, propertyValue, dataTypeService); - - var items = configuration.Items.Where(x => selectedIds.Contains(x.Id.ToInvariantString())).Select(x => x.Value); - return string.Join(",", items); - } - + /// /// Override so that we can return a json array to the editor for multi-select values /// @@ -81,7 +42,7 @@ namespace Umbraco.Web.PropertyEditors /// /// When multiple values are selected a json array will be posted back so we need to format for storage in - /// the database which is a comma separated ID value + /// the database which is a comma separated string value /// /// /// diff --git a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs index e5d9e4d4e8..46069fec79 100644 --- a/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RadioButtonsPropertyEditor.cs @@ -8,19 +8,24 @@ namespace Umbraco.Web.PropertyEditors /// /// A property editor to allow the individual selection of pre-defined items. /// - /// - /// Due to remaining backwards compatible, this stores the id of the item in the database which is why it is marked - /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published - /// in cache and not the string value. - /// [DataEditor(Constants.PropertyEditors.Aliases.RadioButtonList, "Radio button list", "radiobuttons", ValueType = ValueTypes.Integer, Group="lists", Icon="icon-target")] - public class RadioButtonsPropertyEditor : DropDownWithKeysPropertyEditor + public class RadioButtonsPropertyEditor : DataEditor { + private readonly ILocalizedTextService _textService; + /// /// The constructor will setup the property editor based on the attribute if one is found /// public RadioButtonsPropertyEditor(ILogger logger, ILocalizedTextService textService) - : base(logger, textService) - { } + : base(logger) + { + _textService = textService; + } + + /// + /// Return a custom pre-value editor + /// + /// + protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs index 521817a7de..d470f54662 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; @@ -16,7 +17,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview) { - return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + return source?.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToArray() + ?? Enumerable.Empty(); } public override object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 6f122719d0..313b82de29 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -360,7 +360,6 @@ - @@ -814,11 +813,9 @@ - - @@ -828,9 +825,6 @@ - - - From f332e9a07e13b9a27cb4516cc5efefadb1909a74 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 15:45:24 +1100 Subject: [PATCH 2/9] Fix sql and table check --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 7 +++++-- .../Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index c9eba205e8..2f50b9cd72 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -18,7 +18,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 public override void Migrate() { //need to convert the old drop down data types to use the new one - var oldDropDowns = Database.Fetch(Sql().Select().Where(x => x.EditorAlias.Contains(".DropDown"))); + var oldDropDowns = Database.Fetch(Sql() + .Select() + .From() + .Where(x => x.EditorAlias.Contains(".DropDown"))); foreach(var dd in oldDropDowns) { //nothing to change if there is no config @@ -37,7 +40,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 continue; } - var propDataSql = Sql().Select("*").From() + var propDataSql = Sql().Select().From() .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) .Where(x => x.EditorAlias == dd.EditorAlias); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs index 26402cc477..fa6e47fac7 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs @@ -9,7 +9,8 @@ public override void Migrate() { // drop preValues table - Delete.Table("cmsDataTypePreValues").Do(); + if (TableExists("cmsDataTypePreValues")) + Delete.Table("cmsDataTypePreValues").Do(); } } } From df7623e6a7be9d6dfa5056b1b29c81b07ff3cd7c Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:32:13 +1100 Subject: [PATCH 3/9] Fixes migration, ensure's that if it runs again it won't corrupt data, fixes flexible drop down angular editor to post string vals, not the int ids, removes old angular drop down prop editor --- .../DropDownPropertyEditorsMigration.cs | 49 +++++++++---- .../dropdown/dropdown.controller.js | 70 ------------------- .../propertyeditors/dropdown/dropdown.html | 20 ------ .../dropdownFlexible.controller.js | 2 +- .../dropdownFlexible/dropdownFlexible.html | 4 +- .../PublishValuesMultipleValueEditor.cs | 2 +- 6 files changed, 38 insertions(+), 109 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js delete mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 2f50b9cd72..accb755020 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 .Select() .From() .Where(x => x.EditorAlias.Contains(".DropDown"))); - foreach(var dd in oldDropDowns) + foreach (var dd in oldDropDowns) { //nothing to change if there is no config if (dd.Configuration.IsNullOrWhiteSpace()) continue; @@ -30,7 +30,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 ValueListConfiguration config; try { - config = JsonConvert.DeserializeObject(dd.Configuration); + config = JsonConvert.DeserializeObject(dd.Configuration); } catch (Exception ex) { @@ -43,7 +43,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 var propDataSql = Sql().Select().From() .InnerJoin().On(x => x.Id, x => x.PropertyTypeId) .InnerJoin().On(x => x.NodeId, x => x.DataTypeId) - .Where(x => x.EditorAlias == dd.EditorAlias); + .Where(x => x.DataTypeId == dd.NodeId); var propDatas = Database.Query(propDataSql); var toUpdate = new List(); @@ -57,7 +57,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } //run the property data updates - foreach(var propData in toUpdate) + foreach (var propData in toUpdate) { Database.Update(propData); } @@ -97,12 +97,13 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 items = config.Items }; dataType.Configuration = JsonConvert.SerializeObject(flexConfig); + Database.Update(dataType); } private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config) { //Get the INT ids stored for this property/drop down - IEnumerable ids = null; + int[] ids = null; if (!propData.VarcharValue.IsNullOrWhiteSpace()) { ids = ConvertStringValues(propData.VarcharValue); @@ -117,31 +118,49 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } //if there are INT ids, convert them to values based on the configured pre-values - if (ids != null) + if (ids != null && ids.Length > 0) { //map the ids to values var vals = new List(); + var canConvert = true; foreach (var id in ids) { var val = config.Items.FirstOrDefault(x => x.Id == id); if (val != null) vals.Add(val.Value); + else + { + Logger.Warn($"Could not find associated data type configuration for stored Id {id}"); + canConvert = false; + } } - - propData.VarcharValue = string.Join(",", vals); - propData.TextValue = null; - propData.IntegerValue = null; - return true; + if (canConvert) + { + propData.VarcharValue = string.Join(",", vals); + propData.TextValue = null; + propData.IntegerValue = null; + return true; + } + } return false; } - private IEnumerable ConvertStringValues(string val) + private int[] ConvertStringValues(string val) { - return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) - .Where(x => x != int.MinValue); + var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + var intVals = splitVals + .Select(x => int.TryParse(x, out var i) ? i : int.MinValue) + .Where(x => x != int.MinValue) + .ToArray(); + + //only return if the number of values are the same (i.e. All INTs) + if (splitVals.Length == intVals.Length) + return intVals; + + return null; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js deleted file mode 100644 index bcbd13f860..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js +++ /dev/null @@ -1,70 +0,0 @@ -angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownController", - function($scope) { - - //setup the default config - var config = { - items: [], - multiple: false - }; - - //map the user config - angular.extend(config, $scope.model.config); - - //map back to the model - $scope.model.config = config; - - function convertArrayToDictionaryArray(model){ - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - for (var i = 0; i < model.length; i++) { - newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); - } - - return newItems; - } - - - function convertObjectToDictionaryArray(model){ - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - var vals = _.values($scope.model.config.items); - var keys = _.keys($scope.model.config.items); - - for (var i = 0; i < vals.length; i++) { - var label = vals[i].value ? vals[i].value : vals[i]; - newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); - } - - return newItems; - } - - if (angular.isArray($scope.model.config.items)) { - //PP: I dont think this will happen, but we have tests that expect it to happen.. - //if array is simple values, convert to array of objects - if(!angular.isObject($scope.model.config.items[0])){ - $scope.model.config.items = convertArrayToDictionaryArray($scope.model.config.items); - } - } - else if (angular.isObject($scope.model.config.items)) { - $scope.model.config.items = convertObjectToDictionaryArray($scope.model.config.items); - } - else { - throw "The items property must be either an array or a dictionary"; - } - - - //sort the values - $scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); - - //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set - // to "" gets selected by default - if ($scope.model.value === null || $scope.model.value === undefined) { - if ($scope.model.config.multiple) { - $scope.model.value = []; - } - else { - $scope.model.value = ""; - } - } - - }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html deleted file mode 100644 index 663373c8eb..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html +++ /dev/null @@ -1,20 +0,0 @@ -
- - - - - - -
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index c7a472d80e..1ea77ee035 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -74,7 +74,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo // if we run in single mode we'll store the value in a local variable // so we can pass an array as the model as our PropertyValueEditor expects that $scope.model.singleDropdownValue = ""; - if ($scope.model.config.multiple === "0") { + if (Object.toBoolean($scope.model.config.multiple)) { $scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html index 5edbab4f30..7c55f0bda9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -5,7 +5,7 @@ ng-switch-default ng-change="updateSingleDropdownValue()" ng-model="model.singleDropdownValue" - ng-options="item.id as item.value for item in model.config.items"> + ng-options="item.value as item.value for item in model.config.items"> @@ -15,5 +15,5 @@ ng-switch-when="1" multiple ng-model="model.value" - ng-options="item.id as item.value for item in model.config.items"> + ng-options="item.value as item.value for item in model.config.items"> diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index 6aea6edba5..8e0737dedd 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.PropertyEditors { _logger = logger; } - + /// /// Override so that we can return a json array to the editor for multi-select values /// From b199b7346b107c77ad180c691cfed7ffe52d15e0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:35:30 +1100 Subject: [PATCH 4/9] Fixes multiple selection with drop down --- .../dropdownFlexible/dropdownFlexible.controller.js | 5 ++++- .../propertyeditors/dropdownFlexible/dropdownFlexible.html | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index 1ea77ee035..23bd2c9a42 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -12,7 +12,10 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo //map back to the model $scope.model.config = config; - + + //ensure this is a bool, old data could store zeros/ones or string versions + $scope.model.config.multiple = Object.toBoolean($scope.model.config.multiple); + function convertArrayToDictionaryArray(model){ //now we need to format the items in the dictionary because we always want to have an array var newItems = []; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html index 7c55f0bda9..3239e64acc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -12,7 +12,7 @@ From 9347e6205fe5be3a8d1638d5a9626db5555dc416 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 24 Oct 2018 16:36:13 +1100 Subject: [PATCH 5/9] fixes test --- src/Umbraco.Tests/Composing/TypeLoaderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 9b23ec3d6b..1199b37cdb 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -279,7 +279,7 @@ AnotherContentFinder public void GetDataEditors() { var types = _typeLoader.GetDataEditors(); - Assert.AreEqual(43, types.Count()); + Assert.AreEqual(39, types.Count()); } /// From 15eaa33e08be55cc43e1cee59b261a7e22b05083 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 01:15:23 +1100 Subject: [PATCH 6/9] updates migration to invariant string check --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index accb755020..64ee2f6b88 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -65,17 +65,17 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 var requiresCacheRebuild = false; switch (dd.EditorAlias) { - case "Umbraco.DropDown": + case string ea when ea.InvariantEquals("Umbraco.DropDown"): UpdateDataType(dd, config, false); break; - case "Umbraco.DropdownlistPublishingKeys": + case string ea when ea.InvariantEquals("Umbraco.DropdownlistPublishingKeys"): UpdateDataType(dd, config, false); requiresCacheRebuild = true; break; - case "Umbraco.DropDownMultiple": + case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"): UpdateDataType(dd, config, false); break; - case "Umbraco.DropdownlistMultiplePublishKeys": + case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"): UpdateDataType(dd, config, true); requiresCacheRebuild = true; break; From 0d0d26d3e994ad42ecfd9edb77319d15adc0c2dc Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:05:43 +1100 Subject: [PATCH 7/9] Fixes converting the Umbraco.DropDownMultiple to a multiple drop down, fixes boolean logic on the js single drop down --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 2 +- .../dropdownFlexible/dropdownFlexible.controller.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 64ee2f6b88..87d7a8c571 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -73,7 +73,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 requiresCacheRebuild = true; break; case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"): - UpdateDataType(dd, config, false); + UpdateDataType(dd, config, true); break; case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"): UpdateDataType(dd, config, true); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index 23bd2c9a42..f8e02a240a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -77,7 +77,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo // if we run in single mode we'll store the value in a local variable // so we can pass an array as the model as our PropertyValueEditor expects that $scope.model.singleDropdownValue = ""; - if (Object.toBoolean($scope.model.config.multiple)) { + if (!Object.toBoolean($scope.model.config.multiple)) { $scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value; } From f123331d421b4fed7485a3146af10139541bd58c Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:11:33 +1100 Subject: [PATCH 8/9] Fixes updating the storage type --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 87d7a8c571..600f952d6a 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Logging; +using Umbraco.Core.Models; namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 { @@ -96,6 +97,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 multiple = isMultiple, items = config.Items }; + dataType.DbType = ValueStorageType.Nvarchar.ToString(); dataType.Configuration = JsonConvert.SerializeObject(flexConfig); Database.Update(dataType); } From 386dd2281ce321666ce07a1b39069dc7227c68ab Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 30 Oct 2018 02:18:07 +1100 Subject: [PATCH 9/9] Fixes log messages --- .../Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs index 600f952d6a..e5cda85168 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs @@ -35,7 +35,9 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 } catch (Exception ex) { - Logger.Error(ex, $"Invalid drop down configuration detected: \"{dd.Configuration}\", cannot convert editor, values will be cleared"); + Logger.Error( + ex, "Invalid drop down configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared", + dd.Configuration); dd.Configuration = null; Database.Update(dd); continue; @@ -132,7 +134,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 vals.Add(val.Value); else { - Logger.Warn($"Could not find associated data type configuration for stored Id {id}"); + Logger.Warn( + "Could not find associated data type configuration for stored Id {DataTypeId}", id); canConvert = false; } }