Skip to content

Commit

Permalink
Exposes the entity containers (folders) created during a package inst…
Browse files Browse the repository at this point in the history
…allation in the summary available from the ImportedPackageNotification. (#11303)

* Exposes the entity containers (folders) created during a package installation in the summary available from the ImportedPackageNotification.

* Restored original constructors.

* Refactored to use out parameters for tracking installed entity containers.

* Removed unnecessary variable initialization.
  • Loading branch information
AndyButland authored Oct 6, 2021
1 parent e786491 commit bef1cce
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 11 deletions.
2 changes: 2 additions & 0 deletions src/Umbraco.Core/Packaging/InstallationSummary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public InstallationSummary(string packageName)
public IEnumerable<IPartialView> PartialViewsInstalled { get; set; } = Enumerable.Empty<IPartialView>();
public IEnumerable<IContent> ContentInstalled { get; set; } = Enumerable.Empty<IContent>();
public IEnumerable<IMedia> MediaInstalled { get; set; } = Enumerable.Empty<IMedia>();
public IEnumerable<EntityContainer> EntityContainersInstalled { get; set; } = Enumerable.Empty<EntityContainer>();

public override string ToString()
{
Expand Down Expand Up @@ -77,6 +78,7 @@ void WriteCount<T>(string message, IEnumerable<T> 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);

Expand Down
80 changes: 69 additions & 11 deletions src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,25 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i
var installationSummary = new InstallationSummary(compiledPackage.Name)
{
Warnings = compiledPackage.Warnings,
DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId),
DataTypesInstalled = ImportDataTypes(compiledPackage.DataTypes.ToList(), userId, out IEnumerable<EntityContainer> 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),
MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId),
DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId, out IEnumerable<EntityContainer> documentTypeEntityContainersInstalled),
MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId, out IEnumerable<EntityContainer> mediaTypeEntityContainersInstalled),
StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId),
ScriptsInstalled = ImportScripts(compiledPackage.Scripts, userId),
PartialViewsInstalled = ImportPartialViews(compiledPackage.PartialViews, userId)
};

var entityContainersInstalled = new List<EntityContainer>();
entityContainersInstalled.AddRange(dataTypeEntityContainersInstalled);
entityContainersInstalled.AddRange(documentTypeEntityContainersInstalled);
entityContainersInstalled.AddRange(mediaTypeEntityContainersInstalled);
installationSummary.EntityContainersInstalled = entityContainersInstalled;

// We need a reference to the imported doc types to continue
var importedDocTypes = installationSummary.DocumentTypesInstalled.ToDictionary(x => x.Alias, x => x);
var importedMediaTypes = installationSummary.MediaTypesInstalled.ToDictionary(x => x.Alias, x => x);
Expand All @@ -116,14 +122,25 @@ public InstallationSummary InstallPackageData(CompiledPackage compiledPackage, i
return installationSummary;
}
}

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="docTypeElements">Xml to import</param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId)
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService);
=> ImportMediaTypes(docTypeElements, userId, out _);

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="docTypeElements">Xml to import</param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <param name="entityContainersInstalled">Collection of entity containers installed by the package to be populated with those created in installing data types.</param>
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId, out IEnumerable<EntityContainer> entityContainersInstalled)
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService, out entityContainersInstalled);

#endregion

Expand Down Expand Up @@ -408,7 +425,7 @@ private TContentBase CreateContent<TContentBase, TContentTypeComposition>(string
#region DocumentTypes

public IReadOnlyList<IContentType> ImportDocumentType(XElement docTypeElement, int userId)
=> ImportDocumentTypes(new[] { docTypeElement }, userId);
=> ImportDocumentTypes(new[] { docTypeElement }, userId, out _);

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
Expand All @@ -417,7 +434,17 @@ public IReadOnlyList<IContentType> ImportDocumentType(XElement docTypeElement, i
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IContentType> ImportDocumentTypes(IEnumerable<XElement> docTypeElements, int userId)
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService);
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out _);

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="docTypeElements">Xml to import</param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <param name="entityContainersInstalled">Collection of entity containers installed by the package to be populated with those created in installing data types.</param>
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IContentType> ImportDocumentTypes(IEnumerable<XElement> docTypeElements, int userId, out IEnumerable<EntityContainer> entityContainersInstalled)
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _contentTypeService, out entityContainersInstalled);

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
Expand All @@ -428,6 +455,18 @@ public IReadOnlyList<IContentType> ImportDocumentTypes(IEnumerable<XElement> doc
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<T> ImportDocumentTypes<T>(IReadOnlyCollection<XElement> unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService<T> service)
where T : class, IContentTypeComposition
=> ImportDocumentTypes(unsortedDocumentTypes, importStructure, userId, service);

/// <summary>
/// Imports and saves package xml as <see cref="IContentType"/>
/// </summary>
/// <param name="unsortedDocumentTypes">Xml to import</param>
/// <param name="importStructure">Boolean indicating whether or not to import the </param>
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <param name="entityContainersInstalled">Collection of entity containers installed by the package to be populated with those created in installing data types.</param>
/// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<T> ImportDocumentTypes<T>(IReadOnlyCollection<XElement> unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService<T> service, out IEnumerable<EntityContainer> entityContainersInstalled)
where T : class, IContentTypeComposition
{
var importedContentTypes = new Dictionary<string, T>();

Expand All @@ -436,7 +475,7 @@ public IReadOnlyList<T> ImportDocumentTypes<T>(IReadOnlyCollection<XElement> uns
var graph = new TopoGraph<string, TopoGraph.Node<string, XElement>>(x => x.Key, x => x.Dependencies);
var isSingleDocTypeImport = unsortedDocumentTypes.Count == 1;

var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes);
var importedFolders = CreateContentTypeFolderStructure(unsortedDocumentTypes, out entityContainersInstalled);

if (isSingleDocTypeImport == false)
{
Expand Down Expand Up @@ -532,9 +571,10 @@ public IReadOnlyList<T> ImportDocumentTypes<T>(IReadOnlyCollection<XElement> uns
return list;
}

private Dictionary<string, int> CreateContentTypeFolderStructure(IEnumerable<XElement> unsortedDocumentTypes)
private Dictionary<string, int> CreateContentTypeFolderStructure(IEnumerable<XElement> unsortedDocumentTypes, out IEnumerable<EntityContainer> entityContainersInstalled)
{
var importedFolders = new Dictionary<string, int>();
var trackEntityContainersInstalled = new List<EntityContainer>();
foreach (var documentType in unsortedDocumentTypes)
{
var foldersAttribute = documentType.Attribute("Folders");
Expand Down Expand Up @@ -578,8 +618,10 @@ private Dictionary<string, int> CreateContentTypeFolderStructure(IEnumerable<XEl
_logger.LogError(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder);
throw tryCreateFolder.Exception;
}

var rootFolderId = tryCreateFolder.Result.Entity.Id;
current = _contentTypeService.GetContainer(rootFolderId);
trackEntityContainersInstalled.Add(current);
}

importedFolders.Add(alias, current.Id);
Expand All @@ -589,11 +631,13 @@ private Dictionary<string, int> CreateContentTypeFolderStructure(IEnumerable<XEl
var folderName = WebUtility.UrlDecode(folders[i]);
Guid? folderKey = (folderKeys.Length == folders.Length) ? folderKeys[i] : null;
current = CreateContentTypeChildFolder(folderName, folderKey ?? Guid.NewGuid(), current);
trackEntityContainersInstalled.Add(current);
importedFolders[alias] = current.Id;
}
}
}

entityContainersInstalled = trackEntityContainersInstalled;
return importedFolders;
}

Expand Down Expand Up @@ -1012,10 +1056,20 @@ private T FindContentTypeByAlias<T>(string contentTypeAlias, IContentTypeBaseSer
/// <param name="userId">Optional id of the user</param>
/// <returns>An enumerable list of generated DataTypeDefinitions</returns>
public IReadOnlyList<IDataType> ImportDataTypes(IReadOnlyCollection<XElement> dataTypeElements, int userId)
=> ImportDataTypes(dataTypeElements, userId, out _);

/// <summary>
/// Imports and saves package xml as <see cref="IDataType"/>
/// </summary>
/// <param name="dataTypeElements">Xml to import</param>
/// <param name="userId">Optional id of the user</param>
/// <param name="entityContainersInstalled">Collection of entity containers installed by the package to be populated with those created in installing data types.</param>
/// <returns>An enumerable list of generated DataTypeDefinitions</returns>
public IReadOnlyList<IDataType> ImportDataTypes(IReadOnlyCollection<XElement> dataTypeElements, int userId, out IEnumerable<EntityContainer> entityContainersInstalled)
{
var dataTypes = new List<IDataType>();

var importedFolders = CreateDataTypeFolderStructure(dataTypeElements);
var importedFolders = CreateDataTypeFolderStructure(dataTypeElements, out entityContainersInstalled);

foreach (var dataTypeElement in dataTypeElements)
{
Expand Down Expand Up @@ -1072,9 +1126,10 @@ public IReadOnlyList<IDataType> ImportDataTypes(IReadOnlyCollection<XElement> da
return dataTypes;
}

private Dictionary<string, int> CreateDataTypeFolderStructure(IEnumerable<XElement> datatypeElements)
private Dictionary<string, int> CreateDataTypeFolderStructure(IEnumerable<XElement> datatypeElements, out IEnumerable<EntityContainer> entityContainersInstalled)
{
var importedFolders = new Dictionary<string, int>();
var trackEntityContainersInstalled = new List<EntityContainer>();
foreach (var datatypeElement in datatypeElements)
{
var foldersAttribute = datatypeElement.Attribute("Folders");
Expand Down Expand Up @@ -1103,7 +1158,9 @@ private Dictionary<string, int> CreateDataTypeFolderStructure(IEnumerable<XEleme
_logger.LogError(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder);
throw tryCreateFolder.Exception;
}

current = _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id);
trackEntityContainersInstalled.Add(current);
}

importedFolders.Add(name, current.Id);
Expand All @@ -1113,11 +1170,12 @@ private Dictionary<string, int> CreateDataTypeFolderStructure(IEnumerable<XEleme
var folderName = WebUtility.UrlDecode(folders[i]);
Guid? folderKey = (folderKeys.Length == folders.Length) ? folderKeys[i] : null;
current = CreateDataTypeChildFolder(folderName, folderKey ?? Guid.NewGuid(), current);
trackEntityContainersInstalled.Add(current);
importedFolders[name] = current.Id;
}
}
}

entityContainersInstalled = trackEntityContainersInstalled;
return importedFolders;
}

Expand Down

0 comments on commit bef1cce

Please sign in to comment.