Initially adding the Core Value Converters package into Core! Currently this will break all the existing things but it makes views insanely simple with ModelsBuilder!!

This commit is contained in:
Jeavon Leopold
2016-06-12 16:36:26 +02:00
parent 38e59373c6
commit e7754d313e
10 changed files with 1118 additions and 87 deletions

View File

@@ -301,5 +301,21 @@ namespace Umbraco.Core
&& list1Groups.All(g => g.Count() == list2Groups[g.Key].Count());
}
///<summary>
/// Returns the items of the given enumerable as a pure enumerable.
/// <remarks>
/// When quering lists using methods such as <see cref="M:List.Where"/>, the result, despite appearing to look like and quack like an
/// <see cref="T:Enumerable{T}"/> the type is actually an instance of <see cref="T:System.Linq.Enumerable.WhereEnumerableIterator"/>
/// </remarks>
/// </summary>
///<param name="source">The item to find.</param>
///<returns>The index of the first matching item, or -1 if the item was not found.</returns>
internal static IEnumerable<T> Yield<T>(this IEnumerable<T> source)
{
foreach (var element in source)
{
yield return element;
}
}
}
}

View File

@@ -0,0 +1,184 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RelatedLink.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// Defines the RelatedLink type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using Newtonsoft.Json.Linq;
namespace Umbraco.Web.Models
{
/// <summary>
/// The related link model
/// </summary>
public class RelatedLink
{
// ReSharper disable InconsistentNaming
/// <summary>
/// The _link item.
/// </summary>
private readonly JToken _linkItem;
/// <summary>
/// The _caption.
/// </summary>
private string _caption;
/// <summary>
/// The _new window.
/// </summary>
private bool? _newWindow;
/// <summary>
/// The _is internal.
/// </summary>
private bool? _isInternal;
/// <summary>
/// The _link.
/// </summary>
private string _link;
/// <summary>
/// The _linkDeleted.
/// </summary>
private bool? _linkDeleted;
/// <summary>
/// The _type.
/// </summary>
private RelatedLinkType _type;
/// <summary>
/// Initializes a new instance of the <see cref="RelatedLink"/> class.
/// </summary>
/// <param name="linkItem">
/// The link item.
/// </param>
public RelatedLink(JToken linkItem)
{
this._linkItem = linkItem;
// get the current Link to set the _linkDeleted is a internal link
var currentLink = this.Link;
}
/// <summary>
/// Gets the caption.
/// </summary>
public string Caption
{
get
{
if (string.IsNullOrEmpty(this._caption))
{
this._caption = this._linkItem.Value<string>("caption");
}
return this._caption;
}
}
/// <summary>
/// Gets a value indicating whether new window.
/// </summary>
public bool NewWindow
{
get
{
if (this._newWindow == null)
{
this._newWindow = this._linkItem.Value<bool>("newWindow");
}
return this._newWindow.GetValueOrDefault();
}
}
/// <summary>
/// Gets a value indicating whether the link is internal.
/// </summary>
public bool IsInternal
{
get
{
if (this._isInternal == null)
{
this._isInternal = this._linkItem.Value<bool>("isInternal");
}
return this._isInternal.GetValueOrDefault();
}
}
/// <summary>
/// Gets the type.
/// </summary>
public RelatedLinkType? Type
{
get
{
if (Enum.TryParse(this._linkItem.Value<string>("type"), true, out this._type))
{
return this._type;
}
return null;
}
}
/// <summary>
/// Gets the link.
/// </summary>
public string Link
{
get
{
if (string.IsNullOrEmpty(this._link))
{
if (this.IsInternal)
{
if (UmbracoContext.Current == null)
{
return null;
}
this._link = UmbracoContext.Current.UrlProvider.GetUrl(this._linkItem.Value<int>("internal"));
if (this._link.Equals("#"))
{
this._linkDeleted = true;
this._link = this._linkItem.Value<string>("internal");
}
else
{
this._linkDeleted = false;
}
}
else
{
this._link = this._linkItem.Value<string>("link");
}
}
return this._link;
}
}
/// <summary>
/// Gets a value indicating whether deleted.
/// </summary>
internal bool InternalLinkDeleted
{
get
{
var linkDeleted = this._linkDeleted;
return linkDeleted != null && (bool)linkDeleted;
}
}
}
}

View File

@@ -0,0 +1,27 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RelatedLinkType.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// Defines the RelatedLinkType type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Umbraco.Web.Models
{
/// <summary>
/// The related link type.
/// </summary>
public enum RelatedLinkType
{
/// <summary>
/// Internal link type
/// </summary>
Internal,
/// <summary>
/// External link type
/// </summary>
External
}
}

View File

@@ -0,0 +1,110 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RelatedLinks.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// Defines the RelatedLinks type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Models
{
/// <summary>
/// The related links model
/// </summary>
public class RelatedLinks : IEnumerable<RelatedLink>
{
// ReSharper disable InconsistentNaming
/// <summary>
/// The _property data.
/// </summary>
private readonly string _propertyData;
/// <summary>
/// The _related links.
/// </summary>
private readonly List<RelatedLink> _relatedLinks = new List<RelatedLink>();
/// <summary>
/// Initializes a new instance of the <see cref="RelatedLinks"/> class.
/// </summary>
/// <param name="propertyData">
/// The property data.
/// </param>
public RelatedLinks(string propertyData)
{
this._propertyData = propertyData;
if (!string.IsNullOrEmpty(propertyData))
{
var relatedLinks = JsonConvert.DeserializeObject<JArray>(propertyData);
foreach (var item in relatedLinks)
{
var relatedLink = new RelatedLink(item);
if (!relatedLink.InternalLinkDeleted)
{
this._relatedLinks.Add(relatedLink);
}
else
{
LogHelper.Warn<RelatedLinks>(
string.Format("Related Links value converter skipped a link as the node has been unpublished/deleted (Internal Link NodeId: {0}, Link Caption: \"{1}\")", relatedLink.Link, relatedLink.Caption));
}
}
}
}
/// <summary>
/// Gets the property data.
/// </summary>
public string PropertyData
{
get
{
return this._propertyData;
}
}
/// <summary>
/// The any.
/// </summary>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public bool Any()
{
return Enumerable.Any(this);
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
public IEnumerator<RelatedLink> GetEnumerator()
{
return this._relatedLinks.GetEnumerator();
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@@ -0,0 +1,177 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ContentPickerPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// The content picker property editor converter.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Globalization;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The content picker property value converter.
/// </summary>
public class ContentPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
/// <summary>
/// The properties to exclude.
/// </summary>
private static readonly List<string> PropertiesToExclude = new List<string>()
{
Constants.Conventions.Content.InternalRedirectId.ToLower(CultureInfo.InvariantCulture),
Constants.Conventions.Content.Redirect.ToLower(CultureInfo.InvariantCulture)
};
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPickerAlias);
}
/// <summary>
/// Convert the raw string into a nodeId integer
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var attemptConvertInt = source.TryConvertTo<int>();
if (attemptConvertInt.Success)
{
return attemptConvertInt.Result;
}
return null;
}
/// <summary>
/// Convert the source nodeId into a IPublishedContent (or DynamicPublishedContent)
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
if (UmbracoContext.Current != null)
{
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.Contains(propertyType.PropertyTypeAlias.ToLower(CultureInfo.InvariantCulture))) == false)
{
var content = UmbracoContext.Current.ContentCache.GetById((int)source);
return content;
}
}
return source;
}
/// <summary>
/// The convert source to xPath.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <param name="source">
/// The source.
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
{
return source.ToString();
}
/// <summary>
/// The CLR type that the value converter returns.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="Type"/>.
/// </returns>
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(IPublishedContent);
}
/// <summary>
/// The get property cache level.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <param name="cacheValue">
/// The cache value.
/// </param>
/// <returns>
/// The <see cref="PropertyCacheLevel"/>.
/// </returns>
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;
}
}
}

View File

@@ -0,0 +1,145 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MediaPickerPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// The legacy media picker value converter
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The media picker property value converter.
/// </summary>
public class MediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
// ** Value converter disabled as not sure if we want to convert the legacy media picker or not **
return false;
//return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias);
}
/// <summary>
/// Convert the raw string into a nodeId integer
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var attemptConvertInt = source.TryConvertTo<int>();
if (attemptConvertInt.Success)
{
return attemptConvertInt.Result;
}
return null;
}
/// <summary>
/// Convert the source nodeId into a IPublishedContent (or DynamicPublishedContent)
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
if (UmbracoContext.Current != null)
{
return UmbracoContext.Current.MediaCache.GetById((int)source);
}
return null;
}
/// <summary>
/// The get property cache level.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <param name="cacheValue">
/// The cache value.
/// </param>
/// <returns>
/// The <see cref="PropertyCacheLevel"/>.
/// </returns>
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;
}
/// <summary>
/// The CLR type that the value converter returns.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="Type"/>.
/// </returns>
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(IPublishedContent);
}
}
}

View File

@@ -0,0 +1,194 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MultiNodeTreePickerPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// The multi node tree picker property editor value converter.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The multi node tree picker property editor value converter.
/// </summary>
public class MultiNodeTreePickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias);
}
/// <summary>
/// Convert the raw string into a nodeId integer array
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var nodeIds =
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
return nodeIds;
}
/// <summary>
/// Convert the source nodeId into a IEnumerable of IPublishedContent (or DynamicPublishedContent)
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
var nodeIds = (int[])source;
var multiNodeTreePicker = new List<IPublishedContent>();
if (UmbracoContext.Current != null)
{
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
if (nodeIds.Length > 0)
{
var objectType = UmbracoObjectTypes.Unknown;
foreach (var nodeId in nodeIds)
{
var multiNodeTreePickerItem = GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Document, umbHelper.TypedContent)
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Media, umbHelper.TypedMedia)
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Member, umbHelper.TypedMember);
if (multiNodeTreePickerItem != null)
{
multiNodeTreePicker.Add(multiNodeTreePickerItem);
}
}
}
return multiNodeTreePicker.Yield().Where(x => x != null);
}
return null;
}
/// <summary>
/// The get property cache level.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <param name="cacheValue">
/// The cache value.
/// </param>
/// <returns>
/// The <see cref="PropertyCacheLevel"/>.
/// </returns>
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;
}
/// <summary>
/// The CLR type that the value converter returns.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="Type"/>.
/// </returns>
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return typeof(IEnumerable<IPublishedContent>);
}
/// <summary>
/// Attempt to get an IPublishedContent instance based on ID and content type
/// </summary>
/// <param name="nodeId">The content node ID</param>
/// <param name="actualType">The type of content being requested</param>
/// <param name="expectedType">The type of content expected/supported by <paramref name="contentFetcher"/></param>
/// <param name="contentFetcher">A function to fetch content of type <paramref name="expectedType"/></param>
/// <returns>The requested content, or null if either it does not exist or <paramref name="actualType"/> does not match <paramref name="expectedType"/></returns>
private IPublishedContent GetPublishedContent(int nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func<int, IPublishedContent> contentFetcher)
{
// is the actual type supported by the content fetcher?
if (actualType != UmbracoObjectTypes.Unknown && actualType != expectedType)
{
// no, return null
return null;
}
// attempt to get the content
var content = contentFetcher(nodeId);
if (content != null)
{
// if we found the content, assign the expected type to the actual type so we don't have to keep looking for other types of content
actualType = expectedType;
}
return content;
}
}
}

View File

@@ -0,0 +1,212 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MultipleMediaPickerPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// The multiple media picker property editor converter.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The multiple media picker property value converter.
/// </summary>
public class MultipleMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias);
}
/// <summary>
/// Convert the raw string into a nodeId integer array or a single integer
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (IsMultipleDataType(propertyType.DataTypeId))
{
var nodeIds =
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
return nodeIds;
}
var attemptConvertInt = source.TryConvertTo<int>();
if (attemptConvertInt.Success)
{
return attemptConvertInt.Result;
}
else
{
var nodeIds =
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
if (nodeIds.Length > 0)
{
var error =
string.Format(
"Data type \"{0}\" is not set to allow multiple items but appears to contain multiple items, check the setting and save the data type again",
ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(
propertyType.DataTypeId).Name);
LogHelper.Warn<MultipleMediaPickerPropertyConverter>(error);
throw new Exception(error);
}
}
return null;
}
/// <summary>
/// Convert the source nodeId into a IPublishedContent or IEnumerable of IPublishedContent (or DynamicPublishedContent) depending on data type setting
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
if (UmbracoContext.Current == null)
{
return null;
}
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
if (IsMultipleDataType(propertyType.DataTypeId))
{
var nodeIds = (int[])source;
var multiMediaPicker = Enumerable.Empty<IPublishedContent>();
if (nodeIds.Length > 0)
{
multiMediaPicker = umbHelper.TypedMedia(nodeIds).Where(x => x != null);
}
return multiMediaPicker;
}
// single value picker
var nodeId = (int)source;
return umbHelper.TypedMedia(nodeId);
}
/// <summary>
/// The get property cache level.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <param name="cacheValue">
/// The cache value.
/// </param>
/// <returns>
/// The <see cref="PropertyCacheLevel"/>.
/// </returns>
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;
}
/// <summary>
/// The get property value type.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="Type"/>.
/// </returns>
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
{
return IsMultipleDataType(propertyType.DataTypeId) ? typeof(IEnumerable<IPublishedContent>) : typeof(IPublishedContent);
}
/// <summary>
/// The is multiple data type.
/// </summary>
/// <param name="dataTypeId">
/// The data type id.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public bool IsMultipleDataType(int dataTypeId)
{
var dts = ApplicationContext.Current.Services.DataTypeService;
var multiPickerPreValue =
dts.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "multiPicker", StringComparison.InvariantCultureIgnoreCase)).Value;
return multiPickerPreValue != null && multiPickerPreValue.Value.TryConvertTo<bool>().Result;
}
}
}

View File

@@ -1,106 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RelatedLinksPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// Defines the RelatedLinksPropertyConverter type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Web.Models;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
[PropertyValueType(typeof(JArray))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
public class RelatedLinksEditorValueConvertor : PropertyValueConverterBase
/// <summary>
/// The related links property value converter.
/// </summary>
[PropertyValueType(typeof(RelatedLinks))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.ContentCache)]
public class RelatedLinksPropertyConverter : PropertyValueConverterBase
{
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
return Constants.PropertyEditors.RelatedLinksAlias.Equals(propertyType.PropertyEditorAlias);
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinksAlias);
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
/// <summary>
/// Convert the source nodeId into a RelatedLinks object
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return null;
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
if (source == null)
{
try
{
var obj = JsonConvert.DeserializeObject<JArray>(sourceString);
//update the internal links if we have a context
if (UmbracoContext.Current != null)
{
var helper = new UmbracoHelper(UmbracoContext.Current);
foreach (var a in obj)
{
var type = a.Value<string>("type");
if (type.IsNullOrWhiteSpace() == false)
{
if (type == "internal")
{
var linkId = a.Value<int>("link");
var link = helper.NiceUrl(linkId);
a["link"] = link;
}
}
}
}
return obj;
}
catch (Exception ex)
{
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
}
return null;
}
//it's not json, just return the string
return sourceString;
}
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return null;
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
{
try
{
var obj = JsonConvert.DeserializeObject<Array>(sourceString);
var d = new XmlDocument();
var e = d.CreateElement("links");
d.AppendChild(e);
var values = (IEnumerable<string>)source;
foreach (dynamic link in obj)
{
var ee = d.CreateElement("link");
ee.SetAttribute("title", link.title);
ee.SetAttribute("link", link.link);
ee.SetAttribute("type", link.type);
ee.SetAttribute("newwindow", link.newWindow);
e.AppendChild(ee);
}
return d.CreateNavigator();
}
catch (Exception ex)
{
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
}
}
//it's not json, just return the string
return sourceString;
return UmbracoContext.Current != null ? new RelatedLinks(sourceString) : null;
}
}
}
}

View File

@@ -342,6 +342,9 @@
<Compile Include="Models\Mapping\ContentTypeModelMapperExtensions.cs" />
<Compile Include="Models\Mapping\LockedCompositionsResolver.cs" />
<Compile Include="Models\Mapping\PropertyGroupDisplayResolver.cs" />
<Compile Include="Models\RelatedLink.cs" />
<Compile Include="Models\RelatedLinks.cs" />
<Compile Include="Models\RelatedLinkType.cs" />
<Compile Include="Models\SetPasswordModel.cs" />
<Compile Include="Models\RequestPasswordResetModel.cs" />
<Compile Include="Models\PublishedContentWithKeyBase.cs" />
@@ -356,8 +359,12 @@
<Compile Include="OwinMiddlewareConfiguredEventArgs.cs" />
<Compile Include="PropertyEditors\DatePreValueEditor.cs" />
<Compile Include="PropertyEditors\DecimalPropertyEditor.cs" />
<Compile Include="PropertyEditors\ValueConverters\ContentPickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropDataSetConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MediaPickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MultiNodeTreePickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MultipleMediaPickerPropertyConverter.cs" />
<Compile Include="RequestLifespanMessagesFactory.cs" />
<Compile Include="RouteDataExtensions.cs" />
<Compile Include="Scheduling\LatchedBackgroundTaskBase.cs" />