From 92480b8446e498ffefe36fbaf83a42a65ed2d180 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Thu, 10 Mar 2022 16:29:56 +0100 Subject: [PATCH] Changes in the editors so we can track the items --- .../MultipleMediaPickerParameterEditor.cs | 57 +++++++++++++++++- .../PropertyEditors/GridPropertyEditor.cs | 58 +++++++++++++++++-- .../PropertyEditors/RichTextPropertyEditor.cs | 53 +++++++++++++++-- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs index d8f74b1b28..f4be58b753 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs @@ -1,5 +1,8 @@ -using Microsoft.Extensions.Logging; -using Umbraco.Cms.Core.Hosting; +using System; +using System.Collections.Generic; +using Umbraco.Cms.Core.IO; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Editors; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; @@ -26,5 +29,55 @@ namespace Umbraco.Cms.Core.PropertyEditors.ParameterEditors { DefaultConfiguration.Add("multiPicker", "1"); } + + protected override IDataValueEditor CreateValueEditor() => DataValueEditorFactory.Create(Attribute); + + internal class MultipleMediaPickerPropertyValueEditor : DataValueEditor, IDataValueReference + { + private readonly IEntityService _entityService; + + public MultipleMediaPickerPropertyValueEditor( + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + DataEditorAttribute attribute, + IEntityService entityService) + : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) + { + _entityService = entityService; + } + + public IEnumerable GetReferences(object value) + { + var asString = value is string str ? str : value?.ToString(); + + if (string.IsNullOrEmpty(asString)) + { + yield break; + } + + foreach (var udiStr in asString.Split(',')) + { + if (UdiParser.TryParse(udiStr, out Udi udi)) + { + yield return new UmbracoEntityReference(udi); + } + + // this is needed to support the legacy case when the multiple media picker parameter editor stores ints not udis + if (int.TryParse(udiStr, out var id)) + { + Attempt guidAttempt = _entityService.GetKey(id, UmbracoObjectTypes.Media); + Guid guid = guidAttempt.Success ? guidAttempt.Result : Guid.Empty; + + if (guid != Guid.Empty) + { + yield return new UmbracoEntityReference(new GuidUdi(Constants.UdiEntityType.Media, guid)); + } + + } + } + } + } } } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs index f149757919..c3d8be8f50 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Media; @@ -14,6 +15,8 @@ using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Core.Templates; +using Umbraco.Cms.Infrastructure.Templates; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Core.PropertyEditors @@ -37,6 +40,7 @@ namespace Umbraco.Cms.Core.PropertyEditors private readonly RichTextEditorPastedImages _pastedImages; private readonly HtmlLocalLinkParser _localLinkParser; private readonly IImageUrlGenerator _imageUrlGenerator; + private readonly IHtmlMacroParameterParser _macroParameterParser; public GridPropertyEditor( IDataValueEditorFactory dataValueEditorFactory, @@ -45,7 +49,8 @@ namespace Umbraco.Cms.Core.PropertyEditors RichTextEditorPastedImages pastedImages, HtmlLocalLinkParser localLinkParser, IIOHelper ioHelper, - IImageUrlGenerator imageUrlGenerator) + IImageUrlGenerator imageUrlGenerator, + IHtmlMacroParameterParser macroParameterParser) : base(dataValueEditorFactory) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; @@ -54,6 +59,20 @@ namespace Umbraco.Cms.Core.PropertyEditors _pastedImages = pastedImages; _localLinkParser = localLinkParser; _imageUrlGenerator = imageUrlGenerator; + _macroParameterParser = macroParameterParser; + } + + [Obsolete("Use the constructor which takes an IHtmlMacroParameterParser instead")] + public GridPropertyEditor( + IDataValueEditorFactory dataValueEditorFactory, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + HtmlImageSourceParser imageSourceParser, + RichTextEditorPastedImages pastedImages, + HtmlLocalLinkParser localLinkParser, + IIOHelper ioHelper, + IImageUrlGenerator imageUrlGenerator) + : this (dataValueEditorFactory, backOfficeSecurityAccessor, imageSourceParser, pastedImages, localLinkParser, ioHelper, imageUrlGenerator, StaticServiceProvider.Instance.GetRequiredService()) + { } public override IPropertyIndexValueFactory PropertyIndexValueFactory => new GridPropertyIndexValueFactory(); @@ -74,6 +93,7 @@ namespace Umbraco.Cms.Core.PropertyEditors private readonly RichTextPropertyEditor.RichTextPropertyValueEditor _richTextPropertyValueEditor; private readonly MediaPickerPropertyEditor.MediaPickerPropertyValueEditor _mediaPickerPropertyValueEditor; private readonly IImageUrlGenerator _imageUrlGenerator; + private readonly IHtmlMacroParameterParser _macroParameterParser; public GridPropertyValueEditor( IDataValueEditorFactory dataValueEditorFactory, @@ -85,7 +105,8 @@ namespace Umbraco.Cms.Core.PropertyEditors IShortStringHelper shortStringHelper, IImageUrlGenerator imageUrlGenerator, IJsonSerializer jsonSerializer, - IIOHelper ioHelper) + IIOHelper ioHelper, + IHtmlMacroParameterParser macroParameterParser) : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; @@ -96,6 +117,25 @@ namespace Umbraco.Cms.Core.PropertyEditors _mediaPickerPropertyValueEditor = dataValueEditorFactory.Create(attribute); _imageUrlGenerator = imageUrlGenerator; + _macroParameterParser = macroParameterParser; + } + + [Obsolete("Use the constructor which takes an IHtmlMacroParameterParser instead")] + public GridPropertyValueEditor( + IDataValueEditorFactory dataValueEditorFactory, + DataEditorAttribute attribute, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + ILocalizedTextService localizedTextService, + HtmlImageSourceParser imageSourceParser, + RichTextEditorPastedImages pastedImages, + IShortStringHelper shortStringHelper, + IImageUrlGenerator imageUrlGenerator, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper) + : this (dataValueEditorFactory, attribute, backOfficeSecurityAccessor, localizedTextService, + imageSourceParser, pastedImages, shortStringHelper, imageUrlGenerator, jsonSerializer, ioHelper, + StaticServiceProvider.Instance.GetRequiredService()) + { } /// @@ -120,7 +160,7 @@ namespace Umbraco.Cms.Core.PropertyEditors var mediaParent = config?.MediaParentId; var mediaParentId = mediaParent == null ? Guid.Empty : mediaParent.Guid; - var grid = DeserializeGridValue(rawJson, out var rtes, out _); + var grid = DeserializeGridValue(rawJson, out var rtes, out _, out _); var userId = _backOfficeSecurityAccessor?.BackOfficeSecurity?.CurrentUser?.Id ?? Constants.Security.SuperUserId; @@ -154,7 +194,7 @@ namespace Umbraco.Cms.Core.PropertyEditors if (val.IsNullOrWhiteSpace()) return string.Empty; - var grid = DeserializeGridValue(val, out var rtes, out _); + var grid = DeserializeGridValue(val, out var rtes, out _, out _); //process the rte values foreach (var rte in rtes.ToList()) @@ -168,7 +208,7 @@ namespace Umbraco.Cms.Core.PropertyEditors return grid; } - private GridValue DeserializeGridValue(string rawJson, out IEnumerable richTextValues, out IEnumerable mediaValues) + private GridValue DeserializeGridValue(string rawJson, out IEnumerable richTextValues, out IEnumerable mediaValues, out IEnumerable macroValues) { var grid = JsonConvert.DeserializeObject(rawJson); @@ -177,6 +217,9 @@ namespace Umbraco.Cms.Core.PropertyEditors richTextValues = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "rte"); mediaValues = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "media"); + // Find all the macros + macroValues = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "macro"); + return grid; } @@ -192,7 +235,7 @@ namespace Umbraco.Cms.Core.PropertyEditors if (rawJson.IsNullOrWhiteSpace()) yield break; - DeserializeGridValue(rawJson, out var richTextEditorValues, out var mediaValues); + DeserializeGridValue(rawJson, out var richTextEditorValues, out var mediaValues, out var macroValues); foreach (var umbracoEntityReference in richTextEditorValues.SelectMany(x => _richTextPropertyValueEditor.GetReferences(x.Value))) @@ -201,6 +244,9 @@ namespace Umbraco.Cms.Core.PropertyEditors foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value.HasValues) .SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"]))) yield return umbracoEntityReference; + + foreach (var umbracoEntityReference in _macroParameterParser.FindUmbracoEntityReferencesFromGridControlMacros(macroValues)) + yield return umbracoEntityReference; } } } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs index 1cfbc3449e..18c3fe0902 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -3,8 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.Extensions.Logging; -using Umbraco.Cms.Core.Hosting; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Models; @@ -16,6 +15,8 @@ using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Core.Templates; using Umbraco.Cms.Infrastructure.Examine; using Umbraco.Cms.Infrastructure.Macros; +using Umbraco.Cms.Infrastructure.Templates; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Core.PropertyEditors @@ -36,12 +37,13 @@ namespace Umbraco.Cms.Core.PropertyEditors private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; private readonly HtmlImageSourceParser _imageSourceParser; private readonly HtmlLocalLinkParser _localLinkParser; + private readonly IHtmlMacroParameterParser _macroParameterParser; private readonly RichTextEditorPastedImages _pastedImages; private readonly IIOHelper _ioHelper; private readonly IImageUrlGenerator _imageUrlGenerator; /// - /// The constructor will setup the property editor based on the attribute if one is found + /// The constructor will setup the property editor based on the attribute if one is found. /// public RichTextPropertyEditor( IDataValueEditorFactory dataValueEditorFactory, @@ -50,7 +52,8 @@ namespace Umbraco.Cms.Core.PropertyEditors HtmlLocalLinkParser localLinkParser, RichTextEditorPastedImages pastedImages, IIOHelper ioHelper, - IImageUrlGenerator imageUrlGenerator) + IImageUrlGenerator imageUrlGenerator, + IHtmlMacroParameterParser macroParameterParser) : base(dataValueEditorFactory) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; @@ -59,6 +62,20 @@ namespace Umbraco.Cms.Core.PropertyEditors _pastedImages = pastedImages; _ioHelper = ioHelper; _imageUrlGenerator = imageUrlGenerator; + _macroParameterParser = macroParameterParser; + } + + [Obsolete("Use the constructor which takes an IHtmlMacroParameterParser instead")] + public RichTextPropertyEditor( + IDataValueEditorFactory dataValueEditorFactory, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + HtmlImageSourceParser imageSourceParser, + HtmlLocalLinkParser localLinkParser, + RichTextEditorPastedImages pastedImages, + IIOHelper ioHelper, + IImageUrlGenerator imageUrlGenerator) + : this (dataValueEditorFactory, backOfficeSecurityAccessor, imageSourceParser, localLinkParser, pastedImages, ioHelper, imageUrlGenerator, StaticServiceProvider.Instance.GetRequiredService()) + { } /// @@ -79,6 +96,7 @@ namespace Umbraco.Cms.Core.PropertyEditors private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; private readonly HtmlImageSourceParser _imageSourceParser; private readonly HtmlLocalLinkParser _localLinkParser; + private readonly IHtmlMacroParameterParser _macroParameterParser; private readonly RichTextEditorPastedImages _pastedImages; private readonly IImageUrlGenerator _imageUrlGenerator; private readonly IHtmlSanitizer _htmlSanitizer; @@ -94,7 +112,8 @@ namespace Umbraco.Cms.Core.PropertyEditors IImageUrlGenerator imageUrlGenerator, IJsonSerializer jsonSerializer, IIOHelper ioHelper, - IHtmlSanitizer htmlSanitizer) + IHtmlSanitizer htmlSanitizer, + IHtmlMacroParameterParser macroParameterParser) : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; @@ -103,6 +122,26 @@ namespace Umbraco.Cms.Core.PropertyEditors _pastedImages = pastedImages; _imageUrlGenerator = imageUrlGenerator; _htmlSanitizer = htmlSanitizer; + _macroParameterParser = macroParameterParser; + } + + [Obsolete("Use the constructor which takes an HtmlMacroParameterParser instead")] + public RichTextPropertyValueEditor( + DataEditorAttribute attribute, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, + HtmlImageSourceParser imageSourceParser, + HtmlLocalLinkParser localLinkParser, + RichTextEditorPastedImages pastedImages, + IImageUrlGenerator imageUrlGenerator, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + IHtmlSanitizer htmlSanitizer) + : this(attribute, backOfficeSecurityAccessor, localizedTextService, shortStringHelper, imageSourceParser, + localLinkParser, pastedImages, imageUrlGenerator, jsonSerializer, ioHelper, htmlSanitizer, + StaticServiceProvider.Instance.GetRequiredService()) + { } /// @@ -182,6 +221,10 @@ namespace Umbraco.Cms.Core.PropertyEditors yield return new UmbracoEntityReference(udi); //TODO: Detect Macros too ... but we can save that for a later date, right now need to do media refs + //UPDATE: We are getting the Macros in 'FindUmbracoEntityReferencesFromEmbeddedMacros' - perhaps we just return the macro Udis here too or do they need their own relationAlias? + + foreach (var umbracoEntityReference in _macroParameterParser.FindUmbracoEntityReferencesFromEmbeddedMacros(asString)) + yield return umbracoEntityReference; } }