From 63512462fd639aff888880d7ddde3795b35fa98b Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Wed, 30 May 2018 23:25:00 +0100 Subject: [PATCH] Added flexible dropdown property value converter --- .../FlexibleDropdownPropertyValueConverter.cs | 137 + src/Umbraco.Core/Umbraco.Core.csproj | 3367 +++++++++-------- 2 files changed, 1821 insertions(+), 1683 deletions(-) create mode 100644 src/Umbraco.Core/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs new file mode 100644 index 0000000000..f9c1cd3cd7 --- /dev/null +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/FlexibleDropdownPropertyValueConverter.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; + +namespace Umbraco.Core.PropertyEditors.ValueConverters +{ + [DefaultPropertyValueConverter] + public class FlexibleDropdownPropertyValueConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + { + private static readonly ConcurrentDictionary Storages = new ConcurrentDictionary(); + private readonly IDataTypeService _dataTypeService; + + // TODO: Remove this ctor in v8 - the other one will be usable via IoC + public FlexibleDropdownPropertyValueConverter() : this(ApplicationContext.Current.Services.DataTypeService) + { } + + public FlexibleDropdownPropertyValueConverter(IDataTypeService dataTypeService) + { + Mandate.ParameterNotNull(dataTypeService, "dataTypeService"); + _dataTypeService = dataTypeService; + } + + public override bool IsConverter(PublishedPropertyType propertyType) + { + return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.DropDownListFlexibleAlias); + } + + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + return source != null + ? source.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + : null; + } + + public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview) + { + if (source == null) + { + return null; + } + + var selectedValues = (string[]) source; + if (selectedValues.Any()) + { + if (IsMultipleDataType(propertyType.DataTypeId, propertyType.PropertyEditorAlias)) + { + return selectedValues; + } + + return selectedValues.First(); + } + + return source; + } + + public Type GetPropertyValueType(PublishedPropertyType propertyType) + { + return IsMultipleDataType(propertyType.DataTypeId, propertyType.PropertyEditorAlias) + ? typeof(IEnumerable) + : typeof(string); + } + + public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, + PropertyCacheValue cacheValue) + { + PropertyCacheLevel returnLevel; + switch (cacheValue) + { + case PropertyCacheValue.Object: + returnLevel = PropertyCacheLevel.ContentCache; + break; + case PropertyCacheValue.Source: + returnLevel = PropertyCacheLevel.Content; + break; + case PropertyCacheValue.XPath: + returnLevel = PropertyCacheLevel.Content; + break; + default: + returnLevel = PropertyCacheLevel.None; + break; + } + + return returnLevel; + } + + /// + /// Determines if the "enable multiple choice" prevalue has been ticked. + /// + /// The ID of this particular datatype instance. + /// The property editor alias. + /// true if the data type has been configured to return multiple values. + /// + private bool IsMultipleDataType(int dataTypeId, string propertyEditorAlias) + { + // GetPreValuesCollectionByDataTypeId is cached at repository level; + // still, the collection is deep-cloned so this is kinda expensive, + // better to cache here + trigger refresh in DataTypeCacheRefresher + return Storages.GetOrAdd(dataTypeId, id => + { + var preVals = _dataTypeService.GetPreValuesCollectionByDataTypeId(id).PreValuesAsDictionary; + + if (preVals.ContainsKey("multiple")) + { + var preValue = preVals + .FirstOrDefault(x => string.Equals(x.Key, "multiple", + StringComparison.InvariantCultureIgnoreCase)) + .Value; + + return preValue != null && preValue.Value.TryConvertTo().Result; + } + + //in some odd cases, the pre-values in the db won't exist but their default pre-values contain this key so check there + var propertyEditor = PropertyEditorResolver.Current.GetByAlias(propertyEditorAlias); + if (propertyEditor != null) + { + var preValue = propertyEditor.DefaultPreValues + .FirstOrDefault(x => string.Equals(x.Key, "multiple", + StringComparison + .InvariantCultureIgnoreCase)) + .Value; + + return preValue != null && preValue.TryConvertTo().Result; + } + + return false; + }); + } + + internal static void ClearCaches() + { + Storages.Clear(); + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index f12ff4f4f1..5d070be719 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1,1684 +1,1685 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {31785BC3-256C-4613-B2F5-A1B0BDDED8C1} - Library - Properties - Umbraco.Core - Umbraco.Core - v4.5 - 512 - ..\ - true - - latest - - - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - false - latest - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Umbraco.Core.xml - false - - - - ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll - - - ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll - - - ..\packages\ClientDependency.1.9.6\lib\net45\ClientDependency.Core.dll - - - ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll - - - ..\packages\ImageProcessor.2.5.6\lib\net45\ImageProcessor.dll - - - ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll - - - ..\packages\Log4Net.Async.2.0.4\lib\net40\Log4Net.Async.dll - - - ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - - - ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll - - - ..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll - - - ..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll - - - ..\packages\Microsoft.Owin.Security.Cookies.3.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - ..\packages\Microsoft.Owin.Security.OAuth.3.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - ..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll - - - ..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll - True - - - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\packages\semver.1.1.2\lib\net45\Semver.dll - - - - - - - - ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll - - - ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll - - - - - - - - - - - - - ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - - - - False - - - - - - - - - - Properties\SolutionInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Files.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Component - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - Constants.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {511F6D8D-7717-440A-9A57-A507E9A8B27F} - umbraco.interfaces - - - - - ResXFileCodeGenerator - Files.Designer.cs - - - - - + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {31785BC3-256C-4613-B2F5-A1B0BDDED8C1} + Library + Properties + Umbraco.Core + Umbraco.Core + v4.5 + 512 + ..\ + true + + latest + + + true + full + false + bin\Debug\ + TRACE;DEBUG + prompt + 4 + false + latest + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Umbraco.Core.xml + false + + + + ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll + + + ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll + + + ..\packages\ClientDependency.1.9.6\lib\net45\ClientDependency.Core.dll + + + ..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll + + + ..\packages\ImageProcessor.2.5.6\lib\net45\ImageProcessor.dll + + + ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll + + + ..\packages\Log4Net.Async.2.0.4\lib\net40\Log4Net.Async.dll + + + ..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll + + + ..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll + + + ..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll + + + ..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll + + + ..\packages\Microsoft.Owin.Security.Cookies.3.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll + + + ..\packages\Microsoft.Owin.Security.OAuth.3.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll + + + ..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll + + + ..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll + True + + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Owin.1.0\lib\net40\Owin.dll + + + ..\packages\semver.1.1.2\lib\net45\Semver.dll + + + + + + + + ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll + + + ..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll + + + + + + + + + + + + + ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll + + + + + + False + + + + + + + + + + Properties\SolutionInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Files.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + Constants.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {511F6D8D-7717-440A-9A57-A507E9A8B27F} + umbraco.interfaces + + + + + ResXFileCodeGenerator + Files.Designer.cs + + + + + \ No newline at end of file