From 8145a90094da67335306cd66ace3fdd8dae417d5 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 14 Feb 2024 12:34:18 +0100 Subject: [PATCH 1/5] Content type picker in dynamic root pickers (#15514) --- .../pickdynamicrootcustomstep.controller.js | 19 +++--- .../pickdynamicrootorigin.controller.js | 58 +++++++++++++------ .../pickdynamicrootquerystep.controller.js | 36 +++++++----- .../treesourcetypepicker.controller.js | 10 ++-- 4 files changed, 76 insertions(+), 47 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootcustomstep/pickdynamicrootcustomstep.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootcustomstep/pickdynamicrootcustomstep.controller.js index 1af37043f1..170e0075f2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootcustomstep/pickdynamicrootcustomstep.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootcustomstep/pickdynamicrootcustomstep.controller.js @@ -3,31 +3,32 @@ function PickDynamicRootCustomStepController($scope, localizationService) { - var vm = this; + const vm = this; + + vm.submit = submit; + vm.close = close; function onInit() { - if(!$scope.model.title) { - localizationService.localize("dynamicRoot_pickDynamicRootQueryStepTitle").then(function(value){ + if (!$scope.model.title) { + localizationService.localize("dynamicRoot_pickDynamicRootQueryStepTitle").then(value => { $scope.model.title = value; }); } - if(!$scope.model.subtitle) { - localizationService.localize("dynamicRoot_pickDynamicRootQueryStepDesc").then(function(value){ + if (!$scope.model.subtitle) { + localizationService.localize("dynamicRoot_pickDynamicRootQueryStepDesc").then(value => { $scope.model.subtitle = value; }); } } - - vm.submit = submit; + function submit() { if ($scope.model.submit) { $scope.model.submit($scope.model); } } - vm.close = close; function close() { - if($scope.model.close) { + if ($scope.model.close) { $scope.model.close(); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootorigin/pickdynamicrootorigin.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootorigin/pickdynamicrootorigin.controller.js index 9851c5f710..c7643d390b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootorigin/pickdynamicrootorigin.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootorigin/pickdynamicrootorigin.controller.js @@ -3,48 +3,59 @@ function PickDynamicRootOriginController($scope, localizationService, editorService, udiParser) { - var vm = this; + const vm = this; + + vm.chooseRoot = chooseRoot; + vm.chooseParent = chooseParent; + vm.chooseCurrent = chooseCurrent; + vm.chooseSite = chooseSite; + vm.chooseByKey = chooseByKey; + + vm.submit = submit; + vm.close = close; function onInit() { - if(!$scope.model.title) { - localizationService.localize("dynamicRoot_pickDynamicRootOriginTitle").then(function(value){ + if (!$scope.model.title) { + localizationService.localize("dynamicRoot_pickDynamicRootOriginTitle").then(value => { $scope.model.title = value; }); } - if(!$scope.model.subtitle) { - localizationService.localize("dynamicRoot_pickDynamicRootOriginDesc").then(function(value){ + if (!$scope.model.subtitle) { + localizationService.localize("dynamicRoot_pickDynamicRootOriginDesc").then(value => { $scope.model.subtitle = value; }); } } - vm.chooseRoot = function() { + function chooseRoot() { $scope.model.value.originAlias = "Root"; $scope.model.value.originKey = null; vm.submit($scope.model); } - vm.chooseParent = function() { + + function chooseParent() { $scope.model.value.originAlias = "Parent"; $scope.model.value.originKey = null; vm.submit($scope.model); } - vm.chooseCurrent = function() { + + function chooseCurrent() { $scope.model.value.originAlias = "Current"; $scope.model.value.originKey = null; vm.submit($scope.model); } - vm.chooseSite = function() { + + function chooseSite() { $scope.model.value.originAlias = "Site"; $scope.model.value.originKey = null; vm.submit($scope.model); } - vm.chooseByKey = function() { - var treePicker = { + + function chooseByKey() { + const editor = { idType: "udi", - section: $scope.model.contentType, - treeAlias: $scope.model.contentType, multiPicker: false, submit: function(model) { var item = model.selection[0]; @@ -57,19 +68,28 @@ editorService.close(); } }; - editorService.treePicker(treePicker); - } - vm.submit = submit; + switch ($scope.model.contentType) { + case "content": + editorService.contentPicker(editor); + break; + case "media": + editorService.mediaPicker(editor); + break; + case "member": + editorService.memberPicker(editor); + break; + } + } + function submit(model) { if ($scope.model.submit) { $scope.model.submit(model); } } - - vm.close = close; + function close() { - if($scope.model.close) { + if ($scope.model.close) { $scope.model.close(); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootquerystep/pickdynamicrootquerystep.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootquerystep/pickdynamicrootquerystep.controller.js index 00005aa019..0a1e607ebc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootquerystep/pickdynamicrootquerystep.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/pickdynamicrootquerystep/pickdynamicrootquerystep.controller.js @@ -3,23 +3,29 @@ function PickDynamicRootQueryStepController($scope, localizationService, editorService, udiParser) { - var vm = this; + const vm = this; + + vm.choose = choose; + vm.chooseCustom = chooseCustom; + + vm.submit = submit; + vm.close = close; function onInit() { - if(!$scope.model.title) { - localizationService.localize("dynamicRoot_pickDynamicRootQueryStepTitle").then(function(value){ + if (!$scope.model.title) { + localizationService.localize("dynamicRoot_pickDynamicRootQueryStepTitle").then(value => { $scope.model.title = value; }); } - if(!$scope.model.subtitle) { - localizationService.localize("dynamicRoot_pickDynamicRootQueryStepDesc").then(function(value){ + if (!$scope.model.subtitle) { + localizationService.localize("dynamicRoot_pickDynamicRootQueryStepDesc").then(value => { $scope.model.subtitle = value; }); } } - vm.choose = function(queryStepAlias) { - var editor = { + function choose(queryStepAlias) { + const editor = { multiPicker: true, filterCssClass: "not-allowed not-published", filter: function (item) { @@ -42,16 +48,18 @@ switch ($scope.model.contentType) { case "content": - editorService.contentTypePicker(editor); + editor.entityType = "documentType"; break; case "media": - editorService.mediaTypePicker(editor); + editor.entityType = "mediaType"; break; } + + editorService.contentTypePicker(editor); } - vm.chooseCustom = function() { - var customStepPicker = { + function chooseCustom() { + const customStepPicker = { view: "views/common/infiniteeditors/pickdynamicrootcustomstep/pickdynamicrootcustomstep.html", size: "small", value: "", @@ -68,17 +76,15 @@ }; editorService.open(customStepPicker); } - - vm.submit = submit; + function submit(model) { if ($scope.model.submit) { $scope.model.submit(model); } } - vm.close = close; function close() { - if($scope.model.close) { + if ($scope.model.close) { $scope.model.close(); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js index d02e626bfa..0bfe20f28e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesourcetypepicker.controller.js @@ -39,7 +39,7 @@ function TreeSourceTypePickerController($scope, contentTypeResource, mediaTypeRe return; } - var editor = { + const editor = { multiPicker: true, filterCssClass: "not-allowed not-published", filter: function (item) { @@ -62,15 +62,17 @@ function TreeSourceTypePickerController($scope, contentTypeResource, mediaTypeRe switch (currentItemType) { case "content": - editorService.contentTypePicker(editor); + editor.entityType = "documentType"; break; case "media": - editorService.mediaTypePicker(editor); + editor.entityType = "mediaType"; break; case "member": - editorService.memberTypePicker(editor); + editor.entityType = "memberType"; break; } + + editorService.contentTypePicker(editor); } function remove(itemType) { From 5978412b23fbdbe80c3115333e9ce344c12cdaf5 Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Fri, 12 Jan 2024 11:32:06 +0000 Subject: [PATCH 2/5] Add custom Examine FileSystemDirectoryFactory So that the Umbraco SiteName property is used when generating the temp folder name hash --- .../ConfigurationEnabledDirectoryFactory.cs | 2 +- .../UmbracoBuilderExtensions.cs | 24 +++++++++++-- ...mbracoTempEnvFileSystemDirectoryFactory.cs | 36 +++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Examine.Lucene/UmbracoTempEnvFileSystemDirectoryFactory.cs diff --git a/src/Umbraco.Examine.Lucene/ConfigurationEnabledDirectoryFactory.cs b/src/Umbraco.Examine.Lucene/ConfigurationEnabledDirectoryFactory.cs index f58dffacac..e627802222 100644 --- a/src/Umbraco.Examine.Lucene/ConfigurationEnabledDirectoryFactory.cs +++ b/src/Umbraco.Examine.Lucene/ConfigurationEnabledDirectoryFactory.cs @@ -54,7 +54,7 @@ public class ConfigurationEnabledDirectoryFactory : DirectoryFactoryBase case LuceneDirectoryFactory.SyncedTempFileSystemDirectoryFactory: return _services.GetRequiredService(); case LuceneDirectoryFactory.TempFileSystemDirectoryFactory: - return _services.GetRequiredService(); + return _services.GetRequiredService(); case LuceneDirectoryFactory.Default: default: return _services.GetRequiredService(); diff --git a/src/Umbraco.Examine.Lucene/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Examine.Lucene/DependencyInjection/UmbracoBuilderExtensions.cs index baaf10907c..211ebd8b71 100644 --- a/src/Umbraco.Examine.Lucene/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Examine.Lucene/DependencyInjection/UmbracoBuilderExtensions.cs @@ -1,8 +1,10 @@ using Examine; using Examine.Lucene.Directories; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Cms.Core; using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Hosting; namespace Umbraco.Cms.Infrastructure.Examine.DependencyInjection; @@ -22,8 +24,26 @@ public static class UmbracoBuilderExtensions services.AddExamine(); - // Create the indexes - services + services.AddSingleton(); + services.RemoveAll(); + services.AddSingleton( + s => + { + var baseDir = s.GetRequiredService().ApplicationRoot; + + var tempDir = UmbracoTempEnvFileSystemDirectoryFactory.GetTempPath( + s.GetRequiredService(), s.GetRequiredService()); + + return ActivatorUtilities.CreateInstance( + s, + new object[] + { + new DirectoryInfo(tempDir), s.GetRequiredService().ApplicationRoot + }); + }); + + // Create the indexes + services .AddExamineLuceneIndex(Constants.UmbracoIndexes .InternalIndexName) .AddExamineLuceneIndex(Constants.UmbracoIndexes diff --git a/src/Umbraco.Examine.Lucene/UmbracoTempEnvFileSystemDirectoryFactory.cs b/src/Umbraco.Examine.Lucene/UmbracoTempEnvFileSystemDirectoryFactory.cs new file mode 100644 index 0000000000..367181d143 --- /dev/null +++ b/src/Umbraco.Examine.Lucene/UmbracoTempEnvFileSystemDirectoryFactory.cs @@ -0,0 +1,36 @@ +using Examine; +using Examine.Lucene.Directories; +using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment; + +namespace Umbraco.Cms.Infrastructure.Examine +{ + /// + /// Custom version of https://github.com/Shazwazza/Examine/blob/release/3.0/src/Examine.Lucene/Directories/TempEnvFileSystemDirectoryFactory.cs that includes the Umbraco SiteName property in the path hash + /// + public class UmbracoTempEnvFileSystemDirectoryFactory : FileSystemDirectoryFactory + { + public UmbracoTempEnvFileSystemDirectoryFactory( + IApplicationIdentifier applicationIdentifier, + ILockFactory lockFactory, + IHostingEnvironment hostingEnvironment) + : base(new DirectoryInfo(GetTempPath(applicationIdentifier, hostingEnvironment)), lockFactory) + { + } + + public static string GetTempPath(IApplicationIdentifier applicationIdentifier, IHostingEnvironment hostingEnvironment) + { + var hashString = hostingEnvironment.SiteName + "::" + applicationIdentifier.GetApplicationUniqueIdentifier(); + var appDomainHash = hashString.GenerateHash(); + + var cachePath = Path.Combine( + Path.GetTempPath(), + "ExamineIndexes", + //include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back + // to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not + // utilizing an old index + appDomainHash); + + return cachePath; + } + } +} From a7cacc9bb39d08bde68349bf9693c458c07964b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20V=C3=A5gan?= Date: Tue, 20 Feb 2024 11:05:38 +0100 Subject: [PATCH 3/5] Add CultureInfo.InvariantCulture argument to nodeId.ToString() in CheckPermissionsPath() call --- src/Umbraco.Core/Security/ContentPermissions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Security/ContentPermissions.cs b/src/Umbraco.Core/Security/ContentPermissions.cs index 6c70326699..d0eca368e8 100644 --- a/src/Umbraco.Core/Security/ContentPermissions.cs +++ b/src/Umbraco.Core/Security/ContentPermissions.cs @@ -200,7 +200,7 @@ public class ContentPermissions // get the implicit/inherited permissions for the user for this path // if there is no entity for this id, than just use the id as the path (i.e. -1 or -20) - return CheckPermissionsPath(entity?.Path ?? nodeId.ToString(), user, permissionsToCheck) + return CheckPermissionsPath(entity?.Path ?? nodeId.ToString(CultureInfo.InvariantCulture), user, permissionsToCheck) ? ContentAccess.Granted : ContentAccess.Denied; } @@ -259,7 +259,7 @@ public class ContentPermissions // get the implicit/inherited permissions for the user for this path // if there is no content item for this id, than just use the id as the path (i.e. -1 or -20) - return CheckPermissionsPath(contentItem?.Path ?? nodeId.ToString(), user, permissionsToCheck) + return CheckPermissionsPath(contentItem?.Path ?? nodeId.ToString(CultureInfo.InvariantCulture), user, permissionsToCheck) ? ContentAccess.Granted : ContentAccess.Denied; } From 99f841b7aecdfb1b9a7ef9b12dc42eb3f5cab468 Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Thu, 22 Feb 2024 14:44:01 +0100 Subject: [PATCH 4/5] Bump rc version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 43d283b98f..44ba7dcf8f 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": "13.2.0-rc", + "version": "13.2.0-rc2", "assemblyVersion": { "precision": "build" }, From f17f5522c00db37241e4f559a36094bba8a0e2a0 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:40:11 +0100 Subject: [PATCH 5/5] revert changes in Default.cshtml regarding external login providers, as there are still parts of the backoffice using the AngularJS variables --- .../umbraco/UmbracoBackOffice/Default.cshtml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml b/src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml index 10d67be2da..b80ee34272 100644 --- a/src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml +++ b/src/Umbraco.Cms.StaticAssets/umbraco/UmbracoBackOffice/Default.cshtml @@ -16,6 +16,7 @@ @inject IOptions globalSettings @inject IRuntimeMinifier runtimeMinifier @inject IProfilerHtml profilerHtml +@inject IBackOfficeExternalLoginProviders externalLogins @{ bool.TryParse(Context.Request.Query["umbDebug"], out bool isDebug); var backOfficePath = globalSettings.Value.GetBackOfficePath(hostingEnvironment); @@ -113,6 +114,8 @@