diff --git a/appveyor.yml b/appveyor.yml index c5aed11..58780ae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ os: Visual Studio 2015 # version format -version: 1.7.0.{build} +version: 1.7.1.{build} # UMBRACO_PACKAGE_PRERELEASE_SUFFIX if a rtm release build this should be blank, otherwise if empty will default to alpha # example UMBRACO_PACKAGE_PRERELEASE_SUFFIX=beta diff --git a/src/Our.Umbraco.Vorto/Extensions/IPublishedContentExtensions.cs b/src/Our.Umbraco.Vorto/Extensions/IPublishedContentExtensions.cs index 845bc76..29f9691 100644 --- a/src/Our.Umbraco.Vorto/Extensions/IPublishedContentExtensions.cs +++ b/src/Our.Umbraco.Vorto/Extensions/IPublishedContentExtensions.cs @@ -9,56 +9,56 @@ namespace Our.Umbraco.Vorto.Extensions { - public static class IPublishedContentExtensions - { + public static class IPublishedContentExtensions + { #region HasValue - private static bool DoHasVortoValue(this IPublishedContent content, string propertyAlias, + private static bool DoHasVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false) - { - if (content.HasValue(propertyAlias)) - { - var prop = content.GetProperty(propertyAlias); - if (prop == null) - { - return false; - } - - var dataValue = prop.DataValue; - if (dataValue == null) - { - return false; - } - - VortoValue vortoModel; - - try - { - // We purposfully parse the raw data value ourselves bypassing the property - // value converters so that we don't require an UmbracoContext during a - // HasValue check. As we won't actually use the value, this is ok here. - vortoModel = JsonConvert.DeserializeObject(dataValue.ToString()); - } - catch - { - return false; - } - - if (vortoModel?.Values != null) - { - var bestMatchCultureName = vortoModel.FindBestMatchCulture(cultureName); - if (!bestMatchCultureName.IsNullOrWhiteSpace() - && vortoModel.Values.ContainsKey(bestMatchCultureName) - && vortoModel.Values[bestMatchCultureName] != null - && !vortoModel.Values[bestMatchCultureName].ToString().IsNullOrWhiteSpace()) - return true; - } - } - - return recursive && content.Parent != null - ? content.Parent.DoHasVortoValue(propertyAlias, cultureName, recursive) - : false; - } + { + if (content.HasValue(propertyAlias)) + { + var prop = content.GetProperty(propertyAlias); + if (prop == null) + { + return false; + } + + var dataValue = prop.DataValue; + if (dataValue == null) + { + return false; + } + + VortoValue vortoModel; + + try + { + // We purposfully parse the raw data value ourselves bypassing the property + // value converters so that we don't require an UmbracoContext during a + // HasValue check. As we won't actually use the value, this is ok here. + vortoModel = JsonConvert.DeserializeObject(dataValue.ToString()); + } + catch + { + return false; + } + + if (vortoModel?.Values != null) + { + var bestMatchCultureName = vortoModel.FindBestMatchCulture(cultureName); + if (!bestMatchCultureName.IsNullOrWhiteSpace() + && vortoModel.Values.ContainsKey(bestMatchCultureName) + && vortoModel.Values[bestMatchCultureName] != null + && !vortoModel.Values[bestMatchCultureName].ToString().IsNullOrWhiteSpace()) + return true; + } + } + + return recursive && content.Parent != null + ? content.Parent.DoHasVortoValue(propertyAlias, cultureName, recursive) + : false; + } /// /// Returns a value indicating whether the given content property has a Vorto value @@ -73,13 +73,13 @@ public static bool HasVortoValue(this IPublishedContent content, string property string cultureName = null, bool recursive = false, string fallbackCultureName = null) { - if (cultureName.IsNullOrWhiteSpace()) - cultureName = Thread.CurrentThread.CurrentUICulture.Name; + if (cultureName.IsNullOrWhiteSpace()) + cultureName = Thread.CurrentThread.CurrentUICulture.Name; - if (fallbackCultureName.IsNullOrWhiteSpace()) - fallbackCultureName = Vorto.DefaultFallbackCultureName; + if (fallbackCultureName.IsNullOrWhiteSpace()) + fallbackCultureName = Vorto.DefaultFallbackCultureName; - var hasValue = content.DoHasVortoValue(propertyAlias, cultureName, recursive); + var hasValue = content.DoHasVortoValue(propertyAlias, cultureName, recursive); if (!hasValue && !string.IsNullOrEmpty(fallbackCultureName) && !fallbackCultureName.Equals(cultureName)) hasValue = content.DoHasVortoValue(propertyAlias, fallbackCultureName, recursive); return hasValue; @@ -89,67 +89,71 @@ public static bool HasVortoValue(this IPublishedContent content, string property #region GetValue - private static T DoGetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, + private static T DoGetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false, T defaultValue = default(T)) - { - var prop = content.GetProperty(propertyAlias); - if (prop == null) - { - // PR #100 - Prevent generation of NullReferenceException: allow return of defaultValue or traversal up the tree if prop is null - return defaultValue; - } - - var vortoModel = prop.Value as VortoValue; - if (vortoModel != null) - { - return vortoModel.GetValue(cultureName, defaultValue); - } - - return recursive && content.Parent != null - ? content.Parent.DoGetVortoValue(propertyAlias, cultureName, recursive, defaultValue) - : defaultValue; - } - - /// - /// Gets the Vorto value for the given content property as the given type. - /// - /// The type of value to return - /// The cached content - /// The property alias - /// The culture name in the format languagecode2-country/regioncode2. Optional - /// Whether to recursively travel up the content tree looking for the value. Optional - /// The default value to return if none is found. Optional - /// The culture name in the format languagecode2-country/regioncode2. Optional - /// The value - public static T GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, + { + var prop = content.GetProperty(propertyAlias); + if (prop == null) + { + // PR #100 - Prevent generation of NullReferenceException: allow return of defaultValue or traversal up the tree if prop is null + return defaultValue; + } + + var vortoModel = prop.Value as IVortoValue; + if (vortoModel != null) + { + var typedVortoModel = vortoModel.CastToVortoValue(); + if (typedVortoModel != null) + { + return typedVortoModel.GetValue(cultureName, defaultValue); + } + } + + return recursive && content.Parent != null + ? content.Parent.DoGetVortoValue(propertyAlias, cultureName, recursive, defaultValue) + : defaultValue; + } + + /// + /// Gets the Vorto value for the given content property as the given type. + /// + /// The type of value to return + /// The cached content + /// The property alias + /// The culture name in the format languagecode2-country/regioncode2. Optional + /// Whether to recursively travel up the content tree looking for the value. Optional + /// The default value to return if none is found. Optional + /// The culture name in the format languagecode2-country/regioncode2. Optional + /// The value + public static T GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false, T defaultValue = default(T), string fallbackCultureName = null) - { - if (cultureName.IsNullOrWhiteSpace()) - cultureName = Thread.CurrentThread.CurrentUICulture.Name; + { + if (cultureName.IsNullOrWhiteSpace()) + cultureName = Thread.CurrentThread.CurrentUICulture.Name; - if (fallbackCultureName.IsNullOrWhiteSpace()) - fallbackCultureName = Vorto.DefaultFallbackCultureName; + if (fallbackCultureName.IsNullOrWhiteSpace()) + fallbackCultureName = Vorto.DefaultFallbackCultureName; - var result = content.DoGetVortoValue(propertyAlias, cultureName, recursive); + var result = content.DoGetVortoValue(propertyAlias, cultureName, recursive); if (EqualityComparer.Default.Equals(result, default(T)) && !string.IsNullOrEmpty(fallbackCultureName) && !fallbackCultureName.Equals(cultureName)) result = content.DoGetVortoValue(propertyAlias, fallbackCultureName, recursive); - if (EqualityComparer.Default.Equals(result, default(T))) - result = defaultValue; + if (EqualityComparer.Default.Equals(result, default(T))) + result = defaultValue; return result; } - /// - /// Gets the Vorto value for the given content property. - /// - /// The cached content - /// The property alias - /// The culture name in the format languagecode2-country/regioncode2. Optional - /// Whether to recursively travel up the content tree looking for the value. Optional - /// The default value to return if none is found. Optional - /// The culture name in the format languagecode2-country/regioncode2. Optional - /// The value - public static object GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, + /// + /// Gets the Vorto value for the given content property. + /// + /// The cached content + /// The property alias + /// The culture name in the format languagecode2-country/regioncode2. Optional + /// Whether to recursively travel up the content tree looking for the value. Optional + /// The default value to return if none is found. Optional + /// The culture name in the format languagecode2-country/regioncode2. Optional + /// The value + public static object GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false, object defaultValue = null, string fallbackCultureName = null) { @@ -172,5 +176,5 @@ public static bool IsVortoProperty(this IPublishedContent content, string proper } #endregion - } + } } diff --git a/src/Our.Umbraco.Vorto/Models/IVortoValue.cs b/src/Our.Umbraco.Vorto/Models/IVortoValue.cs new file mode 100644 index 0000000..6e2890f --- /dev/null +++ b/src/Our.Umbraco.Vorto/Models/IVortoValue.cs @@ -0,0 +1,18 @@ +using System; + +namespace Our.Umbraco.Vorto.Models +{ + public interface IVortoValue + { + /// + /// Gets or sets the data type definition id + /// + Guid DtdGuid { get; set; } + + /// + /// Attempts to cast the vorto value instance to another generic type. + /// + /// The cast vorto value instance, or null if no values have a value. + VortoValue CastToVortoValue(); + } +} diff --git a/src/Our.Umbraco.Vorto/Models/IVortoValueOfT.cs b/src/Our.Umbraco.Vorto/Models/IVortoValueOfT.cs new file mode 100644 index 0000000..452abbc --- /dev/null +++ b/src/Our.Umbraco.Vorto/Models/IVortoValueOfT.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Our.Umbraco.Vorto.Models +{ + public interface IVortoValue : IVortoValue + { + /// + /// Gets or sets the data type definition id + /// + IDictionary Values { get; set; } + } +} diff --git a/src/Our.Umbraco.Vorto/Models/VortoValueOfT.cs b/src/Our.Umbraco.Vorto/Models/VortoValueOfT.cs index d336cc4..86ea9a5 100644 --- a/src/Our.Umbraco.Vorto/Models/VortoValueOfT.cs +++ b/src/Our.Umbraco.Vorto/Models/VortoValueOfT.cs @@ -1,29 +1,47 @@ using Newtonsoft.Json; using System; +using System.Linq; using System.Collections.Generic; +using Umbraco.Core; namespace Our.Umbraco.Vorto.Models { - /// - /// Represents a multilingual property value - /// - public partial class VortoValue - { - /// - /// Gets or sets the collection of language independent values - /// - [JsonProperty("values")] - public IDictionary Values { get; set; } + /// + /// Represents a multilingual property value + /// + public partial class VortoValue : IVortoValue + { + /// + /// Gets or sets the collection of language independent values + /// + [JsonProperty("values")] + public IDictionary Values { get; set; } - /// - /// Gets or sets the data type definition id - /// - [JsonProperty("dtdGuid")] - public Guid DtdGuid { get; set; } + /// + /// Gets or sets the data type definition id + /// + [JsonProperty("dtdGuid")] + public Guid DtdGuid { get; set; } - public VortoValue() - { - Values = new Dictionary(); - } - } + public VortoValue() + { + Values = new Dictionary(); + } + + /// + /// Attempts to cast the vorto value instance to another generic type. + /// + /// The cast vorto value instance, or null if no values have a value. + public VortoValue CastToVortoValue() + { + var newVortoValue = new VortoValue() + { + Values = Values.ToDictionary(x => x.Key, x => { var v = x.Value.TryConvertTo(); return v.Success ? v.Result : default(TAs); }) + .Where(x => !EqualityComparer.Default.Equals(x.Value, default(TAs))) + .ToDictionary(x => x.Key, x => x.Value) + }; + + return newVortoValue.Values.Count > 0 ? newVortoValue : null; + } + } } diff --git a/src/Our.Umbraco.Vorto/Our.Umbraco.Vorto.csproj b/src/Our.Umbraco.Vorto/Our.Umbraco.Vorto.csproj index d75c510..a7000e6 100644 --- a/src/Our.Umbraco.Vorto/Our.Umbraco.Vorto.csproj +++ b/src/Our.Umbraco.Vorto/Our.Umbraco.Vorto.csproj @@ -226,6 +226,8 @@ + +