From 77f3012548cd690a7b2eb018992e52b2cdad8956 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 6 Oct 2021 15:30:04 +0200 Subject: [PATCH 1/4] Exposes the entity containers (folders) created during a package installation in the summary available from the ImportedPackageNotification. --- .../Packaging/InstallationSummary.cs | 2 + .../Packaging/PackageDataInstallation.cs | 38 ++++++++----- .../Packaging/PackageDataInstallationTests.cs | 53 +++++++++++-------- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/Umbraco.Core/Packaging/InstallationSummary.cs b/src/Umbraco.Core/Packaging/InstallationSummary.cs index 2aa74474d12e..42ac9f7ef069 100644 --- a/src/Umbraco.Core/Packaging/InstallationSummary.cs +++ b/src/Umbraco.Core/Packaging/InstallationSummary.cs @@ -32,6 +32,7 @@ public InstallationSummary(string packageName) public IEnumerable PartialViewsInstalled { get; set; } = Enumerable.Empty(); public IEnumerable ContentInstalled { get; set; } = Enumerable.Empty(); public IEnumerable MediaInstalled { get; set; } = Enumerable.Empty(); + public IEnumerable EntityContainersInstalled { get; set; } = Enumerable.Empty(); public override string ToString() { @@ -77,6 +78,7 @@ void WriteCount(string message, IEnumerable source, bool appendLine = true WriteCount("Stylesheets installed: ", StylesheetsInstalled); WriteCount("Scripts installed: ", ScriptsInstalled); WriteCount("Partial views installed: ", PartialViewsInstalled); + WriteCount("Entity containers installed: ", EntityContainersInstalled); WriteCount("Content items installed: ", ContentInstalled); WriteCount("Media items installed: ", MediaInstalled, false); diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index c691b74a0cb2..828c619a854f 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -88,21 +88,23 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i { using (var scope = _scopeProvider.CreateScope()) { + var entityContainersInstalled = new List(); var installationSummary = new InstallationSummary(compiledPackage.Name) { Warnings = compiledPackage.Warnings, - DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId), + DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId, entityContainersInstalled), LanguagesInstalled = ImportLanguages(compiledPackage.Languages, userId), DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId), MacrosInstalled = ImportMacros(compiledPackage.Macros, userId), MacroPartialViewsInstalled = ImportMacroPartialViews(compiledPackage.MacroPartialViews, userId), TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId), - DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId), - MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId), + DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId, entityContainersInstalled), + MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId, entityContainersInstalled), StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId), ScriptsInstalled = ImportScripts(compiledPackage.Scripts, userId), PartialViewsInstalled = ImportPartialViews(compiledPackage.PartialViews, userId) }; + installationSummary.EntityContainersInstalled = entityContainersInstalled; // We need a reference to the imported doc types to continue var importedDocTypes = installationSummary.DocumentTypesInstalled.ToDictionary(x => x.Alias, x => x); @@ -121,9 +123,10 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i /// /// Xml to import /// Optional id of the User performing the operation. Default is zero (admin). + /// List of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService); + public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId, List entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, entityContainersInstalled, _mediaTypeService); #endregion @@ -408,16 +411,17 @@ private TContentBase CreateContent(string #region DocumentTypes public IReadOnlyList ImportDocumentType(XElement docTypeElement, int userId) - => ImportDocumentTypes(new[] { docTypeElement }, userId); + => ImportDocumentTypes(new[] { docTypeElement }, userId, new List()); /// /// Imports and saves package xml as /// /// Xml to import /// Optional id of the User performing the operation. Default is zero (admin). + /// List of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService); + public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId, List entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, entityContainersInstalled, _contentTypeService); /// /// Imports and saves package xml as @@ -425,8 +429,9 @@ public IReadOnlyList ImportDocumentTypes(IEnumerable doc /// Xml to import /// Boolean indicating whether or not to import the /// Optional id of the User performing the operation. Default is zero (admin). + /// List of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service) + public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, List entityContainersInstalled, IContentTypeBaseService service) where T : class, IContentTypeComposition { var importedContentTypes = new Dictionary(); @@ -436,7 +441,7 @@ public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection uns var graph = new TopoGraph>(x => x.Key, x => x.Dependencies); var isSingleDocTypeImport = unsortedDocumentTypes.Count == 1; - var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes); + var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes, entityContainersInstalled); if (isSingleDocTypeImport == false) { @@ -532,7 +537,7 @@ public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection uns return list; } - private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes) + private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes, List entityContainersInstalled) { var importedFolders = new Dictionary(); foreach (var documentType in unsortedDocumentTypes) @@ -578,8 +583,10 @@ private Dictionary CreateContentTypeFolderStructure(IEnumerable(string contentTypeAlias, IContentTypeBaseSer /// /// Xml to import /// Optional id of the user + /// List of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated DataTypeDefinitions - public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId) + public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId, List entityContainersInstalled) { var dataTypes = new List(); - var importedFolders = CreateDataTypeFolderStructure(dataTypeElements); + var importedFolders = CreateDataTypeFolderStructure(dataTypeElements, entityContainersInstalled); foreach (var dataTypeElement in dataTypeElements) { @@ -1072,7 +1080,7 @@ public IReadOnlyList ImportDataTypes(IReadOnlyCollection da return dataTypes; } - private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements) + private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements, List entityContainersInstalled) { var importedFolders = new Dictionary(); foreach (var datatypeElement in datatypeElements) @@ -1103,7 +1111,9 @@ private Dictionary CreateDataTypeFolderStructure(IEnumerable dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfTemplates = (from doc in templateElement.Elements("Template") select doc).Count(); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); @@ -141,9 +142,10 @@ public void Can_Import_Inherited_ContentTypes_And_Verify_PropertyTypes_UniqueIds XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); // Assert IContentType mRBasePage = contentTypes.First(x => x.Alias == "MRBasePage"); @@ -166,9 +168,10 @@ public void Can_Import_Inherited_ContentTypes_And_Verify_PropertyGroups_And_Prop XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); @@ -274,9 +277,10 @@ public void Can_Import_StandardMvc_ContentTypes_Package_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert @@ -309,13 +313,14 @@ public void Can_Import_StandardMvc_ContentTypes_And_Templates_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert - Re-Import contenttypes doesn't throw - Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0)); + Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled)); Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes)); Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); @@ -333,13 +338,14 @@ public void Can_Import_Fanoe_Starterkit_ContentTypes_And_Templates_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert - Re-Import contenttypes doesn't throw - Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0)); + Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled)); Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes)); Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); @@ -358,8 +364,9 @@ public void Can_Import_Content_Package_Xml() var packageDocument = CompiledPackageContentBase.Create(element); // Act - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0, entityContainersInstalled); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService); int numberOfDocs = (from doc in element.Descendants() @@ -385,7 +392,8 @@ public void Can_Import_Media_Package_Xml() var packageMedia = CompiledPackageContentBase.Create(element); // Act - IReadOnlyList mediaTypes = PackageDataInstallation.ImportMediaTypes(mediaTypesElement.Elements("MediaType"), 0); + var entityContainersInstalled = new List(); + IReadOnlyList mediaTypes = PackageDataInstallation.ImportMediaTypes(mediaTypesElement.Elements("MediaType"), 0, entityContainersInstalled); var importedMediaTypes = mediaTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList medias = PackageDataInstallation.ImportContentBase(packageMedia.Yield(), importedMediaTypes, 0, MediaTypeService, MediaService); int numberOfDocs = (from doc in element.Descendants() @@ -413,8 +421,9 @@ private void AssertCheckBoxListTests(string strXml) var packageDocument = CompiledPackageContentBase.Create(element); // Act - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); + var entityContainersInstalled = new List(); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0, entityContainersInstalled); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService); int numberOfDocs = (from doc in element.Descendants() @@ -724,8 +733,9 @@ public void Can_Import_Package_With_Compositions() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act + var entityContainersInstalled = new List(); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert @@ -751,7 +761,8 @@ public void Can_Import_Package_With_Compositions_Ordered() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); + var entityContainersInstalled = new List(); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert From a570df1adac6fe04de7447bfc6ac22fcd8bb0ac9 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 6 Oct 2021 15:56:22 +0200 Subject: [PATCH 2/4] Restored original constructors. --- .../Packaging/PackageDataInstallation.cs | 40 ++++++++++++++ .../Packaging/PackageDataInstallationTests.cs | 53 ++++++++----------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index 828c619a854f..9dd1a9339b87 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -118,6 +118,16 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i return installationSummary; } } + + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the User performing the operation. Default is zero (admin). + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId) + => ImportMediaTypes(docTypeElements, userId, new List()); + /// /// Imports and saves package xml as /// @@ -413,6 +423,15 @@ private TContentBase CreateContent(string public IReadOnlyList ImportDocumentType(XElement docTypeElement, int userId) => ImportDocumentTypes(new[] { docTypeElement }, userId, new List()); + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the User performing the operation. Default is zero (admin). + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, new List(), _contentTypeService); + /// /// Imports and saves package xml as /// @@ -423,6 +442,17 @@ public IReadOnlyList ImportDocumentType(XElement docTypeElement, i public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId, List entityContainersInstalled) => ImportDocumentTypes(docTypeElements.ToList(), true, userId, entityContainersInstalled, _contentTypeService); + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Boolean indicating whether or not to import the + /// Optional id of the User performing the operation. Default is zero (admin). + /// An enumerable list of generated ContentTypes + public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service) + where T : class, IContentTypeComposition + => ImportDocumentTypes(unsortedDocumentTypes, importStructure, userId, new List(), service); + /// /// Imports and saves package xml as /// @@ -596,6 +626,7 @@ private Dictionary CreateContentTypeFolderStructure(IEnumerable(string contentTypeAlias, IContentTypeBaseSer #region DataTypes + /// + /// Imports and saves package xml as + /// + /// Xml to import + /// Optional id of the user + /// An enumerable list of generated DataTypeDefinitions + public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId) + => ImportDataTypes(dataTypeElements, userId, new List()); + /// /// Imports and saves package xml as /// diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs index d7643a425884..39ca764f9414 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs @@ -94,10 +94,9 @@ public void Can_Import_uBlogsy_ContentTypes_And_Verify_Structure() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfTemplates = (from doc in templateElement.Elements("Template") select doc).Count(); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); @@ -142,10 +141,9 @@ public void Can_Import_Inherited_ContentTypes_And_Verify_PropertyTypes_UniqueIds XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); // Assert IContentType mRBasePage = contentTypes.First(x => x.Alias == "MRBasePage"); @@ -168,10 +166,9 @@ public void Can_Import_Inherited_ContentTypes_And_Verify_PropertyGroups_And_Prop XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypes = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); @@ -277,10 +274,9 @@ public void Can_Import_StandardMvc_ContentTypes_Package_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert @@ -313,14 +309,13 @@ public void Can_Import_StandardMvc_ContentTypes_And_Templates_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert - Re-Import contenttypes doesn't throw - Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled)); + Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0)); Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes)); Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); @@ -338,14 +333,13 @@ public void Can_Import_Fanoe_Starterkit_ContentTypes_And_Templates_Xml() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert - Re-Import contenttypes doesn't throw - Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled)); + Assert.DoesNotThrow(() => PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0)); Assert.That(contentTypes.Count(), Is.EqualTo(numberOfDocTypes)); Assert.That(dataTypeDefinitions, Is.Not.Null); Assert.That(dataTypeDefinitions.Any(), Is.True); @@ -364,9 +358,8 @@ public void Can_Import_Content_Package_Xml() var packageDocument = CompiledPackageContentBase.Create(element); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService); int numberOfDocs = (from doc in element.Descendants() @@ -392,8 +385,7 @@ public void Can_Import_Media_Package_Xml() var packageMedia = CompiledPackageContentBase.Create(element); // Act - var entityContainersInstalled = new List(); - IReadOnlyList mediaTypes = PackageDataInstallation.ImportMediaTypes(mediaTypesElement.Elements("MediaType"), 0, entityContainersInstalled); + IReadOnlyList mediaTypes = PackageDataInstallation.ImportMediaTypes(mediaTypesElement.Elements("MediaType"), 0); var importedMediaTypes = mediaTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList medias = PackageDataInstallation.ImportContentBase(packageMedia.Yield(), importedMediaTypes, 0, MediaTypeService, MediaService); int numberOfDocs = (from doc in element.Descendants() @@ -421,9 +413,8 @@ private void AssertCheckBoxListTests(string strXml) var packageDocument = CompiledPackageContentBase.Create(element); // Act - var entityContainersInstalled = new List(); - IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0, entityContainersInstalled); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); IReadOnlyList contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService); int numberOfDocs = (from doc in element.Descendants() @@ -733,9 +724,8 @@ public void Can_Import_Package_With_Compositions() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); IReadOnlyList templates = PackageDataInstallation.ImportTemplates(templateElement.Elements("Template").ToList(), 0); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert @@ -761,8 +751,7 @@ public void Can_Import_Package_With_Compositions_Ordered() XElement docTypeElement = xml.Descendants("DocumentTypes").First(); // Act - var entityContainersInstalled = new List(); - IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0, entityContainersInstalled); + IReadOnlyList contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypeElement.Elements("DocumentType"), 0); int numberOfDocTypes = (from doc in docTypeElement.Elements("DocumentType") select doc).Count(); // Assert From 50654cfee45017a00475abdd419b7a76d2998016 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 6 Oct 2021 16:20:38 +0200 Subject: [PATCH 3/4] Refactored to use out parameters for tracking installed entity containers. --- .../Packaging/PackageDataInstallation.cs | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index 9dd1a9339b87..cc95c0226a24 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -88,22 +88,26 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i { using (var scope = _scopeProvider.CreateScope()) { - var entityContainersInstalled = new List(); var installationSummary = new InstallationSummary(compiledPackage.Name) { Warnings = compiledPackage.Warnings, - DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId, entityContainersInstalled), + DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId, out IEnumerable dataTypeEntityContainersInstalled), LanguagesInstalled = ImportLanguages(compiledPackage.Languages, userId), DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId), MacrosInstalled = ImportMacros(compiledPackage.Macros, userId), MacroPartialViewsInstalled = ImportMacroPartialViews(compiledPackage.MacroPartialViews, userId), TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId), - DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId, entityContainersInstalled), - MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId, entityContainersInstalled), + DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId, out IEnumerable documentTypeEntityContainersInstalled), + MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId, out IEnumerable mediaTypeEntityContainersInstalled), StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId), ScriptsInstalled = ImportScripts(compiledPackage.Scripts, userId), PartialViewsInstalled = ImportPartialViews(compiledPackage.PartialViews, userId) }; + + var entityContainersInstalled = new List(); + entityContainersInstalled.AddRange(dataTypeEntityContainersInstalled); + entityContainersInstalled.AddRange(documentTypeEntityContainersInstalled); + entityContainersInstalled.AddRange(mediaTypeEntityContainersInstalled); installationSummary.EntityContainersInstalled = entityContainersInstalled; // We need a reference to the imported doc types to continue @@ -126,17 +130,17 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i /// Optional id of the User performing the operation. Default is zero (admin). /// An enumerable list of generated ContentTypes public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId) - => ImportMediaTypes(docTypeElements, userId, new List()); + => ImportMediaTypes(docTypeElements, userId, out _); /// /// Imports and saves package xml as /// /// Xml to import /// Optional id of the User performing the operation. Default is zero (admin). - /// List of entity containers installed by the package to be populated with those created in installing data types. + /// Collection of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId, List entityContainersInstalled) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, entityContainersInstalled, _mediaTypeService); + public IReadOnlyList ImportMediaTypes(IEnumerable docTypeElements, int userId, out IEnumerable entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService, out entityContainersInstalled); #endregion @@ -421,7 +425,7 @@ private TContentBase CreateContent(string #region DocumentTypes public IReadOnlyList ImportDocumentType(XElement docTypeElement, int userId) - => ImportDocumentTypes(new[] { docTypeElement }, userId, new List()); + => ImportDocumentTypes(new[] { docTypeElement }, userId, out _); /// /// Imports and saves package xml as @@ -430,17 +434,17 @@ public IReadOnlyList ImportDocumentType(XElement docTypeElement, i /// Optional id of the User performing the operation. Default is zero (admin). /// An enumerable list of generated ContentTypes public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, new List(), _contentTypeService); + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out _); /// /// Imports and saves package xml as /// /// Xml to import /// Optional id of the User performing the operation. Default is zero (admin). - /// List of entity containers installed by the package to be populated with those created in installing data types. + /// Collection of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId, List entityContainersInstalled) - => ImportDocumentTypes(docTypeElements.ToList(), true, userId, entityContainersInstalled, _contentTypeService); + public IReadOnlyList ImportDocumentTypes(IEnumerable docTypeElements, int userId, out IEnumerable entityContainersInstalled) + => ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out entityContainersInstalled); /// /// Imports and saves package xml as @@ -451,7 +455,7 @@ public IReadOnlyList ImportDocumentTypes(IEnumerable doc /// An enumerable list of generated ContentTypes public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service) where T : class, IContentTypeComposition - => ImportDocumentTypes(unsortedDocumentTypes, importStructure, userId, new List(), service); + => ImportDocumentTypes(unsortedDocumentTypes, importStructure, userId, service); /// /// Imports and saves package xml as @@ -459,19 +463,20 @@ public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection uns /// Xml to import /// Boolean indicating whether or not to import the /// Optional id of the User performing the operation. Default is zero (admin). - /// List of entity containers installed by the package to be populated with those created in installing data types. + /// Collection of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated ContentTypes - public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, List entityContainersInstalled, IContentTypeBaseService service) + public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService service, out IEnumerable entityContainersInstalled) where T : class, IContentTypeComposition { var importedContentTypes = new Dictionary(); + entityContainersInstalled = new List(); //When you are importing a single doc type we have to assume that the dependencies are already there. //Otherwise something like uSync won't work. var graph = new TopoGraph>(x => x.Key, x => x.Dependencies); var isSingleDocTypeImport = unsortedDocumentTypes.Count == 1; - var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes, entityContainersInstalled); + var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes, out entityContainersInstalled); if (isSingleDocTypeImport == false) { @@ -567,9 +572,10 @@ public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection uns return list; } - private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes, List entityContainersInstalled) + private Dictionary CreateContentTypeFolderStructure(IEnumerable unsortedDocumentTypes, out IEnumerable entityContainersInstalled) { var importedFolders = new Dictionary(); + var trackEntityContainersInstalled = new List(); foreach (var documentType in unsortedDocumentTypes) { var foldersAttribute = documentType.Attribute("Folders"); @@ -616,7 +622,7 @@ private Dictionary CreateContentTypeFolderStructure(IEnumerable CreateContentTypeFolderStructure(IEnumerable(string contentTypeAlias, IContentTypeBaseSer /// Optional id of the user /// An enumerable list of generated DataTypeDefinitions public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId) - => ImportDataTypes(dataTypeElements, userId, new List()); + => ImportDataTypes(dataTypeElements, userId, out _); /// /// Imports and saves package xml as /// /// Xml to import /// Optional id of the user - /// List of entity containers installed by the package to be populated with those created in installing data types. + /// Collection of entity containers installed by the package to be populated with those created in installing data types. /// An enumerable list of generated DataTypeDefinitions - public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId, List entityContainersInstalled) + public IReadOnlyList ImportDataTypes(IReadOnlyCollection dataTypeElements, int userId, out IEnumerable entityContainersInstalled) { var dataTypes = new List(); - var importedFolders = CreateDataTypeFolderStructure(dataTypeElements, entityContainersInstalled); + var importedFolders = CreateDataTypeFolderStructure(dataTypeElements, out entityContainersInstalled); foreach (var dataTypeElement in dataTypeElements) { @@ -1120,9 +1127,10 @@ public IReadOnlyList ImportDataTypes(IReadOnlyCollection da return dataTypes; } - private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements, List entityContainersInstalled) + private Dictionary CreateDataTypeFolderStructure(IEnumerable datatypeElements, out IEnumerable entityContainersInstalled) { var importedFolders = new Dictionary(); + var trackEntityContainersInstalled = new List(); foreach (var datatypeElement in datatypeElements) { var foldersAttribute = datatypeElement.Attribute("Folders"); @@ -1153,7 +1161,7 @@ private Dictionary CreateDataTypeFolderStructure(IEnumerable CreateDataTypeFolderStructure(IEnumerable Date: Wed, 6 Oct 2021 16:49:43 +0200 Subject: [PATCH 4/4] Removed unnecessary variable initialization. --- src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index cc95c0226a24..5c9942f945ac 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -469,7 +469,6 @@ public IReadOnlyList ImportDocumentTypes(IReadOnlyCollection uns where T : class, IContentTypeComposition { var importedContentTypes = new Dictionary(); - entityContainersInstalled = new List(); //When you are importing a single doc type we have to assume that the dependencies are already there. //Otherwise something like uSync won't work.