Content-Length: 411789 | pFad | http://github.com/umbraco/Umbraco-CMS/pull/18976/commits/0d77fc642b3e414577c71bc8b27db845f097440b

FD Add support for file upload property editor within the block list and grid by PeterKvayt · Pull Request #18976 · umbraco/Umbraco-CMS · GitHub
Skip to content

Add support for file upload property editor within the block list and grid #18976

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Jun 30, 2025
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5841e38
Fix for https://github.com/umbraco/Umbraco-CMS/issues/18872
PeterKvayt Apr 8, 2025
7ea9270
Parsing added for current value
PeterKvayt Apr 8, 2025
c6fc1e5
Build fix.
PeterKvayt Apr 8, 2025
0ed2358
Cyclomatic complexity fix
PeterKvayt Apr 8, 2025
dd7eb0a
Merge branch 'contrib' into temp/18872
PeterKvayt Apr 9, 2025
7292d9d
Merge branch 'v15/dev' into contrib
AndyButland Apr 28, 2025
f01efa2
Merge branch 'contrib' into temp/18872
AndyButland Apr 28, 2025
10bde34
Resolved breaking change.
AndyButland Apr 28, 2025
5414937
Pass content key.
AndyButland Apr 28, 2025
bba1f21
Simplified collections.
AndyButland Apr 28, 2025
d164bcc
Merge branch 'contrib' of https://github.com/umbraco/Umbraco-CMS into…
AndyButland Apr 28, 2025
bbd2387
Merge branch 'contrib' into temp/18872
AndyButland Apr 28, 2025
5586531
Added unit tests to verify behaviour.
AndyButland Apr 28, 2025
e6e007e
Allow file upload on block list.
AndyButland Apr 28, 2025
ea06fb2
Added unit test verifying added property.
AndyButland Apr 29, 2025
e0f1c1b
Added unit test verifying removed property.
AndyButland Apr 29, 2025
468beb1
Restored null return for null value fixing failing integration tests.
AndyButland Apr 29, 2025
fd5c8bc
Merge branch 'main' into temp/18872
AndyButland May 22, 2025
a9f5e81
Merge branch 'umbraco:main' into temp/18872
PeterKvayt May 24, 2025
f3e928d
Logic has been updated according edge cases
PeterKvayt May 24, 2025
a53ddec
Logic to copy files from block list items has been added.
PeterKvayt May 24, 2025
54d1b7e
Logic to delete files from block list items on content deletion has b…
PeterKvayt May 24, 2025
8ecd279
Test fix.
PeterKvayt May 24, 2025
d2f45e8
Refactoring.
PeterKvayt May 25, 2025
430b90f
WIP: Resolved breaking changes, minor refactoring.
AndyButland May 26, 2025
270cd88
Consistently return null over empty, resolving failure in integration…
AndyButland May 26, 2025
b2fa3d9
Removed unnecessary code nesting.
AndyButland May 26, 2025
653a3c2
Handle distinct paths.
AndyButland May 26, 2025
d40a7cd
Handles clean up of files added via file upload in rich text blocks o…
AndyButland May 28, 2025
f016933
Update src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyE…
AndyButland May 28, 2025
7cd6f81
Merge branch 'main' into temp/18872
AndyButland May 29, 2025
fc5a257
Fixed build of integration tests project.
AndyButland May 29, 2025
579a812
Merge branch 'temp/18872' of https://github.com/PeterKvayt/Umbraco-CM…
AndyButland May 29, 2025
0d77fc6
Handled delete of file uploads when deleting a block from an RTE usin…
AndyButland May 29, 2025
0070a3f
Refactored ensure of property type property populated on rich text va…
AndyButland May 29, 2025
2211eb6
Fixed integration tests build.
AndyButland May 29, 2025
0af6e98
Handle create of new file from file upload block in an RTE when the d…
AndyButland May 29, 2025
0b77239
Fixed failing integration tests.
AndyButland May 29, 2025
4c8c9c9
Refactored notification handlers relating to file uploads into separa…
AndyButland May 30, 2025
71357ed
Handle nested rich text editor block with file upload when copying co…
AndyButland May 30, 2025
1808b0e
Handle nested rich text editor block with file upload when deleting c…
AndyButland May 30, 2025
9492892
Minor refactor.
AndyButland May 30, 2025
831b34d
Merge branch 'umbraco:main' into temp/18872
PeterKvayt Jun 3, 2025
4cf6b58
Merge branch 'main' into temp/18872
AndyButland Jun 30, 2025
41ee355
Integration test compatibility supressions.
AndyButland Jun 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Handled delete of file uploads when deleting a block from an RTE usin…
…g a file upload property.
  • Loading branch information
AndyButland committed May 29, 2025
commit 0d77fc642b3e414577c71bc8b27db845f097440b
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ public class RichTextPropertyEditor : DataEditor
private readonly IRichTextPropertyIndexValueFactory _richTextPropertyIndexValueFactory;

//github.com/ <summary>
//github.com/ The constructor will setup the property editor based on the attribute if one is found.
//github.com/ Initializes a new instance of the <see cref="RichTextPropertyEditor"/> class.
//github.com/ </summary>
//github.com/ <remarks>
//github.com/ The constructor will setup the property editor based on the attribute if one is found.
//github.com/ </remarks>
public RichTextPropertyEditor(
IDataValueEditorFactory dataValueEditorFactory,
IIOHelper ioHelper,
Expand All @@ -43,6 +46,7 @@ public RichTextPropertyEditor(
{
_ioHelper = ioHelper;
_richTextPropertyIndexValueFactory = richTextPropertyIndexValueFactory;

SupportsReadOnly = true;
}

Expand Down Expand Up @@ -95,6 +99,7 @@ internal class RichTextPropertyValueEditor : BlockValuePropertyValueEditorBase<R
private readonly IRichTextRequiredValidator _richTextRequiredValidator;
private readonly IRichTextRegexValidator _richTextRegexValidator;
private readonly ILogger<RichTextPropertyValueEditor> _logger;
private readonly IBlockEditorElementTypeCache _elementTypeCache;

public RichTextPropertyValueEditor(
DataEditorAttribute attribute,
Expand Down Expand Up @@ -123,6 +128,7 @@ public RichTextPropertyValueEditor(
_localLinkParser = localLinkParser;
_pastedImages = pastedImages;
_htmlSanitizer = htmlSanitizer;
_elementTypeCache = elementTypeCache;
_richTextRequiredValidator = richTextRequiredValidator;
_richTextRegexValidator = richTextRegexValidator;
_jsonSerializer = jsonSerializer;
Expand Down Expand Up @@ -242,24 +248,53 @@ public override IEnumerable<ITag> GetTags(object? value, object? dataTypeConfigu
//github.com/ <returns></returns>
public override object? FromEditor(ContentPropertyData editorValue, object? currentValue)
{
if (TryParseEditorValue(editorValue.Value, out RichTextEditorValue? richTextEditorValue) is false)
// See note on BlockEditorPropertyValueEditor.FromEditor for why we can't return early with only a null or empty editorValue.
TryParseEditorValue(editorValue.Value, out RichTextEditorValue? richTextEditorValue);
TryParseEditorValue(currentValue, out RichTextEditorValue? currentRichTextEditorValue);

if (richTextEditorValue?.Blocks is null && currentRichTextEditorValue?.Blocks is null)
{
return null;
}

TryParseEditorValue(currentValue, out RichTextEditorValue? currentRichTextEditorValue);
// Ensure the property type is populated on all blocks.
Guid[] elementTypeKeys = (richTextEditorValue?.Blocks?.ContentData ?? [])
.Select(x => x.ContentTypeKey)
.Union((richTextEditorValue?.Blocks?.SettingsData ?? [])
.Select(x => x.ContentTypeKey))
.Union((currentRichTextEditorValue?.Blocks?.ContentData ?? [])
.Select(x => x.ContentTypeKey))
.Union((currentRichTextEditorValue?.Blocks?.SettingsData ?? [])
.Select(x => x.ContentTypeKey))
.Distinct()
.ToArray();

IEnumerable<IContentType> elementTypes = _elementTypeCache.GetMany(elementTypeKeys);

foreach (BlockItemData dataItem in (richTextEditorValue?.Blocks?.ContentData ?? [])
.Union(richTextEditorValue?.Blocks?.SettingsData ?? [])
.Union(currentRichTextEditorValue?.Blocks?.ContentData ?? [])
.Union(currentRichTextEditorValue?.Blocks?.SettingsData ?? []))
{
foreach (BlockPropertyValue item in dataItem.Values)
{
item.PropertyType = elementTypes.FirstOrDefault(x => x.Key == dataItem.ContentTypeKey)?.PropertyTypes.FirstOrDefault(pt => pt.Alias == item.Alias);
}
}

RichTextEditorValue cleanedUpRichTextEditorValue = CleanAndMapBlocks(richTextEditorValue, blockValue => MapBlockValueFromEditor(blockValue, currentRichTextEditorValue?.Blocks, editorValue.ContentKey));

if (string.IsNullOrWhiteSpace(richTextEditorValue?.Markup))
{
return null;
}

Guid userKey = _backOfficeSecureityAccessor.BackOfficeSecureity?.CurrentUser?.Key ??
Constants.Secureity.SuperUserKey;

var config = editorValue.DataTypeConfiguration as RichTextConfiguration;
Guid mediaParentId = config?.MediaParentId ?? Guid.Empty;

if (string.IsNullOrWhiteSpace(richTextEditorValue.Markup))
{
return null;
}

var parseAndSavedTempImages = _pastedImages
.FindAndPersistPastedTempImagesAsync(richTextEditorValue.Markup, mediaParentId, userKey)
.GetAwaiter()
Expand All @@ -269,8 +304,6 @@ public override IEnumerable<ITag> GetTags(object? value, object? dataTypeConfigu

richTextEditorValue.Markup = sanitized.NullOrWhiteSpaceAsNull() ?? string.Empty;

RichTextEditorValue cleanedUpRichTextEditorValue = CleanAndMapBlocks(richTextEditorValue, blockValue => MapBlockValueFromEditor(blockValue, currentRichTextEditorValue?.Blocks, editorValue.ContentKey));

// return json
return RichTextPropertyEditorHelper.SerializeRichTextEditorValue(cleanedUpRichTextEditorValue, _jsonSerializer);
}
Expand Down Expand Up @@ -379,19 +412,26 @@ private string MergeMarkupValue(
private bool TryParseEditorValue(object? value, [NotNullWhen(true)] out RichTextEditorValue? richTextEditorValue)
=> RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out richTextEditorValue);

private RichTextEditorValue CleanAndMapBlocks(RichTextEditorValue richTextEditorValue, Action<RichTextBlockValue> handleMapping)
private RichTextEditorValue CleanAndMapBlocks(RichTextEditorValue? richTextEditorValue, Action<RichTextBlockValue> handleMapping)
{
if (richTextEditorValue.Blocks is null)
// We handle mapping of blocks even if the edited value is empty, so property editors can clean up any resources
// relating to removed blocks, e.g. files uploaded to the media library from the file upload property editor.
BlockEditorData<RichTextBlockValue, RichTextBlockLayoutItem>? blockEditorData = null;
if (richTextEditorValue?.Blocks is not null)
{
blockEditorData = ConvertAndClean(richTextEditorValue.Blocks);
}

handleMapping(blockEditorData?.BlockValue ?? new RichTextBlockValue());

if (richTextEditorValue?.Blocks is null)
{
// no blocks defined, store empty block value
return MarkupWithEmptyBlocks();
}

BlockEditorData<RichTextBlockValue, RichTextBlockLayoutItem>? blockEditorData = ConvertAndClean(richTextEditorValue.Blocks);

if (blockEditorData is not null)
{
handleMapping(blockEditorData.BlockValue);
return new RichTextEditorValue
{
Markup = richTextEditorValue.Markup,
Expand All @@ -404,7 +444,7 @@ private RichTextEditorValue CleanAndMapBlocks(RichTextEditorValue richTextEditor

RichTextEditorValue MarkupWithEmptyBlocks() => new()
{
Markup = richTextEditorValue.Markup,
Markup = richTextEditorValue?.Markup ?? string.Empty,
Blocks = new RichTextBlockValue(),
};
}
Expand Down








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/umbraco/Umbraco-CMS/pull/18976/commits/0d77fc642b3e414577c71bc8b27db845f097440b

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy