Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Controllers.Template;
using Umbraco.Cms.Api.Management.ViewModels.DocumentType;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.OperationStatus;

namespace Umbraco.Cms.Api.Management.Controllers.DocumentType;

[ApiVersion("1.0")]
public class CreateDocumentTypeTemplateController : DocumentTypeControllerBase
{
private readonly IContentTypeService _contentTypeService;
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;

public CreateDocumentTypeTemplateController(
IContentTypeService contentTypeService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_contentTypeService = contentTypeService;
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
}

[HttpPost("{id:guid}/template")]
[MapToApiVersion("1.0")]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateTemplate(
CancellationToken cancellationToken,
Guid id,
CreateDocumentTypeTemplateRequestModel requestModel)
{
Attempt<Guid?, ContentTypeOperationStatus> result = await _contentTypeService.CreateTemplateAsync(
id,
requestModel.Name,
requestModel.Alias,
requestModel.IsDefault,
CurrentUserKey(_backOfficeSecurityAccessor));

return result.Success
? CreatedAtId<ByKeyTemplateController>(controller => nameof(controller.ByKey), result.Result!.Value)
: OperationStatusResult(result.Status);
}
}
153 changes: 153 additions & 0 deletions src/Umbraco.Cms.Api.Management/OpenApi.json
Original file line number Diff line number Diff line change
Expand Up @@ -5597,6 +5597,137 @@
]
}
},
"/umbraco/management/api/v1/document-type/{id}/template": {
"post": {
"tags": [
"Document Type"
],
"operationId": "PostDocumentTypeByIdTemplate",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/CreateDocumentTypeTemplateRequestModel"
}
]
}
},
"text/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/CreateDocumentTypeTemplateRequestModel"
}
]
}
},
"application/*+json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/CreateDocumentTypeTemplateRequestModel"
}
]
}
}
}
},
"responses": {
"201": {
"description": "Created",
"headers": {
"Umb-Generated-Resource": {
"description": "Identifier of the newly created resource",
"schema": {
"type": "string",
"description": "Identifier of the newly created resource"
}
},
"Location": {
"description": "Location of the newly created resource",
"schema": {
"type": "string",
"description": "Location of the newly created resource",
"format": "uri"
}
},
"Umb-Notifications": {
"description": "The list of notifications produced during the request.",
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationHeaderModel"
},
"nullable": true
}
}
}
},
"400": {
"description": "Bad Request",
"headers": {
"Umb-Notifications": {
"description": "The list of notifications produced during the request.",
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationHeaderModel"
},
"nullable": true
}
}
},
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/ProblemDetails"
}
]
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
},
"403": {
"description": "The authenticated user does not have access to this resource",
"headers": {
"Umb-Notifications": {
"description": "The list of notifications produced during the request.",
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationHeaderModel"
},
"nullable": true
}
}
}
}
},
"security": [
{
"Backoffice-User": [ ]
}
]
}
},
"/umbraco/management/api/v1/document-type/allowed-at-root": {
"get": {
"tags": [
Expand Down Expand Up @@ -36823,6 +36954,28 @@
},
"additionalProperties": false
},
"CreateDocumentTypeTemplateRequestModel": {
"required": [
"alias",
"isDefault",
"name"
],
"type": "object",
"properties": {
"alias": {
"minLength": 1,
"type": "string"
},
"name": {
"minLength": 1,
"type": "string"
},
"isDefault": {
"type": "boolean"
}
},
"additionalProperties": false
},
"CreateFolderRequestModel": {
"required": [
"name"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.ComponentModel.DataAnnotations;

namespace Umbraco.Cms.Api.Management.ViewModels.DocumentType;

public class CreateDocumentTypeTemplateRequestModel
{
[Required]
public required string Alias { get; set; }

[Required]
public required string Name { get; set; }

public bool IsDefault { get; set; }
}
119 changes: 115 additions & 4 deletions src/Umbraco.Core/Services/ContentTypeService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;

Check warning on line 1 in src/Umbraco.Core/Services/ContentTypeService.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

❌ New issue: Missing Arguments Abstractions

The average number of function arguments in this module is 4.14 across 22 functions. The average arguments threshold is 4.00. The functions in this file have too many arguments, indicating a lack of encapsulation or too many responsibilities in the same functions. Avoid adding more.
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
Expand All @@ -10,6 +10,7 @@
using Umbraco.Cms.Core.Services.Changes;
using Umbraco.Cms.Core.Services.Filters;
using Umbraco.Cms.Core.Services.Locking;
using Umbraco.Cms.Core.Services.OperationStatus;

namespace Umbraco.Cms.Core.Services;

Expand All @@ -18,6 +19,8 @@
/// </summary>
public class ContentTypeService : ContentTypeServiceBase<IContentTypeRepository, IContentType>, IContentTypeService
{
private readonly ITemplateService _templateService;

public ContentTypeService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
Expand All @@ -29,7 +32,8 @@
IEntityRepository entityRepository,
IEventAggregator eventAggregator,
IUserIdKeyResolver userIdKeyResolver,
ContentTypeFilterCollection contentTypeFilters)
ContentTypeFilterCollection contentTypeFilters,
ITemplateService templateService)
: base(
provider,
loggerFactory,
Expand All @@ -40,8 +44,40 @@
entityRepository,
eventAggregator,
userIdKeyResolver,
contentTypeFilters) =>
contentTypeFilters)
{
_templateService = templateService;
ContentService = contentService;
}

[Obsolete("Use the non-obsolete constructor. Scheduled for removal in Umbraco 19.")]
public ContentTypeService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IContentService contentService,
IContentTypeRepository repository,
IAuditService auditService,
IDocumentTypeContainerRepository entityContainerRepository,
IEntityRepository entityRepository,
IEventAggregator eventAggregator,
IUserIdKeyResolver userIdKeyResolver,
ContentTypeFilterCollection contentTypeFilters)
: this(
provider,
loggerFactory,
eventMessagesFactory,
contentService,
repository,
auditService,
entityContainerRepository,
entityRepository,
eventAggregator,
userIdKeyResolver,
contentTypeFilters,
StaticServiceProvider.Instance.GetRequiredService<ITemplateService>())
{
}

Check notice on line 80 in src/Umbraco.Core/Services/ContentTypeService.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

✅ Getting better: Constructor Over-Injection

ContentTypeService decreases from 12 to 11 arguments, max arguments = 5. This constructor has too many arguments, indicating an object with low cohesion or missing function argument abstraction. Avoid adding more arguments.

[Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public ContentTypeService(
Expand All @@ -67,7 +103,8 @@
entityRepository,
eventAggregator,
userIdKeyResolver,
contentTypeFilters)
contentTypeFilters,
StaticServiceProvider.Instance.GetRequiredService<ITemplateService>())

Check warning on line 107 in src/Umbraco.Core/Services/ContentTypeService.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

❌ New issue: Code Duplication

The module contains 5 functions with similar structure: ContentTypeService,ContentTypeService,ContentTypeService,ContentTypeService and 1 more functions. Avoid duplicated, aka copy-pasted, code inside the module. More duplication lowers the code health.
{
}

Expand Down Expand Up @@ -96,7 +133,39 @@
entityRepository,
eventAggregator,
userIdKeyResolver,
contentTypeFilters)
contentTypeFilters,
StaticServiceProvider.Instance.GetRequiredService<ITemplateService>())
{
}

[Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public ContentTypeService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IContentService contentService,
IContentTypeRepository repository,
IAuditRepository auditRepository,
IAuditService auditService,
IDocumentTypeContainerRepository entityContainerRepository,
IEntityRepository entityRepository,
IEventAggregator eventAggregator,
IUserIdKeyResolver userIdKeyResolver,
ContentTypeFilterCollection contentTypeFilters,
ITemplateService templateService)
: this(
provider,
loggerFactory,
eventMessagesFactory,
contentService,
repository,
auditService,
entityContainerRepository,
entityRepository,
eventAggregator,
userIdKeyResolver,
contentTypeFilters,
templateService)
{
}

Expand Down Expand Up @@ -165,6 +234,48 @@
return contentTypes;
}

/// <inheritdoc />
public async Task<Attempt<Guid?, ContentTypeOperationStatus>> CreateTemplateAsync(
Guid contentTypeKey,
string templateName,
string templateAlias,
bool isDefaultTemplate,
Guid userKey)
{
IContentType? contentType = await GetAsync(contentTypeKey);
if (contentType is null)
{
return Attempt<Guid?, ContentTypeOperationStatus>.Fail(ContentTypeOperationStatus.NotFound);
}

Attempt<ITemplate?, TemplateOperationStatus> templateResult =
await _templateService.CreateForContentTypeAsync(templateName, templateAlias, contentType.Alias, userKey);
if (templateResult.Success is false)
{
return Attempt<Guid?, ContentTypeOperationStatus>.Fail(
templateResult.Status switch
{
TemplateOperationStatus.CancelledByNotification => ContentTypeOperationStatus
.CancelledByNotification,
TemplateOperationStatus.InvalidAlias => ContentTypeOperationStatus.InvalidAlias,
_ => ContentTypeOperationStatus.Unknown,
});
}

ITemplate template = templateResult.Result!;
contentType.AllowedTemplates = [..contentType.AllowedTemplates ?? [], template];
if (isDefaultTemplate)
{
contentType.DefaultTemplateId = template.Id;
}

Attempt<ContentTypeOperationStatus> updateContentTypeResult = await UpdateAsync(contentType, userKey);

return updateContentTypeResult.Success
? Attempt<Guid?, ContentTypeOperationStatus>.Succeed(ContentTypeOperationStatus.Success, template.Key)
: Attempt<Guid?, ContentTypeOperationStatus>.Fail(updateContentTypeResult.Result);
}

Check warning on line 277 in src/Umbraco.Core/Services/ContentTypeService.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Code Health Review (main)

❌ New issue: Excess Number of Function Arguments

CreateTemplateAsync has 5 arguments, max arguments = 4. This function has too many arguments, indicating a lack of encapsulation. Avoid adding more arguments.

protected override void DeleteItemsOfTypes(IEnumerable<int> typeIds)
{
using (ICoreScope scope = ScopeProvider.CreateCoreScope())
Expand Down
Loading
Loading