Skip to content

Commit e5d3927

Browse files
authored
Merge pull request #19368 from umbraco/v16/merge-15-to-16-release
Merged v15 dev to release 16
2 parents 2dd2329 + 66c997a commit e5d3927

File tree

25 files changed

+1260
-33
lines changed

25 files changed

+1260
-33
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ contact_links:
44
url: https://github.com/umbraco/Umbraco-CMS/discussions/new?category=features-and-ideas
55
about: Start a new discussion when you have ideas or feature requests, eventually discussions can turn into plans
66
- name: ⁉️ Support Question
7-
url: https://our.umbraco.com
7+
url: https://forum.umbraco.com
88
about: This issue tracker is NOT meant for support questions. If you have a question, please join us on the forum.
99
- name: 📖 Documentation Issue
1010
url: https://github.com/umbraco/UmbracoDocs/issues
1111
about: Documentation issues should be reported on the Umbraco documentation repository.
1212
- name: 🔐 Security Issue
13-
url: https://umbraco.com/about-us/trust-center/security-and-umbraco/how-to-report-a-vulnerability-in-umbraco/
13+
url: https://umbraco.com/trust-center/security-and-umbraco/how-to-report-a-vulnerability-in-umbraco/
1414
about: Discovered a Security Issue in Umbraco?

.github/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
[![NuGet Version](https://img.shields.io/nuget/v/Umbraco.Cms)](https://www.nuget.org/packages/Umbraco.Cms)
55
[![Build status](https://img.shields.io/azure-devops/build/umbraco/Umbraco%2520Cms/301?logo=azurepipelines&label=Azure%20Pipelines)](https://umbraco.visualstudio.com/Umbraco%20Cms/_build?definitionId=301)
66
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
7+
[![Forum](https://img.shields.io/badge/help-forum-blue)](https://forum.umbraco.com)
78
[![Chat about Umbraco on Discord](https://img.shields.io/discord/869656431308189746?logo=discord&logoColor=fff)](https://discord.gg/umbraco)
8-
[![Read what's going on in the Umbraco Discord chat now](https://img.shields.io/badge/read-discord-blue)](https://discord-chats.umbraco.com)
99
![Mastodon Follow](https://img.shields.io/mastodon/follow/110661369750014952?domain=https%3A%2F%2Fumbracocommunity.social)
1010

1111

build/azure-pipelines.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,33 @@ stages:
432432
displayName: Start SQL Server Docker image (Linux)
433433
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
434434

435+
- powershell: |
436+
$maxAttempts = 12
437+
$attempt = 0
438+
$status = ""
439+
440+
while (($status -ne 'running') -and ($attempt -lt $maxAttempts)) {
441+
Start-Sleep -Seconds 5
442+
# We use the docker inspect command to check the status of the container. If the container is not running, we wait 5 seconds and try again. And if reaches 12 attempts, we fail the build.
443+
$status = docker inspect -f '{{.State.Status}}' mssql
444+
445+
if ($status -ne 'running') {
446+
Write-Host "Waiting for SQL Server to be ready... Attempt $($attempt + 1)"
447+
$attempt++
448+
}
449+
}
450+
451+
if ($status -eq 'running') {
452+
Write-Host "SQL Server container is running"
453+
docker ps -a
454+
} else {
455+
Write-Host "SQL Server did not become ready in time. Last known status: $status"
456+
docker logs mssql
457+
exit 1
458+
}
459+
displayName: Wait for SQL Server to be ready (Linux)
460+
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
461+
435462
- pwsh: SqlLocalDB start MSSQLLocalDB
436463
displayName: Start SQL Server LocalDB (Windows)
437464
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))

build/nightly-E2E-test-pipelines.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,17 @@ stages:
291291
testCommand: "npm run testSqlite -- --shard=1/3"
292292
vmImage: "ubuntu-latest"
293293
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
294-
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
294+
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
295295
LinuxPart2Of3:
296296
testCommand: "npm run testSqlite -- --shard=2/3"
297297
vmImage: "ubuntu-latest"
298298
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
299-
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
299+
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
300300
LinuxPart3Of3:
301301
testCommand: "npm run testSqlite -- --shard=3/3"
302302
vmImage: "ubuntu-latest"
303303
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
304-
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
304+
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
305305
WindowsPart1Of3:
306306
vmImage: "windows-latest"
307307
testCommand: "npm run testSqlite -- --shard=1/3"
@@ -457,4 +457,4 @@ stages:
457457
testResultsFormat: 'JUnit'
458458
testResultsFiles: '*.xml'
459459
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
460-
testRunTitle: "$(Agent.JobName)"
460+
testRunTitle: "$(Agent.JobName)"

src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Logging;
13
using Umbraco.Cms.Core.Composing;
4+
using Umbraco.Cms.Core.DependencyInjection;
25
using Umbraco.Cms.Core.Models;
36
using Umbraco.Cms.Core.Models.Editors;
47

@@ -12,14 +15,27 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
1215
// TODO: We could further reduce circular dependencies with PropertyEditorCollection by not having IDataValueReference implemented
1316
// by property editors and instead just use the already built in IDataValueReferenceFactory and/or refactor that into a more normal collection
1417

18+
private readonly ILogger<DataValueReferenceFactoryCollection> _logger;
19+
1520
/// <summary>
1621
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
1722
/// </summary>
1823
/// <param name="items">The items.</param>
24+
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
1925
public DataValueReferenceFactoryCollection(Func<IEnumerable<IDataValueReferenceFactory>> items)
20-
: base(items)
26+
: this(
27+
items,
28+
StaticServiceProvider.Instance.GetRequiredService<ILogger<DataValueReferenceFactoryCollection>>())
2129
{ }
2230

31+
/// <summary>
32+
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
33+
/// </summary>
34+
/// <param name="items">The items.</param>
35+
/// <param name="logger">The logger.</param>
36+
public DataValueReferenceFactoryCollection(Func<IEnumerable<IDataValueReferenceFactory>> items, ILogger<DataValueReferenceFactoryCollection> logger)
37+
: base(items) => _logger = logger;
38+
2339
/// <summary>
2440
/// Gets all unique references from the specified properties.
2541
/// </summary>
@@ -33,7 +49,7 @@ public ISet<UmbracoEntityReference> GetAllReferences(IPropertyCollection propert
3349
var references = new HashSet<UmbracoEntityReference>();
3450

3551
// Group by property editor alias to avoid duplicate lookups and optimize value parsing
36-
foreach (var propertyValuesByPropertyEditorAlias in properties.GroupBy(x => x.PropertyType.PropertyEditorAlias, x => x.Values))
52+
foreach (IGrouping<string, IReadOnlyCollection<IPropertyValue>> propertyValuesByPropertyEditorAlias in properties.GroupBy(x => x.PropertyType.PropertyEditorAlias, x => x.Values))
3753
{
3854
if (!propertyEditors.TryGet(propertyValuesByPropertyEditorAlias.Key, out IDataEditor? dataEditor))
3955
{
@@ -48,7 +64,7 @@ public ISet<UmbracoEntityReference> GetAllReferences(IPropertyCollection propert
4864
values.Add(propertyValue.PublishedValue);
4965
}
5066

51-
references.UnionWith(GetReferences(dataEditor, values));
67+
references.UnionWith(GetReferences(dataEditor, values, propertyValuesByPropertyEditorAlias.Key));
5268
}
5369

5470
return references;
@@ -74,14 +90,18 @@ public IEnumerable<UmbracoEntityReference> GetReferences(IDataEditor dataEditor,
7490
/// The references.
7591
/// </returns>
7692
public ISet<UmbracoEntityReference> GetReferences(IDataEditor dataEditor, IEnumerable<object?> values) =>
77-
GetReferencesEnumerable(dataEditor, values).ToHashSet();
78-
private IEnumerable<UmbracoEntityReference> GetReferencesEnumerable(IDataEditor dataEditor, IEnumerable<object?> values)
93+
GetReferencesEnumerable(dataEditor, values, null).ToHashSet();
94+
95+
private ISet<UmbracoEntityReference> GetReferences(IDataEditor dataEditor, IEnumerable<object?> values, string propertyEditorAlias) =>
96+
GetReferencesEnumerable(dataEditor, values, propertyEditorAlias).ToHashSet();
97+
98+
private IEnumerable<UmbracoEntityReference> GetReferencesEnumerable(IDataEditor dataEditor, IEnumerable<object?> values, string? propertyEditorAlias)
7999
{
80100
// TODO: We will need to change this once we support tracking via variants/segments
81101
// for now, we are tracking values from ALL variants
82102
if (dataEditor.GetValueEditor() is IDataValueReference dataValueReference)
83103
{
84-
foreach (UmbracoEntityReference reference in values.SelectMany(dataValueReference.GetReferences))
104+
foreach (UmbracoEntityReference reference in GetReferencesFromPropertyValues(values, dataValueReference, propertyEditorAlias))
85105
{
86106
yield return reference;
87107
}
@@ -107,13 +127,49 @@ private IEnumerable<UmbracoEntityReference> GetReferencesEnumerable(IDataEditor
107127
}
108128
}
109129

130+
private IEnumerable<UmbracoEntityReference> GetReferencesFromPropertyValues(IEnumerable<object?> values, IDataValueReference dataValueReference, string? propertyEditorAlias)
131+
{
132+
var result = new List<UmbracoEntityReference>();
133+
foreach (var value in values)
134+
{
135+
// When property editors on data types are changed, we could have values that are incompatible with the new editor.
136+
// Leading to issues such as:
137+
// - https://github.com/umbraco/Umbraco-CMS/issues/17628
138+
// - https://github.com/umbraco/Umbraco-CMS/issues/17725
139+
// Although some changes like this are not intended to be compatible, we should handle them gracefully and not
140+
// error in retrieving references, which would prevent manipulating or deleting the content that uses the data type.
141+
try
142+
{
143+
IEnumerable<UmbracoEntityReference> references = dataValueReference.GetReferences(value);
144+
result.AddRange(references);
145+
}
146+
catch (Exception ex)
147+
{
148+
// Log the exception but don't throw, continue with the next value.
149+
_logger.LogError(
150+
ex,
151+
"Error getting references from value {Value} with data editor {DataEditor} and property editor alias {PropertyEditorAlias}.",
152+
value,
153+
dataValueReference.GetType().FullName,
154+
propertyEditorAlias ?? "n/a");
155+
throw;
156+
}
157+
}
158+
159+
return result;
160+
}
161+
110162
/// <summary>
111163
/// Gets all relation type aliases that are automatically tracked.
112164
/// </summary>
113165
/// <param name="propertyEditors">The property editors.</param>
114166
/// <returns>
115167
/// All relation type aliases that are automatically tracked.
116168
/// </returns>
169+
[Obsolete("Use GetAllAutomaticRelationTypesAliases. This will be removed in Umbraco 15.")]
170+
public ISet<string> GetAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors) =>
171+
GetAllAutomaticRelationTypesAliases(propertyEditors);
172+
117173
public ISet<string> GetAllAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors)
118174
{
119175
// Always add default automatic relation types

src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyValueEditorBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@ protected IEnumerable<UmbracoEntityReference> GetBlockValueReferences(TValue blo
7171
continue;
7272
}
7373

74-
var districtValues = valuesByPropertyEditorAlias.Distinct().ToArray();
74+
var distinctValues = valuesByPropertyEditorAlias.Distinct().ToArray();
7575

7676
if (dataEditor.GetValueEditor() is IDataValueReference reference)
7777
{
78-
foreach (UmbracoEntityReference value in districtValues.SelectMany(reference.GetReferences))
78+
foreach (UmbracoEntityReference value in distinctValues.SelectMany(reference.GetReferences))
7979
{
8080
result.Add(value);
8181
}
8282
}
8383

84-
IEnumerable<UmbracoEntityReference> references = _dataValueReferenceFactoryCollection.GetReferences(dataEditor, districtValues);
84+
IEnumerable<UmbracoEntityReference> references = _dataValueReferenceFactoryCollection.GetReferences(dataEditor, distinctValues);
8585

8686
foreach (UmbracoEntityReference value in references)
8787
{

0 commit comments

Comments
 (0)