From e7754d313e6baae2bbfdcd7bbddc84478777769e Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Sun, 12 Jun 2016 16:36:26 +0200 Subject: [PATCH] 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!! --- src/Umbraco.Core/EnumerableExtensions.cs | 16 ++ src/Umbraco.Web/Models/RelatedLink.cs | 184 +++++++++++++++ src/Umbraco.Web/Models/RelatedLinkType.cs | 27 +++ src/Umbraco.Web/Models/RelatedLinks.cs | 110 +++++++++ .../ContentPickerPropertyConverter.cs | 177 +++++++++++++++ .../MediaPickerPropertyConverter.cs | 145 ++++++++++++ .../MultiNodeTreePickerPropertyConverter.cs | 194 ++++++++++++++++ .../MultipleMediaPickerPropertyConverter.cs | 212 ++++++++++++++++++ .../RelatedLinksEditorValueConvertor.cs | 133 ++++------- src/Umbraco.Web/Umbraco.Web.csproj | 7 + 10 files changed, 1118 insertions(+), 87 deletions(-) create mode 100644 src/Umbraco.Web/Models/RelatedLink.cs create mode 100644 src/Umbraco.Web/Models/RelatedLinkType.cs create mode 100644 src/Umbraco.Web/Models/RelatedLinks.cs create mode 100644 src/Umbraco.Web/PropertyEditors/ValueConverters/ContentPickerPropertyConverter.cs create mode 100644 src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs create mode 100644 src/Umbraco.Web/PropertyEditors/ValueConverters/MultiNodeTreePickerPropertyConverter.cs create mode 100644 src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs index 58d4d453b7..83eb080049 100644 --- a/src/Umbraco.Core/EnumerableExtensions.cs +++ b/src/Umbraco.Core/EnumerableExtensions.cs @@ -301,5 +301,21 @@ namespace Umbraco.Core && list1Groups.All(g => g.Count() == list2Groups[g.Key].Count()); } + /// + /// Returns the items of the given enumerable as a pure enumerable. + /// + /// When quering lists using methods such as , the result, despite appearing to look like and quack like an + /// the type is actually an instance of + /// + /// + ///The item to find. + ///The index of the first matching item, or -1 if the item was not found. + internal static IEnumerable Yield(this IEnumerable source) + { + foreach (var element in source) + { + yield return element; + } + } } } diff --git a/src/Umbraco.Web/Models/RelatedLink.cs b/src/Umbraco.Web/Models/RelatedLink.cs new file mode 100644 index 0000000000..145ca6ea7d --- /dev/null +++ b/src/Umbraco.Web/Models/RelatedLink.cs @@ -0,0 +1,184 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// Defines the RelatedLink type. +// +// -------------------------------------------------------------------------------------------------------------------- + +using System; +using Newtonsoft.Json.Linq; + +namespace Umbraco.Web.Models +{ + /// + /// The related link model + /// + public class RelatedLink + { + // ReSharper disable InconsistentNaming + + /// + /// The _link item. + /// + private readonly JToken _linkItem; + + /// + /// The _caption. + /// + private string _caption; + + /// + /// The _new window. + /// + private bool? _newWindow; + + /// + /// The _is internal. + /// + private bool? _isInternal; + + /// + /// The _link. + /// + private string _link; + + /// + /// The _linkDeleted. + /// + private bool? _linkDeleted; + + /// + /// The _type. + /// + private RelatedLinkType _type; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The link item. + /// + public RelatedLink(JToken linkItem) + { + this._linkItem = linkItem; + + // get the current Link to set the _linkDeleted is a internal link + var currentLink = this.Link; + } + + /// + /// Gets the caption. + /// + public string Caption + { + get + { + if (string.IsNullOrEmpty(this._caption)) + { + this._caption = this._linkItem.Value("caption"); + } + + return this._caption; + } + } + + /// + /// Gets a value indicating whether new window. + /// + public bool NewWindow + { + get + { + if (this._newWindow == null) + { + this._newWindow = this._linkItem.Value("newWindow"); + } + + return this._newWindow.GetValueOrDefault(); + } + } + + /// + /// Gets a value indicating whether the link is internal. + /// + public bool IsInternal + { + get + { + if (this._isInternal == null) + { + this._isInternal = this._linkItem.Value("isInternal"); + } + + return this._isInternal.GetValueOrDefault(); + } + } + + /// + /// Gets the type. + /// + public RelatedLinkType? Type + { + get + { + if (Enum.TryParse(this._linkItem.Value("type"), true, out this._type)) + { + return this._type; + } + + return null; + } + } + + /// + /// Gets the link. + /// + 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("internal")); + if (this._link.Equals("#")) + { + this._linkDeleted = true; + this._link = this._linkItem.Value("internal"); + } + else + { + this._linkDeleted = false; + } + } + else + { + this._link = this._linkItem.Value("link"); + } + } + + return this._link; + } + } + + /// + /// Gets a value indicating whether deleted. + /// + internal bool InternalLinkDeleted + { + get + { + var linkDeleted = this._linkDeleted; + return linkDeleted != null && (bool)linkDeleted; + } + } + } +} diff --git a/src/Umbraco.Web/Models/RelatedLinkType.cs b/src/Umbraco.Web/Models/RelatedLinkType.cs new file mode 100644 index 0000000000..8de88d5520 --- /dev/null +++ b/src/Umbraco.Web/Models/RelatedLinkType.cs @@ -0,0 +1,27 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// Defines the RelatedLinkType type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace Umbraco.Web.Models +{ + /// + /// The related link type. + /// + public enum RelatedLinkType + { + /// + /// Internal link type + /// + Internal, + + /// + /// External link type + /// + External + } +} diff --git a/src/Umbraco.Web/Models/RelatedLinks.cs b/src/Umbraco.Web/Models/RelatedLinks.cs new file mode 100644 index 0000000000..60d2ef03b5 --- /dev/null +++ b/src/Umbraco.Web/Models/RelatedLinks.cs @@ -0,0 +1,110 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// Defines the RelatedLinks type. +// +// -------------------------------------------------------------------------------------------------------------------- + +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 +{ + /// + /// The related links model + /// + public class RelatedLinks : IEnumerable + { + // ReSharper disable InconsistentNaming + + /// + /// The _property data. + /// + private readonly string _propertyData; + + /// + /// The _related links. + /// + private readonly List _relatedLinks = new List(); + + /// + /// Initializes a new instance of the class. + /// + /// + /// The property data. + /// + public RelatedLinks(string propertyData) + { + this._propertyData = propertyData; + + if (!string.IsNullOrEmpty(propertyData)) + { + var relatedLinks = JsonConvert.DeserializeObject(propertyData); + + foreach (var item in relatedLinks) + { + var relatedLink = new RelatedLink(item); + if (!relatedLink.InternalLinkDeleted) + { + this._relatedLinks.Add(relatedLink); + } + else + { + LogHelper.Warn( + 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)); + } + } + } + } + + /// + /// Gets the property data. + /// + public string PropertyData + { + get + { + return this._propertyData; + } + } + + /// + /// The any. + /// + /// + /// The . + /// + public bool Any() + { + return Enumerable.Any(this); + } + + /// + /// The get enumerator. + /// + /// + /// The . + /// + public IEnumerator GetEnumerator() + { + return this._relatedLinks.GetEnumerator(); + } + + /// + /// The get enumerator. + /// + /// + /// The . + /// + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/ContentPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/ContentPickerPropertyConverter.cs new file mode 100644 index 0000000000..643e936c06 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/ContentPickerPropertyConverter.cs @@ -0,0 +1,177 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// The content picker property editor converter. +// +// -------------------------------------------------------------------------------------------------------------------- + +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 +{ + /// + /// The content picker property value converter. + /// + public class ContentPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + { + /// + /// The properties to exclude. + /// + private static readonly List PropertiesToExclude = new List() + { + Constants.Conventions.Content.InternalRedirectId.ToLower(CultureInfo.InvariantCulture), + Constants.Conventions.Content.Redirect.ToLower(CultureInfo.InvariantCulture) + }; + + /// + /// Checks if this converter can convert the property editor and registers if it can. + /// + /// + /// The published property type. + /// + /// + /// The . + /// + public override bool IsConverter(PublishedPropertyType propertyType) + { + return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPickerAlias); + } + + /// + /// Convert the raw string into a nodeId integer + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + var attemptConvertInt = source.TryConvertTo(); + if (attemptConvertInt.Success) + { + return attemptConvertInt.Result; + } + + return null; + } + + /// + /// Convert the source nodeId into a IPublishedContent (or DynamicPublishedContent) + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + 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; + } + + /// + /// The convert source to xPath. + /// + /// + /// The property type. + /// + /// + /// The source. + /// + /// + /// The preview. + /// + /// + /// The . + /// + public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview) + { + return source.ToString(); + } + + /// + /// The CLR type that the value converter returns. + /// + /// + /// The property type. + /// + /// + /// The . + /// + public virtual Type GetPropertyValueType(PublishedPropertyType propertyType) + { + return typeof(IPublishedContent); + } + + /// + /// The get property cache level. + /// + /// + /// The property type. + /// + /// + /// The cache value. + /// + /// + /// The . + /// + 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; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs new file mode 100644 index 0000000000..3bdba5d07b --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MediaPickerPropertyConverter.cs @@ -0,0 +1,145 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// The legacy media picker value converter +// +// -------------------------------------------------------------------------------------------------------------------- + +using System; + +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors.ValueConverters +{ + /// + /// The media picker property value converter. + /// + public class MediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + { + /// + /// Checks if this converter can convert the property editor and registers if it can. + /// + /// + /// The published property type. + /// + /// + /// The . + /// + 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); + } + + /// + /// Convert the raw string into a nodeId integer + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + var attemptConvertInt = source.TryConvertTo(); + if (attemptConvertInt.Success) + { + return attemptConvertInt.Result; + } + + return null; + } + + /// + /// Convert the source nodeId into a IPublishedContent (or DynamicPublishedContent) + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + 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; + } + + /// + /// The get property cache level. + /// + /// + /// The property type. + /// + /// + /// The cache value. + /// + /// + /// The . + /// + 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; + } + + /// + /// The CLR type that the value converter returns. + /// + /// + /// The property type. + /// + /// + /// The . + /// + public virtual Type GetPropertyValueType(PublishedPropertyType propertyType) + { + return typeof(IPublishedContent); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiNodeTreePickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiNodeTreePickerPropertyConverter.cs new file mode 100644 index 0000000000..af72de0cb2 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultiNodeTreePickerPropertyConverter.cs @@ -0,0 +1,194 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// The multi node tree picker property editor value converter. +// +// -------------------------------------------------------------------------------------------------------------------- + +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 +{ + + /// + /// The multi node tree picker property editor value converter. + /// + public class MultiNodeTreePickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + { + /// + /// Checks if this converter can convert the property editor and registers if it can. + /// + /// + /// The published property type. + /// + /// + /// The . + /// + public override bool IsConverter(PublishedPropertyType propertyType) + { + return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias); + } + + /// + /// Convert the raw string into a nodeId integer array + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + var nodeIds = + source.ToString() + .Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) + .Select(int.Parse) + .ToArray(); + + return nodeIds; + } + + /// + /// Convert the source nodeId into a IEnumerable of IPublishedContent (or DynamicPublishedContent) + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview) + { + if (source == null) + { + return null; + } + + var nodeIds = (int[])source; + + var multiNodeTreePicker = new List(); + + 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; + } + + /// + /// The get property cache level. + /// + /// + /// The property type. + /// + /// + /// The cache value. + /// + /// + /// The . + /// + 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; + } + + /// + /// The CLR type that the value converter returns. + /// + /// + /// The property type. + /// + /// + /// The . + /// + public virtual Type GetPropertyValueType(PublishedPropertyType propertyType) + { + return typeof(IEnumerable); + } + + /// + /// Attempt to get an IPublishedContent instance based on ID and content type + /// + /// The content node ID + /// The type of content being requested + /// The type of content expected/supported by + /// A function to fetch content of type + /// The requested content, or null if either it does not exist or does not match + private IPublishedContent GetPublishedContent(int nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func 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; + } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs new file mode 100644 index 0000000000..a31e6e2ef4 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MultipleMediaPickerPropertyConverter.cs @@ -0,0 +1,212 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// The multiple media picker property editor converter. +// +// -------------------------------------------------------------------------------------------------------------------- + +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 +{ + /// + /// The multiple media picker property value converter. + /// + public class MultipleMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta + { + /// + /// Checks if this converter can convert the property editor and registers if it can. + /// + /// + /// The property type. + /// + /// + /// The . + /// + public override bool IsConverter(PublishedPropertyType propertyType) + { + return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias); + } + + /// + /// Convert the raw string into a nodeId integer array or a single integer + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + 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(); + 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(error); + throw new Exception(error); + } + } + + return null; + } + + /// + /// Convert the source nodeId into a IPublishedContent or IEnumerable of IPublishedContent (or DynamicPublishedContent) depending on data type setting + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + 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(); + 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); + } + + /// + /// The get property cache level. + /// + /// + /// The property type. + /// + /// + /// The cache value. + /// + /// + /// The . + /// + 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; + } + + /// + /// The get property value type. + /// + /// + /// The property type. + /// + /// + /// The . + /// + public virtual Type GetPropertyValueType(PublishedPropertyType propertyType) + { + return IsMultipleDataType(propertyType.DataTypeId) ? typeof(IEnumerable) : typeof(IPublishedContent); + } + + /// + /// The is multiple data type. + /// + /// + /// The data type id. + /// + /// + /// The . + /// + 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().Result; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksEditorValueConvertor.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksEditorValueConvertor.cs index a0368db769..5df37ebfb9 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksEditorValueConvertor.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksEditorValueConvertor.cs @@ -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; +// -------------------------------------------------------------------------------------------------------------------- +// +// Umbraco +// +// +// Defines the RelatedLinksPropertyConverter type. +// +// -------------------------------------------------------------------------------------------------------------------- + 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 + /// + /// The related links property value converter. + /// + [PropertyValueType(typeof(RelatedLinks))] + [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.ContentCache)] + public class RelatedLinksPropertyConverter : PropertyValueConverterBase { + /// + /// Checks if this converter can convert the property editor and registers if it can. + /// + /// + /// The property type. + /// + /// + /// The . + /// 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) + /// + /// Convert the source nodeId into a RelatedLinks object + /// + /// + /// The published property type. + /// + /// + /// The value of the property + /// + /// + /// The preview. + /// + /// + /// The . + /// + 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(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("type"); - if (type.IsNullOrWhiteSpace() == false) - { - if (type == "internal") - { - var linkId = a.Value("link"); - var link = helper.NiceUrl(linkId); - a["link"] = link; - } - } - } - } - return obj; - } - catch (Exception ex) - { - LogHelper.Error("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(sourceString); - - var d = new XmlDocument(); - var e = d.CreateElement("links"); - d.AppendChild(e); - - var values = (IEnumerable)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("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; } } -} +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index de4b49bc77..6d44805856 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -342,6 +342,9 @@ + + + @@ -356,8 +359,12 @@ + + + +