Elements: Add reference settings support#21601
Merged
Conversation
1285e01 to
5d35055
Compare
03b23fd to
c85ffbc
Compare
Base automatically changed from
v18/feature/element-reference-tracking
to
v18/dev
February 4, 2026 14:54
…fications - Add DisableDeleteWhenReferenced check to ElementContainerService delete operations - Fire ElementDeletedNotification and EntityContainerDeletedNotification per item during descendant deletion - Fix potential infinite loop when items are skipped due to being referenced - Simplify EmptyRecycleBinAsync to use DeleteDescendantsLocked directly - Use path descending ordering for consistent deletion order (children before parents) - Add test for descendant delete notifications
…nced When DisableDeleteWhenReferenced is enabled and some items are skipped, the standard skip/take pagination breaks. This change: - Adds SqlLessThan/SqlGreaterThan SQL expression extensions for string comparison in LINQ queries - Uses path-based cursor pagination instead of skip/take - Tracks protected paths to prevent deleting containers that have referenced descendants - Adds ElementRecycleBin to UmbracoObjectTypes enum
Verify that DisableUnpublishWhenReferenced works correctly for elements (inherited from ContentPublishingServiceBase): - Cannot unpublish an element that is being referenced - Can unpublish an element that is doing the referencing
The Trashed filter was redundant because: - EmptyRecycleBinAsync only operates on items under the recycle bin root - DeleteFromRecycleBinAsync requires containers to be trashed, and all descendants are marked as trashed when moved to recycle bin Removing the filter simplifies the query and handles edge cases better.
…ndpoints Move ContentPublishingOperationStatusResult from DocumentControllerBase to ContentControllerBase so it can be shared. Add ElementPublishingOperationStatusResult to ElementControllerBase and update PublishElementController and UnpublishElementController to return proper error responses instead of empty BadRequest() when operations fail (e.g., when DisableUnpublishWhenReferenced is enabled).
272346b to
e19dbe7
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds reference settings support for elements, including DisableDeleteWhenReferenced when emptying the recycle bin and verification that DisableUnpublishWhenReferenced works for elements (inherited from base class). The implementation fixes pagination in EmptyRecycleBin by using cursor-based pagination instead of skip/take when items are skipped due to being referenced.
Changes:
- Implements cursor-based pagination for emptying element recycle bin to handle referenced items correctly
- Adds
SqlLessThanandSqlGreaterThanSQL expression extensions for string comparison in LINQ queries - Refactors API error handling to use centralized
ContentPublishingOperationStatusResultmethod - Adds comprehensive tests for reference protection during delete and unpublish operations
- Adds
ElementRecycleBintoUmbracoObjectTypesenum and fires deletion notifications for descendant items
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Umbraco.Core/Services/ElementContainerService.cs | Implements cursor-based pagination with DisableDeleteWhenReferenced support and proper notification firing for descendants |
| src/Umbraco.Core/Persistence/SqlExpressionExtensions.cs | Adds SqlLessThan and SqlGreaterThan extension methods for SQL string comparisons |
| src/Umbraco.Infrastructure/Persistence/Querying/ExpressionVisitorBase.cs | Adds expression visitor handling for new SQL comparison operators |
| src/Umbraco.Core/Models/UmbracoObjectTypes.cs | Adds ElementRecycleBin enum value |
| src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs | Centralizes ContentPublishingOperationStatusResult for reuse by document and element controllers |
| src/Umbraco.Cms.Api.Management/Controllers/Document/DocumentControllerBase.cs | Refactored to delegate to base class implementation |
| src/Umbraco.Cms.Api.Management/Controllers/Element/ElementControllerBase.cs | Adds ElementPublishingOperationStatusResult helper method |
| src/Umbraco.Cms.Api.Management/Controllers/Element/PublishElementController.cs | Uses proper error handling instead of generic BadRequest |
| src/Umbraco.Cms.Api.Management/Controllers/Element/UnpublishElementController.cs | Uses proper error handling instead of generic BadRequest |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ElementContainerServiceTests.cs | Adds notification handler registration for element deletions |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ElementContainerServiceTests.EmptyRecycleBin.cs | Adds test for multi-page pagination with referenced items |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ElementContainerServiceTests.DeleteFromRecycleBin.cs | Adds test verifying notifications are fired for descendant deletions |
| tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ElementPublishingServiceTests.Unpublish.cs | Adds tests verifying DisableUnpublishWhenReferenced works for elements |
src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs
Outdated
Show resolved
Hide resolved
Replace hardcoded "document" terminology in shared ContentControllerBase error messages with an abstract EntityName property, so each subclass (document, element, media, member, etc.) provides context-appropriate error messages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ycle bin ElementEditingService.MoveToRecycleBinAsync was missing the reference check that ContentEditingService already performs for documents. This allowed referenced elements to be moved to the recycle bin even when DisableUnpublishWhenReferenced was enabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # src/Umbraco.Core/Services/ElementContainerService.cs
Add server-side validation to ElementContainerService.MoveToRecycleBinAsync that checks for referenced descendants when DisableUnpublishWhenReferenced is enabled. Uses ITrackedReferencesService.GetPagedDescendantsInReferencesAsync as an upfront check before any move processing begins.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DisableDeleteWhenReferencedsupport for elements when emptying recycle binEmptyRecycleBinwhen some items are skipped due to being referencedSqlLessThan/SqlGreaterThanSQL expression extensions for string comparison in LINQ queriesDisableUnpublishWhenReferencedworks for elements (inherited from base class)Changes
EmptyRecycleBin pagination fix
When
DisableDeleteWhenReferencedis enabled and some items are skipped, the standard skip/take pagination breaks. This change:ElementRecycleBintoUmbracoObjectTypesenumSQL expression extensions
SqlLessThanandSqlGreaterThanextension methods for string comparison in LINQ queries<and>operatorsTests
DisableDeleteWhenReferencedwith pagination across multiple pagesDisableUnpublishWhenReferencedfor elements