Skip to content

Elements: Add reference settings support#21601

Merged
kjac merged 14 commits intov18/devfrom
v18/feature/element-reference-settings
Feb 13, 2026
Merged

Elements: Add reference settings support#21601
kjac merged 14 commits intov18/devfrom
v18/feature/element-reference-settings

Conversation

@lauraneto
Copy link
Contributor

Summary

  • Add DisableDeleteWhenReferenced support for elements when emptying recycle bin
  • Fix pagination in EmptyRecycleBin when some items are skipped due to being referenced
  • Add SqlLessThan/SqlGreaterThan SQL expression extensions for string comparison in LINQ queries
  • Verify DisableUnpublishWhenReferenced works for elements (inherited from base class)

Changes

EmptyRecycleBin pagination fix

When DisableDeleteWhenReferenced is enabled and some items are skipped, the standard skip/take pagination breaks. This change:

  • 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

SQL expression extensions

  • Adds SqlLessThan and SqlGreaterThan extension methods for string comparison in LINQ queries
  • These translate to SQL < and > operators

Tests

  • Add test for DisableDeleteWhenReferenced with pagination across multiple pages
  • Add tests for DisableUnpublishWhenReferenced for elements

@lauraneto lauraneto force-pushed the v18/feature/element-reference-tracking branch from 1285e01 to 5d35055 Compare February 3, 2026 12:46
@lauraneto lauraneto force-pushed the v18/feature/element-reference-settings branch from 03b23fd to c85ffbc Compare February 3, 2026 14:48
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).
@lauraneto lauraneto force-pushed the v18/feature/element-reference-settings branch from 272346b to e19dbe7 Compare February 4, 2026 15:25
@lauraneto lauraneto marked this pull request as ready for review February 5, 2026 14:26
Copilot AI review requested due to automatic review settings February 5, 2026 14:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 SqlLessThan and SqlGreaterThan SQL expression extensions for string comparison in LINQ queries
  • Refactors API error handling to use centralized ContentPublishingOperationStatusResult method
  • Adds comprehensive tests for reference protection during delete and unpublish operations
  • Adds ElementRecycleBin to UmbracoObjectTypes enum 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

lauraneto and others added 6 commits February 9, 2026 13:35
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.
Copy link
Contributor

@kjac kjac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💪

@kjac kjac merged commit 6f0fd8f into v18/dev Feb 13, 2026
25 of 26 checks passed
@kjac kjac deleted the v18/feature/element-reference-settings branch February 13, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants