Entity search - take one (#15951)

* Add entity search endpoints (to be replaced with Examine based ones for content, media and member)

* Update OpenApi.json
This commit is contained in:
Kenn Jacobsen
2024-04-02 10:40:45 +02:00
committed by GitHub
parent 892a39d39a
commit 96f2b17c5a
12 changed files with 1118 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DataType.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.DataType.Item;
[ApiVersion("1.0")]
public class SearchDataTypeItemController : DatatypeItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IDataTypeService _dataTypeService;
private readonly IUmbracoMapper _mapper;
public SearchDataTypeItemController(IEntitySearchService entitySearchService, IDataTypeService dataTypeService, IUmbracoMapper mapper)
{
_entitySearchService = entitySearchService;
_dataTypeService = dataTypeService;
_mapper = mapper;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<DataTypeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.DataType, query, skip, take);
if (searchResult.Items.Any() is false)
{
return Ok(new PagedModel<DataTypeItemResponseModel> { Total = searchResult.Total });
}
IEnumerable<IDataType> dataTypes = await _dataTypeService.GetAllAsync(searchResult.Items.Select(item => item.Key).ToArray());
var result = new PagedModel<DataTypeItemResponseModel>
{
Items = _mapper.MapEnumerable<IDataType, DataTypeItemResponseModel>(dataTypes),
Total = searchResult.Total
};
return Ok(result);
}
}

View File

@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Document.Item;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Document.Item;
[ApiVersion("1.0")]
public class SearchDocumentItemController : DocumentItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IDocumentPresentationFactory _documentPresentationFactory;
public SearchDocumentItemController(IEntitySearchService entitySearchService, IDocumentPresentationFactory documentPresentationFactory)
{
_entitySearchService = entitySearchService;
_documentPresentationFactory = documentPresentationFactory;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<DocumentItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine and handle user start nodes
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Document, query, skip, take);
var result = new PagedModel<DocumentItemResponseModel>
{
Items = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total
};
return await Task.FromResult(Ok(result));
}
}

View File

@@ -0,0 +1,47 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.DocumentType.Item;
using Umbraco.Cms.Core.Mapping;
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.DocumentType.Item;
[ApiVersion("1.0")]
public class SearchDocumentTypeItemController : DocumentTypeItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IContentTypeService _contentTypeService;
private readonly IUmbracoMapper _mapper;
public SearchDocumentTypeItemController(IEntitySearchService entitySearchService, IContentTypeService contentTypeService, IUmbracoMapper mapper)
{
_entitySearchService = entitySearchService;
_contentTypeService = contentTypeService;
_mapper = mapper;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<DocumentTypeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.DocumentType, query, skip, take);
if (searchResult.Items.Any() is false)
{
return await Task.FromResult(Ok(new PagedModel<DocumentTypeItemResponseModel> { Total = searchResult.Total }));
}
IEnumerable<IContentType> contentTypes = _contentTypeService.GetAll(searchResult.Items.Select(item => item.Key).ToArray().EmptyNull());
var result = new PagedModel<DocumentTypeItemResponseModel>
{
Items = _mapper.MapEnumerable<IContentType, DocumentTypeItemResponseModel>(contentTypes),
Total = searchResult.Total
};
return Ok(result);
}
}

View File

@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Media.Item;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Media.Item;
[ApiVersion("1.0")]
public class SearchMediaItemController : MediaItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IMediaPresentationFactory _mediaPresentationFactory;
public SearchMediaItemController(IEntitySearchService entitySearchService, IMediaPresentationFactory mediaPresentationFactory)
{
_entitySearchService = entitySearchService;
_mediaPresentationFactory = mediaPresentationFactory;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MediaItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine and handle user start nodes
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Media, query, skip, take);
var result = new PagedModel<MediaItemResponseModel>
{
Items = searchResult.Items.OfType<IMediaEntitySlim>().Select(_mediaPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total
};
return await Task.FromResult(Ok(result));
}
}

View File

@@ -0,0 +1,47 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.MediaType.Item;
using Umbraco.Cms.Core.Mapping;
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.MediaType.Item;
[ApiVersion("1.0")]
public class SearchMediaTypeItemController : MediaTypeItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IMediaTypeService _mediaTypeService;
private readonly IUmbracoMapper _mapper;
public SearchMediaTypeItemController(IEntitySearchService entitySearchService, IMediaTypeService mediaTypeService, IUmbracoMapper mapper)
{
_entitySearchService = entitySearchService;
_mediaTypeService = mediaTypeService;
_mapper = mapper;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MediaTypeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.MediaType, query, skip, take);
if (searchResult.Items.Any() is false)
{
return await Task.FromResult(Ok(new PagedModel<MediaTypeItemResponseModel> { Total = searchResult.Total }));
}
IEnumerable<IMediaType> mediaTypes = _mediaTypeService.GetAll(searchResult.Items.Select(item => item.Key).ToArray().EmptyNull());
var result = new PagedModel<MediaTypeItemResponseModel>
{
Items = _mapper.MapEnumerable<IMediaType, MediaTypeItemResponseModel>(mediaTypes),
Total = searchResult.Total
};
return Ok(result);
}
}

View File

@@ -0,0 +1,39 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Member.Item;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Member.Item;
[ApiVersion("1.0")]
public class SearchMemberItemController : MemberItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IMemberPresentationFactory _memberPresentationFactory;
public SearchMemberItemController(IEntitySearchService entitySearchService, IMemberPresentationFactory memberPresentationFactory)
{
_entitySearchService = entitySearchService;
_memberPresentationFactory = memberPresentationFactory;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MemberItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
// FIXME: use Examine
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Member, query, skip, take);
var result = new PagedModel<MemberItemResponseModel>
{
Items = searchResult.Items.OfType<IMemberEntitySlim>().Select(_memberPresentationFactory.CreateItemResponseModel),
Total = searchResult.Total
};
return await Task.FromResult(Ok(result));
}
}

View File

@@ -0,0 +1,46 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.MemberType.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Item;
[ApiVersion("1.0")]
public class SearchMemberTypeItemController : MemberTypeItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly IMemberTypeService _memberTypeService;
private readonly IUmbracoMapper _mapper;
public SearchMemberTypeItemController(IEntitySearchService entitySearchService, IMemberTypeService memberTypeService, IUmbracoMapper mapper)
{
_entitySearchService = entitySearchService;
_memberTypeService = memberTypeService;
_mapper = mapper;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<MemberTypeItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.MemberType, query, skip, take);
if (searchResult.Items.Any() is false)
{
return await Task.FromResult(Ok(new PagedModel<MemberTypeItemResponseModel> { Total = searchResult.Total }));
}
IEnumerable<IMemberType> memberTypes = _memberTypeService.GetAll(searchResult.Items.Select(item => item.Key).ToArray());
var result = new PagedModel<MemberTypeItemResponseModel>
{
Items = _mapper.MapEnumerable<IMemberType, MemberTypeItemResponseModel>(memberTypes),
Total = searchResult.Total
};
return Ok(result);
}
}

View File

@@ -0,0 +1,46 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.ViewModels.Template.Item;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Template.Item;
[ApiVersion("1.0")]
public class SearchTemplateItemController : TemplateItemControllerBase
{
private readonly IEntitySearchService _entitySearchService;
private readonly ITemplateService _templateService;
private readonly IUmbracoMapper _mapper;
public SearchTemplateItemController(IEntitySearchService entitySearchService, ITemplateService templateService, IUmbracoMapper mapper)
{
_entitySearchService = entitySearchService;
_templateService = templateService;
_mapper = mapper;
}
[HttpGet("search")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedModel<TemplateItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult> Search(string query, int skip = 0, int take = 100)
{
PagedModel<IEntitySlim> searchResult = _entitySearchService.Search(UmbracoObjectTypes.Template, query, skip, take);
if (searchResult.Items.Any() is false)
{
return Ok(new PagedModel<TemplateItemResponseModel> { Total = searchResult.Total });
}
IEnumerable<ITemplate> templates = await _templateService.GetAllAsync(searchResult.Items.Select(item => item.Key).ToArray());
var result = new PagedModel<TemplateItemResponseModel>
{
Items = _mapper.MapEnumerable<ITemplate, TemplateItemResponseModel>(templates),
Total = searchResult.Total
};
return Ok(result);
}
}

View File

@@ -1818,6 +1818,71 @@
]
}
},
"/umbraco/management/api/v1/item/data-type/search": {
"get": {
"tags": [
"Data Type"
],
"operationId": "GetItemDataTypeSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDataTypeItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDataTypeItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelDataTypeItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/tree/data-type/ancestors": {
"get": {
"tags": [
@@ -5107,6 +5172,71 @@
]
}
},
"/umbraco/management/api/v1/item/document-type/search": {
"get": {
"tags": [
"Document Type"
],
"operationId": "GetItemDocumentTypeSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentTypeItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentTypeItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentTypeItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/tree/document-type/ancestors": {
"get": {
"tags": [
@@ -8415,6 +8545,71 @@
]
}
},
"/umbraco/management/api/v1/item/document/search": {
"get": {
"tags": [
"Document"
],
"operationId": "GetItemDocumentSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelDocumentItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/recycle-bin/document": {
"delete": {
"tags": [
@@ -11730,6 +11925,71 @@
]
}
},
"/umbraco/management/api/v1/item/media-type/search": {
"get": {
"tags": [
"Media Type"
],
"operationId": "GetItemMediaTypeSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaTypeItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaTypeItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaTypeItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/media-type": {
"post": {
"tags": [
@@ -13700,6 +13960,71 @@
]
}
},
"/umbraco/management/api/v1/item/media/search": {
"get": {
"tags": [
"Media"
],
"operationId": "GetItemMediaSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelMediaItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/media": {
"post": {
"tags": [
@@ -16669,6 +16994,71 @@
]
}
},
"/umbraco/management/api/v1/item/member-type/search": {
"get": {
"tags": [
"Member Type"
],
"operationId": "GetItemMemberTypeSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberTypeItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberTypeItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberTypeItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/member-type": {
"post": {
"tags": [
@@ -17699,6 +18089,71 @@
]
}
},
"/umbraco/management/api/v1/item/member/search": {
"get": {
"tags": [
"Member"
],
"operationId": "GetItemMemberSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelMemberItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/member": {
"post": {
"tags": [
@@ -25726,6 +26181,71 @@
]
}
},
"/umbraco/management/api/v1/item/template/search": {
"get": {
"tags": [
"Template"
],
"operationId": "GetItemTemplateSearch",
"parameters": [
{
"name": "query",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelTemplateItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedModelTemplateItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedModelTemplateItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/template": {
"post": {
"tags": [
@@ -38737,6 +39257,198 @@
},
"additionalProperties": false
},
"PagedModelDataTypeItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/DataTypeItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelDocumentItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/DocumentItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelDocumentTypeItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/DocumentTypeItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelMediaItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MediaItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelMediaTypeItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MediaTypeItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelMemberItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MemberItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelMemberTypeItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MemberTypeItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedModelTemplateItemResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/TemplateItemResponseModel"
}
]
}
},
"total": {
"type": "integer",
"format": "int64"
}
},
"additionalProperties": false
},
"PagedNamedEntityTreeItemResponseModel": {
"required": [
"items",
@@ -42318,4 +43030,4 @@
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
namespace Umbraco.Cms.Core.Services;
public interface IEntitySearchService
{
PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100);
}

View File

@@ -62,6 +62,7 @@ public static partial class UmbracoBuilderExtensions
builder.Services.AddTransient<IPartialViewPopulator, PartialViewPopulator>();
builder.Services.AddUnique<IContentListViewService, ContentListViewService>();
builder.Services.AddUnique<IMediaListViewService, MediaListViewService>();
builder.Services.AddUnique<IEntitySearchService, EntitySearchService>();
return builder;
}

View File

@@ -0,0 +1,46 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Services.Implement;
internal sealed class EntitySearchService : IEntitySearchService
{
private readonly IEntityService _entityService;
private readonly ISqlContext _sqlContext;
public EntitySearchService(IEntityService entityService, ISqlContext sqlContext)
{
_entityService = entityService;
_sqlContext = sqlContext;
}
public PagedModel<IEntitySlim> Search(UmbracoObjectTypes objectType, string query, int skip = 0, int take = 100)
{
PaginationHelper.ConvertSkipTakeToPaging(skip, take, out long pageNumber, out int pageSize);
// if the query is a GUID, search for that explicitly
Guid.TryParse(query, out Guid guidQuery);
IEntitySlim[] entities = _entityService
.GetPagedDescendants(
objectType,
pageNumber,
pageSize,
out long totalRecords,
_sqlContext.Query<IUmbracoEntity>()
.Where(x => x.Name!.Contains(query) || x.Key == guidQuery),
Ordering.By(nameof(NodeDto.Text).ToFirstLowerInvariant()))
.ToArray();
return new PagedModel<IEntitySlim>
{
Items = entities,
Total = totalRecords
};
}
}