Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
mattbrailsford committed Feb 18, 2019
2 parents 44b9af7 + d6b6f95 commit 84edce8
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 125 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
212 changes: 108 additions & 104 deletions src/Our.Umbraco.Vorto/Extensions/IPublishedContentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<VortoValue>(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<VortoValue>(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;
}

/// <summary>
/// Returns a value indicating whether the given content property has a Vorto value
Expand All @@ -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;
Expand All @@ -89,67 +89,71 @@ public static bool HasVortoValue(this IPublishedContent content, string property

#region GetValue

private static T DoGetVortoValue<T>(this IPublishedContent content, string propertyAlias, string cultureName = null,
private static T DoGetVortoValue<T>(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<T>;
if (vortoModel != null)
{
return vortoModel.GetValue(cultureName, defaultValue);
}

return recursive && content.Parent != null
? content.Parent.DoGetVortoValue<T>(propertyAlias, cultureName, recursive, defaultValue)
: defaultValue;
}

/// <summary>
/// Gets the Vorto value for the given content property as the given type.
/// </summary>
/// <typeparam name="T">The type of value to return</typeparam>
/// <param name="content">The cached content</param>
/// <param name="propertyAlias">The property alias</param>
/// <param name="cultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <param name="recursive">Whether to recursively travel up the content tree looking for the value. Optional</param>
/// <param name="defaultValue">The default value to return if none is found. Optional</param>
/// <param name="fallbackCultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <returns>The <typeparamref name="T"/> value</returns>
public static T GetVortoValue<T>(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<T>();
if (typedVortoModel != null)
{
return typedVortoModel.GetValue(cultureName, defaultValue);
}
}

return recursive && content.Parent != null
? content.Parent.DoGetVortoValue<T>(propertyAlias, cultureName, recursive, defaultValue)
: defaultValue;
}

/// <summary>
/// Gets the Vorto value for the given content property as the given type.
/// </summary>
/// <typeparam name="T">The type of value to return</typeparam>
/// <param name="content">The cached content</param>
/// <param name="propertyAlias">The property alias</param>
/// <param name="cultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <param name="recursive">Whether to recursively travel up the content tree looking for the value. Optional</param>
/// <param name="defaultValue">The default value to return if none is found. Optional</param>
/// <param name="fallbackCultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <returns>The <typeparamref name="T"/> value</returns>
public static T GetVortoValue<T>(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<T>(propertyAlias, cultureName, recursive);
var result = content.DoGetVortoValue<T>(propertyAlias, cultureName, recursive);
if (EqualityComparer<T>.Default.Equals(result, default(T)) && !string.IsNullOrEmpty(fallbackCultureName) && !fallbackCultureName.Equals(cultureName))
result = content.DoGetVortoValue<T>(propertyAlias, fallbackCultureName, recursive);
if (EqualityComparer<T>.Default.Equals(result, default(T)))
result = defaultValue;
if (EqualityComparer<T>.Default.Equals(result, default(T)))
result = defaultValue;

return result;
}

/// <summary>
/// Gets the Vorto value for the given content property.
/// </summary>
/// <param name="content">The cached content</param>
/// <param name="propertyAlias">The property alias</param>
/// <param name="cultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <param name="recursive">Whether to recursively travel up the content tree looking for the value. Optional</param>
/// <param name="defaultValue">The default value to return if none is found. Optional</param>
/// <param name="fallbackCultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <returns>The <see cref="object"/> value</returns>
public static object GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null,
/// <summary>
/// Gets the Vorto value for the given content property.
/// </summary>
/// <param name="content">The cached content</param>
/// <param name="propertyAlias">The property alias</param>
/// <param name="cultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <param name="recursive">Whether to recursively travel up the content tree looking for the value. Optional</param>
/// <param name="defaultValue">The default value to return if none is found. Optional</param>
/// <param name="fallbackCultureName">The culture name in the format languagecode2-country/regioncode2. Optional</param>
/// <returns>The <see cref="object"/> value</returns>
public static object GetVortoValue(this IPublishedContent content, string propertyAlias, string cultureName = null,
bool recursive = false, object defaultValue = null,
string fallbackCultureName = null)
{
Expand All @@ -172,5 +176,5 @@ public static bool IsVortoProperty(this IPublishedContent content, string proper
}

#endregion
}
}
}
18 changes: 18 additions & 0 deletions src/Our.Umbraco.Vorto/Models/IVortoValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace Our.Umbraco.Vorto.Models
{
public interface IVortoValue
{
/// <summary>
/// Gets or sets the data type definition id
/// </summary>
Guid DtdGuid { get; set; }

/// <summary>
/// Attempts to cast the vorto value instance to another generic type.
/// </summary>
/// <returns>The cast vorto value instance, or null if no values have a value.</returns>
VortoValue<T> CastToVortoValue<T>();
}
}
12 changes: 12 additions & 0 deletions src/Our.Umbraco.Vorto/Models/IVortoValueOfT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;

namespace Our.Umbraco.Vorto.Models
{
public interface IVortoValue<T> : IVortoValue
{
/// <summary>
/// Gets or sets the data type definition id
/// </summary>
IDictionary<string, T> Values { get; set; }
}
}
58 changes: 38 additions & 20 deletions src/Our.Umbraco.Vorto/Models/VortoValueOfT.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Collections.Generic;
using Umbraco.Core;

namespace Our.Umbraco.Vorto.Models
{
/// <summary>
/// Represents a multilingual property value
/// </summary>
public partial class VortoValue<T>
{
/// <summary>
/// Gets or sets the collection of language independent values
/// </summary>
[JsonProperty("values")]
public IDictionary<string, T> Values { get; set; }
/// <summary>
/// Represents a multilingual property value
/// </summary>
public partial class VortoValue<T> : IVortoValue<T>
{
/// <summary>
/// Gets or sets the collection of language independent values
/// </summary>
[JsonProperty("values")]
public IDictionary<string, T> Values { get; set; }

/// <summary>
/// Gets or sets the data type definition id
/// </summary>
[JsonProperty("dtdGuid")]
public Guid DtdGuid { get; set; }
/// <summary>
/// Gets or sets the data type definition id
/// </summary>
[JsonProperty("dtdGuid")]
public Guid DtdGuid { get; set; }

public VortoValue()
{
Values = new Dictionary<string, T>();
}
}
public VortoValue()
{
Values = new Dictionary<string, T>();
}

/// <summary>
/// Attempts to cast the vorto value instance to another generic type.
/// </summary>
/// <returns>The cast vorto value instance, or null if no values have a value.</returns>
public VortoValue<TAs> CastToVortoValue<TAs>()
{
var newVortoValue = new VortoValue<TAs>()
{
Values = Values.ToDictionary(x => x.Key, x => { var v = x.Value.TryConvertTo<TAs>(); return v.Success ? v.Result : default(TAs); })
.Where(x => !EqualityComparer<TAs>.Default.Equals(x.Value, default(TAs)))
.ToDictionary(x => x.Key, x => x.Value)
};

return newVortoValue.Values.Count > 0 ? newVortoValue : null;
}
}
}
2 changes: 2 additions & 0 deletions src/Our.Umbraco.Vorto/Our.Umbraco.Vorto.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@
<Compile Include="Models\DataTypeInfo.cs" />
<Compile Include="Converters\VortoValueConverter.cs" />
<Compile Include="Extensions\IPublishedContentExtensions.cs" />
<Compile Include="Models\IVortoValue.cs" />
<Compile Include="Models\IVortoValueOfT.cs" />
<Compile Include="Models\Language.cs" />
<Compile Include="Models\VortoValue.cs" />
<Compile Include="Models\VortoValueOfTApi.cs" />
Expand Down

0 comments on commit 84edce8

Please sign in to comment.