From f8c1a560ffb0da45b2ceedbff835259efc3f2abb Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 9 Nov 2023 13:36:57 +0100 Subject: [PATCH 01/14] Bump version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 7b6fdb03be..d733b40e8f 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "10.7.0", + "version": "10.8.0", "assemblyVersion": { "precision": "build" }, From d5b1f5875b295e3b5df2e610cfa8cb9a3b4d8594 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 9 Nov 2023 13:38:13 +0100 Subject: [PATCH 02/14] Bump version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index d733b40e8f..364e6e8834 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "10.8.0", + "version": "10.9.0-rc", "assemblyVersion": { "precision": "build" }, From ddb26632f9d318e832fa90f9472c236b50720633 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 9 Nov 2023 13:38:34 +0100 Subject: [PATCH 03/14] Bump to rc --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index d733b40e8f..3c0aeb9872 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "10.8.0", + "version": "10.8.0-rc", "assemblyVersion": { "precision": "build" }, From d0be4ab263d3996da9ee68456012b6c70c5dba92 Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Thu, 9 Nov 2023 13:51:05 +0100 Subject: [PATCH 04/14] Publish ContentTreeChangeNotification after saving/deleting blueprints (#14898) --- src/Umbraco.Core/Services/ContentService.cs | 3 +++ .../Cache/DistributedCacheBinder_Handlers.cs | 9 --------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 262598451a..f324384a3d 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -3568,6 +3568,7 @@ public class ContentService : RepositoryService, IContentService Audit(AuditType.Save, Constants.Security.SuperUserId, content.Id, $"Saved content template: {content.Name}"); scope.Notifications.Publish(new ContentSavedBlueprintNotification(content, evtMsgs)); + scope.Notifications.Publish(new ContentTreeChangeNotification(content, TreeChangeTypes.RefreshNode, evtMsgs)); scope.Complete(); } @@ -3582,6 +3583,7 @@ public class ContentService : RepositoryService, IContentService scope.WriteLock(Constants.Locks.ContentTree); _documentBlueprintRepository.Delete(content); scope.Notifications.Publish(new ContentDeletedBlueprintNotification(content, evtMsgs)); + scope.Notifications.Publish(new ContentTreeChangeNotification(content, TreeChangeTypes.Remove, evtMsgs)); scope.Complete(); } } @@ -3682,6 +3684,7 @@ public class ContentService : RepositoryService, IContentService } scope.Notifications.Publish(new ContentDeletedBlueprintNotification(blueprints, evtMsgs)); + scope.Notifications.Publish(new ContentTreeChangeNotification(blueprints, TreeChangeTypes.Remove, evtMsgs)); scope.Complete(); } } diff --git a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs index 11119aaf66..0e84c747ac 100644 --- a/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs +++ b/src/Umbraco.Infrastructure/Cache/DistributedCacheBinder_Handlers.cs @@ -67,15 +67,6 @@ public class DistributedCacheBinder : _distributedCache.RefreshContentCache(notification.Changes.ToArray()); } - // private void ContentService_SavedBlueprint(IContentService sender, SaveEventArgs e) - // { - // _distributedCache.RefreshUnpublishedPageCache(e.SavedEntities.ToArray()); - // } - - // private void ContentService_DeletedBlueprint(IContentService sender, DeleteEventArgs e) - // { - // _distributedCache.RemoveUnpublishedPageCache(e.DeletedEntities.ToArray()); - // } #endregion #region LocalizationService / Dictionary From ed65645a33ed884ca4fecb419205d9a243f7da3c Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Thu, 9 Nov 2023 13:52:21 +0100 Subject: [PATCH 05/14] Add global.json and cleanup UI project file (#14900) * Add global.json with minimum .NET 6.0.5 SDK version and roll forward policy * Clean up UI project file --- global.json | 6 ++++++ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 0000000000..49d225529c --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "6.0.300", + "rollForward": "latestFeature" + } +} diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index a205bd0efb..b7be2ba90f 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -11,14 +11,6 @@ - - - - - - - - From 919138c299b69e46af19828209fc1062e3dbf4bb Mon Sep 17 00:00:00 2001 From: Rasmus Berntsen Date: Thu, 9 Nov 2023 13:53:18 +0100 Subject: [PATCH 06/14] #14835 Update link on permissionsreport.html (#14872) * #14835 Update link on permissionsreport.html Updated link to permissions page to point to 10-LTS documentation * retrigger checks --------- Co-authored-by: Rasmus Berntsen --- .../src/installer/steps/permissionsreport.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html b/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html index f3067e8fb6..ae3d4ed49a 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html @@ -3,7 +3,7 @@

In order to run Umbraco, you'll need to update your permission settings. Detailed information about the correct file and folder permissions for Umbraco can be found - here. + here.

The following report list the permissions that are currently failing. Once the permissions are fixed press the 'Go back' button to restart the installation. From e5de8bf56b7f9f350c9ee25b79519007fa47e153 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 13 Nov 2023 14:59:52 +0100 Subject: [PATCH 07/14] Updated nuget packages (#15192) --- src/JsonSchema/JsonSchema.csproj | 2 +- .../Umbraco.Cms.Persistence.Sqlite.csproj | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 4 ++-- .../Enrichers/ThreadAbortExceptionEnricher.cs | 2 +- .../Umbraco.Infrastructure.csproj | 22 +++++++++---------- .../Umbraco.PublishedCache.NuCache.csproj | 6 ++--- .../Umbraco.Web.BackOffice.csproj | 2 +- .../Umbraco.Web.Common.csproj | 8 +++---- .../Umbraco.Tests.Common.csproj | 2 +- .../Umbraco.Tests.Integration.csproj | 6 ++--- .../Umbraco.Tests.UnitTests.csproj | 6 ++--- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/JsonSchema/JsonSchema.csproj b/src/JsonSchema/JsonSchema.csproj index 967a3c7aa1..5c2ba04f58 100644 --- a/src/JsonSchema/JsonSchema.csproj +++ b/src/JsonSchema/JsonSchema.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj index cd88791019..10bb499c7d 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 97ad56596d..ef23b4fc00 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -8,10 +8,10 @@ - + - + diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/Enrichers/ThreadAbortExceptionEnricher.cs b/src/Umbraco.Infrastructure/Logging/Serilog/Enrichers/ThreadAbortExceptionEnricher.cs index 45495de9e8..f773fe248f 100644 --- a/src/Umbraco.Infrastructure/Logging/Serilog/Enrichers/ThreadAbortExceptionEnricher.cs +++ b/src/Umbraco.Infrastructure/Logging/Serilog/Enrichers/ThreadAbortExceptionEnricher.cs @@ -67,7 +67,7 @@ public class ThreadAbortExceptionEnricher : ILogEventEnricher private void DumpThreadAborts(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { - if (!IsTimeoutThreadAbortException(logEvent.Exception)) + if (logEvent.Exception is null || !IsTimeoutThreadAbortException(logEvent.Exception)) { return; } diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index c72c2022c4..9f46b4f4fb 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -12,34 +12,34 @@ - - + + - + - + - - + + - + - + - + - + - + diff --git a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj index f0e07283fa..725715b4dc 100644 --- a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj +++ b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj @@ -8,9 +8,9 @@ - - - + + + diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj index 952f4fbbc5..32598379b4 100644 --- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj +++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index 8f7ea5f935..5ffee1aa11 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -12,13 +12,13 @@ - - + + - - + + diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj index 82cf5d9c32..24c7fcdab2 100644 --- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj +++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj @@ -11,7 +11,7 @@ - + diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 48140b64dc..373d273786 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -11,10 +11,10 @@ - - + + - + diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index 8b6085bf6d..9f28c725ae 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -9,9 +9,9 @@ - - - + + + From abfa07367fcefc71c6a23ca83827039dfc961669 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 13 Nov 2023 18:06:41 +0100 Subject: [PATCH 08/14] Bump version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 3c0aeb9872..364e6e8834 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "10.8.0-rc", + "version": "10.9.0-rc", "assemblyVersion": { "precision": "build" }, From 74cfd9c9a0e0c2bc3e16accb4ccd5890c89793bf Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 13 Nov 2023 18:38:15 +0100 Subject: [PATCH 09/14] Updated nuget packages --- .../Umbraco.Cms.ManagementApi.csproj | 2 +- .../Umbraco.Cms.Persistence.Sqlite.csproj | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 6 +++--- src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj | 8 ++++---- src/Umbraco.Web.Common/Umbraco.Web.Common.csproj | 8 ++++---- tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj | 4 ++-- .../Umbraco.Tests.Integration.csproj | 2 +- .../Umbraco.Tests.UnitTests.csproj | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Cms.ManagementApi/Umbraco.Cms.ManagementApi.csproj b/src/Umbraco.Cms.ManagementApi/Umbraco.Cms.ManagementApi.csproj index 47612499b5..edcfe8545a 100644 --- a/src/Umbraco.Cms.ManagementApi/Umbraco.Cms.ManagementApi.csproj +++ b/src/Umbraco.Cms.ManagementApi/Umbraco.Cms.ManagementApi.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj index d9f9ac5123..912f809ec0 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 86bf11d4ef..6fc9e3c1e8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -8,12 +8,12 @@ - + - + - + diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 9eba11ea40..edeefac347 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -12,16 +12,16 @@ - + - + - + @@ -39,7 +39,7 @@ - + diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index d774577bbf..12238f8447 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -12,13 +12,13 @@ - - - + + + - + diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj index b73e08a1ac..067d2c4058 100644 --- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj +++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj @@ -8,10 +8,10 @@ - + - + diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 781e50d0ed..2fee674a69 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -12,7 +12,7 @@ - + diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index 109652b73d..a5dcc4b299 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -7,7 +7,7 @@ - + From fee9bf12c01bc513fe6235b3556fec5d2fe5d794 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 13 Nov 2023 18:56:57 +0100 Subject: [PATCH 10/14] Updated nuget packages --- .../Umbraco.Cms.Imaging.ImageSharp.csproj | 2 -- .../Umbraco.Cms.Persistence.EFCore.SqlServer.csproj | 2 +- .../Umbraco.Cms.Persistence.EFCore.Sqlite.csproj | 2 +- .../Umbraco.Cms.Persistence.EFCore.csproj | 4 ++-- .../Umbraco.Cms.Persistence.Sqlite.csproj | 1 - src/Umbraco.Core/Umbraco.Core.csproj | 4 ---- .../Umbraco.Infrastructure.csproj | 12 +----------- .../Umbraco.PublishedCache.NuCache.csproj | 5 +---- .../Umbraco.Web.BackOffice.csproj | 2 -- src/Umbraco.Web.Common/Umbraco.Web.Common.csproj | 3 --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- .../Umbraco.Tests.Common/Umbraco.Tests.Common.csproj | 4 ---- .../Umbraco.Tests.Integration.csproj | 2 -- .../Umbraco.Tests.UnitTests.csproj | 2 -- 14 files changed, 7 insertions(+), 40 deletions(-) diff --git a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj index 3baebde370..c34595576f 100644 --- a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj +++ b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj @@ -7,8 +7,6 @@ - - diff --git a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj index f710397004..eec419d34e 100644 --- a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj index 6087a86746..d12b9affab 100644 --- a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj index afeab8aa89..7b2b4b17f3 100644 --- a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj +++ b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj index 7c7d86456a..912f809ec0 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj +++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj @@ -5,7 +5,6 @@ - diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 66bae14e2c..115db79161 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -8,10 +8,6 @@ - - - - diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index c1020d76fd..daf2f7e375 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -12,32 +12,23 @@ - - - - - - - - - - + @@ -49,7 +40,6 @@ - diff --git a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj index 9db9e0e516..a61eba6c79 100644 --- a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj +++ b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj @@ -7,11 +7,8 @@ - - - - + diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj index beaf8aaf8c..a64d0d2408 100644 --- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj +++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj @@ -13,8 +13,6 @@ - - diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj index daf183a657..f6f969f97d 100644 --- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj +++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj @@ -14,9 +14,6 @@ - - - diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 5f359bf99e..43a3fdc940 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -18,7 +18,7 @@ - + all diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj index de870edb61..08500c9389 100644 --- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj +++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj @@ -13,10 +13,6 @@ - - - - diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 08c4af358d..b2378ca09a 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -12,8 +12,6 @@ - - diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index e98fcd04d1..9ddd95090d 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -5,8 +5,6 @@ - - From 151fccee97eeabc84039c8c7d7a9224c49883a76 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 14 Nov 2023 08:12:05 +0100 Subject: [PATCH 11/14] Performance optimisations related to blocks (and multi url picker) (#15184) * Added content types to property index value factory, because the deep cloning is too expensive to execute often * Do not use entityservice in ToEditor, as it goes to the database. We need to use something that is cached. * Small performance optimization for nested content too * A little formatting and an obsoletion message --------- Co-authored-by: kjac --- .../DefaultPropertyIndexValueFactory.cs | 15 +- .../IPropertyIndexValueFactory.cs | 7 +- .../JsonPropertyIndexValueFactoryBase.cs | 47 +++++- .../NoopPropertyIndexValueFactory.cs | 6 + .../Examine/BaseValueSetBuilder.cs | 26 +++- .../Examine/ContentValueSetBuilder.cs | 52 +++++-- .../Examine/MediaValueSetBuilder.cs | 29 +++- .../Examine/MemberValueSetBuilder.cs | 18 ++- .../BlockValuePropertyIndexValueFactory.cs | 5 +- .../MultiUrlPickerValueEditor.cs | 139 +++++++++++------- .../NestedContentPropertyIndexValueFactory.cs | 5 + .../NestedPropertyIndexValueFactoryBase.cs | 27 +++- 12 files changed, 286 insertions(+), 90 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs index 0193f45778..e0ec2c4ccf 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs @@ -9,15 +9,22 @@ namespace Umbraco.Cms.Core.PropertyEditors; /// public class DefaultPropertyIndexValueFactory : IPropertyIndexValueFactory { - /// - public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable availableCultures) + public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, + IEnumerable availableCultures, IDictionary contentTypeDictionary) { yield return new KeyValuePair>( property.Alias, property.GetValue(culture, segment, published).Yield()); } - [Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")] + /// + [Obsolete("Use the non-obsolete overload, scheduled for removal in v14")] + public IEnumerable>> GetIndexValues(IProperty property, string? culture, + string? segment, bool published, IEnumerable availableCultures) + => GetIndexValues(property, culture, segment, published, availableCultures, + new Dictionary()); + + [Obsolete("Use the non-obsolete overload, scheduled for removal in v14")] public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published) - => GetIndexValues(property, culture, segment, published, Enumerable.Empty()); + => GetIndexValues(property, culture, segment, published, Enumerable.Empty(), new Dictionary()); } diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs index 732644b288..8f8b64a9eb 100644 --- a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs @@ -22,9 +22,14 @@ public interface IPropertyIndexValueFactory /// more than one value for a given field. /// /// + IEnumerable>> GetIndexValues(IProperty property, string? culture, + string? segment, bool published, IEnumerable availableCultures, + IDictionary contentTypeDictionary) => GetIndexValues(property, culture, segment, published); + + [Obsolete("Use non-obsolete overload, scheduled for removal in v14")] IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable availableCultures) => GetIndexValues(property, culture, segment, published); - [Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")] + [Obsolete("Use non-obsolete overload, scheduled for removal in v14")] IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published); } diff --git a/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs b/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs index bf549e2d2e..973ee3d40c 100644 --- a/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs +++ b/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Services; using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; @@ -39,13 +40,13 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty } - /// public IEnumerable>> GetIndexValues( IProperty property, string? culture, string? segment, bool published, - IEnumerable availableCultures) + IEnumerable availableCultures, + IDictionary contentTypeDictionary) { var result = new List>>(); @@ -63,7 +64,7 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty return result; } - result.AddRange(Handle(deserializedPropertyValue, property, culture, segment, published, availableCultures)); + result.AddRange(Handle(deserializedPropertyValue, property, culture, segment, published, availableCultures, contentTypeDictionary)); } catch (InvalidCastException) { @@ -87,9 +88,31 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty return summary; } + /// + [Obsolete("Use non-obsolete constructor. This will be removed in Umbraco 14.")] + public IEnumerable>> GetIndexValues( + IProperty property, + string? culture, + string? segment, + bool published, + IEnumerable availableCultures) + => GetIndexValues( + property, + culture, + segment, + published, + Enumerable.Empty(), + StaticServiceProvider.Instance.GetRequiredService().GetAll().ToDictionary(x=>x.Key)); + [Obsolete("Use method overload that has availableCultures, scheduled for removal in v14")] public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published) - => GetIndexValues(property, culture, segment, published, Enumerable.Empty()); + => GetIndexValues( + property, + culture, + segment, + published, + Enumerable.Empty(), + StaticServiceProvider.Instance.GetRequiredService().GetAll().ToDictionary(x=>x.Key)); ///

/// Method to return a list of summary of the content. By default this returns an empty list @@ -104,7 +127,7 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty /// /// Method that handle the deserialized object. /// - [Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")] + [Obsolete("Use the non-obsolete overload instead, scheduled for removal in v14")] protected abstract IEnumerable>> Handle( TSerialized deserializedPropertyValue, IProperty property, @@ -112,6 +135,15 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty string? segment, bool published); + [Obsolete("Use the non-obsolete overload instead, scheduled for removal in v14")] + protected virtual IEnumerable>> Handle( + TSerialized deserializedPropertyValue, + IProperty property, + string? culture, + string? segment, + bool published, + IEnumerable availableCultures) => Handle(deserializedPropertyValue, property, culture, segment, published); + /// /// Method that handle the deserialized object. /// @@ -121,6 +153,7 @@ public abstract class JsonPropertyIndexValueFactoryBase : IProperty string? culture, string? segment, bool published, - IEnumerable availableCultures) => - Handle(deserializedPropertyValue, property, culture, segment, published); + IEnumerable availableCultures, + IDictionary contentTypeDictionary) + => Handle(deserializedPropertyValue, property, culture, segment, published, availableCultures); } diff --git a/src/Umbraco.Core/PropertyEditors/NoopPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/NoopPropertyIndexValueFactory.cs index 223f8632ff..004138e370 100644 --- a/src/Umbraco.Core/PropertyEditors/NoopPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/NoopPropertyIndexValueFactory.cs @@ -8,6 +8,12 @@ namespace Umbraco.Cms.Core.PropertyEditors; public class NoopPropertyIndexValueFactory : IPropertyIndexValueFactory { /// + public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, + IEnumerable availableCultures, IDictionary contentTypeDictionary) + => Array.Empty>>(); + + + [Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")] public IEnumerable>> GetIndexValues(IProperty property, string? culture, string? segment, bool published, IEnumerable availableCultures) => Array.Empty>>(); [Obsolete("Use the overload with the availableCultures parameter instead, scheduled for removal in v14")] diff --git a/src/Umbraco.Infrastructure/Examine/BaseValueSetBuilder.cs b/src/Umbraco.Infrastructure/Examine/BaseValueSetBuilder.cs index 3574c3077f..83ecd85da4 100644 --- a/src/Umbraco.Infrastructure/Examine/BaseValueSetBuilder.cs +++ b/src/Umbraco.Infrastructure/Examine/BaseValueSetBuilder.cs @@ -1,6 +1,9 @@ using Examine; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Examine; @@ -24,9 +27,26 @@ public abstract class BaseValueSetBuilder : IValueSetBuilder [Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")] protected void AddPropertyValue(IProperty property, string? culture, string? segment, IDictionary>? values) - => AddPropertyValue(property, culture, segment, values, Enumerable.Empty()); + => AddPropertyValue( + property, + culture, + segment, + values, + Enumerable.Empty(), + StaticServiceProvider.Instance.GetRequiredService().GetAll().ToDictionary(x=>x.Key)); - protected void AddPropertyValue(IProperty property, string? culture, string? segment, IDictionary>? values, IEnumerable availableCultures) + [Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")] + protected void AddPropertyValue(IProperty property, string? culture, string? segment, + IDictionary>? values, IEnumerable availableCultures) + => AddPropertyValue( + property, + culture, + segment, + values, + Enumerable.Empty(), + StaticServiceProvider.Instance.GetRequiredService().GetAll().ToDictionary(x=>x.Key)); + + protected void AddPropertyValue(IProperty property, string? culture, string? segment, IDictionary>? values, IEnumerable availableCultures, IDictionary contentTypeDictionary) { IDataEditor? editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; if (editor == null) @@ -35,7 +55,7 @@ public abstract class BaseValueSetBuilder : IValueSetBuilder } IEnumerable>> indexVals = - editor.PropertyIndexValueFactory.GetIndexValues(property, culture, segment, PublishedValuesOnly, availableCultures); + editor.PropertyIndexValueFactory.GetIndexValues(property, culture, segment, PublishedValuesOnly, availableCultures, contentTypeDictionary); foreach (KeyValuePair> keyVal in indexVals) { if (keyVal.Key.IsNullOrWhiteSpace()) diff --git a/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs b/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs index 228610879d..2d59e0ebe3 100644 --- a/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs +++ b/src/Umbraco.Infrastructure/Examine/ContentValueSetBuilder.cs @@ -21,13 +21,34 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal private static readonly object[] NoValue = new[] { "n" }; private static readonly object[] YesValue = new[] { "y" }; - private readonly IScopeProvider _scopeProvider; + private readonly ICoreScopeProvider _scopeProvider; private readonly IShortStringHelper _shortStringHelper; private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; private readonly ILocalizationService _localizationService; + private readonly IContentTypeService _contentTypeService; + public ContentValueSetBuilder( + PropertyEditorCollection propertyEditors, + UrlSegmentProviderCollection urlSegmentProviders, + IUserService userService, + IShortStringHelper shortStringHelper, + ICoreScopeProvider scopeProvider, + bool publishedValuesOnly, + ILocalizationService localizationService, + IContentTypeService contentTypeService) + : base(propertyEditors, publishedValuesOnly) + { + _urlSegmentProviders = urlSegmentProviders; + _userService = userService; + _shortStringHelper = shortStringHelper; + _scopeProvider = scopeProvider; + _localizationService = localizationService; + _contentTypeService = contentTypeService; + } + + [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] public ContentValueSetBuilder( PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, @@ -36,16 +57,20 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal IScopeProvider scopeProvider, bool publishedValuesOnly, ILocalizationService localizationService) - : base(propertyEditors, publishedValuesOnly) + : this( + propertyEditors, + urlSegmentProviders, + userService, + shortStringHelper, + scopeProvider, + publishedValuesOnly, + localizationService, + StaticServiceProvider.Instance.GetRequiredService()) { - _urlSegmentProviders = urlSegmentProviders; - _userService = userService; - _shortStringHelper = shortStringHelper; - _scopeProvider = scopeProvider; - _localizationService = localizationService; + } - [Obsolete("Use the constructor that takes an ILocalizationService, scheduled for removal in v14")] + [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] public ContentValueSetBuilder( PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, @@ -60,7 +85,8 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal shortStringHelper, scopeProvider, publishedValuesOnly, - StaticServiceProvider.Instance.GetRequiredService()) + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) { } @@ -72,7 +98,7 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal // We can lookup all of the creator/writer names at once which can save some // processing below instead of one by one. - using (IScope scope = _scopeProvider.CreateScope()) + using (ICoreScope scope = _scopeProvider.CreateCoreScope()) { creatorIds = _userService.GetProfilesById(content.Select(x => x.CreatorId).ToArray()) .ToDictionary(x => x.Id, x => x); @@ -86,6 +112,8 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal private IEnumerable GetValueSetsEnumerable(IContent[] content, Dictionary creatorIds, Dictionary writerIds) { + IDictionary contentTypeDictionary = _contentTypeService.GetAll().ToDictionary(x => x.Key); + // TODO: There is a lot of boxing going on here and ultimately all values will be boxed by Lucene anyways // but I wonder if there's a way to reduce the boxing that we have to do or if it will matter in the end since // Lucene will do it no matter what? One idea was to create a `FieldValue` struct which would contain `object`, `object[]`, `ValueType` and `ValueType[]` @@ -162,13 +190,13 @@ public class ContentValueSetBuilder : BaseValueSetBuilder, IContentVal { if (!property.PropertyType.VariesByCulture()) { - AddPropertyValue(property, null, null, values, availableCultures); + AddPropertyValue(property, null, null, values, availableCultures, contentTypeDictionary); } else { foreach (var culture in c.AvailableCultures) { - AddPropertyValue(property, culture.ToLowerInvariant(), null, values, availableCultures); + AddPropertyValue(property, culture.ToLowerInvariant(), null, values, availableCultures, contentTypeDictionary); } } } diff --git a/src/Umbraco.Infrastructure/Examine/MediaValueSetBuilder.cs b/src/Umbraco.Infrastructure/Examine/MediaValueSetBuilder.cs index fa7d6509cd..d2da36b347 100644 --- a/src/Umbraco.Infrastructure/Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Infrastructure/Examine/MediaValueSetBuilder.cs @@ -1,10 +1,12 @@ using Examine; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Examine; @@ -14,6 +16,7 @@ public class MediaValueSetBuilder : BaseValueSetBuilder private readonly ContentSettings _contentSettings; private readonly MediaUrlGeneratorCollection _mediaUrlGenerators; private readonly IShortStringHelper _shortStringHelper; + private readonly IContentTypeService _contentTypeService; private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; @@ -23,19 +26,41 @@ public class MediaValueSetBuilder : BaseValueSetBuilder MediaUrlGeneratorCollection mediaUrlGenerators, IUserService userService, IShortStringHelper shortStringHelper, - IOptions contentSettings) + IOptions contentSettings, + IContentTypeService contentTypeService) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _mediaUrlGenerators = mediaUrlGenerators; _userService = userService; _shortStringHelper = shortStringHelper; + _contentTypeService = contentTypeService; _contentSettings = contentSettings.Value; } + [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] + public MediaValueSetBuilder( + PropertyEditorCollection propertyEditors, + UrlSegmentProviderCollection urlSegmentProviders, + MediaUrlGeneratorCollection mediaUrlGenerators, + IUserService userService, + IShortStringHelper shortStringHelper, + IOptions contentSettings) + : this(propertyEditors, + urlSegmentProviders, + mediaUrlGenerators, + userService, + shortStringHelper, + contentSettings, + StaticServiceProvider.Instance.GetRequiredService()) + { + + } /// public override IEnumerable GetValueSets(params IMedia[] media) { + IDictionary contentTypeDictionary = _contentTypeService.GetAll().ToDictionary(x => x.Key); + foreach (IMedia m in media) { var urlValue = m.GetUrlSegment(_shortStringHelper, _urlSegmentProviders); @@ -65,7 +90,7 @@ public class MediaValueSetBuilder : BaseValueSetBuilder foreach (IProperty property in m.Properties) { - AddPropertyValue(property, null, null, values, m.AvailableCultures); + AddPropertyValue(property, null, null, values, m.AvailableCultures, contentTypeDictionary); } var vs = new ValueSet(m.Id.ToInvariantString(), IndexTypes.Media, m.ContentType.Alias, values); diff --git a/src/Umbraco.Infrastructure/Examine/MemberValueSetBuilder.cs b/src/Umbraco.Infrastructure/Examine/MemberValueSetBuilder.cs index 1b0bf7219f..8fe2a56856 100644 --- a/src/Umbraco.Infrastructure/Examine/MemberValueSetBuilder.cs +++ b/src/Umbraco.Infrastructure/Examine/MemberValueSetBuilder.cs @@ -1,20 +1,34 @@ using Examine; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Examine; public class MemberValueSetBuilder : BaseValueSetBuilder { - public MemberValueSetBuilder(PropertyEditorCollection propertyEditors) + private readonly IContentTypeService _contentTypeService; + + public MemberValueSetBuilder(PropertyEditorCollection propertyEditors, IContentTypeService contentTypeService) : base(propertyEditors, false) + { + _contentTypeService = contentTypeService; + } + + [Obsolete("Use non-obsolete ctor, scheduled for removal in v14")] + public MemberValueSetBuilder(PropertyEditorCollection propertyEditors) + : this(propertyEditors, StaticServiceProvider.Instance.GetRequiredService()) { } /// public override IEnumerable GetValueSets(params IMember[] members) { + IDictionary contentTypeDictionary = _contentTypeService.GetAll().ToDictionary(x => x.Key); + foreach (IMember m in members) { var values = new Dictionary> @@ -37,7 +51,7 @@ public class MemberValueSetBuilder : BaseValueSetBuilder foreach (IProperty property in m.Properties) { - AddPropertyValue(property, null, null, values, m.AvailableCultures); + AddPropertyValue(property, null, null, values, m.AvailableCultures, contentTypeDictionary); } var vs = new ValueSet(m.Id.ToInvariantString(), IndexTypes.Member, m.ContentType.Alias, values); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyIndexValueFactory.cs b/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyIndexValueFactory.cs index adace6126e..95185a3f30 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyIndexValueFactory.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/BlockValuePropertyIndexValueFactory.cs @@ -38,10 +38,13 @@ internal sealed class BlockValuePropertyIndexValueFactory : _contentTypeService = contentTypeService; } - + [Obsolete("Use non-obsolete overload, scheduled for removal in v14")] protected override IContentType? GetContentTypeOfNestedItem(BlockItemData input) => _contentTypeService.Get(input.ContentTypeKey); + protected override IContentType? GetContentTypeOfNestedItem(BlockItemData input, IDictionary contentTypeDictionary) + => contentTypeDictionary.TryGetValue(input.ContentTypeKey, out var result) ? result : null; + protected override IDictionary GetRawProperty(BlockItemData blockItemData) => blockItemData.RawPropertyValues; diff --git a/src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs index 9a7fa4b3bb..1b76cd89a5 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -2,19 +2,20 @@ // See LICENSE for more details. using System.Runtime.Serialization; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Core.Models.Editors; -using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; -using Umbraco.Extensions; +using Umbraco.Cms.Web.Common.DependencyInjection; namespace Umbraco.Cms.Core.PropertyEditors; @@ -26,11 +27,57 @@ public class MultiUrlPickerValueEditor : DataValueEditor, IDataValueReference NullValueHandling = NullValueHandling.Ignore, }; - private readonly IEntityService _entityService; private readonly ILogger _logger; - private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IPublishedUrlProvider _publishedUrlProvider; + private readonly IContentService _contentService; + private readonly IMediaService _mediaService; + public MultiUrlPickerValueEditor( + ILogger logger, + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, + DataEditorAttribute attribute, + IPublishedUrlProvider publishedUrlProvider, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + IContentService contentService, + IMediaService mediaService) + : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _publishedUrlProvider = publishedUrlProvider; + _contentService = contentService; + _mediaService = mediaService; + } + + [Obsolete("Use non-obsolete constructor. Scheduled for removal in Umbraco 14.")] + public MultiUrlPickerValueEditor( + IEntityService entityService, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + ILogger logger, + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, + DataEditorAttribute attribute, + IPublishedUrlProvider publishedUrlProvider, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + IContentService contentService, + IMediaService mediaService) + :this( + logger, + localizedTextService, + shortStringHelper, + attribute, + publishedUrlProvider, + jsonSerializer, + ioHelper, + contentService, + mediaService) + { + + } + + [Obsolete("Use non-obsolete constructor. Scheduled for removal in Umbraco 14.")] public MultiUrlPickerValueEditor( IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, @@ -41,13 +88,18 @@ public class MultiUrlPickerValueEditor : DataValueEditor, IDataValueReference IPublishedUrlProvider publishedUrlProvider, IJsonSerializer jsonSerializer, IIOHelper ioHelper) - : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute) + : this( + logger, + localizedTextService, + shortStringHelper, + attribute, + publishedUrlProvider, + jsonSerializer, + ioHelper, + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) { - _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); - _publishedSnapshotAccessor = publishedSnapshotAccessor ?? - throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _publishedUrlProvider = publishedUrlProvider; + } public IEnumerable GetReferences(object? value) @@ -86,26 +138,6 @@ public class MultiUrlPickerValueEditor : DataValueEditor, IDataValueReference { List? links = JsonConvert.DeserializeObject>(value); - List? documentLinks = links?.FindAll(link => - link.Udi != null && link.Udi.EntityType == Constants.UdiEntityType.Document); - List? mediaLinks = links?.FindAll(link => - link.Udi != null && link.Udi.EntityType == Constants.UdiEntityType.Media); - - var entities = new List(); - if (documentLinks?.Count > 0) - { - entities.AddRange( - _entityService.GetAll( - UmbracoObjectTypes.Document, - documentLinks.Select(link => link.Udi!.Guid).ToArray())); - } - - if (mediaLinks?.Count > 0) - { - entities.AddRange( - _entityService.GetAll(UmbracoObjectTypes.Media, mediaLinks.Select(link => link.Udi!.Guid).ToArray())); - } - var result = new List(); if (links is null) { @@ -114,7 +146,7 @@ public class MultiUrlPickerValueEditor : DataValueEditor, IDataValueReference foreach (LinkDto dto in links) { - GuidUdi? udi = null; + GuidUdi? udi = dto.Udi; var icon = "icon-link"; var published = true; var trashed = false; @@ -122,35 +154,30 @@ public class MultiUrlPickerValueEditor : DataValueEditor, IDataValueReference if (dto.Udi != null) { - IUmbracoEntity? entity = entities.Find(e => e.Key == dto.Udi.Guid); - if (entity == null) + if (dto.Udi.EntityType == Constants.UdiEntityType.Document) { - continue; - } + url = _publishedUrlProvider.GetUrl(dto.Udi.Guid, UrlMode.Relative, culture); + IContent? c = _contentService.GetById(dto.Udi.Guid); - IPublishedSnapshot publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); - if (entity is IDocumentEntitySlim documentEntity) - { - icon = documentEntity.ContentTypeIcon; - published = culture == null - ? documentEntity.Published - : documentEntity.PublishedCultures.Contains(culture); - udi = new GuidUdi(Constants.UdiEntityType.Document, documentEntity.Key); - url = publishedSnapshot.Content?.GetById(entity.Key)?.Url(_publishedUrlProvider) ?? "#"; - trashed = documentEntity.Trashed; + if (c is not null) + { + published = culture == null + ? c.Published + : c.PublishedCultures.Contains(culture); + icon = c.ContentType.Icon; + trashed = c.Trashed; + } } - else if (entity is IContentEntitySlim contentEntity) + else if (dto.Udi.EntityType == Constants.UdiEntityType.Media) { - icon = contentEntity.ContentTypeIcon; - published = !contentEntity.Trashed; - udi = new GuidUdi(Constants.UdiEntityType.Media, contentEntity.Key); - url = publishedSnapshot.Media?.GetById(entity.Key)?.Url(_publishedUrlProvider) ?? "#"; - trashed = contentEntity.Trashed; - } - else - { - // Not supported - continue; + url = _publishedUrlProvider.GetMediaUrl(dto.Udi.Guid, UrlMode.Relative, culture); + IMedia? m = _mediaService.GetById(dto.Udi.Guid); + if (m is not null) + { + published = m.Trashed is false; + icon = m.ContentType.Icon; + trashed = m.Trashed; + } } } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyIndexValueFactory.cs b/src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyIndexValueFactory.cs index 121a40bec9..693c21060b 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyIndexValueFactory.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyIndexValueFactory.cs @@ -39,6 +39,11 @@ internal sealed class NestedContentPropertyIndexValueFactory _contentTypeService = contentTypeService; } + protected override IContentType? GetContentTypeOfNestedItem( + NestedContentPropertyEditor.NestedContentValues.NestedContentRowValue input, IDictionary contentTypeDictionary) + => contentTypeDictionary.Values.FirstOrDefault(x=>x.Alias.Equals(input.ContentTypeAlias)); + + [Obsolete("Use non-obsolete overload, scheduled for removal in v14")] protected override IContentType? GetContentTypeOfNestedItem( NestedContentPropertyEditor.NestedContentValues.NestedContentRowValue input) => _contentTypeService.Get(input.ContentTypeAlias); diff --git a/src/Umbraco.Infrastructure/PropertyEditors/NestedPropertyIndexValueFactoryBase.cs b/src/Umbraco.Infrastructure/PropertyEditors/NestedPropertyIndexValueFactoryBase.cs index 94ed0a3e15..a675b38b2c 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/NestedPropertyIndexValueFactoryBase.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/NestedPropertyIndexValueFactoryBase.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Examine; using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; @@ -42,20 +43,39 @@ internal abstract class NestedPropertyIndexValueFactoryBase bool published) => Handle(deserializedPropertyValue, property, culture, segment, published, Enumerable.Empty()); + [Obsolete("Use the overload that specifies availableCultures, scheduled for removal in v14")] protected override IEnumerable>> Handle( TSerialized deserializedPropertyValue, IProperty property, string? culture, string? segment, bool published, - IEnumerable availableCultures) + IEnumerable availableCultures) => + Handle( + deserializedPropertyValue, + property, + culture, + segment, + published, + Enumerable.Empty(), + StaticServiceProvider.Instance.GetRequiredService().GetAll().ToDictionary(x=>x.Key)); + + + protected override IEnumerable>> Handle( + TSerialized deserializedPropertyValue, + IProperty property, + string? culture, + string? segment, + bool published, + IEnumerable availableCultures, + IDictionary contentTypeDictionary) { var result = new List>>(); var index = 0; foreach (TItem nestedContentRowValue in GetDataItems(deserializedPropertyValue)) { - IContentType? contentType = GetContentTypeOfNestedItem(nestedContentRowValue); + IContentType? contentType = GetContentTypeOfNestedItem(nestedContentRowValue, contentTypeDictionary); if (contentType is null) { @@ -125,6 +145,9 @@ internal abstract class NestedPropertyIndexValueFactoryBase /// /// Gets the content type using the nested item. /// + protected abstract IContentType? GetContentTypeOfNestedItem(TItem nestedItem, IDictionary contentTypeDictionary); + + [Obsolete("Use non-obsolete overload. Scheduled for removal in Umbraco 14.")] protected abstract IContentType? GetContentTypeOfNestedItem(TItem nestedItem); /// From d112ba5e4059d8a61ca43d06b3de0af576f49cdc Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 14 Nov 2023 09:11:58 +0100 Subject: [PATCH 12/14] Bump version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 006a78b8bd..ca5f5d35d2 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "12.3.1", + "version": "12.3.2", "assemblyVersion": { "precision": "build" }, From 2266a98fc62d7ca9769f9e9dfc16ce9ad91ef726 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 14 Nov 2023 09:14:01 +0100 Subject: [PATCH 13/14] https://github.com/umbraco/Umbraco-CMS/issues/15195 Fixed issue with media not cached correct (#15196) --- .../Persistence/NuCacheContentRepository.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs index af8c46821f..f54158dac1 100644 --- a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs +++ b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs @@ -224,7 +224,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -242,7 +242,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -265,7 +265,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -301,7 +301,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -319,7 +319,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -342,7 +342,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -990,7 +990,7 @@ WHERE cmsContentNu.nodeId IN ( return s; } - private IEnumerable GetContentNodeDtos(Sql sql) + private IEnumerable GetContentNodeDtos(Sql sql, Guid nodeObjectType) { // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. @@ -1000,7 +1000,7 @@ WHERE cmsContentNu.nodeId IN ( { // Use a more efficient COUNT query Sql? sqlCountQuery = SqlContentSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)); + .Append(SqlObjectTypeNotTrashed(SqlContext, nodeObjectType)); Sql? sqlCount = SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); From 2b7785fcd3bd319afefc0b0b61fae810c64591e8 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 14 Nov 2023 09:14:01 +0100 Subject: [PATCH 14/14] https://github.com/umbraco/Umbraco-CMS/issues/15195 Fixed issue with media not cached correct (#15196) --- .../Persistence/NuCacheContentRepository.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs index af8c46821f..f54158dac1 100644 --- a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs +++ b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs @@ -224,7 +224,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -242,7 +242,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -265,7 +265,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Document); foreach (ContentSourceDto row in dtos) { @@ -301,7 +301,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -319,7 +319,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -342,7 +342,7 @@ AND cmsContentNu.nodeId IS NULL IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - IEnumerable dtos = GetContentNodeDtos(sql); + IEnumerable dtos = GetContentNodeDtos(sql, Constants.ObjectTypes.Media); foreach (ContentSourceDto row in dtos) { @@ -990,7 +990,7 @@ WHERE cmsContentNu.nodeId IN ( return s; } - private IEnumerable GetContentNodeDtos(Sql sql) + private IEnumerable GetContentNodeDtos(Sql sql, Guid nodeObjectType) { // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. @@ -1000,7 +1000,7 @@ WHERE cmsContentNu.nodeId IN ( { // Use a more efficient COUNT query Sql? sqlCountQuery = SqlContentSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)); + .Append(SqlObjectTypeNotTrashed(SqlContext, nodeObjectType)); Sql? sqlCount = SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl");