Add RTE media url -> localLink migration

This commit is contained in:
Rasmus John Pedersen
2019-04-09 15:33:53 +02:00
parent a96bca5fab
commit c96cd09dba
3 changed files with 93 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
using Umbraco.Core.Migrations.Upgrade.V_8_1_0;
namespace Umbraco.Core.Migrations.Upgrade
{
@@ -139,6 +140,7 @@ namespace Umbraco.Core.Migrations.Upgrade
To<RenameLabelAndRichTextPropertyEditorAliases>("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
To<MergeDateAndDateTimePropertyEditor>("{78BAF571-90D0-4D28-8175-EF96316DA789}");
To<ChangeNuCacheJsonFormat>("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
To<ConvertTinyMceAndGridMediaUrlsToLocalLink>("{B69B6E8C-A769-4044-A27E-4A4E18D1645A}");
//FINAL

View File

@@ -0,0 +1,90 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Migrations.PostMigrations;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Services;
namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
{
public class ConvertTinyMceAndGridMediaUrlsToLocalLink : MigrationBase
{
private readonly IMediaService _mediaService;
public ConvertTinyMceAndGridMediaUrlsToLocalLink(IMigrationContext context, IMediaService mediaService) : base(context)
{
_mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService));
}
public override void Migrate()
{
var mediaLinkPattern = new Regex(
@"(<a[^>]*href="")(\/ media[^""\?]*)([^>]*>)",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
var sqlPropertyData = Sql()
.Select<PropertyDataDto>()
.AndSelect<PropertyTypeDto>()
.AndSelect<DataTypeDto>()
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
.InnerJoin<DataTypeDto>().On<PropertyTypeDto, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
.Where<DataTypeDto>(x =>
x.EditorAlias == Constants.PropertyEditors.Aliases.TinyMce ||
x.EditorAlias == Constants.PropertyEditors.Aliases.Grid);
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
foreach (var property in properties)
{
var value = property.TextValue;
if (string.IsNullOrWhiteSpace(value)) continue;
if (property.PropertyTypeDto.DataTypeDto.EditorAlias == Constants.PropertyEditors.Aliases.Grid)
{
var obj = JsonConvert.DeserializeObject<JObject>(value);
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
foreach (var control in allControls.SelectMany(c => c))
{
var controlValue = control["value"];
if (controlValue.Type == JTokenType.String)
{
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
}
}
property.TextValue = JsonConvert.SerializeObject(obj);
}
else
{
property.TextValue = UpdateMediaUrls(mediaLinkPattern, value);
}
Database.Update(property);
}
Context.AddPostMigration<RebuildPublishedSnapshot>();
}
private string UpdateMediaUrls(Regex mediaLinkPattern, string value)
{
return mediaLinkPattern.Replace(value, match =>
{
// match groups:
// - 1 = from the beginning of the a tag until href attribute value begins
// - 2 = the href attribute value excluding the querystring (if present)
// - 3 = anything after group 2 until the a tag is closed
var href = match.Groups[2].Value;
var media = _mediaService.GetMediaByPath(href);
return media == null
? match.Value
: $"{match.Groups[1].Value}/{{localLink:{media.GetUdi()}}}{match.Groups[3].Value}";
});
}
}
}

View File

@@ -219,6 +219,7 @@
<Compile Include="Mapping\MapDefinitionCollectionBuilder.cs" />
<Compile Include="Mapping\IMapDefinition.cs" />
<Compile Include="Mapping\UmbracoMapper.cs" />
<Compile Include="Migrations\Upgrade\V_8_1_0\ConvertTinyMceAndGridMediaUrlsToLocalLink.cs" />
<Compile Include="Models\CultureImpact.cs" />
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
<Compile Include="Persistence\Dtos\PropertyTypeCommonDto.cs" />