From 2f42fc61bfb0ce4941e1572ad2c4f9204730ea88 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 19 Nov 2013 11:51:01 +1100 Subject: [PATCH] Changed method signatures of some of the conversion methods on the PropertyValueEditor to make it more flexible for developers to do what they want. --- src/Umbraco.Core/Models/PropertyExtensions.cs | 7 ++-- .../BackwardsCompatibleData.cs | 2 +- .../PropertyEditors/PropertyValueEditor.cs | 33 +++++++++++-------- .../DropDownPropertyPreValueEditorTests.cs | 27 ++++++++------- .../PropertyEditorValueEditorTests.cs | 15 +++++++-- .../Mapping/ContentPropertyBasicConverter.cs | 15 ++++++--- .../ContentPropertyDisplayConverter.cs | 7 ++-- .../Mapping/ContentPropertyDtoConverter.cs | 6 ++-- .../Mapping/ContentPropertyModelMapper.cs | 2 +- .../PropertyEditors/DatePropertyEditor.cs | 5 +-- .../MultipleTextStringPropertyEditor.cs | 11 ++++--- .../PublishValueValueEditor.cs | 10 +++--- .../PublishValuesMultipleValueEditor.cs | 18 ++++++---- .../PropertyEditors/RichTextPropertyEditor.cs | 12 ++++--- 14 files changed, 103 insertions(+), 67 deletions(-) diff --git a/src/Umbraco.Core/Models/PropertyExtensions.cs b/src/Umbraco.Core/Models/PropertyExtensions.cs index 519b022d39..ccdfa08c37 100644 --- a/src/Umbraco.Core/Models/PropertyExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyExtensions.cs @@ -17,16 +17,17 @@ namespace Umbraco.Core.Models /// Xml of the property and its value public static XElement ToXml(this Property property) { - return property.ToXml(ApplicationContext.Current.Services.DataTypeService); + return property.ToXml(property.PropertyType, ApplicationContext.Current.Services.DataTypeService); } /// /// Creates the xml representation for the object /// /// to generate xml for + /// /// /// Xml of the property and its value - internal static XElement ToXml(this Property property, IDataTypeService dataTypeService) + internal static XElement ToXml(this Property property, PropertyType propertyType, IDataTypeService dataTypeService) { var nodeName = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema ? "data" : property.Alias.ToSafeAlias(); @@ -43,7 +44,7 @@ namespace Umbraco.Core.Models var propertyEditor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias); if (propertyEditor != null) { - var xmlValue = propertyEditor.ValueEditor.ConvertDbToXml(property); + var xmlValue = propertyEditor.ValueEditor.ConvertDbToXml(property, propertyType, dataTypeService); xElement.Add(xmlValue); } diff --git a/src/Umbraco.Core/PropertyEditors/BackwardsCompatibleData.cs b/src/Umbraco.Core/PropertyEditors/BackwardsCompatibleData.cs index 2d257a0d03..0b8496bbab 100644 --- a/src/Umbraco.Core/PropertyEditors/BackwardsCompatibleData.cs +++ b/src/Umbraco.Core/PropertyEditors/BackwardsCompatibleData.cs @@ -41,7 +41,7 @@ namespace Umbraco.Core.PropertyEditors Value = Value }; var xd = new XmlDocument(); - var xNode = propertyEditor.ValueEditor.ConvertDbToXml(property); + var xNode = propertyEditor.ValueEditor.ConvertDbToXml(property, property.PropertyType, ApplicationContext.Current.Services.DataTypeService); //check if this xml fragment can be converted to an XmlNode var xContainer = xNode as XContainer; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs index becc90aefc..48ede3d2b8 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueEditor.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; +using Umbraco.Core.Services; namespace Umbraco.Core.PropertyEditors { @@ -235,15 +236,17 @@ namespace Umbraco.Core.PropertyEditors /// /// A method used to format the database value to a value that can be used by the editor /// - /// + /// + /// + /// /// /// /// The object returned will automatically be serialized into json notation. For most property editors /// the value returned is probably just a string but in some cases a json structure will be returned. /// - public virtual object ConvertDbToEditor(object dbValue) + public virtual object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { - if (dbValue == null) return string.Empty; + if (property.Value == null) return string.Empty; switch (GetDatabaseType()) { @@ -251,7 +254,7 @@ namespace Umbraco.Core.PropertyEditors case DataTypeDatabaseType.Nvarchar: //if it is a string type, we will attempt to see if it is json stored data, if it is we'll try to convert //to a real json object so we can pass the true json object directly to angular! - var asString = dbValue.ToString(); + var asString = property.Value.ToString(); if (asString.DetectIsJson()) { try @@ -264,12 +267,12 @@ namespace Umbraco.Core.PropertyEditors //swallow this exception, we thought it was json but it really isn't so continue returning a string } } - return dbValue.ToString(); + return property.Value.ToString(); case DataTypeDatabaseType.Integer: //we can just ToString() any of these types - return dbValue.ToString(); - case DataTypeDatabaseType.Date: - var date = dbValue.TryConvertTo(); + return property.Value.ToString(); + case DataTypeDatabaseType.Date: + var date = property.Value.TryConvertTo(); if (date.Success == false || date.Result == null) { return string.Empty; @@ -285,6 +288,8 @@ namespace Umbraco.Core.PropertyEditors /// Converts the property db value to an XML fragment /// /// + /// + /// /// /// /// By default this will just return the value of ConvertDbToString but ensure that if the db value type is nvarchar or text @@ -294,23 +299,23 @@ namespace Umbraco.Core.PropertyEditors /// /// If the value is empty we will not return as CDATA since that will just take up more space in the file. /// - public virtual XNode ConvertDbToXml(Property property) + public virtual XNode ConvertDbToXml(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { //check for null or empty value, we don't want to return CDATA if that is the case if (property.Value == null || property.Value.ToString().IsNullOrWhiteSpace()) { - return new XText(ConvertDbToString(property)); + return new XText(ConvertDbToString(property, propertyType, dataTypeService)); } switch (GetDatabaseType()) { case DataTypeDatabaseType.Date: case DataTypeDatabaseType.Integer: - return new XText(ConvertDbToString(property)); + return new XText(ConvertDbToString(property, propertyType, dataTypeService)); case DataTypeDatabaseType.Nvarchar: case DataTypeDatabaseType.Ntext: //put text in cdata - return new XCData(ConvertDbToString(property)); + return new XCData(ConvertDbToString(property, propertyType, dataTypeService)); default: throw new ArgumentOutOfRangeException(); } @@ -320,8 +325,10 @@ namespace Umbraco.Core.PropertyEditors /// Converts the property value for use in the front-end cache /// /// + /// + /// /// - public virtual string ConvertDbToString(Property property) + public virtual string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null) { diff --git a/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs index 199ac5351c..ba842b1800 100644 --- a/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs @@ -25,10 +25,11 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = dataTypeServiceMock.Object; var editor = new PublishValuesMultipleValueEditor(true, dataTypeService, new PropertyValueEditor()); - var result = editor.ConvertDbToString( - new Property(1, Guid.NewGuid(), - new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), - "1234,4567,8910")); + var prop = new Property(1, Guid.NewGuid(), + new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), + "1234,4567,8910"); + + var result = editor.ConvertDbToString(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual("1234,4567,8910", result); } @@ -50,10 +51,11 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = dataTypeServiceMock.Object; var editor = new PublishValuesMultipleValueEditor(false, dataTypeService, new PropertyValueEditor()); - var result = editor.ConvertDbToString( - new Property(1, Guid.NewGuid(), - new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), - "1234,4567,8910")); + var prop = new Property(1, Guid.NewGuid(), + new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), + "1234,4567,8910"); + + var result = editor.ConvertDbToString(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual("Value 1,Value 2,Value 3", result); } @@ -74,10 +76,11 @@ namespace Umbraco.Tests.PropertyEditors var dataTypeService = dataTypeServiceMock.Object; var editor = new PublishValueValueEditor(dataTypeService, new PropertyValueEditor()); - var result = editor.ConvertDbToString( - new Property(1, Guid.NewGuid(), - new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), - "1234")); + var prop = new Property(1, Guid.NewGuid(), + new PropertyType(new DataTypeDefinition(1, "Test.TestEditor")), + "1234"); + + var result = editor.ConvertDbToString(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual("Value 2", result); } diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index 22182a0dcc..9ab275e5fb 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -1,7 +1,10 @@ using System; +using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Tests.PropertyEditors { @@ -14,12 +17,14 @@ namespace Umbraco.Tests.PropertyEditors [TestCase("hello world", false)] public void Value_Editor_Can_Convert_To_Json_Object_For_Editor(string value, bool isOk) { + var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Nvarchar), value); + var valueEditor = new PropertyValueEditor { ValueType = "STRING" }; - var result = valueEditor.ConvertDbToEditor(value); + var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual(isOk, !(result is string)); } @@ -62,12 +67,14 @@ namespace Umbraco.Tests.PropertyEditors [TestCase("DATETIME", "", "")] //test empty string for date public void Value_Editor_Can_Serialize_Value(string valueType, object val, string expected) { + var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Nvarchar), val); + var valueEditor = new PropertyValueEditor { ValueType = valueType }; - var result = valueEditor.ConvertDbToEditor(val); + var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual(expected, result); } @@ -80,7 +87,9 @@ namespace Umbraco.Tests.PropertyEditors ValueType = "DATE" }; - var result = valueEditor.ConvertDbToEditor(now); + var prop = new Property(1, Guid.NewGuid(), new PropertyType("test", DataTypeDatabaseType.Date), now); + + var result = valueEditor.ConvertDbToEditor(prop, prop.PropertyType, new Mock().Object); Assert.AreEqual(now.ToIsoString(), result); } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs index 3d2a857bcd..f95f9f6627 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs @@ -4,6 +4,7 @@ using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping @@ -15,6 +16,13 @@ namespace Umbraco.Web.Models.Mapping internal class ContentPropertyBasicConverter : TypeConverter where T : ContentPropertyBasic, new() { + protected Lazy DataTypeService { get; private set; } + + public ContentPropertyBasicConverter(Lazy dataTypeService) + { + DataTypeService = dataTypeService; + } + /// /// Assigns the PropertyEditor, Id, Alias and Value to the property /// @@ -34,12 +42,11 @@ namespace Umbraco.Web.Models.Mapping var result = new T { Id = property.Id, - Value = editor.ValueEditor.ConvertDbToEditor(property.Value), - Alias = property.Alias + Value = editor.ValueEditor.ConvertDbToEditor(property, property.PropertyType, DataTypeService.Value), + Alias = property.Alias, + PropertyEditor = editor }; - result.PropertyEditor = editor; - return result; } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs index 50f25fd217..b1dd208e9f 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs @@ -13,18 +13,17 @@ namespace Umbraco.Web.Models.Mapping /// internal class ContentPropertyDisplayConverter : ContentPropertyBasicConverter { - private readonly Lazy _dataTypeService; - public ContentPropertyDisplayConverter(Lazy dataTypeService) + : base(dataTypeService) { - _dataTypeService = dataTypeService; + } protected override ContentPropertyDisplay ConvertCore(Property originalProp) { var display = base.ConvertCore(originalProp); - var dataTypeService = _dataTypeService.Value; + var dataTypeService = DataTypeService.Value; var preVals = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProp.PropertyType.DataTypeDefinitionId); //configure the editor for display with the pre-values diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs index 6c6dce65c1..3a6e199f96 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs @@ -12,18 +12,16 @@ namespace Umbraco.Web.Models.Mapping /// internal class ContentPropertyDtoConverter : ContentPropertyBasicConverter { - private readonly Lazy _dataTypeService; - public ContentPropertyDtoConverter(Lazy dataTypeService) + : base(dataTypeService) { - _dataTypeService = dataTypeService; } protected override ContentPropertyDto ConvertCore(Property originalProperty) { var propertyDto = base.ConvertCore(originalProperty); - var dataTypeService = _dataTypeService.Value; + var dataTypeService = DataTypeService.Value; propertyDto.IsRequired = originalProperty.PropertyType.Mandatory; propertyDto.ValidationRegExp = originalProperty.PropertyType.ValidationRegExp; diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs index 9ebb27098c..cf06bce528 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Models.Mapping //FROM Property TO ContentPropertyBasic config.CreateMap() - .ConvertUsing>(); + .ConvertUsing(new ContentPropertyBasicConverter(lazyDataTypeService)); //FROM Property TO ContentPropertyDto config.CreateMap() diff --git a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs index 32473c6af7..4368deb453 100644 --- a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json.Linq; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -47,9 +48,9 @@ namespace Umbraco.Web.PropertyEditors Validators.Add(new DateTimeValidator()); } - public override object ConvertDbToEditor(object dbValue) + public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { - var date = dbValue.TryConvertTo(); + var date = property.Value.TryConvertTo(); if (date.Success == false || date.Result == null) { return string.Empty; diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index 2948e4c520..1f2cfe55fe 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -160,16 +161,18 @@ namespace Umbraco.Web.PropertyEditors /// We are actually passing back an array of simple objects instead of an array of strings because in angular a primitive (string) value /// cannot have 2 way binding, so to get around that each item in the array needs to be an object with a string. /// - /// + /// + /// + /// /// /// /// The legacy property editor saved this data as new line delimited! strange but we have to maintain that. /// - public override object ConvertDbToEditor(object dbValue) + public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { - return dbValue == null + return property.Value == null ? new JObject[] {} - : dbValue.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) + : property.Value.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) .Select(x => JObject.FromObject(new {value = x})); diff --git a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs index d6c81f7c09..053c349ccb 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValueValueEditor.cs @@ -34,8 +34,10 @@ namespace Umbraco.Web.PropertyEditors /// Need to lookup the pre-values and put the string version in cache, not the ID (which is what is stored in the db) /// /// + /// + /// /// - public override string ConvertDbToString(Property property) + public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { var idAttempt = property.Value.TryConvertTo(); if (idAttempt.Success) @@ -52,10 +54,8 @@ namespace Umbraco.Web.PropertyEditors LogHelper.Warn("Could not find a pre value with ID " + preValId + " for property alias " + property.Alias); } } - - - - return base.ConvertDbToString(property); + + return base.ConvertDbToString(property, propertyType, dataTypeService); } protected IDictionary GetPreValues(Property property) diff --git a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs index f9119109dc..eb746405b2 100644 --- a/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/PublishValuesMultipleValueEditor.cs @@ -34,18 +34,20 @@ namespace Umbraco.Web.PropertyEditors /// 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(Property property) + public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (_publishIds) { - return base.ConvertDbToString(property); + return base.ConvertDbToString(property, propertyType, dataTypeService); } var selectedIds = property.Value.ToString().Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); if (selectedIds.Any() == false) { - return base.ConvertDbToString(property); + return base.ConvertDbToString(property, propertyType, dataTypeService); } var preValues = GetPreValues(property); @@ -56,17 +58,19 @@ namespace Umbraco.Web.PropertyEditors preValues.Where(x => selectedIds.Contains(x.Value.Id.ToInvariantString())).Select(x => x.Value.Value)); } - return base.ConvertDbToString(property); + return base.ConvertDbToString(property, propertyType, dataTypeService); } /// /// Override so that we can return a json array to the editor for multi-select values /// - /// + /// + /// + /// /// - public override object ConvertDbToEditor(object dbValue) + public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { - var delimited = base.ConvertDbToEditor(dbValue).ToString(); + var delimited = base.ConvertDbToEditor(property, propertyType, dataTypeService).ToString(); return delimited.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); } diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 3e2b4e00eb..6610c0e12c 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using Umbraco.Core; using Umbraco.Core.Macros; +using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -54,14 +56,16 @@ namespace Umbraco.Web.PropertyEditors /// /// Format the data for the editor /// - /// + /// + /// + /// /// - public override object ConvertDbToEditor(object dbValue) + public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { - if (dbValue == null) + if (property.Value == null) return null; - var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(dbValue.ToString(), new Dictionary()); + var parsed = MacroTagParser.FormatRichTextPersistedDataForEditor(property.Value.ToString(), new Dictionary()); return parsed; }