diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentCollectionControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentCollectionControllerBase.cs index 2adfef96648f..a38ade606019 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentCollectionControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentCollectionControllerBase.cs @@ -1,7 +1,10 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Content; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentEditing; @@ -18,8 +21,19 @@ public abstract class ContentCollectionControllerBase _mapper = mapper; + protected ContentCollectionControllerBase(IUmbracoMapper mapper, SignProviderCollection signProvider) + { + _mapper = mapper; + _signProviders = signProvider; + } + + [Obsolete("Use the constructer with all parameters. To be removed in Umbraco 18")] + protected ContentCollectionControllerBase(IUmbracoMapper mapper) + : this(mapper, StaticServiceProvider.Instance.GetRequiredService()) + { + } [Obsolete("This method is no longer used and will be removed in Umbraco 17.")] protected IActionResult CollectionResult(ListViewPagedModel result) @@ -48,6 +62,9 @@ protected IActionResult CollectionResult(ListViewPagedModel result) return Ok(pageViewModel); } + /// + /// Creates a collection result from the provided collection response models and total number of items. + /// protected IActionResult CollectionResult(List collectionResponseModels, long totalNumberOfItems) { var pageViewModel = new PagedViewModel @@ -104,4 +121,15 @@ protected IActionResult ContentCollectionOperationStatusResult(ContentCollection StatusCode = StatusCodes.Status500InternalServerError, }, }); + + /// + /// Populates the signs for the collection response models. + /// + protected async Task PopulateSigns(IEnumerable itemViewModels) + { + foreach (ISignProvider signProvider in _signProviders.Where(x => x.CanProvideSigns())) + { + await signProvider.PopulateSignsAsync(itemViewModels); + } + } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/AncestorsDataTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/AncestorsDataTypeTreeController.cs index d93b76718dee..b3a103a01a3a 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/AncestorsDataTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/AncestorsDataTypeTreeController.cs @@ -1,6 +1,8 @@ using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree; [ApiVersion("1.0")] public class AncestorsDataTypeTreeController : DataTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService) : base(entityService, dataTypeService) { } + [ActivatorUtilitiesConstructor] + public AncestorsDataTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IDataTypeService dataTypeService) + : base(entityService, signProviders, dataTypeService) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/ChildrenDataTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/ChildrenDataTypeTreeController.cs index cd9f4171cd68..7c801530ac0d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/ChildrenDataTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/ChildrenDataTypeTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree; [ApiVersion("1.0")] public class ChildrenDataTypeTreeController : DataTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService) : base(entityService, dataTypeService) { } + [ActivatorUtilitiesConstructor] + public ChildrenDataTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IDataTypeService dataTypeService) + : base(entityService, signProviders, dataTypeService) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs index 52a7319b1a11..f0dbb8a8ecfd 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/DataTypeTreeControllerBase.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -19,8 +22,17 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + dataTypeService) + { + } + + public DataTypeTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IDataTypeService dataTypeService) + : base(entityService, signProviders) => _dataTypeService = dataTypeService; protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DataType; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/RootDataTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/RootDataTypeTreeController.cs index 0554bff8e5e7..fa1b5c7bfbd8 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/RootDataTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/RootDataTypeTreeController.cs @@ -1,21 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Api.Common.ViewModels.Pagination; -using Umbraco.Cms.Api.Management.ViewModels.DataType.Item; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree; [ApiVersion("1.0")] public class RootDataTypeTreeController : DataTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService) : base(entityService, dataTypeService) { } + [ActivatorUtilitiesConstructor] + public RootDataTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IDataTypeService dataTypeService) + : base(entityService, signProviders, dataTypeService) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/SiblingsDataTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/SiblingsDataTypeTreeController.cs index d487df48ff71..fcc496e71da0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/SiblingsDataTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DataType/Tree/SiblingsDataTypeTreeController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -8,11 +10,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree; public class SiblingsDataTypeTreeController : DataTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService) : base(entityService, dataTypeService) { } + [ActivatorUtilitiesConstructor] + public SiblingsDataTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IDataTypeService dataTypeService) + : base(entityService, signProviders, dataTypeService) + { + } + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings(CancellationToken cancellationToken, Guid target, int before, int after, bool foldersOnly = false) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/AncestorsDictionaryTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/AncestorsDictionaryTreeController.cs index 2c17199602e9..f7c94de4db72 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/AncestorsDictionaryTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/AncestorsDictionaryTreeController.cs @@ -1,6 +1,8 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree; [ApiVersion("1.0")] public class AncestorsDictionaryTreeController : DictionaryTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService) : base(entityService, dictionaryItemService) { } + [ActivatorUtilitiesConstructor] + public AncestorsDictionaryTreeController(IEntityService entityService, SignProviderCollection signProviders, IDictionaryItemService dictionaryItemService) + : base(entityService, signProviders, dictionaryItemService) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/ChildrenDictionaryTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/ChildrenDictionaryTreeController.cs index 59b23ff801d4..39c135be2bfe 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/ChildrenDictionaryTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/ChildrenDictionaryTreeController.cs @@ -1,21 +1,30 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree; [ApiVersion("1.0")] public class ChildrenDictionaryTreeController : DictionaryTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService) : base(entityService, dictionaryItemService) { } + [ActivatorUtilitiesConstructor] + public ChildrenDictionaryTreeController(IEntityService entityService, SignProviderCollection signProviders, IDictionaryItemService dictionaryItemService) + : base(entityService, signProviders, dictionaryItemService) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs index 2b02ff541a0c..653337024573 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/DictionaryTreeControllerBase.cs @@ -1,10 +1,13 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Web.Common.Authorization; @@ -18,8 +21,17 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree; // tree controller base. We'll keep it though, in the hope that we can mend EntityService. public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public DictionaryTreeControllerBase(IEntityService entityService, IDictionaryItemService dictionaryItemService) - : base(entityService) => + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + dictionaryItemService) + { + } + + public DictionaryTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IDictionaryItemService dictionaryItemService) + : base(entityService, signProviders) => DictionaryItemService = dictionaryItemService; // dictionary items do not currently have a known UmbracoObjectType, so we'll settle with Unknown for now diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/RootDictionaryTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/RootDictionaryTreeController.cs index a6d65ed76428..7bac1e66a811 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/RootDictionaryTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Dictionary/Tree/RootDictionaryTreeController.cs @@ -1,10 +1,12 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree; @@ -16,6 +18,12 @@ public RootDictionaryTreeController(IEntityService entityService, IDictionaryIte { } + [ActivatorUtilitiesConstructor] + public RootDictionaryTreeController(IEntityService entityService, SignProviderCollection signProviders, IDictionaryItemService dictionaryItemService) + : base(entityService, signProviders, dictionaryItemService) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs index f55c666cfcaf..5ab89ba2748c 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/ByKeyDocumentCollectionController.cs @@ -1,10 +1,13 @@ using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Security; @@ -20,18 +23,35 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; private readonly IDocumentCollectionPresentationFactory _documentCollectionPresentationFactory; + [ActivatorUtilitiesConstructor] public ByKeyDocumentCollectionController( IContentListViewService contentListViewService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IUmbracoMapper mapper, - IDocumentCollectionPresentationFactory documentCollectionPresentationFactory) - : base(mapper) + IDocumentCollectionPresentationFactory documentCollectionPresentationFactory, + SignProviderCollection signProviders) + : base(mapper, signProviders) { _contentListViewService = contentListViewService; _backOfficeSecurityAccessor = backOfficeSecurityAccessor; _documentCollectionPresentationFactory = documentCollectionPresentationFactory; } + [Obsolete("Please use the constructor with all parameters. Scheduled to be removed in V18")] + public ByKeyDocumentCollectionController( + IContentListViewService contentListViewService, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + IUmbracoMapper mapper, + IDocumentCollectionPresentationFactory documentCollectionPresentationFactory) + : this( + contentListViewService, + backOfficeSecurityAccessor, + mapper, + documentCollectionPresentationFactory, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + [HttpGet("{id:guid}")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] @@ -65,6 +85,7 @@ public async Task ByKey( } List collectionResponseModels = await _documentCollectionPresentationFactory.CreateCollectionModelAsync(collectionAttempt.Result!); + await PopulateSigns(collectionResponseModels); return CollectionResult(collectionResponseModels, collectionAttempt.Result!.Items.Total); } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs index b4ac5a86da1e..97d36434c9b2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Collection/DocumentCollectionControllerBase.cs @@ -1,10 +1,13 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Content; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Document; using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services.OperationStatus; @@ -17,8 +20,14 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Collection; [Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)] public abstract class DocumentCollectionControllerBase : ContentCollectionControllerBase { + protected DocumentCollectionControllerBase(IUmbracoMapper mapper, SignProviderCollection signProviders) + : base(mapper, signProviders) + { + } + + [Obsolete("Please use the constructor with all parameters. Scheduled to be removed in V18")] protected DocumentCollectionControllerBase(IUmbracoMapper mapper) - : base(mapper) + : this(mapper, StaticServiceProvider.Instance.GetRequiredService()) { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs index ebefb5bfb283..afb6575c42aa 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Item/ItemDocumentItemController.cs @@ -1,8 +1,11 @@ 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.Services.Signs; 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; @@ -14,11 +17,24 @@ public class ItemDocumentItemController : DocumentItemControllerBase { private readonly IEntityService _entityService; private readonly IDocumentPresentationFactory _documentPresentationFactory; + private readonly SignProviderCollection _signProviders; - public ItemDocumentItemController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory) + public ItemDocumentItemController( + IEntityService entityService, + IDocumentPresentationFactory documentPresentationFactory, + SignProviderCollection signProvider) { _entityService = entityService; _documentPresentationFactory = documentPresentationFactory; + _signProviders = signProvider; + } + + [Obsolete("Please use the constructor with all parameters. Scheduled for removal in V18")] + public ItemDocumentItemController( + IEntityService entityService, + IDocumentPresentationFactory documentPresentationFactory) + : this(entityService, documentPresentationFactory, StaticServiceProvider.Instance.GetRequiredService()) + { } [HttpGet] @@ -38,6 +54,15 @@ public Task Item( .OfType(); IEnumerable documentItemResponseModels = documents.Select(_documentPresentationFactory.CreateItemResponseModel); + PopulateSigns(documentItemResponseModels).GetAwaiter().GetResult(); return Task.FromResult(Ok(documentItemResponseModels)); } + + protected async Task PopulateSigns(IEnumerable itemViewModels) + { + foreach (ISignProvider signProvider in _signProviders.Where(x => x.CanProvideSigns())) + { + await signProvider.PopulateSignsAsync(itemViewModels); + } + } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/AncestorsDocumentTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/AncestorsDocumentTreeController.cs index eef178ea7086..5e3c347d0015 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/AncestorsDocumentTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/AncestorsDocumentTreeController.cs @@ -1,8 +1,10 @@ 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.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -13,6 +15,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree; [ApiVersion("1.0")] public class AncestorsDocumentTreeController : DocumentTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsDocumentTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -32,6 +35,28 @@ public AncestorsDocumentTreeController( { } + [ActivatorUtilitiesConstructor] + public AncestorsDocumentTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + IPublicAccessService publicAccessService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IDocumentPresentationFactory documentPresentationFactory) + : base( + entityService, + signProviders, + userStartNodeEntitiesService, + dataTypeService, + publicAccessService, + appCaches, + backofficeSecurityAccessor, + documentPresentationFactory) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/ChildrenDocumentTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/ChildrenDocumentTreeController.cs index 5c6b428424a3..1c749f6d15e4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/ChildrenDocumentTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/ChildrenDocumentTreeController.cs @@ -1,21 +1,45 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Cache; -using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Services.Entities; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Security; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree; [ApiVersion("1.0")] public class ChildrenDocumentTreeController : DocumentTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] + public ChildrenDocumentTreeController( + IEntityService entityService, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + IPublicAccessService publicAccessService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IDocumentPresentationFactory documentPresentationFactory) + : base( + entityService, + userStartNodeEntitiesService, + dataTypeService, + publicAccessService, + appCaches, + backofficeSecurityAccessor, + documentPresentationFactory) + { + } + + [ActivatorUtilitiesConstructor] public ChildrenDocumentTreeController( IEntityService entityService, + SignProviderCollection signProviders, IUserStartNodeEntitiesService userStartNodeEntitiesService, IDataTypeService dataTypeService, IPublicAccessService publicAccessService, @@ -24,6 +48,7 @@ public ChildrenDocumentTreeController( IDocumentPresentationFactory documentPresentationFactory) : base( entityService, + signProviders, userStartNodeEntitiesService, dataTypeService, publicAccessService, diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs index cacf862b57bb..a2015d7c7626 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/DocumentTreeControllerBase.cs @@ -1,13 +1,16 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Security; @@ -26,6 +29,7 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly IDocumentPresentationFactory _documentPresentationFactory; + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] protected DocumentTreeControllerBase( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -34,7 +38,29 @@ protected DocumentTreeControllerBase( AppCaches appCaches, IBackOfficeSecurityAccessor backofficeSecurityAccessor, IDocumentPresentationFactory documentPresentationFactory) - : base(entityService, userStartNodeEntitiesService, dataTypeService) + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + userStartNodeEntitiesService, + dataTypeService, + publicAccessService, + appCaches, + backofficeSecurityAccessor, + documentPresentationFactory) + { + } + + [ActivatorUtilitiesConstructor] + protected DocumentTreeControllerBase( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + IPublicAccessService publicAccessService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService) { _publicAccessService = publicAccessService; _appCaches = appCaches; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/RootDocumentTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/RootDocumentTreeController.cs index a9d63dc4b037..822679e5813a 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/RootDocumentTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/RootDocumentTreeController.cs @@ -1,21 +1,45 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Cache; -using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Api.Management.Services.Entities; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Security; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree; [ApiVersion("1.0")] public class RootDocumentTreeController : DocumentTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] + public RootDocumentTreeController( + IEntityService entityService, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + IPublicAccessService publicAccessService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IDocumentPresentationFactory documentPresentationFactory) + : base( + entityService, + userStartNodeEntitiesService, + dataTypeService, + publicAccessService, + appCaches, + backofficeSecurityAccessor, + documentPresentationFactory) + { + } + + [ActivatorUtilitiesConstructor] public RootDocumentTreeController( IEntityService entityService, + SignProviderCollection signProviders, IUserStartNodeEntitiesService userStartNodeEntitiesService, IDataTypeService dataTypeService, IPublicAccessService publicAccessService, @@ -24,6 +48,7 @@ public RootDocumentTreeController( IDocumentPresentationFactory documentPresentationFactory) : base( entityService, + signProviders, userStartNodeEntitiesService, dataTypeService, publicAccessService, diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/SiblingsDocumentTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/SiblingsDocumentTreeController.cs index 850eb9f856a0..d9e591b6644e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/SiblingsDocumentTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/Tree/SiblingsDocumentTreeController.cs @@ -1,9 +1,11 @@ using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -14,6 +16,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree; [ApiVersion("1.0")] public class SiblingsDocumentTreeController : DocumentTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsDocumentTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -33,6 +36,28 @@ public SiblingsDocumentTreeController( { } + [ActivatorUtilitiesConstructor] + public SiblingsDocumentTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + IPublicAccessService publicAccessService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IDocumentPresentationFactory documentPresentationFactory) + : base( + entityService, + signProviders, + userStartNodeEntitiesService, + dataTypeService, + publicAccessService, + appCaches, + backofficeSecurityAccessor, + documentPresentationFactory) + { + } + [HttpGet("siblings")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/AncestorsDocumentBlueprintTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/AncestorsDocumentBlueprintTreeController.cs index 9124b1ae2a10..c3d155e54c5f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/AncestorsDocumentBlueprintTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/AncestorsDocumentBlueprintTreeController.cs @@ -1,7 +1,9 @@ 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.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -10,11 +12,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree; [ApiVersion("1.0")] public class AncestorsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory) : base(entityService, documentPresentationFactory) { } + [ActivatorUtilitiesConstructor] + public AncestorsDocumentBlueprintTreeController(IEntityService entityService, SignProviderCollection signProviders, IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders, documentPresentationFactory) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/ChildrenDocumentBlueprintTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/ChildrenDocumentBlueprintTreeController.cs index 92c1fe28b29a..7f2f3ea2267b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/ChildrenDocumentBlueprintTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/ChildrenDocumentBlueprintTreeController.cs @@ -1,8 +1,10 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -11,11 +13,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree; [ApiVersion("1.0")] public class ChildrenDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory) : base(entityService, documentPresentationFactory) { } + [ActivatorUtilitiesConstructor] + public ChildrenDocumentBlueprintTreeController(IEntityService entityService, SignProviderCollection signProviders, IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders, documentPresentationFactory) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs index aeaf65b7ef08..3a02abb6f0bb 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/DocumentBlueprintTreeControllerBase.cs @@ -1,10 +1,13 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -19,8 +22,17 @@ public class DocumentBlueprintTreeControllerBase : FolderTreeControllerBase(), + documentPresentationFactory) + { + } + + public DocumentBlueprintTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders) => _documentPresentationFactory = documentPresentationFactory; protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DocumentBlueprint; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/RootDocumentBlueprintTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/RootDocumentBlueprintTreeController.cs index 79e20385c1fa..b2a8bfa9cf96 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/RootDocumentBlueprintTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/RootDocumentBlueprintTreeController.cs @@ -1,8 +1,10 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -11,11 +13,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree; [ApiVersion("1.0")] public class RootDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory) : base(entityService, documentPresentationFactory) { } + [ActivatorUtilitiesConstructor] + public RootDocumentBlueprintTreeController(IEntityService entityService, SignProviderCollection signProviders, IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders, documentPresentationFactory) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/SiblingsDocumentBlueprintTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/SiblingsDocumentBlueprintTreeController.cs index 6c5e5314b663..c6592c5dda55 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/SiblingsDocumentBlueprintTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentBlueprint/Tree/SiblingsDocumentBlueprintTreeController.cs @@ -1,7 +1,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree; public class SiblingsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory) : base(entityService, documentPresentationFactory) { } + [ActivatorUtilitiesConstructor] + public SiblingsDocumentBlueprintTreeController(IEntityService entityService, SignProviderCollection signProviders, IDocumentPresentationFactory documentPresentationFactory) + : base(entityService, signProviders, documentPresentationFactory) + { + } + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/AncestorsDocumentTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/AncestorsDocumentTypeTreeController.cs index c49f7b0d3ccc..02bb34403f4f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/AncestorsDocumentTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/AncestorsDocumentTypeTreeController.cs @@ -1,6 +1,8 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree; [ApiVersion("1.0")] public class AncestorsDocumentTypeTreeController : DocumentTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService) : base(entityService, contentTypeService) { } + [ActivatorUtilitiesConstructor] + public AncestorsDocumentTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IContentTypeService contentTypeService) + : base(entityService, signProviders, contentTypeService) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/ChildrenDocumentTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/ChildrenDocumentTypeTreeController.cs index de25c4c1be17..9127a359d306 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/ChildrenDocumentTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/ChildrenDocumentTypeTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree; [ApiVersion("1.0")] public class ChildrenDocumentTypeTreeController : DocumentTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService) : base(entityService, contentTypeService) { } + [ActivatorUtilitiesConstructor] + public ChildrenDocumentTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IContentTypeService contentTypeService) + : base(entityService, signProviders, contentTypeService) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs index 0a5441720016..a76fd49ee8da 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/DocumentTypeTreeControllerBase.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -18,8 +21,17 @@ public class DocumentTypeTreeControllerBase : FolderTreeControllerBase + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + contentTypeService) + { + } + + public DocumentTypeTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IContentTypeService contentTypeService) + : base(entityService, signProviders) => _contentTypeService = contentTypeService; protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.DocumentType; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/RootDocumentTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/RootDocumentTypeTreeController.cs index 4824dc04957a..b581b7bbb459 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/RootDocumentTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/RootDocumentTypeTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree; [ApiVersion("1.0")] public class RootDocumentTypeTreeController : DocumentTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService) : base(entityService, contentTypeService) { } + [ActivatorUtilitiesConstructor] + public RootDocumentTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IContentTypeService contentTypeService) + : base(entityService, signProviders, contentTypeService) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/SiblingsDocumentTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/SiblingsDocumentTypeTreeController.cs index c0c36ab9d86b..3ecce3e3839f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/SiblingsDocumentTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/DocumentType/Tree/SiblingsDocumentTypeTreeController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -8,11 +10,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree; public class SiblingsDocumentTypeTreeController : DocumentTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService) : base(entityService, contentTypeService) { } + [ActivatorUtilitiesConstructor] + public SiblingsDocumentTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IContentTypeService contentTypeService) + : base(entityService, signProviders, contentTypeService) + { + } + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs index ba6eb5c8b398..f2f55e9242ca 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/ByKeyMediaCollectionController.cs @@ -1,10 +1,13 @@ using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Media.Collection; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Security; @@ -20,18 +23,35 @@ public class ByKeyMediaCollectionController : MediaCollectionControllerBase private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; private readonly IMediaCollectionPresentationFactory _mediaCollectionPresentationFactory; + [ActivatorUtilitiesConstructor] public ByKeyMediaCollectionController( IMediaListViewService mediaListViewService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IUmbracoMapper mapper, - IMediaCollectionPresentationFactory mediaCollectionPresentationFactory) - : base(mapper) + IMediaCollectionPresentationFactory mediaCollectionPresentationFactory, + SignProviderCollection signProviders) + : base(mapper, signProviders) { _mediaListViewService = mediaListViewService; _backOfficeSecurityAccessor = backOfficeSecurityAccessor; _mediaCollectionPresentationFactory = mediaCollectionPresentationFactory; } + [Obsolete("Please use the constructors with all the parameters. Scheduled to be removed in Umbraco 18")] + public ByKeyMediaCollectionController( + IMediaListViewService mediaListViewService, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + IUmbracoMapper mapper, + IMediaCollectionPresentationFactory mediaCollectionPresentationFactory) + : this( + mediaListViewService, + backOfficeSecurityAccessor, + mapper, + mediaCollectionPresentationFactory, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + [HttpGet] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] @@ -64,6 +84,7 @@ public async Task ByKey( } List collectionResponseModels = await _mediaCollectionPresentationFactory.CreateCollectionModelAsync(collectionAttempt.Result!); + await PopulateSigns(collectionResponseModels); return CollectionResult(collectionResponseModels, collectionAttempt.Result!.Items.Total); } } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs index cf6b05d8b96c..b7269c603bcf 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Collection/MediaCollectionControllerBase.cs @@ -1,10 +1,14 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Content; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; using Umbraco.Cms.Api.Management.ViewModels.Media; using Umbraco.Cms.Api.Management.ViewModels.Media.Collection; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services.OperationStatus; @@ -17,8 +21,17 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Collection; [Authorize(Policy = AuthorizationPolicies.SectionAccessMedia)] public abstract class MediaCollectionControllerBase : ContentCollectionControllerBase { + private readonly SignProviderCollection _signProviders; + + protected MediaCollectionControllerBase(IUmbracoMapper mapper, SignProviderCollection signProviders) + : base(mapper, signProviders) + { + _signProviders = signProviders; + } + + [Obsolete("Please use the constructors with all the parameters. Scheduled to be removed in Umbraco 18")] protected MediaCollectionControllerBase(IUmbracoMapper mapper) - : base(mapper) + : this(mapper, StaticServiceProvider.Instance.GetRequiredService()) { } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/AncestorsMediaTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/AncestorsMediaTreeController.cs index 9fde8d2a8e39..bf5bade404a6 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/AncestorsMediaTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/AncestorsMediaTreeController.cs @@ -1,8 +1,10 @@ -using Asp.Versioning; +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.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -13,6 +15,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Tree; [ApiVersion("1.0")] public class AncestorsMediaTreeController : MediaTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsMediaTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -24,6 +27,19 @@ public AncestorsMediaTreeController( { } + [ActivatorUtilitiesConstructor] + public AncestorsMediaTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IMediaPresentationFactory mediaPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor, mediaPresentationFactory) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/ChildrenMediaTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/ChildrenMediaTreeController.cs index 6aee4b020678..c61de0a65b25 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/ChildrenMediaTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/ChildrenMediaTreeController.cs @@ -1,9 +1,11 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -14,6 +16,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Tree; [ApiVersion("1.0")] public class ChildrenMediaTreeController : MediaTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenMediaTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -25,6 +28,19 @@ public ChildrenMediaTreeController( { } + [ActivatorUtilitiesConstructor] + public ChildrenMediaTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IMediaPresentationFactory mediaPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor, mediaPresentationFactory) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs index 7b2f7facd4bb..f3283466c4e0 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/MediaTreeControllerBase.cs @@ -1,12 +1,15 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Routing; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Security; @@ -24,6 +27,7 @@ public class MediaTreeControllerBase : UserStartNodeTreeControllerBase(), + userStartNodeEntitiesService, + dataTypeService, + appCaches, + backofficeSecurityAccessor, + mediaPresentationFactory) + { + } + + [ActivatorUtilitiesConstructor] + public MediaTreeControllerBase( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IMediaPresentationFactory mediaPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService) { _appCaches = appCaches; _backofficeSecurityAccessor = backofficeSecurityAccessor; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/RootMediaTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/RootMediaTreeController.cs index d2ffa8a4bbca..2cadb4c4fce1 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/RootMediaTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/RootMediaTreeController.cs @@ -1,9 +1,11 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -14,6 +16,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Tree; [ApiVersion("1.0")] public class RootMediaTreeController : MediaTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootMediaTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -25,6 +28,19 @@ public RootMediaTreeController( { } + [ActivatorUtilitiesConstructor] + public RootMediaTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IMediaPresentationFactory mediaPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor, mediaPresentationFactory) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/SiblingsMediaTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/SiblingsMediaTreeController.cs index 012816dbfc4d..910eeb0bfbc4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/SiblingsMediaTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/Tree/SiblingsMediaTreeController.cs @@ -1,8 +1,10 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.Factories; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Security; @@ -12,6 +14,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Media.Tree; public class SiblingsMediaTreeController : MediaTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsMediaTreeController( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, @@ -23,6 +26,19 @@ public SiblingsMediaTreeController( { } + [ActivatorUtilitiesConstructor] + public SiblingsMediaTreeController( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService, + AppCaches appCaches, + IBackOfficeSecurityAccessor backofficeSecurityAccessor, + IMediaPresentationFactory mediaPresentationFactory) + : base(entityService, signProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backofficeSecurityAccessor, mediaPresentationFactory) + { + } + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings(CancellationToken cancellationToken, Guid target, int before, int after, Guid? dataTypeId = null) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/AncestorsMediaTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/AncestorsMediaTypeTreeController.cs index ff90cea5293e..eeb3c73c5e97 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/AncestorsMediaTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/AncestorsMediaTypeTreeController.cs @@ -1,6 +1,8 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Tree; [ApiVersion("1.0")] public class AncestorsMediaTypeTreeController : MediaTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService) : base(entityService, mediaTypeService) { } + [ActivatorUtilitiesConstructor] + public AncestorsMediaTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IMediaTypeService mediaTypeService) + : base(entityService, signProviders, mediaTypeService) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/ChildrenMediaTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/ChildrenMediaTypeTreeController.cs index 3662360c8954..545c5178e307 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/ChildrenMediaTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/ChildrenMediaTypeTreeController.cs @@ -1,7 +1,9 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -10,11 +12,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Tree; [ApiVersion("1.0")] public class ChildrenMediaTypeTreeController : MediaTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService) : base(entityService, mediaTypeService) { } + [ActivatorUtilitiesConstructor] + public ChildrenMediaTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IMediaTypeService mediaTypeService) + : base(entityService, signProviders, mediaTypeService) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs index a3cc202b2845..9731a7fb4a85 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/MediaTypeTreeControllerBase.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -19,8 +22,17 @@ public class MediaTypeTreeControllerBase : FolderTreeControllerBase + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + mediaTypeService) + { + } + + public MediaTypeTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IMediaTypeService mediaTypeService) + : base(entityService, signProviders) => _mediaTypeService = mediaTypeService; protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MediaType; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/RootMediaTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/RootMediaTypeTreeController.cs index 7c0aca479111..3def7719cf6d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/RootMediaTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/RootMediaTypeTreeController.cs @@ -1,7 +1,9 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -10,11 +12,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Tree; [ApiVersion("1.0")] public class RootMediaTypeTreeController : MediaTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService) : base(entityService, mediaTypeService) { } + [ActivatorUtilitiesConstructor] + public RootMediaTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IMediaTypeService mediaTypeService) + : base(entityService, signProviders, mediaTypeService) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/SiblingsMediaTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/SiblingsMediaTypeTreeController.cs index f4dd06d6325a..5e873fb9cca2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/SiblingsMediaTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MediaType/Tree/SiblingsMediaTypeTreeController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -8,11 +10,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.MediaType.Tree; public class SiblingsMediaTypeTreeController : MediaTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsMediaTypeTreeController(IEntityService entityService, IMediaTypeService mediaTypeService) : base(entityService, mediaTypeService) { } + [ActivatorUtilitiesConstructor] + public SiblingsMediaTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IMediaTypeService mediaTypeService) + : base(entityService, signProviders, mediaTypeService) + { + } + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs index 2066e7976819..90ef8d12d9a1 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/MemberGroupTreeControllerBase.cs @@ -1,7 +1,8 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; @@ -15,10 +16,16 @@ namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup.Tree; [Authorize(Policy = AuthorizationPolicies.TreeAccessMemberGroups)] public class MemberGroupTreeControllerBase : NamedEntityTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public MemberGroupTreeControllerBase(IEntityService entityService) : base(entityService) { } + public MemberGroupTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberGroup; } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/RootMemberGroupTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/RootMemberGroupTreeController.cs index 3328df551435..08f83192050e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/RootMemberGroupTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberGroup/Tree/RootMemberGroupTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Api.Common.ViewModels.Pagination; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Api.Management.Services.Signs; +using Microsoft.Extensions.DependencyInjection; namespace Umbraco.Cms.Api.Management.Controllers.MemberGroup.Tree; [ApiVersion("1.0")] public class RootMemberGroupTreeController : MemberGroupTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootMemberGroupTreeController(IEntityService entityService) : base(entityService) { } + [ActivatorUtilitiesConstructor] + public RootMemberGroupTreeController(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs index 9fc8111b6c27..a612b32d87d4 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/MemberTypeTreeControllerBase.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -18,10 +21,20 @@ public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + memberTypeService) + { + } + + public MemberTypeTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders, IMemberTypeService memberTypeService) + : base(entityService, signProviders) => _memberTypeService = memberTypeService; + protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberType; protected override MemberTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/RootMemberTypeTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/RootMemberTypeTreeController.cs index eeae87da51a2..4ce9248ecc68 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/RootMemberTypeTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/MemberType/Tree/RootMemberTypeTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree; [ApiVersion("1.0")] public class RootMemberTypeTreeController : MemberTypeTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootMemberTypeTreeController(IEntityService entityService, IMemberTypeService memberTypeService) : base(entityService, memberTypeService) { } + [ActivatorUtilitiesConstructor] + public RootMemberTypeTreeController(IEntityService entityService, SignProviderCollection signProviders, IMemberTypeService memberTypeService) + : base(entityService, signProviders, memberTypeService) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/AncestorsTemplateTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/AncestorsTemplateTreeController.cs index 3d5f0d3ff516..943aeba37f59 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/AncestorsTemplateTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/AncestorsTemplateTreeController.cs @@ -1,6 +1,8 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -9,11 +11,18 @@ namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; [ApiVersion("1.0")] public class AncestorsTemplateTreeController : TemplateTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public AncestorsTemplateTreeController(IEntityService entityService) : base(entityService) { } + [ActivatorUtilitiesConstructor] + public AncestorsTemplateTreeController(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + [HttpGet("ancestors")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/ChildrenTemplateTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/ChildrenTemplateTreeController.cs index b5d487b0ed6a..030be7d062b2 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/ChildrenTemplateTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/ChildrenTemplateTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; [ApiVersion("1.0")] public class ChildrenTemplateTreeController : TemplateTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public ChildrenTemplateTreeController(IEntityService entityService) : base(entityService) { } + [ActivatorUtilitiesConstructor] + public ChildrenTemplateTreeController(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + [HttpGet("children")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/RootTemplateTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/RootTemplateTreeController.cs index 4de5731c40a5..871fdcf3682f 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/RootTemplateTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/RootTemplateTreeController.cs @@ -1,20 +1,29 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Core.Services; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; [ApiVersion("1.0")] public class RootTemplateTreeController : TemplateTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public RootTemplateTreeController(IEntityService entityService) : base(entityService) { } + [ActivatorUtilitiesConstructor] + public RootTemplateTreeController(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + [HttpGet("root")] [MapToApiVersion("1.0")] [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/SiblingsTemplateTreeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/SiblingsTemplateTreeController.cs index f566dd52f661..542014c0424b 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/SiblingsTemplateTreeController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/SiblingsTemplateTreeController.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Services; @@ -8,11 +10,19 @@ namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; public class SiblingsTemplateTreeController : TemplateTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public SiblingsTemplateTreeController(IEntityService entityService) : base(entityService) { } + [ActivatorUtilitiesConstructor] + public SiblingsTemplateTreeController(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + + [HttpGet("siblings")] [ProducesResponseType(typeof(SubsetViewModel), StatusCodes.Status200OK)] public async Task>> Siblings( diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs index 2ab19a1ee5fa..aa65c4f7a514 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Template/Tree/TemplateTreeControllerBase.cs @@ -1,7 +1,8 @@ -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Management.Controllers.Tree; using Umbraco.Cms.Api.Management.Routing; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; @@ -15,10 +16,16 @@ namespace Umbraco.Cms.Api.Management.Controllers.Template.Tree; [Authorize(Policy = AuthorizationPolicies.TreeAccessTemplates)] public class TemplateTreeControllerBase : NamedEntityTreeControllerBase { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] public TemplateTreeControllerBase(IEntityService entityService) : base(entityService) { } + public TemplateTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Template; } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/EntityTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/EntityTreeControllerBase.cs index 2f5a62b9bb4f..8a5cc27ece0d 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/EntityTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/EntityTreeControllerBase.cs @@ -1,8 +1,11 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Extensions; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; @@ -13,8 +16,21 @@ namespace Umbraco.Cms.Api.Management.Controllers.Tree; public abstract class EntityTreeControllerBase : ManagementApiControllerBase where TItem : EntityTreeItemResponseModel, new() { + private readonly SignProviderCollection _signProviders; + + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] protected EntityTreeControllerBase(IEntityService entityService) - => EntityService = entityService; + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + + protected EntityTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders) + { + EntityService = entityService; + _signProviders = signProviders; + } protected IEntityService EntityService { get; } @@ -22,34 +38,38 @@ protected EntityTreeControllerBase(IEntityService entityService) protected virtual Ordering ItemOrdering => Ordering.By(nameof(Infrastructure.Persistence.Dtos.NodeDto.Text)); - protected Task>> GetRoot(int skip, int take) + protected async Task>> GetRoot(int skip, int take) { IEntitySlim[] rootEntities = GetPagedRootEntities(skip, take, out var totalItems); TItem[] treeItemViewModels = MapTreeItemViewModels(null, rootEntities); + await PopulateSigns(treeItemViewModels); + PagedViewModel result = PagedViewModel(treeItemViewModels, totalItems); - return Task.FromResult>>(Ok(result)); + return Ok(result); } - protected Task>> GetChildren(Guid parentId, int skip, int take) + protected async Task>> GetChildren(Guid parentId, int skip, int take) { IEntitySlim[] children = GetPagedChildEntities(parentId, skip, take, out var totalItems); TItem[] treeItemViewModels = MapTreeItemViewModels(parentId, children); + await PopulateSigns(treeItemViewModels); + PagedViewModel result = PagedViewModel(treeItemViewModels, totalItems); - return Task.FromResult>>(Ok(result)); + return Ok(result); } - protected Task>> GetSiblings(Guid target, int before, int after) + protected async Task>> GetSiblings(Guid target, int before, int after) { IEntitySlim[] siblings = GetSiblingEntities(target, before, after, out var totalBefore, out var totalAfter); if (siblings.Length == 0) { - return Task.FromResult>>(NotFound()); + return NotFound(); } IEntitySlim? entity = siblings.FirstOrDefault(); @@ -59,16 +79,18 @@ protected Task>> GetSiblings(Guid target, in TItem[] treeItemViewModels = MapTreeItemViewModels(parentKey, siblings); + await PopulateSigns(treeItemViewModels); + SubsetViewModel result = SubsetViewModel(treeItemViewModels, totalBefore, totalAfter); - return Task.FromResult>>(Ok(result)); + return Ok(result); } protected virtual async Task>> GetAncestors(Guid descendantKey, bool includeSelf = true) { IEntitySlim[] ancestorEntities = await GetAncestorEntitiesAsync(descendantKey, includeSelf); - TItem[] result = ancestorEntities + TItem[] treeItemViewModels = ancestorEntities .Select(ancestor => { IEntitySlim? parent = ancestor.ParentId > 0 @@ -79,7 +101,9 @@ protected virtual async Task>> GetAncestors(Guid }) .ToArray(); - return Ok(result); + await PopulateSigns(treeItemViewModels); + + return Ok(treeItemViewModels); } protected virtual Task GetAncestorEntitiesAsync(Guid descendantKey, bool includeSelf) @@ -138,6 +162,14 @@ protected virtual IEntitySlim[] GetSiblingEntities(Guid target, int before, int protected virtual TItem[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities) => entities.Select(entity => MapTreeItemViewModel(parentKey, entity)).ToArray(); + protected virtual async Task PopulateSigns(TItem[] treeItemViewModels) + { + foreach (ISignProvider signProvider in _signProviders.Where(x => x.CanProvideSigns())) + { + await signProvider.PopulateSignsAsync(treeItemViewModels); + } + } + protected virtual TItem MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity) { var viewModel = new TItem @@ -147,9 +179,9 @@ protected virtual TItem MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity Parent = parentKey.HasValue ? new ReferenceByIdModel { - Id = parentKey.Value + Id = parentKey.Value, } - : null + : null, }; return viewModel; diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs index 4e52bbe4e811..d54e53763766 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/FolderTreeControllerBase.cs @@ -1,9 +1,12 @@ +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Extensions; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Extensions; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Controllers.Tree; @@ -28,9 +31,16 @@ protected override Ordering ItemOrdering } } + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] protected FolderTreeControllerBase(IEntityService entityService) - : base(entityService) => - // ReSharper disable once VirtualMemberCallInConstructor + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + + protected FolderTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) => _folderObjectTypeId = FolderObjectType.GetGuid(); protected abstract UmbracoObjectTypes FolderObjectType { get; } diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/NamedEntityTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/NamedEntityTreeControllerBase.cs index a50c6b1cbe42..be1fc3c6ce88 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/NamedEntityTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/NamedEntityTreeControllerBase.cs @@ -1,4 +1,5 @@ -using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; @@ -7,11 +8,17 @@ namespace Umbraco.Cms.Api.Management.Controllers.Tree; public abstract class NamedEntityTreeControllerBase : EntityTreeControllerBase where TItem : NamedEntityTreeItemResponseModel, new() { + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] protected NamedEntityTreeControllerBase(IEntityService entityService) : base(entityService) { } + protected NamedEntityTreeControllerBase(IEntityService entityService, SignProviderCollection signProviders) + : base(entityService, signProviders) + { + } + protected override TItem MapTreeItemViewModel(Guid? parentKey, IEntitySlim entity) { TItem item = base.MapTreeItemViewModel(parentKey, entity); diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs index 6f95e6210e64..a6d3ba5ff56e 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Tree/UserStartNodeTreeControllerBase.cs @@ -1,7 +1,10 @@ +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Management.Models.Entities; using Umbraco.Cms.Api.Management.Services.Entities; +using Umbraco.Cms.Api.Management.Services.Signs; using Umbraco.Cms.Api.Management.ViewModels.Tree; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Services; using Umbraco.Extensions; @@ -19,11 +22,25 @@ public abstract class UserStartNodeTreeControllerBase : EntityTreeControl private Dictionary _accessMap = new(); private Guid? _dataTypeKey; + [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")] protected UserStartNodeTreeControllerBase( IEntityService entityService, IUserStartNodeEntitiesService userStartNodeEntitiesService, IDataTypeService dataTypeService) - : base(entityService) + : this( + entityService, + StaticServiceProvider.Instance.GetRequiredService(), + userStartNodeEntitiesService, + dataTypeService) + { + } + + protected UserStartNodeTreeControllerBase( + IEntityService entityService, + SignProviderCollection signProviders, + IUserStartNodeEntitiesService userStartNodeEntitiesService, + IDataTypeService dataTypeService) + : base(entityService, signProviders) { _userStartNodeEntitiesService = userStartNodeEntitiesService; _dataTypeService = dataTypeService; diff --git a/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilder.Collections.cs b/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilder.Collections.cs new file mode 100644 index 000000000000..e93fb98dfcf8 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilder.Collections.cs @@ -0,0 +1,27 @@ +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Core.DependencyInjection; + +namespace Umbraco.Extensions +{ + /// + /// Extension methods for for the Umbraco back office + /// + public static partial class UmbracoBuilderExtensions + { + internal static void AddCollectionBuilders(this IUmbracoBuilder builder) + { + builder.SignProviders() + .Append() + .Append() + .Append() + .Append(); + } + + /// + /// Gets the sign providers collection builder. + /// + /// The builder. + public static SignProviderCollectionBuilder SignProviders(this IUmbracoBuilder builder) + => builder.WithCollectionBuilder(); + } +} diff --git a/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilderExtensions.cs index 48e53c97e0d3..a788b1fad24d 100644 --- a/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Cms.Api.Management/DependencyInjection/UmbracoBuilderExtensions.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Api.Common.Configuration; using Umbraco.Cms.Api.Common.DependencyInjection; using Umbraco.Cms.Api.Management.Configuration; @@ -95,6 +95,8 @@ public static IUmbracoBuilder AddUmbracoManagementApi(this IUmbracoBuilder build }); } + builder.AddCollectionBuilders(); + return builder; } } diff --git a/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs index 0e9aeba492f5..7aeb4f1b15a9 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs @@ -115,6 +115,7 @@ private void Map(ISimpleContentType source, DocumentTypeCollectionReferenceRespo target.Id = source.Key; target.Alias = source.Alias; target.Icon = source.Icon ?? string.Empty; + target.Collection = ReferenceByIdModel.ReferenceOrNull(source.ListView); } // Umbraco.Code.MapAll diff --git a/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs index af1a0fff090d..c789b9cbc714 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs @@ -99,5 +99,6 @@ private void Map(ISimpleContentType source, MediaTypeCollectionReferenceResponse target.Id = source.Key; target.Alias = source.Alias; target.Icon = source.Icon ?? string.Empty; + target.Collection = ReferenceByIdModel.ReferenceOrNull(source.ListView); } } diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProvider.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProvider.cs new file mode 100644 index 000000000000..9a64bdc7da7d --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProvider.cs @@ -0,0 +1,78 @@ +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Media.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Implements a that provides signs for documents that has a collection. +/// +public class HasCollectionSignProvider : ISignProvider +{ + private const string Alias = Constants.Conventions.Signs.Prefix + "HasCollection"; + + /// + public bool CanProvideSigns() + where TItem : IHasSigns => + typeof(TItem) == typeof(DocumentTreeItemResponseModel) || + typeof(TItem) == typeof(DocumentCollectionResponseModel) || + typeof(TItem) == typeof(MediaTreeItemResponseModel) || + typeof(TItem) == typeof(MediaCollectionResponseModel) || + typeof(TItem) == typeof(DocumentItemResponseModel); + +/// + public Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns + { + foreach (TItem item in itemViewModels) + { + switch (item) + { + case DocumentTreeItemResponseModel response: + if (response.DocumentType.Collection != null) + { + item.AddSign(Alias); + } + + break; + + case DocumentCollectionResponseModel response: + if (response.DocumentType.Collection != null) + { + item.AddSign(Alias); + } + + break; + + case MediaTreeItemResponseModel response: + if (response.MediaType.Collection != null) + { + item.AddSign(Alias); + } + + break; + + case MediaCollectionResponseModel response: + if (response.MediaType.Collection != null) + { + item.AddSign(Alias); + } + + break; + + case DocumentItemResponseModel response: + if (response.DocumentType.Collection != null) + { + item.AddSign(Alias); + } + + break; + } + } + + return Task.CompletedTask; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProvider.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProvider.cs new file mode 100644 index 000000000000..b4c33b5a0caa --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProvider.cs @@ -0,0 +1,60 @@ +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Document; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Implements a that provides signs for documents that have pending changes. +/// +public class HasPendingChangesSignProvider : ISignProvider +{ + private const string Alias = Constants.Conventions.Signs.Prefix + "PendingChanges"; + + /// + public bool CanProvideSigns() + where TItem : IHasSigns => + typeof(TItem) == typeof(DocumentTreeItemResponseModel) || + typeof(TItem) == typeof(DocumentCollectionResponseModel) || + typeof(TItem) == typeof(DocumentItemResponseModel); + + /// + public Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns + { + foreach (TItem item in itemViewModels) + { + switch (item) + { + case DocumentTreeItemResponseModel response: + if (response.Variants.Any(variant => variant.State == DocumentVariantState.PublishedPendingChanges)) + { + item.AddSign(Alias); + } + + break; + + case DocumentCollectionResponseModel response: + if (response.Variants.Any(variant => variant.State == DocumentVariantState.PublishedPendingChanges)) + { + item.AddSign(Alias); + } + + break; + + case DocumentItemResponseModel response: + if (response.Variants.Any(variant => variant.State == DocumentVariantState.PublishedPendingChanges)) + { + item.AddSign(Alias); + } + + break; + } + } + + return Task.CompletedTask; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProvider.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProvider.cs new file mode 100644 index 000000000000..599d10ae67e5 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProvider.cs @@ -0,0 +1,43 @@ +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Services; +using Constants = Umbraco.Cms.Core.Constants; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Implements a that provides signs for documents that are scheduled for publication. +/// +internal class HasScheduleSignProvider : ISignProvider +{ + private const string Alias = Constants.Conventions.Signs.Prefix + "ScheduledForPublish"; + + private readonly IContentService _contentService; + + /// + /// Initializes a new instance of the class. + /// + public HasScheduleSignProvider(IContentService contentService) => _contentService = contentService; + + /// + public bool CanProvideSigns() + where TItem : IHasSigns => + typeof(TItem) == typeof(DocumentTreeItemResponseModel) || + typeof(TItem) == typeof(DocumentCollectionResponseModel) || + typeof(TItem) == typeof(DocumentItemResponseModel); + + /// + public Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns + { + IEnumerable contentKeysScheduledForPublishing = _contentService.GetScheduledContentKeys(itemViewModels.Select(x => x.Id)); + foreach (Guid key in contentKeysScheduledForPublishing) + { + itemViewModels.First(x => x.Id == key).AddSign(Alias); + } + + return Task.CompletedTask; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/ISignProvider.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/ISignProvider.cs new file mode 100644 index 000000000000..f485fd389f54 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/ISignProvider.cs @@ -0,0 +1,25 @@ +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Tree; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Defines operation for the provision of presentation signs for tree and collection nodes. +/// +public interface ISignProvider +{ + /// + /// Gets a value indicating whether this provider can provide signs for the specified item type. + /// + /// Type of view model supporting signs. + bool CanProvideSigns() + where TItem : IHasSigns; + + /// + /// Populates the provided item view models with signs. + /// + /// Type of item view model supporting signs. + /// The collection of item view models to be populated with signs. + Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns; +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProvider.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProvider.cs new file mode 100644 index 000000000000..844599e14fd3 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProvider.cs @@ -0,0 +1,35 @@ +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Implements a that provides signs for documents that are protected. +/// +internal class IsProtectedSignProvider : ISignProvider +{ + private const string Alias = Constants.Conventions.Signs.Prefix + "IsProtected"; + + /// > + public bool CanProvideSigns() + where TItem : IHasSigns => + typeof(IIsProtected).IsAssignableFrom(typeof(TItem)); + + /// > + public Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns + { + foreach (TItem item in itemViewModels) + { + if (item is IIsProtected { IsProtected: true }) + { + item.AddSign(Alias); + } + } + + return Task.CompletedTask; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollection.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollection.cs new file mode 100644 index 000000000000..81c50aafd55e --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollection.cs @@ -0,0 +1,18 @@ +using Umbraco.Cms.Core.Composing; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Defines an ordered collection of . +/// +public class SignProviderCollection : BuilderCollectionBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The collection items. + public SignProviderCollection(Func> items) + : base(items) + { + } +} diff --git a/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollectionBuilder.cs b/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollectionBuilder.cs new file mode 100644 index 000000000000..a07d67634ff6 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Services/Signs/SignProviderCollectionBuilder.cs @@ -0,0 +1,12 @@ +using Umbraco.Cms.Core.Composing; + +namespace Umbraco.Cms.Api.Management.Services.Signs; + +/// +/// Builds an ordered collection of . +/// +public class SignProviderCollectionBuilder : OrderedCollectionBuilderBase +{ + /// + protected override SignProviderCollectionBuilder This => this; +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Content/ContentResponseModelBase.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Content/ContentResponseModelBase.cs index 1eddf7af46f0..8425079f524a 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Content/ContentResponseModelBase.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Content/ContentResponseModelBase.cs @@ -1,11 +1,19 @@ -using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Models.ContentEditing; namespace Umbraco.Cms.Api.Management.ViewModels.Content; public abstract class ContentResponseModelBase - : ContentModelBase + : ContentModelBase, IHasSigns where TValueResponseModelBase : ValueModelBase where TVariantResponseModel : VariantResponseModelBase { + private readonly List _signs = []; + public Guid Id { get; set; } + + public IEnumerable Signs => _signs.AsEnumerable(); + + public void AddSign(string alias) => _signs.Add(new SignModel { Alias = alias }); + + public void RemoveSign(string alias) => _signs.RemoveAll(x => x.Alias == alias); } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/ContentTypeCollectionReferenceResponseModelBase.cs b/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/ContentTypeCollectionReferenceResponseModelBase.cs index 70d3b992ad15..1760b8d36441 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/ContentTypeCollectionReferenceResponseModelBase.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/ContentType/ContentTypeCollectionReferenceResponseModelBase.cs @@ -7,4 +7,6 @@ public abstract class ContentTypeCollectionReferenceResponseModelBase public string Alias { get; set; } = string.Empty; public string Icon { get; set; } = string.Empty; + + public ReferenceByIdModel? Collection { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Collection/DocumentCollectionResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Collection/DocumentCollectionResponseModel.cs index 391714346a9f..107ec0c8917f 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Collection/DocumentCollectionResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Collection/DocumentCollectionResponseModel.cs @@ -3,7 +3,7 @@ namespace Umbraco.Cms.Api.Management.ViewModels.Document.Collection; -public class DocumentCollectionResponseModel : ContentCollectionResponseModelBase +public class DocumentCollectionResponseModel : ContentCollectionResponseModelBase, IHasSigns, IIsProtected { public DocumentTypeCollectionReferenceResponseModel DocumentType { get; set; } = new(); diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs index 25f4975b9f74..4301b8096d55 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs @@ -1,10 +1,9 @@ -using Umbraco.Cms.Api.Management.ViewModels.Content; using Umbraco.Cms.Api.Management.ViewModels.DocumentType; using Umbraco.Cms.Api.Management.ViewModels.Item; namespace Umbraco.Cms.Api.Management.ViewModels.Document.Item; -public class DocumentItemResponseModel : ItemResponseModelBase +public class DocumentItemResponseModel : ItemResponseModelBase, IIsProtected { public bool IsTrashed { get; set; } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/IHasSigns.cs b/src/Umbraco.Cms.Api.Management/ViewModels/IHasSigns.cs new file mode 100644 index 000000000000..23aafd1e2bd8 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/IHasSigns.cs @@ -0,0 +1,30 @@ +namespace Umbraco.Cms.Api.Management.ViewModels; + +/// +/// Marker interface that indicates the type has support for backoffice signs (presented as icons +/// overlaying the main icon for the entity). +/// +public interface IHasSigns +{ + /// + /// Gets the unique identifier for the entity. + /// + Guid Id { get; } + + /// + /// Gets the collection of signs for the entity. + /// + IEnumerable Signs { get; } + + /// + /// Adds a sign to the entity with the specified alias. + /// + /// + void AddSign(string alias); + + /// + /// Removes a sign from the entity with the specified alias. + /// + /// + void RemoveSign(string alias); +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/IIsProtected.cs b/src/Umbraco.Cms.Api.Management/ViewModels/IIsProtected.cs new file mode 100644 index 000000000000..3babb19b82f1 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/IIsProtected.cs @@ -0,0 +1,12 @@ +namespace Umbraco.Cms.Api.Management.ViewModels; + +/// +/// Marker interface that indicates the type can represent the state of protected content. +/// +public interface IIsProtected +{ + /// + /// Gets or sets a value indicating whether the model represents content that is protected. + /// + bool IsProtected { get; set; } +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Item/ItemResponseModelBase.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Item/ItemResponseModelBase.cs index f39ee8c57829..01622557fd9b 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Item/ItemResponseModelBase.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Item/ItemResponseModelBase.cs @@ -1,6 +1,14 @@ namespace Umbraco.Cms.Api.Management.ViewModels.Item; -public abstract class ItemResponseModelBase +public abstract class ItemResponseModelBase : IHasSigns { + private readonly List _signs = []; + public Guid Id { get; set; } + + public IEnumerable Signs => _signs.AsEnumerable(); + + public void AddSign(string alias) => _signs.Add(new SignModel { Alias = alias }); + + public void RemoveSign(string alias) => _signs.RemoveAll(x => x.Alias == alias); } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/SignModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/SignModel.cs new file mode 100644 index 000000000000..0cfec8e36f82 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/SignModel.cs @@ -0,0 +1,6 @@ +namespace Umbraco.Cms.Api.Management.ViewModels; + +public class SignModel +{ + public required string Alias { get; set; } +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/ContentTreeItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/ContentTreeItemResponseModel.cs index a18f1c8ea882..aab2af128da4 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/ContentTreeItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/ContentTreeItemResponseModel.cs @@ -6,7 +6,5 @@ public abstract class ContentTreeItemResponseModel : EntityTreeItemResponseModel public bool IsTrashed { get; set; } - public Guid Id { get; set; } - public DateTimeOffset CreateDate { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/DocumentTreeItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/DocumentTreeItemResponseModel.cs index 1bde7631025b..f784665657ac 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/DocumentTreeItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/DocumentTreeItemResponseModel.cs @@ -3,7 +3,7 @@ namespace Umbraco.Cms.Api.Management.ViewModels.Tree; -public class DocumentTreeItemResponseModel : ContentTreeItemResponseModel +public class DocumentTreeItemResponseModel : ContentTreeItemResponseModel, IIsProtected { public bool IsProtected { get; set; } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/EntityTreeItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/EntityTreeItemResponseModel.cs index 3373daf20d35..ac1057e29ee5 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Tree/EntityTreeItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Tree/EntityTreeItemResponseModel.cs @@ -1,8 +1,16 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.Tree; +namespace Umbraco.Cms.Api.Management.ViewModels.Tree; -public class EntityTreeItemResponseModel : TreeItemPresentationModel +public class EntityTreeItemResponseModel : TreeItemPresentationModel, IHasSigns { + private readonly List _signs = []; + public Guid Id { get; set; } public ReferenceByIdModel? Parent { get; set; } + + public IEnumerable Signs => _signs.AsEnumerable(); + + public void AddSign(string alias) => _signs.Add(new SignModel { Alias = alias }); + + public void RemoveSign(string alias) => _signs.RemoveAll(x => x.Alias == alias); } diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 989b947adc09..7de76870026d 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -303,5 +303,16 @@ public static class Udi { public const string Prefix = "umb://"; } + + /// + /// Constants for all Sign aliases. + /// + public static class Signs + { + /// + /// Prefix for all signs aliases. + /// + public const string Prefix = "Umb."; + } } } diff --git a/src/Umbraco.Core/Constants-System.cs b/src/Umbraco.Core/Constants-System.cs index 62f96bb9cb11..6efc1745747a 100644 --- a/src/Umbraco.Core/Constants-System.cs +++ b/src/Umbraco.Core/Constants-System.cs @@ -115,5 +115,10 @@ public static class System public const string DataDirectoryPlaceholder = "|DataDirectory|"; public const string InvariantCulture = "*"; + + /// + /// The provider name for Umbraco core backoffice tree and collection signs. + /// + public const string UmbracoSignProvider = "umbCore"; } } diff --git a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs index f6ee0b692651..9ff75c2b3d11 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs @@ -50,6 +50,15 @@ public interface IDocumentRepository : IContentRepository, IReadR /// IEnumerable GetContentForRelease(DateTime date); + /// + /// Gets the content keys from the provided collection of keys that are scheduled for publishing. + /// + /// The content keys. + /// + /// The provided collection of content keys filtered for those that are scheduled for publishing. + /// + IEnumerable GetScheduledContentKeys(Guid[] keys) => []; + /// /// Get the count of published items /// diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 0c3b61a1c368..016d4a83caf5 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1007,6 +1007,23 @@ public IEnumerable GetPagedContentInRecycleBin(long pageIndex, int pag /// True if the content has any children otherwise False public bool HasChildren(int id) => CountChildren(id) > 0; + + /// + public IEnumerable GetScheduledContentKeys(IEnumerable keys) + { + Guid[] idsA = keys.ToArray(); + if (idsA.Length == 0) + { + return Enumerable.Empty(); + } + + using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true)) + { + scope.ReadLock(Constants.Locks.ContentTree); + return _documentRepository.GetScheduledContentKeys(idsA); + } + } + /// /// Checks if the passed in can be published based on the ancestors publish state. /// diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index a7bde2dc46a8..228d7fa6dbea 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -275,6 +275,15 @@ IContent CreateBlueprintFromContent(IContent blueprint, string name, int userId /// bool HasChildren(int id); + /// + /// Gets the content keys from the provided collection of keys that are scheduled for publishing. + /// + /// The content keys. + /// + /// The provided collection of content keys filtered for those that are scheduled for publishing. + /// + IEnumerable GetScheduledContentKeys(IEnumerable keys) => []; + #endregion #region Save, Delete Document diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs index 687a878c83c6..1279d621860b 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DocumentRepository.cs @@ -1671,6 +1671,27 @@ public IEnumerable GetContentForRelease(DateTime date) return MapDtosToContent(Database.Fetch(sql)); } + /// + public IEnumerable GetScheduledContentKeys(Guid[] keys) + { + var action = ContentScheduleAction.Release.ToString(); + DateTime now = DateTime.UtcNow; + + Sql sql = SqlContext.Sql(); + sql + .Select(x => x.UniqueId) + .From() + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .InnerJoin().On(left => left.NodeId, right => right.NodeId) + .WhereIn(x => x.UniqueId, keys) + .WhereIn(x => x.NodeId, Sql() + .Select(x => x.NodeId) + .From() + .Where(x => x.Action == action && x.Date >= now)); + + return Database.Fetch(sql); + } + /// public IEnumerable GetContentForExpiration(DateTime date) { diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentServiceTests.cs index 3d04a9fa6cf6..0271b77e8482 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentServiceTests.cs @@ -687,6 +687,25 @@ public void Can_Get_Content_For_Expiration() Assert.That(contents.Count(), Is.EqualTo(1)); } + [Test] + public void Can_Get_Scheduled_Content_Keys() + { + // Arrange + var root = ContentService.GetById(Textpage.Id); + ContentService.Publish(root!, root!.AvailableCultures.ToArray()); + var content = ContentService.GetById(Subpage.Id); + var contentSchedule = ContentScheduleCollection.CreateWithEntry(DateTime.UtcNow.AddDays(1), null); + ContentService.PersistContentSchedule(content!, contentSchedule); + ContentService.Publish(content, content.AvailableCultures.ToArray()); + + // Act + var keys = ContentService.GetScheduledContentKeys([Textpage.Key, Subpage.Key, Subpage2.Key]).ToList(); + + // Assert + Assert.AreEqual(1, keys.Count); + Assert.AreEqual(Subpage.Key, keys.First()); + } + [Test] public void Can_Get_Content_For_Release() { diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProviderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProviderTests.cs new file mode 100644 index 000000000000..b9e72c25dc10 --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasCollectionSignProviderTests.cs @@ -0,0 +1,165 @@ +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.DocumentType; +using Umbraco.Cms.Api.Management.ViewModels.Media.Collection; +using Umbraco.Cms.Api.Management.ViewModels.MediaType; +using Umbraco.Cms.Api.Management.ViewModels.Tree; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Services.Signs; + +[TestFixture] +internal class HasCollectionSignProviderTests +{ + [Test] + public async Task HasCollectionSignProvider_Can_Provide_Tree_Signs() + { + var sut = new HasCollectionSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasCollectionSignProvider_Can_Provide_Collection_Signs() + { + var sut = new HasCollectionSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasCollectionSignProvider_Can_Provide_Plain_Signs() + { + var sut = new HasCollectionSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasCollectionSignProvider_Can_Provide_Media_Tree_Signs() + { + var sut = new HasCollectionSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasCollectionSignProvider_Can_Provide_Media_Collection_Signs() + { + var sut = new HasCollectionSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasCollectionSignProvider_Should_Populate_Tree_Signs() + { + var sut = new HasCollectionSignProvider(); + + var viewModels = new List + { + new() + { + Id = Guid.NewGuid(), DocumentType = new DocumentTypeReferenceResponseModel() { Collection = new ReferenceByIdModel(Guid.NewGuid()) }, + }, + new() { Id = Guid.NewGuid() }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 1); + Assert.AreEqual(viewModels[1].Signs.Count(), 0); + + var signModel = viewModels[0].Signs.First(); + Assert.AreEqual("Umb.HasCollection", signModel.Alias); + } + + [Test] + public async Task HasCollectionSignProvider_Should_Populate_Collection_Signs() + { + var sut = new HasCollectionSignProvider(); + + var viewModels = new List + { + new() + { + Id = Guid.NewGuid(), DocumentType = new DocumentTypeCollectionReferenceResponseModel() { Collection = new ReferenceByIdModel(Guid.NewGuid()) }, + }, + new() { Id = Guid.NewGuid() }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 1); + Assert.AreEqual(viewModels[1].Signs.Count(), 0); + + var signModel = viewModels[0].Signs.First(); + Assert.AreEqual("Umb.HasCollection", signModel.Alias); + } + + [Test] + public async Task HasCollectionSignProvider_Should_Populate_Plain_Signs() + { + var sut = new HasCollectionSignProvider(); + + var viewModels = new List + { + new() + { + Id = Guid.NewGuid(), DocumentType = new DocumentTypeReferenceResponseModel() { Collection = new ReferenceByIdModel(Guid.NewGuid()) }, + }, + new() { Id = Guid.NewGuid() }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 1); + Assert.AreEqual(viewModels[1].Signs.Count(), 0); + + var signModel = viewModels[0].Signs.First(); + Assert.AreEqual("Umb.HasCollection", signModel.Alias); + } + + [Test] + public async Task HasCollectionSignProvider_Should_Populate_Media_Tree_Signs() + { + var sut = new HasCollectionSignProvider(); + + var viewModels = new List + { + new() + { + Id = Guid.NewGuid(), MediaType = new MediaTypeReferenceResponseModel() { Collection = new ReferenceByIdModel(Guid.NewGuid()) }, + }, + new() { Id = Guid.NewGuid() }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 1); + Assert.AreEqual(viewModels[1].Signs.Count(), 0); + + var signModel = viewModels[0].Signs.First(); + Assert.AreEqual("Umb.HasCollection", signModel.Alias); + } + + [Test] + public async Task HasCollectionSignProvider_Should_Populate_Media_Collection_Signs() + { + var sut = new HasCollectionSignProvider(); + + var viewModels = new List + { + new() + { + Id = Guid.NewGuid(), MediaType = new MediaTypeCollectionReferenceResponseModel() { Collection = new ReferenceByIdModel(Guid.NewGuid()) }, + }, + new() { Id = Guid.NewGuid() }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 1); + Assert.AreEqual(viewModels[1].Signs.Count(), 0); + + var signModel = viewModels[0].Signs.First(); + Assert.AreEqual("Umb.HasCollection", signModel.Alias); + } +} diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProviderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProviderTests.cs new file mode 100644 index 000000000000..f694faa17d06 --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasPendingChangesSignProviderTests.cs @@ -0,0 +1,128 @@ +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels.Document; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; + + + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Services.Signs; + +[TestFixture] +internal class HasPendingChangesSignProviderTests +{ + [Test] + public async Task HasPendingChangesSignProvider_Can_Provide_Tree_Signs() + { + var sut = new HasPendingChangesSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasPendingChangesSignProvider_Can_Provide_Collection_Signs() + { + var sut = new HasPendingChangesSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasPendingChangesSignProvider_Can_Provide_Plain_Signs() + { + var sut = new HasPendingChangesSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasPendingChangesSignProvider_Should_Populate_Tree_Signs() + { + var sut = new HasPendingChangesSignProvider(); + + var viewModels = new List + { + new() { Id = Guid.NewGuid() }, + new() + { + Id = Guid.NewGuid(), Variants = new List + { + new() + { + State = DocumentVariantState.PublishedPendingChanges, + Culture = null, + Name = "Test", + }, + }, + }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.PendingChanges", signModel.Alias); + } + + [Test] + public async Task HasPendingChangesSignProvider_Should_Populate_Collection_Signs() + { + var sut = new HasPendingChangesSignProvider(); + + var viewModels = new List + { + new() { Id = Guid.NewGuid() }, + new() + { + Id = Guid.NewGuid(), Variants = new List + { + new() + { + State = DocumentVariantState.PublishedPendingChanges, + Culture = null, + Name = "Test", + }, + }, + }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.PendingChanges", signModel.Alias); + } + + [Test] + public async Task HasPendingChangesSignProvider_Should_Populate_Plain_Signs() + { + var sut = new HasPendingChangesSignProvider(); + + var viewModels = new List + { + new() { Id = Guid.NewGuid() }, + new() + { + Id = Guid.NewGuid(), Variants = new List + { + new() + { + State = DocumentVariantState.PublishedPendingChanges, + Culture = null, + Name = "Test", + }, + }, + }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.PendingChanges", signModel.Alias); + } +} diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProviderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProviderTests.cs new file mode 100644 index 000000000000..07e93ebc792b --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProviderTests.cs @@ -0,0 +1,125 @@ +using Moq; +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; +using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Services.Signs; + +[TestFixture] +internal class HasScheduleSignProviderTests +{ + [Test] + public async Task HasScheduleSignProvider_Can_Provide_Tree_Signs() + { + var contentServiceMock = new Mock(); + + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasScheduleSignProvider_Can_Provide_Collection_Signs() + { + var contentServiceMock = new Mock(); + + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasScheduleSignProvider_Can_Provide_Plain_Signs() + { + var contentServiceMock = new Mock(); + + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task HasScheduleSignProvider_Should_Populate_Tree_Signs() + { + var entities = new List + { + new() { Key = Guid.NewGuid(), Name = "Item 1" }, new() { Key = Guid.NewGuid(), Name = "Item 2" }, + }; + + var contentServiceMock = new Mock(); + contentServiceMock + .Setup(x => x.GetScheduledContentKeys(It.IsAny>())) + .Returns([entities[1].Key]); + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + + var viewModels = new List + { + new() { Id = entities[0].Key }, new() { Id = entities[1].Key }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.ScheduledForPublish", signModel.Alias); + } + + [Test] + public async Task HasScheduleSignProvider_Should_Populate_Collection_Signs() + { + var entities = new List + { + new() { Key = Guid.NewGuid(), Name = "Item 1" }, new() { Key = Guid.NewGuid(), Name = "Item 2" }, + }; + + var contentServiceMock = new Mock(); + contentServiceMock + .Setup(x => x.GetScheduledContentKeys(It.IsAny>())) + .Returns([entities[1].Key]); + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + + var viewModels = new List + { + new() { Id = entities[0].Key }, new() { Id = entities[1].Key }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.ScheduledForPublish", signModel.Alias); + } + + [Test] + public async Task HasScheduleSignProvider_Should_Populate_Plain_Signs() + { + var entities = new List + { + new() { Key = Guid.NewGuid(), Name = "Item 1" }, new() { Key = Guid.NewGuid(), Name = "Item 2" }, + }; + + var contentServiceMock = new Mock(); + contentServiceMock + .Setup(x => x.GetScheduledContentKeys(It.IsAny>())) + .Returns([entities[1].Key]); + var sut = new HasScheduleSignProvider(contentServiceMock.Object); + + var viewModels = new List + { + new() { Id = entities[0].Key }, new() { Id = entities[1].Key }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.ScheduledForPublish", signModel.Alias); + } +} diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProviderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProviderTests.cs new file mode 100644 index 000000000000..1660db2723e6 --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProviderTests.cs @@ -0,0 +1,92 @@ +using NUnit.Framework; +using Umbraco.Cms.Api.Management.Services.Signs; +using Umbraco.Cms.Api.Management.ViewModels.Document.Collection; +using Umbraco.Cms.Api.Management.ViewModels.Document.Item; +using Umbraco.Cms.Api.Management.ViewModels.Tree; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Services.Signs; + +[TestFixture] +internal class IsProtectedSignProviderTests +{ + [Test] + public async Task IsProtectedSignProvider_Can_Provide_Tree_Signs() + { + var sut = new IsProtectedSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task IsProtectedSignProvider_Can_Provide_Collection_Signs() + { + var sut = new IsProtectedSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task IsProtectedSignProvider_Can_Provide_Plain_Signs() + { + var sut = new IsProtectedSignProvider(); + Assert.IsTrue(sut.CanProvideSigns()); + } + + [Test] + public async Task IsProtectedSignProvider_Should_Populate_Tree_Signs() + { + var sut = new IsProtectedSignProvider(); + + var viewModels = new List + { + new(), + new() { IsProtected = true }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.IsProtected", signModel.Alias); + } + + [Test] + public async Task IsProtectedSignProvider_Should_Populate_Collection_Signs() + { + var sut = new IsProtectedSignProvider(); + + var viewModels = new List + { + new(), + new() { IsProtected = true }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.IsProtected", signModel.Alias); + } + + [Test] + public async Task IsProtectedSignProvider_Should_Populate_Plain_Signs() + { + var sut = new IsProtectedSignProvider(); + + var viewModels = new List + { + new(), + new() { IsProtected = true }, + }; + + await sut.PopulateSignsAsync(viewModels); + + Assert.AreEqual(viewModels[0].Signs.Count(), 0); + Assert.AreEqual(viewModels[1].Signs.Count(), 1); + + var signModel = viewModels[1].Signs.First(); + Assert.AreEqual("Umb.IsProtected", signModel.Alias); + } +}