Remove obsoleted RelatedLinks picker (replaced by Multi URL Picker)

This commit is contained in:
Sebastiaan Janssen
2019-01-23 08:56:20 +01:00
parent 78319bae9e
commit fedf0c78de
20 changed files with 7 additions and 626 deletions

View File

@@ -118,12 +118,7 @@ namespace Umbraco.Core
/// RadioButton list.
/// </summary>
public const string RadioButtonList = "Umbraco.RadioButtonList";
/// <summary>
/// Related Links.
/// </summary>
public const string RelatedLinks = "Umbraco.RelatedLinks";
/// <summary>
/// Slider.
/// </summary>

View File

@@ -135,7 +135,7 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1047, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1047", SortOrder = 2, UniqueId = new Guid("1EA2E01F-EBD8-4CE1-8D71-6B1149E63548"), Text = "Member Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Related Links", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Multi URL Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
}
private void CreateLockData()
@@ -301,7 +301,7 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1048, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1049, EditorAlias = Constants.PropertyEditors.Aliases.MediaPicker, DbType = "Ntext",
Configuration = "{\"multiPicker\":1}" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.RelatedLinks, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1050, EditorAlias = Constants.PropertyEditors.Aliases.MultiUrlPicker, DbType = "Ntext" });
}
private void CreateRelationTypeData()

View File

@@ -16,7 +16,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
RenameDataType(Constants.PropertyEditors.Aliases.MediaPicker + "2", Constants.PropertyEditors.Aliases.MediaPicker);
RenameDataType(Constants.PropertyEditors.Aliases.MemberPicker + "2", Constants.PropertyEditors.Aliases.MemberPicker);
RenameDataType(Constants.PropertyEditors.Aliases.MultiNodeTreePicker + "2", Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
RenameDataType(Constants.PropertyEditors.Aliases.RelatedLinks + "2", Constants.PropertyEditors.Aliases.RelatedLinks);
RenameDataType("Umbraco.TextboxMultiple", Constants.PropertyEditors.Aliases.TextArea, false);
RenameDataType("Umbraco.Textbox", Constants.PropertyEditors.Aliases.TextBox, false);
}

View File

@@ -279,7 +279,7 @@ AnotherContentFinder
public void GetDataEditors()
{
var types = _typeLoader.GetDataEditors();
Assert.AreEqual(40, types.Count());
Assert.AreEqual(39, types.Count());
}
/// <summary>

View File

@@ -2215,7 +2215,7 @@ namespace Umbraco.Tests.Services
Assert.That(sut.GetValue<Udi>("contentPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Document, new Guid("74ECA1D4-934E-436A-A7C7-36CC16D4095C"))));
Assert.That(sut.GetValue<Udi>("mediaPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Media, new Guid("44CB39C8-01E5-45EB-9CF8-E70AAF2D1691"))));
Assert.That(sut.GetValue<Udi>("memberPicker"), Is.EqualTo(Udi.Create(Constants.UdiEntityType.Member, new Guid("9A50A448-59C0-4D42-8F93-4F1D55B0F47D"))));
Assert.That(sut.GetValue<string>("relatedLinks"), Is.EqualTo("<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>"));
Assert.That(sut.GetValue<string>("multiUrlPicker"), Is.EqualTo("[{\"name\":\"https://test.com\",\"url\":\"https://test.com\"}]"));
Assert.That(sut.GetValue<string>("tags"), Is.EqualTo("this,is,tags"));
}

View File

@@ -132,7 +132,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
content.SetValue("contentPicker", Udi.Create(Constants.UdiEntityType.Document, new Guid("74ECA1D4-934E-436A-A7C7-36CC16D4095C")).ToString());
content.SetValue("mediaPicker", Udi.Create(Constants.UdiEntityType.Media, new Guid("44CB39C8-01E5-45EB-9CF8-E70AAF2D1691")).ToString());
content.SetValue("memberPicker", Udi.Create(Constants.UdiEntityType.Member, new Guid("9A50A448-59C0-4D42-8F93-4F1D55B0F47D")).ToString());
content.SetValue("relatedLinks", "<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>");
content.SetValue("multiUrlPicker", "[{\"name\":\"https://test.com\",\"url\":\"https://test.com\"}]");
content.SetValue("tags", "this,is,tags");
return content;

View File

@@ -370,7 +370,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.ContentPicker, ValueStorageType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeId = 1046 });
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MediaPicker, ValueStorageType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeId = 1048 });
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MemberPicker, ValueStorageType.Integer) { Alias = "memberPicker", Name = "Member Picker", Mandatory = false, SortOrder = 18, DataTypeId = 1047 });
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.RelatedLinks, ValueStorageType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeId = 1050 });
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.MultiUrlPicker, ValueStorageType.Nvarchar) { Alias = "multiUrlPicker", Name = "Multi URL Picker", Mandatory = false, SortOrder = 21, DataTypeId = 1050 });
contentCollection.Add(new PropertyType(Constants.PropertyEditors.Aliases.Tags, ValueStorageType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeId = 1041 });
contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });

View File

@@ -29,30 +29,5 @@ namespace Umbraco.Tests.Web.Mvc
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
Assert.AreEqual("<div style=\"color:red;\" onclick=\"void();\">hello world</div>", output.ToHtmlString());
}
[Test]
public void GetRelatedLinkHtml_Simple()
{
var relatedLink = new Umbraco.Web.Models.RelatedLink {
Caption = "Link Caption",
NewWindow = true,
Link = "https://www.google.com/"
};
var output = _htmlHelper.GetRelatedLinkHtml(relatedLink);
Assert.AreEqual("<a href=\"https://www.google.com/\" target=\"_blank\">Link Caption</a>", output.ToHtmlString());
}
[Test]
public void GetRelatedLinkHtml_HtmlAttributes()
{
var relatedLink = new Umbraco.Web.Models.RelatedLink
{
Caption = "Link Caption",
NewWindow = true,
Link = "https://www.google.com/"
};
var output = _htmlHelper.GetRelatedLinkHtml(relatedLink, new { @class = "test-class"});
Assert.AreEqual("<a class=\"test-class\" href=\"https://www.google.com/\" target=\"_blank\">Link Caption</a>", output.ToHtmlString());
}
}
}

View File

@@ -830,39 +830,5 @@ namespace Umbraco.Web
}
#endregion
#region RelatedLink
/// <summary>
/// Renders an anchor element for a RelatedLink instance.
/// Format: &lt;a href=&quot;relatedLink.Link&quot; target=&quot;_blank/_self&quot;&gt;relatedLink.Caption&lt;/a&gt;
/// </summary>
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
/// <param name="relatedLink">The RelatedLink instance</param>
/// <returns>An anchor element </returns>
public static MvcHtmlString GetRelatedLinkHtml(this HtmlHelper htmlHelper, RelatedLink relatedLink)
{
return htmlHelper.GetRelatedLinkHtml(relatedLink, null);
}
/// <summary>
/// Renders an anchor element for a RelatedLink instance, accepting htmlAttributes.
/// Format: &lt;a href=&quot;relatedLink.Link&quot; target=&quot;_blank/_self&quot; htmlAttributes&gt;relatedLink.Caption&lt;/a&gt;
/// </summary>
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
/// <param name="relatedLink">The RelatedLink instance</param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
/// <returns></returns>
public static MvcHtmlString GetRelatedLinkHtml(this HtmlHelper htmlHelper, RelatedLink relatedLink, object htmlAttributes)
{
var tagBuilder = new TagBuilder("a");
tagBuilder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
tagBuilder.MergeAttribute("href", relatedLink.Link);
tagBuilder.MergeAttribute("target", relatedLink.NewWindow ? "_blank" : "_self");
tagBuilder.InnerHtml = HttpUtility.HtmlEncode(relatedLink.Caption);
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}
#endregion
}
}

View File

@@ -1,11 +0,0 @@
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Models
{
public class RelatedLink : RelatedLinkBase
{
public int? Id { get; internal set; }
internal bool IsDeleted { get; set; }
public IPublishedContent Content { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
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; }
}
}

View File

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

View File

@@ -1,42 +0,0 @@
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();
}
}
}

View File

@@ -1,13 +0,0 @@
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
/// <summary>
/// Represents the configuration for the related links value editor.
/// </summary>
public class RelatedLinksConfiguration
{
[ConfigurationField("max", "Maximum number of links", "number", Description = "Enter the maximum amount of links to be added, enter 0 for unlimited")]
public int Maximum { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
using System.Collections.Generic;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
/// <summary>
/// Represents the configuration editor for the related links value editor.
/// </summary>
public class RelatedLinksConfigurationEditor : ConfigurationEditor
{
public override IDictionary<string, object> ToValueEditor(object configuration)
{
var d = base.ToValueEditor(configuration);
d["idType"] = "udi";
return d;
}
}
}

View File

@@ -1,16 +0,0 @@
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[DataEditor(Constants.PropertyEditors.Aliases.RelatedLinks, "Related links", "relatedlinks", ValueType = ValueTypes.Json, Icon = "icon-thumbnail-list", Group = "pickers")]
public class RelatedLinksPropertyEditor : DataEditor
{
public RelatedLinksPropertyEditor(ILogger logger)
: base(logger)
{ }
protected override IConfigurationEditor CreateConfigurationEditor() => new RelatedLinksConfigurationEditor();
}
}

View File

@@ -1,132 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Services;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
public class RelatedLinksLegacyValueConverter : PropertyValueConverterBase
{
private static readonly string[] MatchingEditors = {
Constants.PropertyEditors.Aliases.RelatedLinks
};
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ILogger _logger;
private readonly ServiceContext _services;
public RelatedLinksLegacyValueConverter(IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, ILogger logger)
{
_umbracoContextAccessor = umbracoContextAccessor;
_services = services;
_logger = logger;
}
public override bool IsConverter(PublishedPropertyType propertyType)
=> MatchingEditors.Contains(propertyType.EditorAlias);
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
=> typeof (JArray);
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
public override object ConvertSourceToIntermediate(IPublishedElement owner, 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(_umbracoContextAccessor.UmbracoContext, _services);
foreach (var a in obj)
{
var type = a.Value<string>("type");
if (type.IsNullOrWhiteSpace() == false)
{
if (type == "internal")
{
switch (propertyType.EditorAlias)
{
case Constants.PropertyEditors.Aliases.RelatedLinks:
var strLinkId = a.Value<string>("link");
var udiAttempt = strLinkId.TryConvertTo<Udi>();
if (udiAttempt)
{
var content = helper.PublishedContent(udiAttempt.Result);
if (content == null) break;
a["link"] = helper.Url(content.Id);
}
break;
}
}
}
}
}
return obj;
}
catch (Exception ex)
{
_logger.Error<RelatedLinksLegacyValueConverter>(ex, "Could not parse the string '{Json}' to a json object", sourceString);
}
}
//it's not json, just return the string
return sourceString;
}
public override object ConvertIntermediateToXPath(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, 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);
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)
{
_logger.Error<RelatedLinksLegacyValueConverter>(ex, "Could not parse the string '{Json}' to a json object", sourceString);
}
}
//it's not json, just return the string
return sourceString;
}
}
}

View File

@@ -1,169 +0,0 @@
using System;
using System.Collections.Generic;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
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;
using Umbraco.Web.PublishedCache;
namespace Umbraco.Web.PropertyEditors.ValueConverters
{
/// <summary>
/// The related links property value converter.
/// </summary>
[DefaultPropertyValueConverter(typeof(RelatedLinksLegacyValueConverter), typeof(JsonValueConverter))]
public class RelatedLinksValueConverter : PropertyValueConverterBase
{
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly ILogger _logger;
public RelatedLinksValueConverter(IPublishedSnapshotAccessor publishedSnapshotAccessor, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger)
{
_publishedSnapshotAccessor = publishedSnapshotAccessor;
_umbracoContextAccessor = umbracoContextAccessor;
_logger = logger;
}
/// <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)
=> propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.RelatedLinks);
public override Type GetPropertyValueType(PublishedPropertyType propertyType)
=> typeof (JArray);
public override PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
public override object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null) return null;
var sourceString = source.ToString();
var relatedLinksData = JsonConvert.DeserializeObject<IEnumerable<RelatedLink>>(sourceString);
var relatedLinks = new List<RelatedLink>();
foreach (var linkData in relatedLinksData)
{
var relatedLink = new RelatedLink
{
Caption = linkData.Caption,
NewWindow = linkData.NewWindow,
IsInternal = linkData.IsInternal,
Type = linkData.Type,
Link = linkData.Link
};
int contentId;
if (int.TryParse(relatedLink.Link, out contentId))
{
relatedLink.Id = contentId;
relatedLink = CreateLink(relatedLink);
}
else
{
var strLinkId = linkData.Link;
var udiAttempt = strLinkId.TryConvertTo<GuidUdi>();
if (udiAttempt.Success && udiAttempt.Result != null)
{
var content = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(udiAttempt.Result.Guid);
if (content != null)
{
relatedLink.Id = content.Id;
relatedLink = CreateLink(relatedLink);
relatedLink.Content = content;
}
}
}
if (relatedLink.IsDeleted == false)
{
relatedLinks.Add(relatedLink);
}
else
{
_logger.Warn<RelatedLinksValueConverter>("Related Links value converter skipped a link as the node has been unpublished/deleted (Internal Link NodeId: {RelatedLinkNodeId}, Link Caption: '{RelatedLinkCaption}')", relatedLink.Link, relatedLink.Caption);
}
}
return new RelatedLinks(relatedLinks, sourceString);
}
private RelatedLink CreateLink(RelatedLink link)
{
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
if (link.IsInternal && link.Id != null)
{
if (umbracoContext == null)
return null;
var urlProvider = umbracoContext.UrlProvider;
link.Link = urlProvider.GetUrl((int)link.Id);
if (link.Link.Equals("#"))
{
link.IsDeleted = true;
link.Link = link.Id.ToString();
}
else
{
link.IsDeleted = false;
}
}
return link;
}
public override object ConvertIntermediateToXPath(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
{
if (inter == null) return null;
var sourceString = inter.ToString();
if (sourceString.DetectIsJson())
{
try
{
var obj = JsonConvert.DeserializeObject<Array>(sourceString);
var d = new XmlDocument();
var e = d.CreateElement("links");
d.AppendChild(e);
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)
{
_logger.Error<RelatedLinksValueConverter>(ex, "Could not parse the string {Json} to a json object", sourceString);
}
}
//it's not json, just return the string
return sourceString;
}
}
}

View File

@@ -1,98 +0,0 @@
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.Core.Composing;
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.Url(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)
{
Current.Logger.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, Current.Services);
}
}
}

View File

@@ -404,10 +404,6 @@
<Compile Include="Models\Mapping\ContentItemDisplayVariationResolver.cs" />
<Compile Include="Models\PublishedContent\HttpContextVariationContextAccessor.cs" />
<Compile Include="Models\PublishedContent\PublishedValueFallback.cs" />
<Compile Include="Models\RelatedLink.cs" />
<Compile Include="Models\RelatedLinkBase.cs" />
<Compile Include="Models\RelatedLinks.cs" />
<Compile Include="Models\RelatedLinkType.cs" />
<Compile Include="Models\SendCodeViewModel.cs" />
<Compile Include="Models\Trees\ExportMember.cs" />
<Compile Include="Models\UserTourStatus.cs" />
@@ -453,9 +449,6 @@
<Compile Include="PropertyEditors\NestedContentPropertyEditor.cs" />
<Compile Include="PropertyEditors\ParameterEditors\MultipleContentPickerParameterEditor.cs" />
<Compile Include="PropertyEditors\PropertyEditorsComponent.cs" />
<Compile Include="PropertyEditors\RelatedLinksPropertyEditor.cs" />
<Compile Include="PropertyEditors\RelatedLinksConfiguration.cs" />
<Compile Include="PropertyEditors\RelatedLinksConfigurationEditor.cs" />
<Compile Include="PropertyEditors\RichTextConfiguration.cs" />
<Compile Include="PropertyEditors\SliderConfigurationEditor.cs" />
<Compile Include="PropertyEditors\TagConfigurationEditor.cs" />
@@ -471,7 +464,6 @@
<Compile Include="PropertyEditors\ValueConverters\NestedContentManyValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\NestedContentValueConverterBase.cs" />
<Compile Include="PropertyEditors\ValueConverters\NestedContentSingleValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\RelatedLinksLegacyValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MediaPickerValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MemberPickerValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MultiNodeTreePickerValueConverter.cs" />
@@ -535,7 +527,6 @@
<Compile Include="PublishedCache\XmlPublishedCache\XmlStoreFilePersister.cs" />
<Compile Include="PublishedElementExtensions.cs" />
<Compile Include="PublishedModels\DummyClassSoThatPublishedModelsNamespaceExists.cs" />
<Compile Include="RelatedLinksTypeConverter.cs" />
<Compile Include="Routing\ContentFinderByUrl.cs" />
<Compile Include="Routing\ContentFinderByUrlAndTemplate.cs" />
<Compile Include="Routing\ContentFinderCollection.cs" />
@@ -860,7 +851,6 @@
<Compile Include="PropertyEditors\TagsPropertyEditor.cs" />
<Compile Include="PropertyEditors\UploadFileTypeValidator.cs" />
<Compile Include="PropertyEditors\UserPickerPropertyEditor.cs" />
<Compile Include="PropertyEditors\ValueConverters\RelatedLinksValueConverter.cs" />
<Compile Include="PropertyEditors\ValueListConfigurationEditor.cs" />
<Compile Include="PublishedContentQuery.cs" />
<Compile Include="ImageCropperTemplateExtensions.cs" />