Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V14: Merge 13 to 14 #16340

Merged
merged 31 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
52c21b0
Updates JSON schema for Umbraco 10 with latest references for Forms a…
AndyButland Mar 20, 2024
6379f2f
Ported over #15928 changes for 13.3 RC (#16023)
kjac Apr 16, 2024
a6a76d1
Make the API content response builder extendable (#16056)
kjac Apr 16, 2024
a325ba3
bump rc to regular
Migaroez Apr 18, 2024
adc2435
Merge branch 'release/13.3.0' into v13/dev
Migaroez Apr 18, 2024
a27a4dc
Bump to next minor
Migaroez Apr 18, 2024
0980350
Add blocks in RTE telemetry (#16104)
nikolajlauridsen Apr 22, 2024
119fde2
V10: Fix for fallback file upload (#14892) (#15868)
Zeegaan Apr 24, 2024
599ec18
Implementors using Umbraco.Tests.Integration won't have to override G…
lars-erik Apr 4, 2024
5b46c71
Fix logic for retrieving lastKnownElement
jdpnielsen Apr 19, 2024
b6031de
bump version
bergmania May 3, 2024
edb516f
Bump version
bergmania May 3, 2024
fee222d
Bump version
bergmania May 3, 2024
23d0a6b
Since v13 properties can sometimes be of type IRichTextEditorIntermed…
nul800sebastiaan May 6, 2024
cfcdc9c
Webhook log improvements (#16200)
rasmusjp May 6, 2024
ba9ddd1
V13: Optimize custom MVC routing (#16218)
nikolajlauridsen May 10, 2024
1876546
V13: Optimize custom MVC routing (#16218)
nikolajlauridsen May 10, 2024
ab32bac
Property source level variation should only be applied when configure…
kjac May 13, 2024
94cef50
Property source level variation should only be applied when configure…
kjac May 13, 2024
5f24de3
Merge pull request from GHSA-j74q-mv2c-rxmp
bergmania May 17, 2024
c17d4e1
Merge pull request from GHSA-j74q-mv2c-rxmp
bergmania May 17, 2024
d8df405
Merge pull request from GHSA-j74q-mv2c-rxmp
bergmania May 17, 2024
9bacd13
Merge remote-tracking branch 'refs/remotes/origin/release/13.3' into …
bergmania May 17, 2024
0ee0db8
Merge remote-tracking branch 'refs/remotes/origin/release/10.8' into …
bergmania May 21, 2024
5c777f3
Merge remote-tracking branch 'refs/remotes/origin/v10/dev' into v11/dev
bergmania May 21, 2024
60f6560
Merge remote-tracking branch 'refs/remotes/origin/release/12.3' into …
bergmania May 21, 2024
4f382ab
Merge remote-tracking branch 'refs/remotes/origin/v11/dev' into v12/dev
bergmania May 21, 2024
04ed514
Merge remote-tracking branch 'refs/remotes/origin/v12/dev' into v13/dev
bergmania May 21, 2024
bcf48d3
Merge v13 into v14
Zeegaan May 22, 2024
b3b5322
Fix up after merge
Zeegaan May 22, 2024
7a4bee3
Remove obselete test
Zeegaan May 22, 2024
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
27 changes: 20 additions & 7 deletions src/Umbraco.Cms.Api.Delivery/Json/DeliveryApiJsonTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,36 @@
{
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);

Type[] derivedTypes = GetDerivedTypes(jsonTypeInfo);
if (derivedTypes.Length > 0)
{
ConfigureJsonPolymorphismOptions(jsonTypeInfo, derivedTypes);
}

return jsonTypeInfo;
}

protected virtual Type[] GetDerivedTypes(JsonTypeInfo jsonTypeInfo)
{
if (jsonTypeInfo.Type == typeof(IApiContent))
{
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(ApiContent));
return new[] { typeof(ApiContent) };
}
else if (jsonTypeInfo.Type == typeof(IApiContentResponse))

if (jsonTypeInfo.Type == typeof(IApiContentResponse))
{
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(ApiContentResponse));
return new[] { typeof(ApiContentResponse) };
}
else if (jsonTypeInfo.Type == typeof(IRichTextElement))

if (jsonTypeInfo.Type == typeof(IRichTextElement))
{
ConfigureJsonPolymorphismOptions(jsonTypeInfo, typeof(RichTextRootElement), typeof(RichTextGenericElement), typeof(RichTextTextElement));
return new[] { typeof(RichTextRootElement), typeof(RichTextGenericElement), typeof(RichTextTextElement) };
}

return jsonTypeInfo;
return Array.Empty<Type>();

Check notice on line 41 in src/Umbraco.Cms.Api.Delivery/Json/DeliveryApiJsonTypeResolver.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (v14/dev)

✅ No longer an issue: Bumpy Road Ahead

GetTypeInfo is no longer above the threshold for logical blocks with deeply nested code
}

private void ConfigureJsonPolymorphismOptions(JsonTypeInfo jsonTypeInfo, params Type[] derivedTypes)
protected void ConfigureJsonPolymorphismOptions(JsonTypeInfo jsonTypeInfo, params Type[] derivedTypes)
{
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
{
Expand Down
5 changes: 5 additions & 0 deletions src/Umbraco.Core/Constants-Telemetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@ public static class Telemetry
public static string WebhookTotal = $"{WebhookPrefix}Total";
public static string WebhookCustomHeaders = $"{WebhookPrefix}CustomHeaders";
public static string WebhookCustomEvent = $"{WebhookPrefix}CustomEvent";
public static string RichTextEditorCount = "RichTextEditorCount";
public static string RichTextBlockCount = "RichTextBlockCount";
public static string TotalPropertyCount = "TotalPropertyCount";
public static string HighestPropertyCount = "HighestPropertyCount";
public static string TotalCompositions = "TotalCompositions";
}
}
1 change: 1 addition & 0 deletions src/Umbraco.Core/Constants-Web.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public static class Routing
public const string ControllerToken = "controller";
public const string ActionToken = "action";
public const string AreaToken = "area";
public const string DynamicRoutePattern = "/{**umbracoSlug}";
}

public static class RoutePath
Expand Down
11 changes: 8 additions & 3 deletions src/Umbraco.Core/DeliveryApi/ApiContentResponseBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Umbraco.Cms.Core.Models.DeliveryApi;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Routing;
using Umbraco.Extensions;

namespace Umbraco.Cms.Core.DeliveryApi;

public sealed class ApiContentResponseBuilder : ApiContentBuilderBase<IApiContentResponse>, IApiContentResponseBuilder
public class ApiContentResponseBuilder : ApiContentBuilderBase<IApiContentResponse>, IApiContentResponseBuilder
{
private readonly IApiContentRouteBuilder _apiContentRouteBuilder;

Expand All @@ -14,6 +13,12 @@ public ApiContentResponseBuilder(IApiContentNameProvider apiContentNameProvider,
=> _apiContentRouteBuilder = apiContentRouteBuilder;

protected override IApiContentResponse Create(IPublishedContent content, string name, IApiContentRoute route, IDictionary<string, object?> properties)
{
IDictionary<string, IApiContentRoute> cultures = GetCultures(content);
return new ApiContentResponse(content.Key, name, content.ContentType.Alias, content.CreateDate, content.UpdateDate, route, properties, cultures);
}

protected virtual IDictionary<string, IApiContentRoute> GetCultures(IPublishedContent content)
{
var routesByCulture = new Dictionary<string, IApiContentRoute>();

Expand All @@ -35,6 +40,6 @@ protected override IApiContentResponse Create(IPublishedContent content, string
routesByCulture[publishedCultureInfo.Culture] = cultureRoute;
}

return new ApiContentResponse(content.Key, name, content.ContentType.Alias, content.CreateDate, content.UpdateDate, route, properties, routesByCulture);
return routesByCulture;
}
}
2 changes: 1 addition & 1 deletion src/Umbraco.Core/EmbeddedResources/Lang/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@
<key alias="detailedLevelDescription"><![CDATA[We will send:
<ul>
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.</li>
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Property Types, Compositions, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, rich text datatypes, blocks used in rich text datatypes, and Property Editors in use.</li>
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@
We will send:
<ul>
<li>Anonymized site ID, Umbraco version, and packages installed.</li>
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.</li>
<li>Number of: Root nodes, Content nodes, Macros, Media, Document Types, Property Types, Compositions, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, rich text datatypes, blocks used in rich text datatypes, and Property Editors in use.</li>
<li>System information: Webserver, server OS, server framework, server OS language, and database provider.</li>
<li>Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.</li>
</ul>
Expand Down
2 changes: 2 additions & 0 deletions src/Umbraco.Core/Models/WebhookLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ public class WebhookLog
public string ResponseBody { get; set; } = string.Empty;

public bool ExceptionOccured { get; set; }

public bool IsSuccessStatusCode { get; set; }
}
2 changes: 1 addition & 1 deletion src/Umbraco.Core/Routing/UmbracoRequestPaths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private static bool IsPluginControllerRoute(string path)
/// <summary>
/// Checks if the current uri is an install request
/// </summary>
public bool IsInstallerRequest(string absPath) => absPath.InvariantStartsWith(_installPath);
public bool IsInstallerRequest(string absPath) => absPath.InvariantStartsWith(_managementApiPath);

/// <summary>
/// Rudimentary check to see if it's not a server side request
Expand Down
24 changes: 24 additions & 0 deletions src/Umbraco.Core/Routing/WebPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,28 @@ public static string Combine(params string[]? paths)

return sb.ToString();
}


/// <summary>
/// Determines whether the provided web path is well-formed according to the specified UriKind.
/// </summary>
/// <param name="webPath">The web path to check. This can be null.</param>
/// <param name="uriKind">The kind of Uri (Absolute, Relative, or RelativeOrAbsolute).</param>
/// <returns>
/// true if <paramref name="webPath"/> is well-formed; otherwise, false.
/// </returns>
public static bool IsWellFormedWebPath(string? webPath, UriKind uriKind)
{
if (string.IsNullOrWhiteSpace(webPath))
{
return false;
}

if (webPath.StartsWith("//"))
{
return uriKind is not UriKind.Relative;
}

return Uri.IsWellFormedUriString(webPath, uriKind);
}
}
5 changes: 3 additions & 2 deletions src/Umbraco.Core/Services/WebhookLogFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ public async Task<WebhookLog> CreateAsync(string eventAlias, HttpRequestMessage
Url = webhook.Url,
WebhookKey = webhook.Key,
RetryCount = retryCount,
RequestHeaders = requestMessage.Headers.ToString(),
RequestHeaders = $"{requestMessage.Content?.Headers}{requestMessage.Headers}",
RequestBody = await requestMessage.Content?.ReadAsStringAsync(cancellationToken)!,
ExceptionOccured = exception is not null,
};

if (httpResponseMessage is not null)
{
log.StatusCode = MapStatusCodeToMessage(httpResponseMessage.StatusCode);
log.ResponseHeaders = httpResponseMessage.Headers.ToString();
log.IsSuccessStatusCode = httpResponseMessage.IsSuccessStatusCode;
log.ResponseHeaders = $"{httpResponseMessage.Content.Headers}{httpResponseMessage.Headers}";
log.ResponseBody = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken);
}
else if (exception is HttpRequestException httpRequestException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static IUmbracoBuilder AddTelemetryProviders(this IUmbracoBuilder builder
builder.Services.AddTransient<IDetailedTelemetryProvider, SystemTroubleshootingInformationTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, DeliveryApiTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, WebhookTelemetryProvider>();
builder.Services.AddTransient<IDetailedTelemetryProvider, BlocksInRichTextTelemetryProvider>();
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Umbraco.Cms.Core.Models;
using System.Text.RegularExpressions;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Webhooks;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;

Expand Down Expand Up @@ -33,6 +34,7 @@ public static WebhookLog DtoToEntity(WebhookLogDto dto) =>
ResponseBody = dto.ResponseBody,
RetryCount = dto.RetryCount,
StatusCode = dto.StatusCode,
IsSuccessStatusCode = Regex.IsMatch(dto.StatusCode, "^.*\\(2(\\d{2})\\)$"),
Key = dto.Key,
Id = dto.Id,
Url = dto.Url,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;

namespace Umbraco.Cms.Infrastructure.Telemetry.Providers;

public class BlocksInRichTextTelemetryProvider : IDetailedTelemetryProvider
{
private readonly IDataTypeService _dataTypeService;

public BlocksInRichTextTelemetryProvider(IDataTypeService dataTypeService)
{
_dataTypeService = dataTypeService;
}

public IEnumerable<UsageInformation> GetInformation()
{
IEnumerable<IDataType> richTextDataTypes = _dataTypeService.GetByEditorAliasAsync(Constants.PropertyEditors.Aliases.RichText).GetAwaiter().GetResult().ToArray();
int registeredBlocks = 0;
yield return new UsageInformation(Constants.Telemetry.RichTextEditorCount, richTextDataTypes.Count());

foreach (IDataType richTextDataType in richTextDataTypes)
{
if (richTextDataType.ConfigurationObject is not RichTextConfiguration richTextConfiguration)
{
// Might be some custom data type, skip it
continue;
}

if (richTextConfiguration.Blocks is null)
{
continue;
}

registeredBlocks += richTextConfiguration.Blocks.Length;
}

yield return new UsageInformation(Constants.Telemetry.RichTextBlockCount, registeredBlocks);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ public IEnumerable<UsageInformation> GetInformation()
{
IEnumerable<IContentType> contentTypes = _contentTypeService.GetAll();
var propertyTypes = new HashSet<string>();
var propertyTypeCounts = new List<int>();
var totalCompositions = 0;

foreach (IContentType contentType in contentTypes)
{
propertyTypes.UnionWith(contentType.PropertyTypes.Select(x => x.PropertyEditorAlias));
propertyTypeCounts.Add(contentType.CompositionPropertyTypes.Count());
totalCompositions += contentType.CompositionAliases().Count();
}

yield return new UsageInformation(Constants.Telemetry.Properties, propertyTypes);
yield return new UsageInformation(Constants.Telemetry.TotalPropertyCount, propertyTypeCounts.Sum());
yield return new UsageInformation(Constants.Telemetry.HighestPropertyCount, propertyTypeCounts.Count > 0 ? propertyTypeCounts.Max() : 0);
yield return new UsageInformation(Constants.Telemetry.TotalCompositions, totalCompositions);
}
}
Loading
Loading