From 27108036b4264d95f870b2e3cb33220cfd43891e Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Tue, 27 Aug 2024 15:18:25 +0200 Subject: [PATCH] Support parentId in document/media item search endpoints (#16933) * Updated search services to start searching from a guid based key. * Solved api breaking changes with new minor version * Ordering and formatting * Changed interface default implementation to the new method... * Consolidated version * PR review cleanup and renaming --- .../Document/Item/SearchDocumentItemController.cs | 11 ++++++++--- .../Media/Item/SearchMediaItemController.cs | 11 ++++++++--- .../Services/IIndexedEntitySearchService.cs | 4 ++++ .../BackOfficeExamineSearcher.cs | 12 ++++++++++-- .../Services/Implement/IndexedEntitySearchService.cs | 12 +++++++++++- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs index 415fd156d4..f3b7cb1caf 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/SearchDocumentItemController.cs @@ -21,16 +21,21 @@ public class SearchDocumentItemController : DocumentItemControllerBase _documentPresentationFactory = documentPresentationFactory; } + [NonAction] + [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")] + public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100) + => await SearchFromParent(cancellationToken, query, skip, take); + [HttpGet("search")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)] - public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100) + public async Task SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null) { - PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Document, query, skip, take); + PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Document, query, parentId, skip, take); var result = new PagedModel { Items = searchResult.Items.OfType().Select(_documentPresentationFactory.CreateItemResponseModel), - Total = searchResult.Total + Total = searchResult.Total, }; return await Task.FromResult(Ok(result)); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs index 37543444fb..81d4f17748 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Item/SearchMediaItemController.cs @@ -21,16 +21,21 @@ public class SearchMediaItemController : MediaItemControllerBase _mediaPresentationFactory = mediaPresentationFactory; } + [NonAction] + [Obsolete("Scheduled to be removed in v16, use the non obsoleted method instead")] + public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100) + => await SearchFromParent(cancellationToken, query, skip, take, null); + [HttpGet("search")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedModel), StatusCodes.Status200OK)] - public async Task Search(CancellationToken cancellationToken, string query, int skip = 0, int take = 100) + public async Task SearchFromParent(CancellationToken cancellationToken, string query, int skip = 0, int take = 100, Guid? parentId = null) { - PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Media, query, skip, take); + PagedModel searchResult = _indexedEntitySearchService.Search(UmbracoObjectTypes.Media, query, parentId, skip, take); var result = new PagedModel { Items = searchResult.Items.OfType().Select(_mediaPresentationFactory.CreateItemResponseModel), - Total = searchResult.Total + Total = searchResult.Total, }; return await Task.FromResult(Ok(result)); diff --git a/src/Umbraco.Core/Services/IIndexedEntitySearchService.cs b/src/Umbraco.Core/Services/IIndexedEntitySearchService.cs index 047f5e7e2f..4463733146 100644 --- a/src/Umbraco.Core/Services/IIndexedEntitySearchService.cs +++ b/src/Umbraco.Core/Services/IIndexedEntitySearchService.cs @@ -13,4 +13,8 @@ namespace Umbraco.Cms.Core.Services; public interface IIndexedEntitySearchService { PagedModel Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false); + + // default implementation to avoid breaking changes falls back to old behaviour + PagedModel Search(UmbracoObjectTypes objectType, string query, Guid? parentId, int skip = 0, int take = 100, bool ignoreUserStartNodes = false) + => Search(objectType,query, skip, take, ignoreUserStartNodes); } diff --git a/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs b/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs index e843d7954b..82d33ee480 100644 --- a/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs +++ b/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs @@ -356,8 +356,16 @@ public class BackOfficeExamineSearcher : IBackOfficeExamineSearcher throw new ArgumentNullException(nameof(entityService)); } - UdiParser.TryParse(searchFrom, true, out Udi? udi); - searchFrom = udi == null ? searchFrom : entityService.GetId(udi).Result.ToString(); + if (Guid.TryParse(searchFrom, out Guid guid)) + { + searchFrom = entityService.GetId(guid, objectType).Result.ToString(); + } + else + { + // fallback to Udi for legacy reasons as the calling methods take string? + UdiParser.TryParse(searchFrom, true, out Udi? udi); + searchFrom = udi == null ? searchFrom : entityService.GetId(udi).Result.ToString(); + } TreeEntityPath? entityPath = int.TryParse(searchFrom, NumberStyles.Integer, CultureInfo.InvariantCulture, out var searchFromId) && diff --git a/src/Umbraco.Infrastructure/Services/Implement/IndexedEntitySearchService.cs b/src/Umbraco.Infrastructure/Services/Implement/IndexedEntitySearchService.cs index 0055df6244..0f097df262 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/IndexedEntitySearchService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/IndexedEntitySearchService.cs @@ -20,6 +20,15 @@ internal sealed class IndexedEntitySearchService : IIndexedEntitySearchService } public PagedModel Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100, bool ignoreUserStartNodes = false) + => Search(objectType, query, null, skip, take, ignoreUserStartNodes); + + public PagedModel Search( + UmbracoObjectTypes objectType, + string query, + Guid? parentId, + int skip = 0, + int take = 100, + bool ignoreUserStartNodes = false) { UmbracoEntityTypes entityType = objectType switch { @@ -37,7 +46,8 @@ internal sealed class IndexedEntitySearchService : IIndexedEntitySearchService pageSize, pageNumber, out var totalFound, - ignoreUserStartNodes: ignoreUserStartNodes); + ignoreUserStartNodes: ignoreUserStartNodes, + searchFrom: parentId?.ToString()); Guid[] keys = searchResults.Select( result =>