Skip to content

Commit e993c23

Browse files
Merge branch 'v13/dev' into contrib
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
2 parents 71e16d2 + d765e69 commit e993c23

File tree

18 files changed

+371
-34
lines changed

18 files changed

+371
-34
lines changed

src/Umbraco.Cms.Api.Delivery/Controllers/Content/ByRouteContentApiController.cs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
using Umbraco.Cms.Core.Models.DeliveryApi;
99
using Umbraco.Cms.Core.Models.PublishedContent;
1010
using Umbraco.Cms.Core.Services;
11-
using Umbraco.Extensions;
1211

1312
namespace Umbraco.Cms.Api.Delivery.Controllers.Content;
1413

1514
[ApiVersion("1.0")]
1615
[ApiVersion("2.0")]
1716
public class ByRouteContentApiController : ContentApiItemControllerBase
1817
{
19-
private readonly IRequestRoutingService _requestRoutingService;
18+
private readonly IApiContentPathResolver _apiContentPathResolver;
2019
private readonly IRequestRedirectService _requestRedirectService;
2120
private readonly IRequestPreviewService _requestPreviewService;
2221
private readonly IRequestMemberAccessService _requestMemberAccessService;
22+
private const string PreviewContentRequestPathPrefix = $"/{Constants.DeliveryApi.Routing.PreviewContentPathPrefix}";
2323

2424
[Obsolete($"Please use the constructor that does not accept {nameof(IPublicAccessService)}. Will be removed in V14.")]
2525
public ByRouteContentApiController(
@@ -58,20 +58,58 @@ public ByRouteContentApiController(
5858
{
5959
}
6060

61-
[ActivatorUtilitiesConstructor]
61+
[Obsolete($"Please use the constructor that accepts {nameof(IApiContentPathResolver)}. Will be removed in V15.")]
6262
public ByRouteContentApiController(
6363
IApiPublishedContentCache apiPublishedContentCache,
6464
IApiContentResponseBuilder apiContentResponseBuilder,
6565
IRequestRoutingService requestRoutingService,
6666
IRequestRedirectService requestRedirectService,
6767
IRequestPreviewService requestPreviewService,
6868
IRequestMemberAccessService requestMemberAccessService)
69+
: this(
70+
apiPublishedContentCache,
71+
apiContentResponseBuilder,
72+
requestRedirectService,
73+
requestPreviewService,
74+
requestMemberAccessService,
75+
StaticServiceProvider.Instance.GetRequiredService<IApiContentPathResolver>())
76+
{
77+
}
78+
79+
[Obsolete($"Please use the non-obsolete constructor. Will be removed in V15.")]
80+
public ByRouteContentApiController(
81+
IApiPublishedContentCache apiPublishedContentCache,
82+
IApiContentResponseBuilder apiContentResponseBuilder,
83+
IPublicAccessService publicAccessService,
84+
IRequestRoutingService requestRoutingService,
85+
IRequestRedirectService requestRedirectService,
86+
IRequestPreviewService requestPreviewService,
87+
IRequestMemberAccessService requestMemberAccessService,
88+
IApiContentPathResolver apiContentPathResolver)
89+
: this(
90+
apiPublishedContentCache,
91+
apiContentResponseBuilder,
92+
requestRedirectService,
93+
requestPreviewService,
94+
requestMemberAccessService,
95+
apiContentPathResolver)
96+
{
97+
}
98+
99+
[ActivatorUtilitiesConstructor]
100+
public ByRouteContentApiController(
101+
IApiPublishedContentCache apiPublishedContentCache,
102+
IApiContentResponseBuilder apiContentResponseBuilder,
103+
IRequestRedirectService requestRedirectService,
104+
IRequestPreviewService requestPreviewService,
105+
IRequestMemberAccessService requestMemberAccessService,
106+
IApiContentPathResolver apiContentPathResolver)
69107
: base(apiPublishedContentCache, apiContentResponseBuilder)
70108
{
71-
_requestRoutingService = requestRoutingService;
72109
_requestRedirectService = requestRedirectService;
73110
_requestPreviewService = requestPreviewService;
74111
_requestMemberAccessService = requestMemberAccessService;
112+
_apiContentPathResolver = apiContentPathResolver;
75113
}
76114

77115
[HttpGet("item/{*path}")]
@@ -105,8 +143,6 @@ public async Task<IActionResult> ByRouteV20(string path = "")
105143
private async Task<IActionResult> HandleRequest(string path)
106144
{
107145
path = DecodePath(path);
108-
109-
path = path.TrimStart("/");
110146
path = path.Length == 0 ? "/" : path;
111147

112148
IPublishedContent? contentItem = GetContent(path);
@@ -128,17 +164,12 @@ private async Task<IActionResult> HandleRequest(string path)
128164
}
129165

130166
private IPublishedContent? GetContent(string path)
131-
=> path.StartsWith(Constants.DeliveryApi.Routing.PreviewContentPathPrefix)
167+
=> path.StartsWith(PreviewContentRequestPathPrefix)
132168
? GetPreviewContent(path)
133169
: GetPublishedContent(path);
134170

135171
private IPublishedContent? GetPublishedContent(string path)
136-
{
137-
var contentRoute = _requestRoutingService.GetContentRoute(path);
138-
139-
IPublishedContent? contentItem = ApiPublishedContentCache.GetByRoute(contentRoute);
140-
return contentItem;
141-
}
172+
=> _apiContentPathResolver.ResolveContentPath(path);
142173

143174
private IPublishedContent? GetPreviewContent(string path)
144175
{
@@ -147,7 +178,7 @@ private async Task<IActionResult> HandleRequest(string path)
147178
return null;
148179
}
149180

150-
if (Guid.TryParse(path.AsSpan(Constants.DeliveryApi.Routing.PreviewContentPathPrefix.Length).TrimEnd("/"), out Guid contentId) is false)
181+
if (Guid.TryParse(path.AsSpan(PreviewContentRequestPathPrefix.Length).TrimEnd("/"), out Guid contentId) is false)
151182
{
152183
return null;
153184
}

src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="SixLabors.ImageSharp" VersionOverride="[2.1.6, 3)" />
8+
<PackageReference Include="SixLabors.ImageSharp" VersionOverride="[2.1.7, 3)" />
99
<PackageReference Include="SixLabors.ImageSharp.Web" VersionOverride="[2.0.2, 3)" />
1010
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
1111
<PackageReference Include="SixLabors.ImageSharp.Web" Version="2.0.2" />
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Umbraco.Cms.Core.Models.PublishedContent;
2+
using Umbraco.Cms.Core.Routing;
3+
4+
namespace Umbraco.Cms.Core.DeliveryApi;
5+
6+
// NOTE: left unsealed on purpose so it is extendable.
7+
public class ApiContentPathProvider : IApiContentPathProvider
8+
{
9+
private readonly IPublishedUrlProvider _publishedUrlProvider;
10+
11+
public ApiContentPathProvider(IPublishedUrlProvider publishedUrlProvider)
12+
=> _publishedUrlProvider = publishedUrlProvider;
13+
14+
public virtual string? GetContentPath(IPublishedContent content, string? culture)
15+
=> _publishedUrlProvider.GetUrl(content, UrlMode.Relative, culture);
16+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Umbraco.Cms.Core.Models.PublishedContent;
2+
using Umbraco.Extensions;
3+
4+
namespace Umbraco.Cms.Core.DeliveryApi;
5+
6+
// NOTE: left unsealed on purpose so it is extendable.
7+
public class ApiContentPathResolver : IApiContentPathResolver
8+
{
9+
private readonly IRequestRoutingService _requestRoutingService;
10+
private readonly IApiPublishedContentCache _apiPublishedContentCache;
11+
12+
public ApiContentPathResolver(IRequestRoutingService requestRoutingService, IApiPublishedContentCache apiPublishedContentCache)
13+
{
14+
_requestRoutingService = requestRoutingService;
15+
_apiPublishedContentCache = apiPublishedContentCache;
16+
}
17+
18+
public virtual IPublishedContent? ResolveContentPath(string path)
19+
{
20+
path = path.EnsureStartsWith("/");
21+
22+
var contentRoute = _requestRoutingService.GetContentRoute(path);
23+
IPublishedContent? contentItem = _apiPublishedContentCache.GetByRoute(contentRoute);
24+
return contentItem;
25+
}
26+
}

src/Umbraco.Core/DeliveryApi/ApiContentRouteBuilder.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using Microsoft.Extensions.Options;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Options;
23
using Umbraco.Cms.Core.Configuration.Models;
4+
using Umbraco.Cms.Core.DependencyInjection;
35
using Umbraco.Cms.Core.Models.DeliveryApi;
46
using Umbraco.Cms.Core.Models.PublishedContent;
57
using Umbraco.Cms.Core.PublishedCache;
@@ -10,22 +12,47 @@ namespace Umbraco.Cms.Core.DeliveryApi;
1012

1113
public sealed class ApiContentRouteBuilder : IApiContentRouteBuilder
1214
{
13-
private readonly IPublishedUrlProvider _publishedUrlProvider;
15+
private readonly IApiContentPathProvider _apiContentPathProvider;
1416
private readonly GlobalSettings _globalSettings;
1517
private readonly IVariationContextAccessor _variationContextAccessor;
1618
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
1719
private readonly IRequestPreviewService _requestPreviewService;
1820
private RequestHandlerSettings _requestSettings;
1921

22+
[Obsolete($"Use the constructor that does not accept {nameof(IPublishedUrlProvider)}. Will be removed in V15.")]
2023
public ApiContentRouteBuilder(
2124
IPublishedUrlProvider publishedUrlProvider,
2225
IOptions<GlobalSettings> globalSettings,
2326
IVariationContextAccessor variationContextAccessor,
2427
IPublishedSnapshotAccessor publishedSnapshotAccessor,
2528
IRequestPreviewService requestPreviewService,
2629
IOptionsMonitor<RequestHandlerSettings> requestSettings)
30+
: this(StaticServiceProvider.Instance.GetRequiredService<IApiContentPathProvider>(), globalSettings, variationContextAccessor, publishedSnapshotAccessor, requestPreviewService, requestSettings)
2731
{
28-
_publishedUrlProvider = publishedUrlProvider;
32+
}
33+
34+
[Obsolete($"Use the constructor that does not accept {nameof(IPublishedUrlProvider)}. Will be removed in V15.")]
35+
public ApiContentRouteBuilder(
36+
IPublishedUrlProvider publishedUrlProvider,
37+
IApiContentPathProvider apiContentPathProvider,
38+
IOptions<GlobalSettings> globalSettings,
39+
IVariationContextAccessor variationContextAccessor,
40+
IPublishedSnapshotAccessor publishedSnapshotAccessor,
41+
IRequestPreviewService requestPreviewService,
42+
IOptionsMonitor<RequestHandlerSettings> requestSettings)
43+
: this(apiContentPathProvider, globalSettings, variationContextAccessor, publishedSnapshotAccessor, requestPreviewService, requestSettings)
44+
{
45+
}
46+
47+
public ApiContentRouteBuilder(
48+
IApiContentPathProvider apiContentPathProvider,
49+
IOptions<GlobalSettings> globalSettings,
50+
IVariationContextAccessor variationContextAccessor,
51+
IPublishedSnapshotAccessor publishedSnapshotAccessor,
52+
IRequestPreviewService requestPreviewService,
53+
IOptionsMonitor<RequestHandlerSettings> requestSettings)
54+
{
55+
_apiContentPathProvider = apiContentPathProvider;
2956
_variationContextAccessor = variationContextAccessor;
3057
_publishedSnapshotAccessor = publishedSnapshotAccessor;
3158
_requestPreviewService = requestPreviewService;
@@ -72,7 +99,7 @@ public ApiContentRouteBuilder(
7299
}
73100

74101
// grab the content path from the URL provider
75-
var contentPath = _publishedUrlProvider.GetUrl(content, UrlMode.Relative, culture);
102+
var contentPath = _apiContentPathProvider.GetContentPath(content, culture);
76103

77104
// in some scenarios the published content is actually routable, but due to the built-in handling of i.e. lacking culture setup
78105
// the URL provider resolves the content URL as empty string or "#". since the Delivery API handles routing explicitly,
@@ -96,7 +123,7 @@ public ApiContentRouteBuilder(
96123

97124
private string ContentPreviewPath(IPublishedContent content) => $"{Constants.DeliveryApi.Routing.PreviewContentPathPrefix}{content.Key:D}{(_requestSettings.AddTrailingSlash ? "/" : string.Empty)}";
98125

99-
private static bool IsInvalidContentPath(string path) => path.IsNullOrWhiteSpace() || "#".Equals(path);
126+
private static bool IsInvalidContentPath(string? path) => path.IsNullOrWhiteSpace() || "#".Equals(path);
100127

101128
private IPublishedContent GetRoot(IPublishedContent content, bool isPreview)
102129
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Umbraco.Cms.Core.Models.PublishedContent;
2+
3+
namespace Umbraco.Cms.Core.DeliveryApi;
4+
5+
public interface IApiContentPathProvider
6+
{
7+
string? GetContentPath(IPublishedContent content, string? culture);
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Umbraco.Cms.Core.Models.PublishedContent;
2+
3+
namespace Umbraco.Cms.Core.DeliveryApi;
4+
5+
public interface IApiContentPathResolver
6+
{
7+
IPublishedContent? ResolveContentPath(string path);
8+
}

src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ private static IUmbracoBuilder AddDeliveryApiCoreServices(this IUmbracoBuilder b
453453
builder.Services.AddSingleton<IApiMediaQueryService, NoopApiMediaQueryService>();
454454
builder.Services.AddSingleton<IApiMediaUrlProvider, ApiMediaUrlProvider>();
455455
builder.Services.AddSingleton<IApiContentRouteBuilder, ApiContentRouteBuilder>();
456+
builder.Services.AddSingleton<IApiContentPathProvider, ApiContentPathProvider>();
457+
builder.Services.AddSingleton<IApiContentPathResolver, ApiContentPathResolver>();
456458
builder.Services.AddSingleton<IApiPublishedContentCache, ApiPublishedContentCache>();
457459
builder.Services.AddSingleton<IApiRichTextElementParser, ApiRichTextElementParser>();
458460
builder.Services.AddSingleton<IApiRichTextMarkupParser, ApiRichTextMarkupParser>();

src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,6 @@ protected virtual void DefinePlan()
105105
To<V_13_0_0.ChangeWebhookRequestObjectColumnToNvarcharMax>("{F74CDA0C-7AAA-48C8-94C6-C6EC3C06F599}");
106106
To<V_13_0_0.ChangeWebhookUrlColumnsToNvarcharMax>("{21C42760-5109-4C03-AB4F-7EA53577D1F5}");
107107
To<V_13_0_0.AddExceptionOccured>("{6158F3A3-4902-4201-835E-1ED7F810B2D8}");
108+
To<V_13_3_0.AlignUpgradedDatabase>("{985AF2BA-69D3-4DBA-95E0-AD3FA7459FA7}");
108109
}
109110
}

0 commit comments

Comments
 (0)