Compare commits

..

36 Commits

Author SHA1 Message Date
Stephan 6992b0319a Version 7.6-alpha074 2017-03-08 18:59:27 +01:00
Stephan d1111009e3 Fix SemVer lib version 2017-03-08 18:45:00 +01:00
Shannon Deminick 1722831bf5 Merge pull request #1640 from umbraco/temp-u4-7318
Value Converters for All Core Property Editors
2017-03-08 14:29:40 +01:00
Shannon 5291558b23 Further refactoring, using attributes, moving and removing some classes, using DI where necessary. 2017-03-08 14:27:39 +01:00
Shannon a9c5877e5b Merge branch 'refs/heads/dev-v7.6' into temp-u4-7318
# Conflicts:
#	src/Umbraco.Web.UI/config/umbracoSettings.config
#	src/Umbraco.Web/Umbraco.Web.csproj
2017-03-01 15:04:00 +01:00
Stephan 44b90bd4f3 Merge branch 'dev-v7.6' into temp-u4-7318 2016-12-05 17:08:19 +01:00
Jeavon 3e558af18f Merge branch 'dev-v7' into temp-u4-7318 2016-12-05 12:21:02 +00:00
Jeavon 3774d4fc62 Adding comments to the Slider, Tags & Multiple Media picker values converters about the need to cache the prevalues 2016-12-05 12:16:43 +00:00
Jeavon a24acdb8ce Added value converter for the slider property editor and and Range class to be returned when range mode is enabled 2016-12-05 12:13:47 +00:00
Jeavon f91d5b53c1 Added a basic value converter for the tags property editor 2016-12-05 10:58:09 +00:00
Jeavon c053adc9b2 Move the Upload editor value converter from Lars to Core from Web 2016-11-03 17:06:26 +00:00
Jeavon e3bc588164 Merge pull request #1555 from lars-erik/temp-u4-7318
Added converter for upload field
2016-11-03 17:01:58 +00:00
Jeavon 392319d26c Adding check for converter enablement to James's converters that need it 2016-11-03 16:43:23 +00:00
Jeavon 584638977c Merge pull request #1570 from jamescoxhead/U4-7318
U4-7318 Core property value converters
2016-11-03 15:08:29 +00:00
Jeavon be8632db1c Adding EnablePropertyValueConverters setting to umbracoSettings.config so that all the new converters can be disabled.
Readded existing JArray converter for RelatedLinks but renamed to LegacyRelatedLinksEditorValueConvertor
2016-11-03 13:30:41 +00:00
Jeavon 094514b91a Merge branch 'dev-v7' into temp-u4-7318
# Conflicts:
#	src/Umbraco.Web/Umbraco.Web.csproj
2016-11-03 11:31:42 +00:00
James Coxhead 3c43f4f3c5 Added member picker value converter 2016-11-02 23:37:32 +00:00
James Coxhead 12f9392db9 Added user picker value converter 2016-11-02 21:52:27 +00:00
James Coxhead d787cb6ad9 Added radio button list converter 2016-11-02 21:35:42 +00:00
James Coxhead db02c3b73c Added member group picker value converter 2016-11-02 21:26:41 +00:00
James Coxhead a10214d82b Added dropdown with keys value converter 2016-11-01 23:53:55 +00:00
James Coxhead bc61054931 Added dropdown list value converter 2016-11-01 23:46:32 +00:00
James Coxhead 0becdccb68 Added dropdown list multiple with keys value converter 2016-11-01 23:38:05 +00:00
James Coxhead cee92518ea Added dropdown list multiple value converter 2016-11-01 21:44:17 +00:00
James Coxhead a34a8e180d Added checkbox list converter 2016-10-29 23:32:56 +01:00
James Coxhead f9f48753de Updated colour picker converter to return string 2016-10-29 22:51:36 +01:00
James Coxhead c9af13df78 Added email address converter 2016-10-29 22:45:48 +01:00
Lars-Erik Aabech f66b456d7c Added converter for upload field 2016-10-29 09:44:45 +02:00
Jeavon 6d722c5591 Merge branch 'temp-u4-7318' of https://github.com/umbraco/Umbraco-CMS into temp-u4-7318 2016-08-17 10:24:28 +01:00
Jeavon 9ed9aef1d3 Merge branch 'dev-v7' into temp-u4-7318
# Conflicts:
#	src/Umbraco.Web/Umbraco.Web.csproj
2016-08-17 10:16:05 +01:00
Stephan 0cc398130d Merge pull request #1311 from Jeavon/temp-u4-7318
U4-7318 - Initial import of core value converters for Stephan
2016-08-16 15:29:17 +02:00
Jeavon 927f48985e Latest updates from Core Value Converters package including massive simplification of RelatedLinks and exclusion of special property aliases in MNTP 2016-08-03 20:45:01 +01:00
Jeavon 3b31b92f1f Adding a type converter for RelatedLinks so that implementations using JArray (from official docs) still work (e.g. Model.Content.GetPropertyValue<JArray>("relatedLinks")) 2016-06-21 15:20:17 +01:00
Jeavon aaf725a498 Adding Id to the Related Link model 2016-06-21 12:49:45 +01:00
Jeavon Leopold 36aa166a95 Converters and models to support existing GetPropertyValue<int> and GetPropertyValue<string> code 2016-06-13 16:16:12 +02:00
Jeavon Leopold e7754d313e 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!! 2016-06-12 16:36:26 +02:00
58 changed files with 1982 additions and 135 deletions
+3 -3
View File
@@ -36,10 +36,10 @@
<dependency id="Examine" version="[0.1.81, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.2, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<dependency id="semver" version="[2.0.4, 3.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="System.Threading.Tasks.Dataflow" version="[4.6.0, 5.0.0)" />
</dependencies>
</metadata>
+1 -1
View File
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.6.0
alpha073
alpha074
+1 -1
View File
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.6.0")]
[assembly: AssemblyInformationalVersion("7.6.0-alpha073")]
[assembly: AssemblyInformationalVersion("7.6.0-alpha074")]
@@ -177,6 +177,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
}
[ConfigurationProperty("EnablePropertyValueConverters")]
internal InnerTextConfigurationElement<bool> EnablePropertyValueConverters
{
get { return GetOptionalTextElement("EnablePropertyValueConverters", false); }
}
string IContentSection.NotificationEmailAddress
{
get { return Notifications.NotificationEmailAddress; }
@@ -326,5 +332,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return EnableInheritedMediaTypes; }
}
bool IContentSection.EnablePropertyValueConverters
{
get { return EnablePropertyValueConverters; }
}
}
}
@@ -69,5 +69,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool EnableInheritedDocumentTypes { get; }
bool EnableInheritedMediaTypes { get; }
bool EnablePropertyValueConverters { get; }
}
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "alpha073"; } }
public static string CurrentComment { get { return "alpha074"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+16
View File
@@ -296,5 +296,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;
}
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// The published content enumerable, this model is to allow ToString to be overriden for value converters to support legacy requests for string values
/// </summary>
public class PublishedContentEnumerable : IEnumerable<IPublishedContent>
{
/// <summary>
/// The items in the collection
/// </summary>
private readonly IEnumerable<IPublishedContent> _items;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentEnumerable"/> class.
/// </summary>
/// <param name="publishedContent">
/// The published content items
/// </param>
public PublishedContentEnumerable(IEnumerable<IPublishedContent> publishedContent)
{
if (publishedContent == null) throw new ArgumentNullException("publishedContent");
_items = publishedContent;
}
/// <summary>
/// The ToString method to convert the objects back to CSV
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string ToString()
{
return string.Join(",", _items.Select(x => x.Id));
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
public IEnumerator<IPublishedContent> GetEnumerator()
{
return _items.GetEnumerator();
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
[TypeConverter(typeof(PublishedContentTypeConverter))]
public class PublishedContentExtended : PublishedContentWrapped, IPublishedContentExtended
{
#region Constructor
@@ -186,6 +187,11 @@ namespace Umbraco.Core.Models.PublishedContent
}
#endregion
public override string ToString()
{
return Id.ToString();
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
internal class PublishedContentTypeConverter : TypeConverter
{
private static readonly Type[] ConvertableTypes = new[]
{
typeof(int)
};
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ConvertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
|| base.CanConvertFrom(context, destinationType);
}
public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType)
{
var publishedContent = value as IPublishedContent;
if (publishedContent == null)
return null;
if (TypeHelper.IsTypeAssignableFrom<int>(destinationType))
{
return publishedContent.Id;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
+52
View File
@@ -0,0 +1,52 @@
using System;
namespace Umbraco.Core.Models
{
// <summary>The Range class. Adapted from http://stackoverflow.com/questions/5343006/is-there-a-c-sharp-type-for-representing-an-integer-range</summary>
/// <typeparam name="T">Generic parameter.</typeparam>
public class Range<T> where T : IComparable<T>
{
/// <summary>Minimum value of the range.</summary>
public T Minimum { get; set; }
/// <summary>Maximum value of the range.</summary>
public T Maximum { get; set; }
/// <summary>Presents the Range in readable format.</summary>
/// <returns>String representation of the Range</returns>
public override string ToString()
{
return string.Format("{0},{1}", this.Minimum, this.Maximum);
}
/// <summary>Determines if the range is valid.</summary>
/// <returns>True if range is valid, else false</returns>
public bool IsValid()
{
return this.Minimum.CompareTo(this.Maximum) <= 0;
}
/// <summary>Determines if the provided value is inside the range.</summary>
/// <param name="value">The value to test</param>
/// <returns>True if the value is inside Range, else false</returns>
public bool ContainsValue(T value)
{
return (this.Minimum.CompareTo(value) <= 0) && (value.CompareTo(this.Maximum) <= 0);
}
/// <summary>Determines if this Range is inside the bounds of another range.</summary>
/// <param name="Range">The parent range to test on</param>
/// <returns>True if range is inclusive, else false</returns>
public bool IsInsideRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && range.ContainsValue(this.Minimum) && range.ContainsValue(this.Maximum);
}
/// <summary>Determines if another range is inside the bounds of this range.</summary>
/// <param name="Range">The child range to test</param>
/// <returns>True if range is inside, else false</returns>
public bool ContainsRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && this.ContainsValue(range.Minimum) && this.ContainsValue(range.Maximum);
}
}
}
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class CheckboxListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.CheckBoxListAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
var sourceString = (source ?? string.Empty).ToString();
if (string.IsNullOrEmpty(sourceString))
return Enumerable.Empty<string>();
var values =
sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
return values;
}
}
}
@@ -1,18 +1,28 @@
using Umbraco.Core.Models.PublishedContent;
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class ColorPickerValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ColorPickerAlias);
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ColorPickerAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
// make sure it's a string
return source.ToString();
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -6,6 +6,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(DateTime))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DatePickerValueConverter : PropertyValueConverterBase
@@ -3,6 +3,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(decimal))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DecimalValueConverter : PropertyValueConverterBase
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListMultipleValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropDownListMultipleAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
var sourceString = (source ?? "").ToString();
if (string.IsNullOrEmpty(sourceString))
return Enumerable.Empty<string>();
var values =
sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
return values;
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<int>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListMultipleWithKeysValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropdownlistMultiplePublishKeysAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
return new int[] { };
var prevalueIds = source.ToString()
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(p => p.Trim())
.Select(int.Parse)
.ToArray();
return prevalueIds;
}
}
}
@@ -0,0 +1,28 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropDownListAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -0,0 +1,31 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListWithKeysValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropdownlistPublishingKeysAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var intAttempt = source.TryConvertTo<int>();
if (intAttempt.Success)
return intAttempt.Result;
return null;
}
}
}
@@ -0,0 +1,27 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class EmailAddressValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.EmailAddressAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
return source.ToString();
}
}
}
@@ -2,6 +2,7 @@
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class IntegerValueConverter : PropertyValueConverterBase
@@ -4,6 +4,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IHtmlString))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
@@ -0,0 +1,27 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MemberGroupPickerValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.MemberGroupPickerAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -8,6 +8,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MultipleTextStringValueConverter : PropertyValueConverterBase
@@ -0,0 +1,31 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class RadioButtonListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.RadioButtonListAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var intAttempt = source.TryConvertTo<int>();
if (intAttempt.Success)
return intAttempt.Result;
return null;
}
}
}
@@ -0,0 +1,100 @@
using System;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
public class SliderValueConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
public SliderValueConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
public SliderValueConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.SliderAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
if (IsRangeDataType(propertyType.DataTypeId))
{
var rangeRawValues = source.ToString().Split(',');
var minimumAttempt = rangeRawValues[0].TryConvertTo<decimal>();
var maximumAttempt = rangeRawValues[1].TryConvertTo<decimal>();
if (minimumAttempt.Success && maximumAttempt.Success)
{
return new Range<decimal>() { Maximum = maximumAttempt.Result, Minimum = minimumAttempt.Result };
}
}
var valueAttempt = source.ToString().TryConvertTo<decimal>();
if (valueAttempt.Success)
{
return valueAttempt.Result;
}
// Something failed in the conversion of the strings to decimals
return null;
}
public Type GetPropertyValueType(PublishedPropertyType propertyType)
{
if (IsRangeDataType(propertyType.DataTypeId))
{
return typeof(Range<decimal>);
}
return typeof(decimal);
}
public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
/// <summary>
/// Discovers if the slider is set to range mode.
/// </summary>
/// <param name="dataTypeId">
/// The data type id.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
private bool IsRangeDataType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var enableRange =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase)).Value;
return enableRange != null && enableRange.Value.TryConvertTo<bool>().Result;
}
}
}
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TagsValueConverter : PropertyValueConverterBase
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
public TagsValueConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
public TagsValueConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.TagsAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
// if Json storage type deserialzie and return as string array
if (JsonStorageType(propertyType.DataTypeId))
{
var jArray = JsonConvert.DeserializeObject<JArray>(source.ToString());
return jArray.ToObject<string[]>();
}
// Otherwise assume CSV storage type and return as string array
var csvTags =
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
return (string[]) source;
}
/// <summary>
/// Discovers if the tags data type is storing its data in a Json format
/// </summary>
/// <param name="dataTypeId">
/// The data type id.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
private bool JsonStorageType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var storageType =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase)).Value;
if (storageType.Value.InvariantEquals("Json"))
{
return true;
}
return false;
}
}
}
@@ -6,11 +6,12 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TextStringValueConverter : PropertyValueConverterBase
{
private readonly static string[] PropertyTypeAliases =
private static readonly string[] PropertyTypeAliases =
{
Constants.PropertyEditors.TextboxAlias,
Constants.PropertyEditors.TextboxMultipleAlias
@@ -4,10 +4,11 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
/// </summary>
/// <summary>
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
/// </summary>
// PropertyCacheLevel.Content is ok here because that version of RTE converter does not parse {locallink} nor executes macros
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IHtmlString))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TinyMceValueConverter : PropertyValueConverterBase
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// The upload property value converter.
/// </summary>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class UploadPropertyConverter : PropertyValueConverterBase
{
/// <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)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.UploadFieldAlias);
}
return false;
}
/// <summary>
/// Convert the source object to a string
/// </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)
{
return (source ?? "").ToString();
}
}
}
@@ -3,6 +3,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(bool))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class YesNoValueConverter : PropertyValueConverterBase
+16 -2
View File
@@ -101,8 +101,8 @@
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
@@ -338,6 +338,7 @@
<Compile Include="Events\ScopeEventDispatcherBase.cs" />
<Compile Include="Events\ScopeLifespanMessagesFactory.cs" />
<Compile Include="IHttpContextAccessor.cs" />
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
<Compile Include="OrderedHashSet.cs" />
<Compile Include="Events\UninstallPackageEventArgs.cs" />
<Compile Include="Models\GridValue.cs" />
@@ -446,9 +447,11 @@
<Compile Include="Models\PartialViewType.cs" />
<Compile Include="Models\PublicAccessEntry.cs" />
<Compile Include="Models\PublicAccessRule.cs" />
<Compile Include="Models\PublishedContent\PublishedContentEnumerable.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyExtended.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyModel.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyWrapped.cs" />
<Compile Include="Models\Range.cs" />
<Compile Include="Models\Rdbms\AccessDto.cs" />
<Compile Include="Media\Exif\BitConverterEx.cs" />
<Compile Include="Media\Exif\ExifBitConverter.cs" />
@@ -579,10 +582,21 @@
<Compile Include="Persistence\UnitOfWork\ScopeUnitOfWorkProvider.cs" />
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueTypes.cs" />
<Compile Include="PropertyEditors\ValueConverters\CheckboxListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleWithKeysValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListWithKeysValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\EmailAddressValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\LabelValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MemberGroupPickerValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\RadioButtonListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\SliderValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\TagsValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\UploadPropertyConverter.cs" />
<Compile Include="Publishing\UnPublishedStatusType.cs" />
<Compile Include="Publishing\UnPublishStatus.cs" />
<Compile Include="SafeCallContext.cs" />
+5 -1
View File
@@ -14,7 +14,11 @@
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net45" />
</packages>
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.PropertyEditors
{
@@ -58,5 +57,44 @@ namespace Umbraco.Tests.PropertyEditors
Assert.AreEqual(expected, result);
}
}
[TestCase("apples", new[] { "apples" })]
[TestCase("apples,oranges", new[] { "apples", "oranges" })]
[TestCase(" apples, oranges, pears ", new[] { "apples", "oranges", "pears" })]
[TestCase("", new string[] { })]
[TestCase(null, new string[] { })]
public void CanConvertCheckboxListPropertyEditor(object value, IEnumerable<string> expected)
{
var converter = new CheckboxListValueConverter();
var result = converter.ConvertSourceToObject(null, value, false);
Assert.AreEqual(expected, result);
}
[TestCase("apples", new[] {"apples"})]
[TestCase("apples,oranges", new[] {"apples", "oranges"})]
[TestCase("apples , oranges, pears ", new[] {"apples", "oranges", "pears"})]
[TestCase("", new string[] {})]
[TestCase(null, new string[] {})]
public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable<string> expected)
{
var converter = new DropdownListMultipleValueConverter();
var result = converter.ConvertSourceToObject(null, value, false);
Assert.AreEqual(expected, result);
}
[TestCase("100", new[] {100})]
[TestCase("100,200", new[] {100, 200})]
[TestCase("100 , 200, 300 ", new[] {100, 200, 300})]
[TestCase("", new int[] {})]
[TestCase(null, new int[] {})]
public void CanConvertDropdownListMultipleWithKeysPropertyEditor(object value, IEnumerable<int> expected)
{
var converter = new DropdownListMultipleWithKeysValueConverter();
var result = converter.ConvertDataToSource(null, value, false);
Assert.AreEqual(expected, result);
}
}
}
+3 -2
View File
@@ -91,11 +91,12 @@
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
+5 -1
View File
@@ -21,7 +21,11 @@
<package id="NUnit" version="2.6.2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="2.32.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net45" />
</packages>
+11 -21
View File
@@ -10,16 +10,6 @@
</control>
</tab>
</section>
<section alias="StartupFormsDashboardSection">
<areas>
<area>forms</area>
</areas>
<tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption="">
views/dashboard/forms/formsdashboardintro.html
</control>
</tab>
</section>
<section alias="StartupDeveloperDashboardSection">
<areas>
<area>developer</area>
@@ -45,16 +35,6 @@
</control>
</tab>
</section>
<section alias="StartupFormsDashboardSection">
<areas>
<area>forms</area>
</areas>
<tab caption="Install Umbraco Forms">
<control showOnce="true" addPanel="true" panelCaption="">
views/dashboard/forms/formsdashboardintro.html
</control>
</tab>
</section>
<section alias="StartupDashboardSection">
<access>
<deny>translator</deny>
@@ -129,4 +109,14 @@
</control>
</tab>
</section>
</dashBoard>
<section alias="StartupFormsDashboardSection">
<areas>
<area>forms</area>
</areas>
<tab caption="Dashboard">
<control>/app_plugins/umbracoforms/backoffice/dashboards/licensing.html</control>
<control>/app_plugins/umbracoforms/backoffice/dashboards/yourforms.html</control>
<control>/app_plugins/umbracoforms/backoffice/dashboards/activity.html</control>
</tab>
</section>
</dashBoard>
@@ -8,4 +8,11 @@
</Parameters>
</Provider>
<!--
<Provider alias="forms" type="Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core">
<Parameters>
<add key="virtualRoot" value="~/App_Data/ZbForms" />
</Parameters>
</Provider>
-->
</FileSystemProviders>
@@ -55,6 +55,9 @@
<!-- Defines the default document type property used when adding properties in the back-office (if missing or empty, defaults to Textstring -->
<defaultDocumentTypeProperty>Textstring</defaultDocumentTypeProperty>
<!-- Enables value converters for all built in property editors so that they return strongly typed object, recommended for use with Models Builder -->
<EnablePropertyValueConverters>true</EnablePropertyValueConverters>
</content>
<security>
@@ -106,6 +106,9 @@
<defaultDocumentTypeProperty>Textstring</defaultDocumentTypeProperty>
<showDeprecatedPropertyEditors>true</showDeprecatedPropertyEditors>
<!-- Enables value converters for all built in property editors so that they return strongly typed object, recommended for use with Models Builder -->
<EnablePropertyValueConverters>true</EnablePropertyValueConverters>
</content>
<security>
@@ -311,10 +314,10 @@
Configure it here if you need anything specific. Needs to be a complete url with scheme and umbraco
path, eg http://mysite.com/umbraco. NOT just "mysite.com" or "mysite.com/umbraco" or "http://mysite.com".
-->
<web.routing
trySkipIisCustomErrors="false"
internalRedirectPreservesTemplate="false" disableAlternativeTemplates="false" disableFindContentByIdPath="false"
umbracoApplicationUrl="">
<web.routing
trySkipIisCustomErrors="false"
internalRedirectPreservesTemplate="false" disableAlternativeTemplates="false" disableFindContentByIdPath="false"
umbracoApplicationUrl="">
</web.routing>
</settings>
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<language alias="en" intName="English (UK)" localName="English (UK)" lcid="" culture="en-GB">
<creator>
<name>The Umbraco community</name>
@@ -40,7 +40,7 @@
<key alias="translate">Translate</key>
<key alias="update">Update</key>
<key alias="defaultValue">Default value</key>
</area>
<key alias="exportContourForm">Export form</key><key alias="importContourForm">Import form</key><key alias="archiveContourForm">Archive form</key><key alias="unarchiveContourForm">Unarchive form</key><key alias="defaultValue">Default value</key><key alias="exportContourForm">Export form</key><key alias="importContourForm">Import form</key><key alias="archiveContourForm">Archive form</key><key alias="unarchiveContourForm">Unarchive form</key><key alias="defaultValue">Default value</key></area>
<area alias="assignDomain">
<key alias="permissionDenied">Permission denied.</key>
<key alias="addNew">Add new Domain</key>
@@ -934,7 +934,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="help" version="7.0">Help</key>
<key alias="forms">Forms</key>
<key alias="analytics">Analytics</key>
</area>
<key alias="forms">Forms</key><key alias="forms">Forms</key></area>
<area alias="help">
<key alias="goTo">go to</key>
<key alias="helpTopicsFor">Help topics for</key>
@@ -1117,7 +1117,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="iWant">I want</key>
<key alias="allContent">all content</key>
<key alias="contentOfType">content of type &quot;%0%&quot;</key>
<key alias="contentOfType">content of type "%0%"</key>
<key alias="from">from</key>
<key alias="websiteRoot">my website</key>
<key alias="where">where</key>
+8
View File
@@ -0,0 +1,8 @@
namespace Umbraco.Web.Models
{
public class RelatedLink : RelatedLinkBase
{
public int? Id { get; internal set; }
internal bool IsDeleted { get; set; }
}
}
+18
View File
@@ -0,0 +1,18 @@
using Newtonsoft.Json;
namespace Umbraco.Web.Models
{
public abstract class RelatedLinkBase
{
[JsonProperty("caption")]
public string Caption { get; set; }
[JsonProperty("link")]
public string Link { get; set; }
[JsonProperty("newWindow")]
public bool NewWindow { get; set; }
[JsonProperty("isInternal")]
public bool IsInternal { get; set; }
[JsonProperty("type")]
public RelatedLinkType Type { get; set; }
}
}
+27
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
}
}
+42
View File
@@ -0,0 +1,42 @@
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Umbraco.Web.Models
{
[TypeConverter(typeof(RelatedLinksTypeConverter))]
public class RelatedLinks : IEnumerable<RelatedLink>
{
private readonly string _propertyData;
private readonly IEnumerable<RelatedLink> _relatedLinks;
public RelatedLinks(IEnumerable<RelatedLink> relatedLinks, string propertyData)
{
_relatedLinks = relatedLinks;
_propertyData = propertyData;
}
/// <summary>
/// Gets the property data.
/// </summary>
internal string PropertyData
{
get
{
return this._propertyData;
}
}
public IEnumerator<RelatedLink> GetEnumerator()
{
return _relatedLinks.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
@@ -0,0 +1,140 @@
// --------------------------------------------------------------------------------------------------------------------
// <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.Configuration;
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>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IPublishedContent))]
[PropertyValueCache(PropertyCacheValue.Object, PropertyCacheLevel.ContentCache)]
[PropertyValueCache(PropertyCacheValue.Source, PropertyCacheLevel.Content)]
[PropertyValueCache(PropertyCacheValue.XPath, PropertyCacheLevel.Content)]
public class ContentPickerPropertyConverter : PropertyValueConverterBase
{
/// <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)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPickerAlias);
}
return false;
}
/// <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();
}
}
}
@@ -13,14 +13,14 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
/// </summary>
public class ImageCropDataSetConverter : TypeConverter
{
private static readonly Type[] ConvertableTypes = new[]
{
typeof(JObject)
};
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
var convertableTypes = new[]
{
typeof(JObject)
};
return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
return ConvertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
|| base.CanConvertFrom(context, destinationType);
}
@@ -0,0 +1,111 @@
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;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
[PropertyValueType(typeof(JArray))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
public class LegacyRelatedLinksEditorValueConvertor : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters == false)
{
return Constants.PropertyEditors.RelatedLinksAlias.Equals(propertyType.PropertyEditorAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return null;
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
{
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<LegacyRelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
}
}
//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<LegacyRelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
}
}
//it's not json, just return the string
return sourceString;
}
}
}
@@ -0,0 +1,104 @@
// --------------------------------------------------------------------------------------------------------------------
// <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>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IPublishedContent))]
[PropertyValueCache(PropertyCacheValue.Object, PropertyCacheLevel.ContentCache)]
[PropertyValueCache(PropertyCacheValue.Source, PropertyCacheLevel.Content)]
[PropertyValueCache(PropertyCacheValue.XPath, PropertyCacheLevel.Content)]
public class MediaPickerPropertyConverter : PropertyValueConverterBase
{
/// <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;
}
}
}
@@ -0,0 +1,51 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.Security;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IPublishedContent))]
[PropertyValueCache(PropertyCacheValue.Object, PropertyCacheLevel.ContentCache)]
[PropertyValueCache(PropertyCacheValue.Source, PropertyCacheLevel.Content)]
[PropertyValueCache(PropertyCacheValue.XPath, PropertyCacheLevel.Content)]
public class MemberPickerPropertyConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.MemberPickerAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var intAttempt = source.TryConvertTo<int>();
if (intAttempt.Success)
return intAttempt.Result;
return null;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
return null;
if (UmbracoContext.Current != null)
{
var membershipHelper = new MembershipHelper(UmbracoContext.Current);
return membershipHelper.GetById((int) source);
}
return null;
}
}
}
@@ -0,0 +1,175 @@
// --------------------------------------------------------------------------------------------------------------------
// <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.Globalization;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Configuration;
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>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<IPublishedContent>))]
[PropertyValueCache(PropertyCacheValue.Object, PropertyCacheLevel.ContentCache)]
[PropertyValueCache(PropertyCacheValue.Source, PropertyCacheLevel.Content)]
[PropertyValueCache(PropertyCacheValue.XPath, PropertyCacheLevel.Content)]
public class MultiNodeTreePickerPropertyConverter : PropertyValueConverterBase
{
/// <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)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias);
}
return false;
}
/// <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;
}
//TODO: Inject an UmbracoHelper and create a GetUmbracoHelper method based on either injected or singleton
if (UmbracoContext.Current != null)
{
var nodeIds = (int[])source;
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.InvariantContains(propertyType.PropertyTypeAlias)) == false)
{
var multiNodeTreePicker = new List<IPublishedContent>();
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);
}
}
}
//TODO: Get rid of this Yield thing
return multiNodeTreePicker.Yield().Where(x => x != null);
}
// return the first nodeId as this is one of the excluded properties that expects a single id
return nodeIds.FirstOrDefault();
}
else
{
return null;
}
}
/// <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;
}
}
}
@@ -0,0 +1,234 @@
// --------------------------------------------------------------------------------------------------------------------
// <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.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The multiple media picker property value converter.
/// </summary>
[DefaultPropertyValueConverter]
public class MultipleMediaPickerPropertyConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
public MultipleMediaPickerPropertyConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
public MultipleMediaPickerPropertyConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
/// <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)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultipleMediaPickerAlias);
}
return false;
}
/// <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);
}
// in v8 should return multiNodeTreePickerEnumerable but for v7 need to return as PublishedContentEnumerable so that string can be returned for legacy compatibility
return new PublishedContentEnumerable(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)
{
// ** This must be cached (U4-8862) **
var multiPickerPreValue =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "multiPicker", StringComparison.InvariantCultureIgnoreCase)).Value;
return multiPickerPreValue != null && multiPickerPreValue.Value.TryConvertTo<bool>().Result;
}
}
}
@@ -1,106 +1,153 @@
using System;
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RelatedLinksPropertyConverter.cs" company="Umbraco">
// Umbraco
// </copyright>
// <summary>
// Defines the RelatedLinksPropertyConverter type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
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;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Web.Models;
using Umbraco.Web.Routing;
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>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(RelatedLinks))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.ContentCache)]
public class RelatedLinksPropertyConverter : PropertyValueConverterBase
{
private readonly UrlProvider _urlProvider;
public RelatedLinksPropertyConverter()
{
}
public RelatedLinksPropertyConverter(UrlProvider urlProvider)
{
if (urlProvider == null) throw new ArgumentNullException("urlProvider");
_urlProvider = urlProvider;
}
/// <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);
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinksAlias);
}
return false;
}
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;
if (source == null)
{
return null;
}
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
var relatedLinksData = JsonConvert.DeserializeObject<IEnumerable<RelatedLinkData>>(sourceString);
var relatedLinks = new List<RelatedLink>();
foreach (var linkData in relatedLinksData)
{
try
var relatedLink = new RelatedLink()
{
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;
Caption = linkData.Caption,
NewWindow = linkData.NewWindow,
IsInternal = linkData.IsInternal,
Type = linkData.Type,
Id = linkData.Internal,
Link = linkData.Link
};
relatedLink = CreateLink(relatedLink);
if (relatedLink.IsDeleted == false)
{
relatedLinks.Add(relatedLink);
}
catch (Exception ex)
else
{
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
LogHelper.Warn<RelatedLinksPropertyConverter>(
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));
}
}
//it's not json, just return the string
return sourceString;
return new RelatedLinks(relatedLinks, sourceString);
}
public override object ConvertSourceToXPath(PublishedPropertyType propertyType, object source, bool preview)
private RelatedLink CreateLink(RelatedLink link)
{
if (source == null) return null;
var sourceString = source.ToString();
if (sourceString.DetectIsJson())
if (link.IsInternal && link.Id != null)
{
try
if (_urlProvider == null && UmbracoContext.Current == null)
{
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();
return null;
}
catch (Exception ex)
var urlProvider = _urlProvider ?? UmbracoContext.Current.UrlProvider;
link.Link = urlProvider.GetUrl((int)link.Id);
if (link.Link.Equals("#"))
{
LogHelper.Error<RelatedLinksEditorValueConvertor>("Could not parse the string " + sourceString + " to a json object", ex);
link.IsDeleted = true;
link.Link = link.Id.ToString();
}
else
{
link.IsDeleted = false;
}
}
//it's not json, just return the string
return sourceString;
return link;
}
internal class RelatedLinkData : RelatedLinkBase
{
[JsonProperty("internal")]
public int? Internal { get; set; }
[JsonProperty("edit")]
public bool Edit { get; set; }
[JsonProperty("internalName")]
public string InternalName { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
}
}
}
}
@@ -15,14 +15,15 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// A value converter for TinyMCE that will ensure any macro content is rendered properly even when
/// used dynamically.
/// </summary>
/// A value converter for TinyMCE that will ensure any macro content is rendered properly even when
/// used dynamically.
/// </summary>
// because that version of RTE converter parses {locallink} and executes macros, when going from
// data to source, its source value has to be cached at the request level, because we have no idea
// what the macros may depend on actually. An so, object and xpath need to follow... request, too.
// note: the TinyMceValueConverter is NOT inherited, so the PropertyValueCache attribute here is not
// actually required (since Request is default) but leave it here to be absolutely explicit.
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IHtmlString))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
public class RteMacroRenderingValueConverter : TinyMceValueConverter
@@ -10,11 +10,12 @@ using Umbraco.Web.Templates;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
public class TextStringValueConverter : PropertyValueConverterBase
{
private readonly static string[] PropertyTypeAliases =
private static readonly string[] PropertyTypeAliases =
{
Constants.PropertyEditors.TextboxAlias,
Constants.PropertyEditors.TextboxMultipleAlias
@@ -0,0 +1,97 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Web.Models;
namespace Umbraco.Web
{
public class RelatedLinksTypeConverter : TypeConverter
{
private readonly UmbracoHelper _umbracoHelper;
public RelatedLinksTypeConverter(UmbracoHelper umbracoHelper)
{
_umbracoHelper = umbracoHelper;
}
public RelatedLinksTypeConverter()
{
}
private static readonly Type[] ConvertableTypes = new[]
{
typeof(JArray)
};
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ConvertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
|| base.CanConvertFrom(context, destinationType);
}
public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType)
{
var relatedLinks = value as RelatedLinks;
if (relatedLinks == null)
return null;
if (TypeHelper.IsTypeAssignableFrom<JArray>(destinationType))
{
// Conversion to JArray taken from old value converter
var obj = JsonConvert.DeserializeObject<JArray>(relatedLinks.PropertyData);
var umbracoHelper = GetUmbracoHelper();
//update the internal links if we have a context
if (umbracoHelper != null)
{
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 = umbracoHelper.NiceUrl(linkId);
a["link"] = link;
}
}
}
}
return obj;
}
return base.ConvertTo(context, culture, value, destinationType);
}
private UmbracoHelper GetUmbracoHelper()
{
if (_umbracoHelper != null)
return _umbracoHelper;
if (UmbracoContext.Current == null)
{
LogHelper.Warn<RelatedLinksTypeConverter>("Cannot create an UmbracoHelper the UmbracoContext is null");
return null;
}
//DO NOT assign to _umbracoHelper variable, this is a singleton class and we cannot assign this based on an UmbracoHelper which is request based
return new UmbracoHelper(UmbracoContext.Current);
}
}
}
+14 -2
View File
@@ -186,13 +186,14 @@
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.configuration" />
<Reference Include="System.Data">
@@ -378,10 +379,14 @@
<Compile Include="Models\Mapping\ContentTypeUdiResolver.cs" />
<Compile Include="Models\Mapping\LockedCompositionsResolver.cs" />
<Compile Include="Models\Mapping\PropertyGroupDisplayResolver.cs" />
<Compile Include="Models\RelatedLink.cs" />
<Compile Include="Models\Mapping\TemplateModelMapper.cs" />
<Compile Include="Models\PackageInstallResult.cs" />
<Compile Include="Models\RelatedLinkBase.cs" />
<Compile Include="Models\ContentEditing\CodeFileDisplay.cs" />
<Compile Include="Models\SendCodeViewModel.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" />
@@ -400,12 +405,19 @@
<Compile Include="PropertyEditors\DatePreValueEditor.cs" />
<Compile Include="PropertyEditors\DateTimePreValueEditor.cs" />
<Compile Include="PropertyEditors\DecimalPropertyEditor.cs" />
<Compile Include="PropertyEditors\ValueConverters\ContentPickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ParameterEditors\MultipleContentPickerParameterEditor.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropDataSetConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\LegacyRelatedLinksEditorValueConvertor.cs" />
<Compile Include="PropertyEditors\ValueConverters\MediaPickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MemberPickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MultiNodeTreePickerPropertyConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MultipleMediaPickerPropertyConverter.cs" />
<Compile Include="Routing\RedirectTrackingEventHandler.cs" />
<Compile Include="Editors\RedirectUrlManagementController.cs" />
<Compile Include="Models\ContentEditing\RedirectUrlSearchResults.cs" />
<Compile Include="RelatedLinksTypeConverter.cs" />
<Compile Include="RouteDataExtensions.cs" />
<Compile Include="Routing\ContentFinderByRedirectUrl.cs" />
<Compile Include="Scheduling\LatchedBackgroundTaskBase.cs" />
+5 -1
View File
@@ -26,8 +26,12 @@
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net45" />
<package id="System.Threading.Tasks.Dataflow" version="4.6.0" targetFramework="net45" />
<package id="UrlRewritingNet.UrlRewriter" version="2.0.7" targetFramework="net45" />
<package id="xmlrpcnet" version="2.5.0" targetFramework="net45" />