Skip to content

Content picker search with start node configured not taking user start nodes into account #19871

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
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.Item;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;

Expand All @@ -14,13 +17,52 @@ public class SearchDocumentItemController : DocumentItemControllerBase
{
private readonly IIndexedEntitySearchService _indexedEntitySearchService;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
private readonly IDataTypeService _dataTypeService;

public SearchDocumentItemController(IIndexedEntitySearchService indexedEntitySearchService, IDocumentPresentationFactory documentPresentationFactory)
[ActivatorUtilitiesConstructor]
public SearchDocumentItemController(
IIndexedEntitySearchService indexedEntitySearchService,
IDocumentPresentationFactory documentPresentationFactory,
IDataTypeService dataTypeService)
{
_indexedEntitySearchService = indexedEntitySearchService;
_documentPresentationFactory = documentPresentationFactory;
_dataTypeService = dataTypeService;
}

[Obsolete("Use the non-obsolete constructor instead, will be removed in v18")]
public SearchDocumentItemController(
IIndexedEntitySearchService indexedEntitySearchService,
IDocumentPresentationFactory documentPresentationFactory)
: this(
indexedEntitySearchService,
documentPresentationFactory,
StaticServiceProvider.Instance.GetRequiredService<IDataTypeService>())
{
}

[Obsolete("Please use the overload taking all parameters. Scheduled for removal in Umbraco 18.")]
[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IActionResult> SearchWithTrashed(
CancellationToken cancellationToken,
string query,
bool? trashed = null,
string? culture = null,
int skip = 0,
int take = 100,
Guid? parentId = null,
[FromQuery] IEnumerable<Guid>? allowedDocumentTypes = null)
=> await SearchWithTrashed(
cancellationToken,
query,
trashed,
culture,
skip,
take,
parentId,
allowedDocumentTypes,
null);

[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<DocumentItemResponseModel>), StatusCodes.Status200OK)]
Expand All @@ -32,9 +74,21 @@ public async Task<IActionResult> SearchWithTrashed(
int skip = 0,
int take = 100,
Guid? parentId = null,
[FromQuery] IEnumerable<Guid>? allowedDocumentTypes = null)
[FromQuery] IEnumerable<Guid>? allowedDocumentTypes = null,
Guid? dataTypeId = null)
{
PagedModel<IEntitySlim> searchResult = await _indexedEntitySearchService.SearchAsync(UmbracoObjectTypes.Document, query, parentId, allowedDocumentTypes, trashed, culture, skip, take);
var ignoreUserStartNodes = await IgnoreUserStartNodes(dataTypeId);
PagedModel<IEntitySlim> searchResult = await _indexedEntitySearchService.SearchAsync(
UmbracoObjectTypes.Document,
query,
parentId,
allowedDocumentTypes,
trashed,
culture,
skip,
take,
ignoreUserStartNodes);

var result = new PagedModel<DocumentItemResponseModel>
{
Items = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModel),
Expand All @@ -43,4 +97,7 @@ public async Task<IActionResult> SearchWithTrashed(

return Ok(result);
}

private async Task<bool> IgnoreUserStartNodes(Guid? dataTypeKey) =>
dataTypeKey is not null && await _dataTypeService.IsDataTypeIgnoringUserStartNodesAsync(dataTypeKey.Value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ public ChildrenDocumentTreeController(
[HttpGet("children")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<DocumentTreeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<DocumentTreeItemResponseModel>>> Children(CancellationToken cancellationToken, Guid parentId, int skip = 0, int take = 100, Guid? dataTypeId = null)
public async Task<ActionResult<PagedViewModel<DocumentTreeItemResponseModel>>> Children(
CancellationToken cancellationToken,
Guid parentId,
int skip = 0,
int take = 100,
Guid? dataTypeId = null)
{
IgnoreUserStartNodesForDataType(dataTypeId);
return await GetChildren(parentId, skip, take);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Media.Item;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.Controllers.Media.Item;

Expand All @@ -14,13 +17,52 @@ public class SearchMediaItemController : MediaItemControllerBase
{
private readonly IIndexedEntitySearchService _indexedEntitySearchService;
private readonly IMediaPresentationFactory _mediaPresentationFactory;
private readonly IDataTypeService _dataTypeService;

public SearchMediaItemController(IIndexedEntitySearchService indexedEntitySearchService, IMediaPresentationFactory mediaPresentationFactory)
[ActivatorUtilitiesConstructor]
public SearchMediaItemController(
IIndexedEntitySearchService indexedEntitySearchService,
IMediaPresentationFactory mediaPresentationFactory,
IDataTypeService dataTypeService)
{
_indexedEntitySearchService = indexedEntitySearchService;
_mediaPresentationFactory = mediaPresentationFactory;
_dataTypeService = dataTypeService;
}

[Obsolete("Use the non-obsolete constructor instead, will be removed in Umbraco 18.")]
public SearchMediaItemController(
IIndexedEntitySearchService indexedEntitySearchService,
IMediaPresentationFactory mediaPresentationFactory)
: this(
indexedEntitySearchService,
mediaPresentationFactory,
StaticServiceProvider.Instance.GetRequiredService<IDataTypeService>())
{
}

[Obsolete("Please use the overload taking all parameters. Scheduled for removal in Umbraco 18.")]
[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IActionResult> SearchFromParentWithAllowedTypes(
CancellationToken cancellationToken,
string query,
bool? trashed = null,
string? culture = null,
int skip = 0,
int take = 100,
Guid? parentId = null,
[FromQuery] IEnumerable<Guid>? allowedMediaTypes = null)
=> await SearchFromParentWithAllowedTypes(
cancellationToken,
query,
trashed,
culture,
skip,
take,
parentId,
allowedMediaTypes,
null);

[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MediaItemResponseModel>), StatusCodes.Status200OK)]
Expand All @@ -32,9 +74,20 @@ public async Task<IActionResult> SearchFromParentWithAllowedTypes(
int skip = 0,
int take = 100,
Guid? parentId = null,
[FromQuery]IEnumerable<Guid>? allowedMediaTypes = null)
[FromQuery] IEnumerable<Guid>? allowedMediaTypes = null,
Guid? dataTypeId = null)
{
PagedModel<IEntitySlim> searchResult = await _indexedEntitySearchService.SearchAsync(UmbracoObjectTypes.Media, query, parentId, allowedMediaTypes, trashed, culture, skip, take);
var ignoreUserStartNodes = await IgnoreUserStartNodes(dataTypeId);
PagedModel<IEntitySlim> searchResult = await _indexedEntitySearchService.SearchAsync(
UmbracoObjectTypes.Media,
query,
parentId,
allowedMediaTypes,
trashed,
culture,
skip,
take,
ignoreUserStartNodes);
var result = new PagedModel<MediaItemResponseModel>
{
Items = searchResult.Items.OfType<IMediaEntitySlim>().Select(_mediaPresentationFactory.CreateItemResponseModel),
Expand All @@ -43,4 +96,7 @@ public async Task<IActionResult> SearchFromParentWithAllowedTypes(

return Ok(result);
}

private async Task<bool> IgnoreUserStartNodes(Guid? dataTypeKey) =>
dataTypeKey is not null && await _dataTypeService.IsDataTypeIgnoringUserStartNodesAsync(dataTypeKey.Value);
}
16 changes: 16 additions & 0 deletions src/Umbraco.Cms.Api.Management/OpenApi.json
Original file line number Diff line number Diff line change
Expand Up @@ -10385,6 +10385,14 @@
"format": "uuid"
}
}
},
{
"name": "dataTypeId",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
Expand Down Expand Up @@ -16281,6 +16289,14 @@
"format": "uuid"
}
}
},
{
"name": "dataTypeId",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
Expand Down
13 changes: 5 additions & 8 deletions src/Umbraco.Core/Services/DateTypeServiceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ namespace Umbraco.Extensions;
public static class DateTypeServiceExtensions
{
public static bool IsDataTypeIgnoringUserStartNodes(this IDataTypeService dataTypeService, Guid key)
{
IDataType? dataType = dataTypeService.GetAsync(key).GetAwaiter().GetResult();

if (dataType != null && dataType.ConfigurationObject is IIgnoreUserStartNodesConfig ignoreStartNodesConfig)
{
return ignoreStartNodesConfig.IgnoreUserStartNodes;
}
=> dataTypeService.IsDataTypeIgnoringUserStartNodesAsync(key).GetAwaiter().GetResult();

return false;
public static async Task<bool> IsDataTypeIgnoringUserStartNodesAsync(this IDataTypeService dataTypeService, Guid key)
{
IDataType? dataType = await dataTypeService.GetAsync(key);
return dataType is { ConfigurationObject: IIgnoreUserStartNodesConfig { IgnoreUserStartNodes: true } };
}
}
Loading
Loading