From c96cd09dba012e87eabb133196ce0fd6f82c3067 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Tue, 9 Apr 2019 15:33:53 +0200 Subject: [PATCH] Add RTE media url -> localLink migration --- .../Migrations/Upgrade/UmbracoPlan.cs | 2 + ...nvertTinyMceAndGridMediaUrlsToLocalLink.cs | 90 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 3 files changed, 93 insertions(+) create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_1_0/ConvertTinyMceAndGridMediaUrlsToLocalLink.cs diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index fa24cba21f..cf06a16d31 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -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("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}"); To("{78BAF571-90D0-4D28-8175-EF96316DA789}"); To("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}"); + To("{B69B6E8C-A769-4044-A27E-4A4E18D1645A}"); //FINAL diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_1_0/ConvertTinyMceAndGridMediaUrlsToLocalLink.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_1_0/ConvertTinyMceAndGridMediaUrlsToLocalLink.cs new file mode 100644 index 0000000000..ab8e1cd4d6 --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_1_0/ConvertTinyMceAndGridMediaUrlsToLocalLink.cs @@ -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( + @"(]*href="")(\/ media[^""\?]*)([^>]*>)", + RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + + var sqlPropertyData = Sql() + .Select() + .AndSelect() + .AndSelect() + .From() + .InnerJoin().On((left, right) => left.PropertyTypeId == right.Id) + .InnerJoin().On((left, right) => left.DataTypeId == right.NodeId) + .Where(x => + x.EditorAlias == Constants.PropertyEditors.Aliases.TinyMce || + x.EditorAlias == Constants.PropertyEditors.Aliases.Grid); + + var properties = Database.Fetch(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(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()); + } + } + + property.TextValue = JsonConvert.SerializeObject(obj); + } + else + { + property.TextValue = UpdateMediaUrls(mediaLinkPattern, value); + } + + Database.Update(property); + } + + Context.AddPostMigration(); + } + + 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}"; + }); + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 68091fb3a9..8005049742 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -219,6 +219,7 @@ +