Netcore: Package support for media + media types (#9547)

* Add support for media when installing a package

* clean up

* Fix tests

* Add support for media when installing a package

* clean up

* Fix tests

* moved tests + test data

* Migrated package tests + resources

* Fix issue with media picker on package page, was empty after save.

* Added missing files

* Fix casing issue of resources

* Added test for media

* Fix tests for linux

* Fix test

* Fix issue with move media..

* Fix issue with adding files to packages

* Add MediaType permissions.

* Fix test

* Fix test

* Retry flaky tests, and added TODOs to fix those

* new attempt to fix test

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
Bjarke Berg
2020-12-16 22:26:47 +01:00
committed by GitHub
parent 5119e8da9c
commit 0151c435f1
55 changed files with 1130 additions and 953 deletions

View File

@@ -15,7 +15,7 @@
"version": { "version": {
"type": "parameter", "type": "parameter",
"datatype": "string", "datatype": "string",
"defaultValue": "0.5.0-alpha003", "defaultValue": "0.5.0-alpha*",
"description": "The version of Umbraco to load using NuGet", "description": "The version of Umbraco to load using NuGet",
"replaces": "UMBRACO_VERSION_FROM_TEMPLATE" "replaces": "UMBRACO_VERSION_FROM_TEMPLATE"
}, },

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Core
/// <remarks> /// <remarks>
/// This is not the same as the Umbraco web folder which is configurable for serving front-end files. /// This is not the same as the Umbraco web folder which is configurable for serving front-end files.
/// </remarks> /// </remarks>
public const string Umbraco = "~/Umbraco"; public const string Umbraco = "~/umbraco";
/// <summary> /// <summary>
/// The Umbraco data folder in the content root /// The Umbraco data folder in the content root

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
namespace Umbraco.Core.Models.Packaging namespace Umbraco.Core.Models.Packaging
@@ -40,6 +39,8 @@ namespace Umbraco.Core.Models.Packaging
public IEnumerable<XElement> Languages { get; set; } // TODO: make strongly typed public IEnumerable<XElement> Languages { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> DictionaryItems { get; set; } // TODO: make strongly typed public IEnumerable<XElement> DictionaryItems { get; set; } // TODO: make strongly typed
public IEnumerable<XElement> DocumentTypes { get; set; } // TODO: make strongly typed public IEnumerable<XElement> DocumentTypes { get; set; } // TODO: make strongly typed
public IEnumerable<CompiledPackageDocument> Documents { get; set; } public IEnumerable<XElement> MediaTypes { get; set; } // TODO: make strongly typed
public IEnumerable<CompiledPackageContentBase> Documents { get; set; }
public IEnumerable<CompiledPackageContentBase> Media { get; set; }
} }
} }

View File

@@ -1,20 +1,18 @@
using System;
using System.Xml.Linq; using System.Xml.Linq;
namespace Umbraco.Core.Models.Packaging namespace Umbraco.Core.Models.Packaging
{ {
public class CompiledPackageDocument /// <summary>
/// Compiled representation of a content base (Document or Media)
/// </summary>
public class CompiledPackageContentBase
{ {
public static CompiledPackageDocument Create(XElement xml) public static CompiledPackageContentBase Create(XElement xml) =>
{ new CompiledPackageContentBase
if (xml.Name.LocalName != "DocumentSet")
throw new ArgumentException("The xml isn't formatted correctly, a document element is defined by <DocumentSet>", nameof(xml));
return new CompiledPackageDocument
{ {
XmlData = xml, XmlData = xml,
ImportMode = xml.AttributeValue<string>("importMode") ImportMode = xml.AttributeValue<string>("importMode")
}; };
}
public string ImportMode { get; set; } //this is never used public string ImportMode { get; set; } //this is never used
@@ -23,4 +21,4 @@ namespace Umbraco.Core.Models.Packaging
/// </summary> /// </summary>
public XElement XmlData { get; set; } public XElement XmlData { get; set; }
} }
} }

View File

@@ -6,7 +6,6 @@ using System.Xml.Linq;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Models.Packaging; using Umbraco.Core.Models.Packaging;
using File = System.IO.File;
namespace Umbraco.Core.Packaging namespace Umbraco.Core.Packaging
{ {
@@ -64,7 +63,9 @@ namespace Umbraco.Core.Packaging
Languages = xml.Root.Element("Languages")?.Elements("Language") ?? Enumerable.Empty<XElement>(), Languages = xml.Root.Element("Languages")?.Elements("Language") ?? Enumerable.Empty<XElement>(),
DictionaryItems = xml.Root.Element("DictionaryItems")?.Elements("DictionaryItem") ?? Enumerable.Empty<XElement>(), DictionaryItems = xml.Root.Element("DictionaryItems")?.Elements("DictionaryItem") ?? Enumerable.Empty<XElement>(),
DocumentTypes = xml.Root.Element("DocumentTypes")?.Elements("DocumentType") ?? Enumerable.Empty<XElement>(), DocumentTypes = xml.Root.Element("DocumentTypes")?.Elements("DocumentType") ?? Enumerable.Empty<XElement>(),
Documents = xml.Root.Element("Documents")?.Elements("DocumentSet")?.Select(CompiledPackageDocument.Create) ?? Enumerable.Empty<CompiledPackageDocument>(), MediaTypes = xml.Root.Element("MediaTypes")?.Elements("MediaType") ?? Enumerable.Empty<XElement>(),
Documents = xml.Root.Element("Documents")?.Elements("DocumentSet")?.Select(CompiledPackageContentBase.Create) ?? Enumerable.Empty<CompiledPackageContentBase>(),
Media = xml.Root.Element("MediaItems")?.Elements()?.Select(CompiledPackageContentBase.Create) ?? Enumerable.Empty<CompiledPackageContentBase>(),
}; };
def.Warnings = GetPreInstallWarnings(def, applicationRootFolder); def.Warnings = GetPreInstallWarnings(def, applicationRootFolder);

View File

@@ -17,11 +17,13 @@ namespace Umbraco.Core.Models.Packaging
public IEnumerable<string> FilesInstalled { get; set; } = Enumerable.Empty<string>(); public IEnumerable<string> FilesInstalled { get; set; } = Enumerable.Empty<string>();
public IEnumerable<ITemplate> TemplatesInstalled { get; set; } = Enumerable.Empty<ITemplate>(); public IEnumerable<ITemplate> TemplatesInstalled { get; set; } = Enumerable.Empty<ITemplate>();
public IEnumerable<IContentType> DocumentTypesInstalled { get; set; } = Enumerable.Empty<IContentType>(); public IEnumerable<IContentType> DocumentTypesInstalled { get; set; } = Enumerable.Empty<IContentType>();
public IEnumerable<IMediaType> MediaTypesInstalled { get; set; } = Enumerable.Empty<IMediaType>();
public IEnumerable<IFile> StylesheetsInstalled { get; set; } = Enumerable.Empty<IFile>(); public IEnumerable<IFile> StylesheetsInstalled { get; set; } = Enumerable.Empty<IFile>();
public IEnumerable<IContent> ContentInstalled { get; set; } = Enumerable.Empty<IContent>(); public IEnumerable<IContent> ContentInstalled { get; set; } = Enumerable.Empty<IContent>();
public IEnumerable<IMedia> MediaInstalled { get; set; } = Enumerable.Empty<IMedia>();
public IEnumerable<PackageAction> Actions { get; set; } = Enumerable.Empty<PackageAction>(); public IEnumerable<PackageAction> Actions { get; set; } = Enumerable.Empty<PackageAction>();
public IEnumerable<string> ActionErrors { get; set; } = Enumerable.Empty<string>(); public IEnumerable<string> ActionErrors { get; set; } = Enumerable.Empty<string>();
} }
} }

View File

@@ -4,7 +4,6 @@ using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Umbraco.Core.Composing;
namespace Umbraco.Core.Models.Packaging namespace Umbraco.Core.Models.Packaging
{ {
@@ -114,6 +113,9 @@ namespace Umbraco.Core.Models.Packaging
[DataMember(Name = "documentTypes")] [DataMember(Name = "documentTypes")]
public IList<string> DocumentTypes { get; set; } = new List<string>(); public IList<string> DocumentTypes { get; set; } = new List<string>();
[DataMember(Name = "mediaTypes")]
public IList<string> MediaTypes { get; set; } = new List<string>();
[DataMember(Name = "stylesheets")] [DataMember(Name = "stylesheets")]
public IList<string> Stylesheets { get; set; } = new List<string>(); public IList<string> Stylesheets { get; set; } = new List<string>();
@@ -133,6 +135,12 @@ namespace Umbraco.Core.Models.Packaging
[DataMember(Name = "iconUrl")] [DataMember(Name = "iconUrl")]
public string IconUrl { get; set; } = string.Empty; public string IconUrl { get; set; } = string.Empty;
[DataMember(Name = "mediaUdis")]
public IList<GuidUdi> MediaUdis { get; set; } = Array.Empty<GuidUdi>();
[DataMember(Name = "mediaLoadChildNodes")]
public bool MediaLoadChildNodes { get; set; }
} }

View File

@@ -46,10 +46,13 @@ namespace Umbraco.Core.Packaging
Actions = xml.Element("actions")?.ToString(SaveOptions.None) ?? "<actions></actions>", //take the entire outer xml value Actions = xml.Element("actions")?.ToString(SaveOptions.None) ?? "<actions></actions>", //take the entire outer xml value
ContentNodeId = xml.Element("content")?.AttributeValue<string>("nodeId") ?? string.Empty, ContentNodeId = xml.Element("content")?.AttributeValue<string>("nodeId") ?? string.Empty,
ContentLoadChildNodes = xml.Element("content")?.AttributeValue<bool>("loadChildNodes") ?? false, ContentLoadChildNodes = xml.Element("content")?.AttributeValue<bool>("loadChildNodes") ?? false,
MediaUdis = xml.Element("media")?.Elements("nodeUdi").Select(x => (GuidUdi)UdiParser.Parse(x.Value)).ToList() ?? new List<GuidUdi>(),
MediaLoadChildNodes = xml.Element("media")?.AttributeValue<bool>("loadChildNodes") ?? false,
Macros = xml.Element("macros")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), Macros = xml.Element("macros")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
Templates = xml.Element("templates")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), Templates = xml.Element("templates")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
Stylesheets = xml.Element("stylesheets")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), Stylesheets = xml.Element("stylesheets")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
DocumentTypes = xml.Element("documentTypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), DocumentTypes = xml.Element("documentTypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
MediaTypes = xml.Element("mediaTypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
Languages = xml.Element("languages")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), Languages = xml.Element("languages")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
DictionaryItems = xml.Element("dictionaryitems")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), DictionaryItems = xml.Element("dictionaryitems")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
DataTypes = xml.Element("datatypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(), DataTypes = xml.Element("datatypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List<string>(),
@@ -103,11 +106,17 @@ namespace Umbraco.Core.Packaging
new XElement("templates", string.Join(",", def.Templates ?? Array.Empty<string>())), new XElement("templates", string.Join(",", def.Templates ?? Array.Empty<string>())),
new XElement("stylesheets", string.Join(",", def.Stylesheets ?? Array.Empty<string>())), new XElement("stylesheets", string.Join(",", def.Stylesheets ?? Array.Empty<string>())),
new XElement("documentTypes", string.Join(",", def.DocumentTypes ?? Array.Empty<string>())), new XElement("documentTypes", string.Join(",", def.DocumentTypes ?? Array.Empty<string>())),
new XElement("mediaTypes", string.Join(",", def.MediaTypes ?? Array.Empty<string>())),
new XElement("macros", string.Join(",", def.Macros ?? Array.Empty<string>())), new XElement("macros", string.Join(",", def.Macros ?? Array.Empty<string>())),
new XElement("files", (def.Files ?? Array.Empty<string>()).Where(x => !x.IsNullOrWhiteSpace()).Select(x => new XElement("file", x))), new XElement("files", (def.Files ?? Array.Empty<string>()).Where(x => !x.IsNullOrWhiteSpace()).Select(x => new XElement("file", x))),
new XElement("languages", string.Join(",", def.Languages ?? Array.Empty<string>())), new XElement("languages", string.Join(",", def.Languages ?? Array.Empty<string>())),
new XElement("dictionaryitems", string.Join(",", def.DictionaryItems ?? Array.Empty<string>()))); new XElement("dictionaryitems", string.Join(",", def.DictionaryItems ?? Array.Empty<string>())),
new XElement(
"media",
def.MediaUdis.Select(x=> (object)new XElement("nodeUdi", x))
.Union(new []{new XAttribute("loadChildNodes", def.MediaLoadChildNodes) }))
);
return packageXml; return packageXml;
} }

View File

@@ -5,8 +5,8 @@ using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration; using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Hosting; using Umbraco.Core.Hosting;
@@ -38,6 +38,8 @@ namespace Umbraco.Core.Packaging
private readonly string _tempFolderPath; private readonly string _tempFolderPath;
private readonly PackageDefinitionXmlParser _parser; private readonly PackageDefinitionXmlParser _parser;
private readonly IUmbracoVersion _umbracoVersion; private readonly IUmbracoVersion _umbracoVersion;
private readonly IMediaService _mediaService;
private readonly IMediaTypeService _mediaTypeService;
/// <summary> /// <summary>
/// Constructor /// Constructor
@@ -65,6 +67,8 @@ namespace Umbraco.Core.Packaging
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IUmbracoVersion umbracoVersion, IUmbracoVersion umbracoVersion,
IOptions<GlobalSettings> globalSettings, IOptions<GlobalSettings> globalSettings,
IMediaService mediaService,
IMediaTypeService mediaTypeService,
string packageRepositoryFileName, string packageRepositoryFileName,
string tempFolderPath = null, string packagesFolderPath = null, string mediaFolderPath = null) string tempFolderPath = null, string packagesFolderPath = null, string mediaFolderPath = null)
{ {
@@ -87,6 +91,8 @@ namespace Umbraco.Core.Packaging
_parser = new PackageDefinitionXmlParser(_loggerFactory.CreateLogger<PackageDefinitionXmlParser>(), umbracoVersion); _parser = new PackageDefinitionXmlParser(_loggerFactory.CreateLogger<PackageDefinitionXmlParser>(), umbracoVersion);
_umbracoVersion = umbracoVersion; _umbracoVersion = umbracoVersion;
_mediaService = mediaService;
_mediaTypeService = mediaTypeService;
} }
private string CreatedPackagesFile => _packagesFolderPath.EnsureEndsWith('/') + _packageRepositoryFileName; private string CreatedPackagesFile => _packagesFolderPath.EnsureEndsWith('/') + _packageRepositoryFileName;
@@ -181,12 +187,15 @@ namespace Umbraco.Core.Packaging
PackageDocumentsAndTags(definition, root); PackageDocumentsAndTags(definition, root);
PackageDocumentTypes(definition, root); PackageDocumentTypes(definition, root);
PackageMediaTypes(definition, root);
PackageTemplates(definition, root); PackageTemplates(definition, root);
PackageStylesheets(definition, root); PackageStylesheets(definition, root);
PackageMacros(definition, root, filesXml, temporaryPath); PackageMacros(definition, root, filesXml, temporaryPath);
PackageDictionaryItems(definition, root); PackageDictionaryItems(definition, root);
PackageLanguages(definition, root); PackageLanguages(definition, root);
PackageDataTypes(definition, root); PackageDataTypes(definition, root);
PackageMedia(definition, root);
// TODO: This needs to be split into content vs web files, for now we are going to // TODO: This needs to be split into content vs web files, for now we are going to
// assume all files are web (www) files. But this is a larger discussion/change since // assume all files are web (www) files. But this is a larger discussion/change since
@@ -194,13 +203,13 @@ namespace Umbraco.Core.Packaging
//Files //Files
foreach (var fileName in definition.Files) foreach (var fileName in definition.Files)
AppendFileToPackage(fileName, temporaryPath, filesXml, true); AppendFileToPackage(fileName, temporaryPath, filesXml);
//Load view on install... //Load view on install...
if (!string.IsNullOrEmpty(definition.PackageView)) if (!string.IsNullOrEmpty(definition.PackageView))
{ {
var control = new XElement("view", definition.PackageView); var control = new XElement("view", definition.PackageView);
AppendFileToPackage(definition.PackageView, temporaryPath, filesXml, true); AppendFileToPackage(definition.PackageView, temporaryPath, filesXml);
root.Add(control); root.Add(control);
} }
@@ -310,7 +319,7 @@ namespace Umbraco.Core.Packaging
macros.Add(macroXml); macros.Add(macroXml);
//if the macro has a file copy it to the xml //if the macro has a file copy it to the xml
if (!string.IsNullOrEmpty(macro.MacroSource)) if (!string.IsNullOrEmpty(macro.MacroSource))
AppendFileToPackage(macro.MacroSource, temporaryPath, filesXml, false); AppendFileToPackage(macro.MacroSource, temporaryPath, filesXml);
} }
root.Add(macros); root.Add(macros);
} }
@@ -358,6 +367,23 @@ namespace Umbraco.Core.Packaging
root.Add(docTypesXml); root.Add(docTypesXml);
} }
private void PackageMediaTypes(PackageDefinition definition, XContainer root)
{
var mediaTypes = new HashSet<IMediaType>();
var mediaTypesXml = new XElement("MediaTypes");
foreach (var mediaTypeId in definition.MediaTypes)
{
if (!int.TryParse(mediaTypeId, out var outInt)) continue;
var mediaType = _mediaTypeService.Get(outInt);
if (mediaType == null) continue;
AddMediaType(mediaType, mediaTypes);
}
foreach (var mediaType in mediaTypes)
mediaTypesXml.Add(_serializer.Serialize(mediaType));
root.Add(mediaTypesXml);
}
private void PackageDocumentsAndTags(PackageDefinition definition, XContainer root) private void PackageDocumentsAndTags(PackageDefinition definition, XContainer root)
{ {
//Documents and tags //Documents and tags
@@ -442,6 +468,18 @@ namespace Umbraco.Core.Packaging
} }
} }
private void PackageMedia(PackageDefinition definition, XElement root)
{
IEnumerable<IMedia> medias = _mediaService.GetByIds(definition.MediaUdis);
root.Add(
new XElement(
"MediaItems",
medias.Select(x => new XElement("MediaSet", _serializer.Serialize(x, definition.MediaLoadChildNodes)))));
}
/// <summary> /// <summary>
/// Zips the package. /// Zips the package.
/// </summary> /// </summary>
@@ -461,12 +499,12 @@ namespace Umbraco.Core.Packaging
/// <param name="packageDirectory">The package directory.</param> /// <param name="packageDirectory">The package directory.</param>
/// <param name="filesXml">The files xml node</param> /// <param name="filesXml">The files xml node</param>
/// <param name="isWebFile">true if it's a web file, false if it's a content file</param> /// <param name="isWebFile">true if it's a web file, false if it's a content file</param>
private void AppendFileToPackage(string path, string packageDirectory, XContainer filesXml, bool isWebFile) private void AppendFileToPackage(string path, string packageDirectory, XContainer filesXml)
{ {
if (!path.StartsWith("~/") && !path.StartsWith("/")) if (!path.StartsWith("~/") && !path.StartsWith("/"))
path = "~/" + path; path = "~/" + path;
var serverPath = isWebFile ? _hostingEnvironment.MapPathWebRoot(path) : _hostingEnvironment.MapPathContentRoot(path); var serverPath = _hostingEnvironment.MapPathContentRoot(path);
if (File.Exists(serverPath)) if (File.Exists(serverPath))
AppendFileXml(new FileInfo(serverPath), path, packageDirectory, filesXml); AppendFileXml(new FileInfo(serverPath), path, packageDirectory, filesXml);
@@ -562,6 +600,19 @@ namespace Umbraco.Core.Packaging
dtl.Add(dt); dtl.Add(dt);
} }
private void AddMediaType(IMediaType mediaType, HashSet<IMediaType> mediaTypes)
{
if (mediaType.ParentId > 0)
{
var parent = _mediaTypeService.Get(mediaType.ParentId);
if (parent != null) // could be a container
AddMediaType(parent, mediaTypes);
}
if (!mediaTypes.Contains(mediaType))
mediaTypes.Add(mediaType);
}
private static XElement GetPackageInfoXml(PackageDefinition definition, IUmbracoVersion umbracoVersion) private static XElement GetPackageInfoXml(PackageDefinition definition, IUmbracoVersion umbracoVersion)
{ {

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Querying;
@@ -10,7 +9,7 @@ namespace Umbraco.Core.Services
/// <summary> /// <summary>
/// Defines the ContentService, which is an easy access to operations involving <see cref="IContent"/> /// Defines the ContentService, which is an easy access to operations involving <see cref="IContent"/>
/// </summary> /// </summary>
public interface IContentService : IContentServiceBase public interface IContentService : IContentServiceBase<IContent>
{ {
#region Blueprints #region Blueprints

View File

@@ -1,7 +1,16 @@
using Umbraco.Core.Models; using System;
using System.Collections.Generic;
using Umbraco.Core.Models;
namespace Umbraco.Core.Services namespace Umbraco.Core.Services
{ {
public interface IContentServiceBase<TItem> : IContentServiceBase
where TItem: class, IContentBase
{
TItem GetById(Guid key);
Attempt<OperationResult> Save(IEnumerable<TItem> contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true);
}
/// <summary> /// <summary>
/// Placeholder for sharing logic between the content, media (and member) services /// Placeholder for sharing logic between the content, media (and member) services
/// TODO: Start sharing the logic! /// TODO: Start sharing the logic!

View File

@@ -58,7 +58,6 @@ namespace Umbraco.Core.Services
void Save(TItem item, int userId = Constants.Security.SuperUserId); void Save(TItem item, int userId = Constants.Security.SuperUserId);
void Save(IEnumerable<TItem> items, int userId = Constants.Security.SuperUserId); void Save(IEnumerable<TItem> items, int userId = Constants.Security.SuperUserId);
void Delete(TItem item, int userId = Constants.Security.SuperUserId); void Delete(TItem item, int userId = Constants.Security.SuperUserId);
void Delete(IEnumerable<TItem> item, int userId = Constants.Security.SuperUserId); void Delete(IEnumerable<TItem> item, int userId = Constants.Security.SuperUserId);

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.IO; using System.IO;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Querying;
@@ -10,7 +9,7 @@ namespace Umbraco.Core.Services
/// <summary> /// <summary>
/// Defines the Media Service, which is an easy access to operations involving <see cref="IMedia"/> /// Defines the Media Service, which is an easy access to operations involving <see cref="IMedia"/>
/// </summary> /// </summary>
public interface IMediaService : IContentServiceBase public interface IMediaService : IContentServiceBase<IMedia>
{ {
int CountNotTrashed(string contentTypeAlias = null); int CountNotTrashed(string contentTypeAlias = null);
int Count(string mediaTypeAlias = null); int Count(string mediaTypeAlias = null);

View File

@@ -2,15 +2,14 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Umbraco.Core.DependencyInjection; using Microsoft.Extensions.Options;
using Umbraco.Core.Cache; using Umbraco.Core.Cache;
using Umbraco.Core.Configuration; using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.Models;
using Umbraco.Core.DependencyInjection;
using Umbraco.Core.Events; using Umbraco.Core.Events;
using Umbraco.Core.Hosting; using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Packaging; using Umbraco.Core.Packaging;
using Umbraco.Core.Routing; using Umbraco.Core.Routing;
using Umbraco.Core.Services; using Umbraco.Core.Services;
@@ -99,6 +98,8 @@ namespace Umbraco.Core.Composing.CompositionExtensions
factory.GetRequiredService<ILoggerFactory>(), factory.GetRequiredService<ILoggerFactory>(),
factory.GetRequiredService<IUmbracoVersion>(), factory.GetRequiredService<IUmbracoVersion>(),
factory.GetRequiredService<IOptions<GlobalSettings>>(), factory.GetRequiredService<IOptions<GlobalSettings>>(),
factory.GetRequiredService<IMediaService>(),
factory.GetRequiredService<IMediaTypeService>(),
packageRepoFileName); packageRepoFileName);
private static LocalizedTextServiceFileSources SourcesFactory(IServiceProvider container) private static LocalizedTextServiceFileSources SourcesFactory(IServiceProvider container)

View File

@@ -34,15 +34,32 @@ namespace Umbraco.Core.Packaging
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
private readonly ILocalizedTextService _localizedTextService; private readonly ILocalizedTextService _localizedTextService;
private readonly IConfigurationEditorJsonSerializer _serializer; private readonly IConfigurationEditorJsonSerializer _serializer;
private readonly IMediaService _mediaService;
private readonly IMediaTypeService _mediaTypeService;
private readonly IJsonSerializer _jsonSerializer; private readonly IJsonSerializer _jsonSerializer;
private readonly IEntityService _entityService; private readonly IEntityService _entityService;
private readonly IContentTypeService _contentTypeService; private readonly IContentTypeService _contentTypeService;
private readonly IContentService _contentService; private readonly IContentService _contentService;
public PackageDataInstallation(ILogger<PackageDataInstallation> logger, ILoggerFactory loggerFactory, IFileService fileService, IMacroService macroService, ILocalizationService localizationService, public PackageDataInstallation(
IDataTypeService dataTypeService, IEntityService entityService, IContentTypeService contentTypeService, ILogger<PackageDataInstallation> logger,
IContentService contentService, PropertyEditorCollection propertyEditors, IScopeProvider scopeProvider, IShortStringHelper shortStringHelper, IOptions<GlobalSettings> globalSettings, ILoggerFactory loggerFactory,
ILocalizedTextService localizedTextService, IConfigurationEditorJsonSerializer serializer, IJsonSerializer jsonSerializer) IFileService fileService,
IMacroService macroService,
ILocalizationService localizationService,
IDataTypeService dataTypeService,
IEntityService entityService,
IContentTypeService contentTypeService,
IContentService contentService,
PropertyEditorCollection propertyEditors,
IScopeProvider scopeProvider,
IShortStringHelper shortStringHelper,
IOptions<GlobalSettings> globalSettings,
ILocalizedTextService localizedTextService,
IConfigurationEditorJsonSerializer serializer,
IMediaService mediaService,
IMediaTypeService mediaTypeService,
IJsonSerializer jsonSerializer)
{ {
_logger = logger; _logger = logger;
_loggerFactory = loggerFactory; _loggerFactory = loggerFactory;
@@ -57,6 +74,8 @@ namespace Umbraco.Core.Packaging
_localizedTextService = localizedTextService; _localizedTextService = localizedTextService;
_serializer = serializer; _serializer = serializer;
_jsonSerializer = jsonSerializer; _jsonSerializer = jsonSerializer;
_mediaService = mediaService;
_mediaTypeService = mediaTypeService;
_entityService = entityService; _entityService = entityService;
_contentTypeService = contentTypeService; _contentTypeService = contentTypeService;
_contentService = contentService; _contentService = contentService;
@@ -197,29 +216,58 @@ namespace Umbraco.Core.Packaging
DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId), DictionaryItemsInstalled = ImportDictionaryItems(compiledPackage.DictionaryItems, userId),
MacrosInstalled = ImportMacros(compiledPackage.Macros, userId), MacrosInstalled = ImportMacros(compiledPackage.Macros, userId),
TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId), TemplatesInstalled = ImportTemplates(compiledPackage.Templates.ToList(), userId),
DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId) DocumentTypesInstalled = ImportDocumentTypes(compiledPackage.DocumentTypes, userId),
MediaTypesInstalled = ImportMediaTypes(compiledPackage.MediaTypes, userId),
}; };
//we need a reference to the imported doc types to continue //we need a reference to the imported doc types to continue
var importedDocTypes = installationSummary.DocumentTypesInstalled.ToDictionary(x => x.Alias, x => x); var importedDocTypes = installationSummary.DocumentTypesInstalled.ToDictionary(x => x.Alias, x => x);
var importedMediaTypes = installationSummary.MediaTypesInstalled.ToDictionary(x => x.Alias, x => x);
installationSummary.StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId); installationSummary.StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId);
installationSummary.ContentInstalled = ImportContent(compiledPackage.Documents, importedDocTypes, userId); installationSummary.ContentInstalled = ImportContentBase(compiledPackage.Documents, importedDocTypes, userId, _contentTypeService, _contentService);
installationSummary.MediaInstalled = ImportContentBase(compiledPackage.Media, importedMediaTypes, userId, _mediaTypeService, _mediaService);
scope.Complete(); scope.Complete();
return installationSummary; 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)
{
return ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService);
}
#endregion #endregion
#region Content #region Content
public IReadOnlyList<IContent> ImportContent(IEnumerable<CompiledPackageDocument> docs, IDictionary<string, IContentType> importedDocumentTypes, int userId) public IReadOnlyList<T> ImportContentBase<T, S>(
IEnumerable<CompiledPackageContentBase> docs,
IDictionary<string, S> importedDocumentTypes,
int userId,
IContentTypeBaseService<S> typeService,
IContentServiceBase<T> service)
where T: class, IContentBase
where S: IContentTypeComposition
{ {
return docs.SelectMany(x => ImportContent(x, -1, importedDocumentTypes, userId)).ToList(); return docs.SelectMany(x => ImportContentBase<T, S>(
x.XmlData.Elements().Where(doc => (string)doc.Attribute("isDoc") == string.Empty),
-1,
importedDocumentTypes,
userId,
typeService,
service)).ToList();
} }
/// <summary> /// <summary>
@@ -230,17 +278,20 @@ namespace Umbraco.Core.Packaging
/// <param name="importedDocumentTypes">A dictionary of already imported document types (basically used as a cache)</param> /// <param name="importedDocumentTypes">A dictionary of already imported document types (basically used as a cache)</param>
/// <param name="userId">Optional Id of the user performing the import</param> /// <param name="userId">Optional Id of the user performing the import</param>
/// <returns>An enumerable list of generated content</returns> /// <returns>An enumerable list of generated content</returns>
public IEnumerable<IContent> ImportContent(CompiledPackageDocument packageDocument, int parentId, IDictionary<string, IContentType> importedDocumentTypes, int userId) public IEnumerable<T> ImportContentBase<T, S>(
IEnumerable<XElement> roots,
int parentId,
IDictionary<string, S> importedDocumentTypes,
int userId,
IContentTypeBaseService<S> typeService,
IContentServiceBase<T> service)
where T: class, IContentBase
where S: IContentTypeComposition
{ {
var element = packageDocument.XmlData;
var roots = from doc in element.Elements() var contents = ParseContentBaseRootXml(roots, parentId, importedDocumentTypes, typeService, service).ToList();
where (string)doc.Attribute("isDoc") == ""
select doc;
var contents = ParseDocumentRootXml(roots, parentId, importedDocumentTypes).ToList();
if (contents.Any()) if (contents.Any())
_contentService.Save(contents, userId); service.Save(contents, userId);
return contents; return contents;
@@ -249,7 +300,7 @@ namespace Umbraco.Core.Packaging
//{ //{
// //This is a single doc import // //This is a single doc import
// var elements = new List<XElement> { element }; // var elements = new List<XElement> { element };
// var contents = ParseDocumentRootXml(elements, parentId, importedDocumentTypes).ToList(); // var contents = ParseContentBaseRootXml(elements, parentId, importedDocumentTypes).ToList();
// if (contents.Any()) // if (contents.Any())
// _contentService.Save(contents, userId); // _contentService.Save(contents, userId);
@@ -261,50 +312,64 @@ namespace Umbraco.Core.Packaging
// "'DocumentSet' (for structured imports) nor is the first element a Document (for single document import)."); // "'DocumentSet' (for structured imports) nor is the first element a Document (for single document import).");
} }
private IEnumerable<IContent> ParseDocumentRootXml(IEnumerable<XElement> roots, int parentId, IDictionary<string, IContentType> importedContentTypes) private IEnumerable<T> ParseContentBaseRootXml<T, S>(
IEnumerable<XElement> roots,
int parentId,
IDictionary<string, S> importedContentTypes,
IContentTypeBaseService<S> typeService,
IContentServiceBase<T> service)
where T: class, IContentBase
where S: IContentTypeComposition
{ {
var contents = new List<IContent>(); var contents = new List<T>();
foreach (var root in roots) foreach (var root in roots)
{ {
var contentTypeAlias = root.Name.LocalName; var contentTypeAlias = root.Name.LocalName;
if (!importedContentTypes.ContainsKey(contentTypeAlias)) if (!importedContentTypes.ContainsKey(contentTypeAlias))
{ {
var contentType = FindContentTypeByAlias(contentTypeAlias); var contentType = FindContentTypeByAlias(contentTypeAlias, typeService);
importedContentTypes.Add(contentTypeAlias, contentType); importedContentTypes.Add(contentTypeAlias, contentType);
} }
var content = CreateContentFromXml(root, importedContentTypes[contentTypeAlias], null, parentId); var content = CreateContentFromXml(root, importedContentTypes[contentTypeAlias], default(T), parentId, service);
if (content == null) continue; if (content == null) continue;
contents.Add(content); contents.Add(content);
var children = (from child in root.Elements() var children = root.Elements().Where(doc => (string)doc.Attribute("isDoc") == string.Empty)
where (string)child.Attribute("isDoc") == ""
select child)
.ToList(); .ToList();
if (children.Count > 0) if (children.Count > 0)
contents.AddRange(CreateContentFromXml(children, content, importedContentTypes).WhereNotNull()); {
contents.AddRange(CreateContentFromXml<T, S>(children, content, importedContentTypes, typeService, service).WhereNotNull());
}
} }
return contents; return contents;
} }
private IEnumerable<IContent> CreateContentFromXml(IEnumerable<XElement> children, IContent parent, IDictionary<string, IContentType> importedContentTypes) private IEnumerable<T> CreateContentFromXml<T, S>(
IEnumerable<XElement> children,
T parent,
IDictionary<string, S> importedContentTypes,
IContentTypeBaseService<S> typeService,
IContentServiceBase<T> service)
where T: class, IContentBase
where S: IContentTypeComposition
{ {
var list = new List<IContent>(); var list = new List<T>();
foreach (var child in children) foreach (var child in children)
{ {
string contentTypeAlias = child.Name.LocalName; string contentTypeAlias = child.Name.LocalName;
if (importedContentTypes.ContainsKey(contentTypeAlias) == false) if (importedContentTypes.ContainsKey(contentTypeAlias) == false)
{ {
var contentType = FindContentTypeByAlias(contentTypeAlias); var contentType = FindContentTypeByAlias(contentTypeAlias, typeService);
importedContentTypes.Add(contentTypeAlias, contentType); importedContentTypes.Add(contentTypeAlias, contentType);
} }
//Create and add the child to the list //Create and add the child to the list
var content = CreateContentFromXml(child, importedContentTypes[contentTypeAlias], parent, default); var content = CreateContentFromXml(child, importedContentTypes[contentTypeAlias], parent, default, service);
list.Add(content); list.Add(content);
//Recursive call //Recursive call
@@ -314,19 +379,26 @@ namespace Umbraco.Core.Packaging
select grand).ToList(); select grand).ToList();
if (grandChildren.Any()) if (grandChildren.Any())
list.AddRange(CreateContentFromXml(grandChildren, content, importedContentTypes)); list.AddRange(CreateContentFromXml(grandChildren, content,importedContentTypes, typeService, service));
} }
return list; return list;
} }
private IContent CreateContentFromXml(XElement element, IContentType contentType, IContent parent, int parentId) private T CreateContentFromXml<T, S>(
XElement element,
S contentType,
T parent,
int parentId,
IContentServiceBase<T> service)
where T: class, IContentBase
where S: IContentTypeComposition
{ {
var key = Guid.Empty; var key = Guid.Empty;
if (element.Attribute("key") != null && Guid.TryParse(element.Attribute("key").Value, out key)) if (element.Attribute("key") != null && Guid.TryParse(element.Attribute("key").Value, out key))
{ {
//if a Key is supplied, then we need to check if the content already exists and if so we ignore the installation for this item //if a Key is supplied, then we need to check if the content already exists and if so we ignore the installation for this item
if (_contentService.GetById(key) != null) if (service.GetById(key) != null)
return null; return null;
} }
@@ -346,9 +418,9 @@ namespace Umbraco.Core.Packaging
var template = templateId.HasValue ? _fileService.GetTemplate(templateId.Value) : null; var template = templateId.HasValue ? _fileService.GetTemplate(templateId.Value) : null;
//now double check this is correct since its an INT it could very well be pointing to an invalid template :/ //now double check this is correct since its an INT it could very well be pointing to an invalid template :/
if (template != null) if (template != null && contentType is IContentType contentTypex)
{ {
if (!contentType.IsAllowedTemplate(template.Alias)) if (!contentTypex.IsAllowedTemplate(template.Alias))
{ {
//well this is awkward, we'll set the template to null and it will be wired up to the default template //well this is awkward, we'll set the template to null and it will be wired up to the default template
// when it's persisted in the document repository // when it's persisted in the document repository
@@ -356,21 +428,15 @@ namespace Umbraco.Core.Packaging
} }
} }
IContent content = parent == null T content = CreateContent(
? new Content(nodeName, parentId, contentType) nodeName,
{ parent,
Level = int.Parse(level), parentId,
SortOrder = int.Parse(sortOrder), contentType,
TemplateId = template?.Id, key,
Key = key int.Parse(level),
} int.Parse(sortOrder),
: new Content(nodeName, parent, contentType) template?.Id);
{
Level = int.Parse(level),
SortOrder = int.Parse(sortOrder),
TemplateId = template?.Id,
Key = key
};
//Here we make sure that we take composition properties in account as well //Here we make sure that we take composition properties in account as well
//otherwise we would skip them and end up losing content //otherwise we would skip them and end up losing content
@@ -396,6 +462,37 @@ namespace Umbraco.Core.Packaging
return content; return content;
} }
private T CreateContent<T, S>(string name, T parent, int parentId, S contentType, Guid key, int level, int sortOrder, int? templateId)
where T : class, IContentBase
where S : IContentTypeComposition
{
switch (contentType)
{
case IContentType c:
if (parent is null)
{
return new Content(name, parentId, c) { Key = key, Level = level, SortOrder = sortOrder, TemplateId = templateId, } as T;
}
else
{
return new Content(name, (IContent)parent, c) { Key = key, Level = level, SortOrder = sortOrder, TemplateId = templateId, } as T;
}
case IMediaType m:
if (parent is null)
{
return new Umbraco.Core.Models.Media(name, parentId, m) { Key = key, Level = level, SortOrder = sortOrder, } as T;
}
else
{
return new Umbraco.Core.Models.Media(name, (IMedia)parent, m) { Key = key, Level = level, SortOrder = sortOrder, } as T;
}
default:
throw new NotSupportedException($"Type {typeof(S)} is not supported");
}
}
#endregion #endregion
#region DocumentTypes #region DocumentTypes
@@ -413,7 +510,7 @@ namespace Umbraco.Core.Packaging
/// <returns>An enumerable list of generated ContentTypes</returns> /// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IContentType> ImportDocumentTypes(IEnumerable<XElement> docTypeElements, int userId) public IReadOnlyList<IContentType> ImportDocumentTypes(IEnumerable<XElement> docTypeElements, int userId)
{ {
return ImportDocumentTypes(docTypeElements.ToList(), true, userId); return ImportDocumentTypes<IContentType>(docTypeElements.ToList(), true, userId, _contentTypeService);
} }
/// <summary> /// <summary>
@@ -423,9 +520,10 @@ namespace Umbraco.Core.Packaging
/// <param name="importStructure">Boolean indicating whether or not to import the </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="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
/// <returns>An enumerable list of generated ContentTypes</returns> /// <returns>An enumerable list of generated ContentTypes</returns>
public IReadOnlyList<IContentType> ImportDocumentTypes(IReadOnlyCollection<XElement> unsortedDocumentTypes, bool importStructure, int userId) public IReadOnlyList<T> ImportDocumentTypes<T>(IReadOnlyCollection<XElement> unsortedDocumentTypes, bool importStructure, int userId, IContentTypeBaseService<T> service)
where T: class, IContentTypeComposition
{ {
var importedContentTypes = new Dictionary<string, IContentType>(); var importedContentTypes = new Dictionary<string, T>();
//When you are importing a single doc type we have to assume that the dependencies are already there. //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. //Otherwise something like uSync won't work.
@@ -479,10 +577,10 @@ namespace Umbraco.Core.Packaging
var alias = documentType.Element("Info").Element("Alias").Value; var alias = documentType.Element("Info").Element("Alias").Value;
if (importedContentTypes.ContainsKey(alias) == false) if (importedContentTypes.ContainsKey(alias) == false)
{ {
var contentType = _contentTypeService.Get(alias); var contentType = service.Get(alias);
importedContentTypes.Add(alias, contentType == null importedContentTypes.Add(alias, contentType == null
? CreateContentTypeFromXml(documentType, importedContentTypes) ? CreateContentTypeFromXml(documentType, importedContentTypes, service)
: UpdateContentTypeFromXml(documentType, contentType, importedContentTypes)); : UpdateContentTypeFromXml(documentType, contentType, importedContentTypes, service));
} }
} }
@@ -497,27 +595,27 @@ namespace Umbraco.Core.Packaging
//Save the newly created/updated IContentType objects //Save the newly created/updated IContentType objects
var list = importedContentTypes.Select(x => x.Value).ToList(); var list = importedContentTypes.Select(x => x.Value).ToList();
_contentTypeService.Save(list, userId); service.Save(list, userId);
//Now we can finish the import by updating the 'structure', //Now we can finish the import by updating the 'structure',
//which requires the doc types to be saved/available in the db //which requires the doc types to be saved/available in the db
if (importStructure) if (importStructure)
{ {
var updatedContentTypes = new List<IContentType>(); var updatedContentTypes = new List<T>();
//Update the structure here - we can't do it until all DocTypes have been created //Update the structure here - we can't do it until all DocTypes have been created
foreach (var documentType in documentTypes) foreach (var documentType in documentTypes)
{ {
var alias = documentType.Element("Info").Element("Alias").Value; var alias = documentType.Element("Info").Element("Alias").Value;
var structureElement = documentType.Element("Structure"); var structureElement = documentType.Element("Structure");
//Ensure that we only update ContentTypes which has actual structure-elements //Ensure that we only update ContentTypes which has actual structure-elements
if (structureElement == null || structureElement.Elements("DocumentType").Any() == false) continue; if (structureElement == null || structureElement.Elements().Any() == false) continue;
var updated = UpdateContentTypesStructure(importedContentTypes[alias], structureElement, importedContentTypes); var updated = UpdateContentTypesStructure(importedContentTypes[alias], structureElement, importedContentTypes, service);
updatedContentTypes.Add(updated); updatedContentTypes.Add(updated);
} }
//Update ContentTypes with a newly added structure/list of allowed children //Update ContentTypes with a newly added structure/list of allowed children
if (updatedContentTypes.Any()) if (updatedContentTypes.Any())
_contentTypeService.Save(updatedContentTypes, userId); service.Save(updatedContentTypes, userId);
} }
return list; return list;
@@ -586,33 +684,65 @@ namespace Umbraco.Core.Packaging
return _contentTypeService.GetContainer(tryCreateFolder.Result.Entity.Id); return _contentTypeService.GetContainer(tryCreateFolder.Result.Entity.Id);
} }
private IContentType CreateContentTypeFromXml(XElement documentType, IReadOnlyDictionary<string, IContentType> importedContentTypes) private T CreateContentTypeFromXml<T>(XElement documentType, IReadOnlyDictionary<string, T> importedContentTypes, IContentTypeBaseService<T> service)
where T : class, IContentTypeComposition
{ {
var infoElement = documentType.Element("Info"); var infoElement = documentType.Element("Info");
//Name of the master corresponds to the parent //Name of the master corresponds to the parent
var masterElement = infoElement.Element("Master"); var masterElement = infoElement.Element("Master");
IContentType parent = null; T parent = default;
if (masterElement != null) if (masterElement != null)
{ {
var masterAlias = masterElement.Value; var masterAlias = masterElement.Value;
parent = importedContentTypes.ContainsKey(masterAlias) parent = importedContentTypes.ContainsKey(masterAlias)
? importedContentTypes[masterAlias] ? importedContentTypes[masterAlias]
: _contentTypeService.Get(masterAlias); : service.Get(masterAlias);
} }
var alias = infoElement.Element("Alias").Value; var alias = infoElement.Element("Alias").Value;
var contentType = parent == null T contentType = CreateContentType(parent, -1, alias);
? new ContentType(_shortStringHelper, -1) { Alias = alias }
: new ContentType(_shortStringHelper, parent, alias);
if (parent != null) if (parent != null)
contentType.AddContentType(parent); contentType.AddContentType(parent);
return UpdateContentTypeFromXml(documentType, contentType, importedContentTypes); return UpdateContentTypeFromXml(documentType, contentType, importedContentTypes, service);
} }
private IContentType UpdateContentTypeFromXml(XElement documentType, IContentType contentType, IReadOnlyDictionary<string, IContentType> importedContentTypes) private T CreateContentType<T>(T parent, int parentId, string alias)
where T : class, IContentTypeComposition
{
if (typeof(T) == typeof(IContentType))
{
if (parent is null)
{
return new ContentType(_shortStringHelper, parentId) { Alias = alias } as T;
}
else
{
return new ContentType(_shortStringHelper, (IContentType) parent, alias) as T;
}
}
if (typeof(T) == typeof(IMediaType))
{
if (parent is null)
{
return new MediaType(_shortStringHelper, parentId) { Alias = alias } as T;
}
else
{
return new MediaType(_shortStringHelper, (IMediaType)parent, alias) as T;
}
}
throw new NotSupportedException($"Type {typeof(T)} is not supported");
}
private T UpdateContentTypeFromXml<T>(XElement documentType, T contentType, IReadOnlyDictionary<string, T> importedContentTypes, IContentTypeBaseService<T> service)
where T : IContentTypeComposition
{ {
var infoElement = documentType.Element("Info"); var infoElement = documentType.Element("Info");
var defaultTemplateElement = infoElement.Element("DefaultTemplate"); var defaultTemplateElement = infoElement.Element("DefaultTemplate");
@@ -646,9 +776,9 @@ namespace Umbraco.Core.Packaging
if (masterElement != null) if (masterElement != null)
{ {
var masterAlias = masterElement.Value; var masterAlias = masterElement.Value;
IContentType parent = importedContentTypes.ContainsKey(masterAlias) T parent = importedContentTypes.ContainsKey(masterAlias)
? importedContentTypes[masterAlias] ? importedContentTypes[masterAlias]
: _contentTypeService.Get(masterAlias); : service.Get(masterAlias);
contentType.SetParent(parent); contentType.SetParent(parent);
} }
@@ -665,13 +795,17 @@ namespace Umbraco.Core.Packaging
var compositionAlias = composition.Value; var compositionAlias = composition.Value;
var compositionContentType = importedContentTypes.ContainsKey(compositionAlias) var compositionContentType = importedContentTypes.ContainsKey(compositionAlias)
? importedContentTypes[compositionAlias] ? importedContentTypes[compositionAlias]
: _contentTypeService.Get(compositionAlias); : service.Get(compositionAlias);
contentType.AddContentType(compositionContentType); contentType.AddContentType(compositionContentType);
} }
} }
} }
UpdateContentTypesAllowedTemplates(contentType, infoElement.Element("AllowedTemplates"), defaultTemplateElement); if (contentType is IContentType contentTypex)
{
UpdateContentTypesAllowedTemplates(contentTypex, infoElement.Element("AllowedTemplates"), defaultTemplateElement);
}
UpdateContentTypesTabs(contentType, documentType.Element("Tabs")); UpdateContentTypesTabs(contentType, documentType.Element("Tabs"));
UpdateContentTypesProperties(contentType, documentType.Element("GenericProperties")); UpdateContentTypesProperties(contentType, documentType.Element("GenericProperties"));
@@ -716,7 +850,8 @@ namespace Umbraco.Core.Packaging
} }
} }
private void UpdateContentTypesTabs(IContentType contentType, XElement tabElement) private void UpdateContentTypesTabs<T>(T contentType, XElement tabElement)
where T: IContentTypeComposition
{ {
if (tabElement == null) if (tabElement == null)
return; return;
@@ -742,7 +877,8 @@ namespace Umbraco.Core.Packaging
} }
} }
private void UpdateContentTypesProperties(IContentType contentType, XElement genericPropertiesElement) private void UpdateContentTypesProperties<T>(T contentType, XElement genericPropertiesElement)
where T: IContentTypeComposition
{ {
var properties = genericPropertiesElement.Elements("GenericProperty"); var properties = genericPropertiesElement.Elements("GenericProperty");
foreach (var property in properties) foreach (var property in properties)
@@ -834,15 +970,16 @@ namespace Umbraco.Core.Packaging
} }
} }
private IContentType UpdateContentTypesStructure(IContentType contentType, XElement structureElement, IReadOnlyDictionary<string, IContentType> importedContentTypes) private T UpdateContentTypesStructure<T>(T contentType, XElement structureElement, IReadOnlyDictionary<string, T> importedContentTypes, IContentTypeBaseService<T> service)
where T: IContentTypeComposition
{ {
var allowedChildren = contentType.AllowedContentTypes.ToList(); var allowedChildren = contentType.AllowedContentTypes.ToList();
int sortOrder = allowedChildren.Any() ? allowedChildren.Last().SortOrder : 0; int sortOrder = allowedChildren.Any() ? allowedChildren.Last().SortOrder : 0;
foreach (var element in structureElement.Elements("DocumentType")) foreach (var element in structureElement.Elements())
{ {
var alias = element.Value; var alias = element.Value;
var allowedChild = importedContentTypes.ContainsKey(alias) ? importedContentTypes[alias] : _contentTypeService.Get(alias); var allowedChild = importedContentTypes.ContainsKey(alias) ? importedContentTypes[alias] : service.Get(alias);
if (allowedChild == null) if (allowedChild == null)
{ {
_logger.LogWarning( _logger.LogWarning(
@@ -866,9 +1003,10 @@ namespace Umbraco.Core.Packaging
/// </summary> /// </summary>
/// <param name="contentTypeAlias"></param> /// <param name="contentTypeAlias"></param>
/// <returns></returns> /// <returns></returns>
private IContentType FindContentTypeByAlias(string contentTypeAlias) private S FindContentTypeByAlias<S>(string contentTypeAlias, IContentTypeBaseService<S> typeService)
where S: IContentTypeComposition
{ {
var contentType = _contentTypeService.Get(contentTypeAlias); var contentType = typeService.Get(contentTypeAlias);
if (contentType == null) if (contentType == null)
throw new Exception($"ContentType matching the passed in Alias: '{contentTypeAlias}' was null"); throw new Exception($"ContentType matching the passed in Alias: '{contentTypeAlias}' was null");

View File

@@ -22,6 +22,7 @@ using Umbraco.Core.Migrations;
using Umbraco.Core.Migrations.Install; using Umbraco.Core.Migrations.Install;
using Umbraco.Core.Migrations.PostMigrations; using Umbraco.Core.Migrations.PostMigrations;
using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Packaging;
using Umbraco.Core.Persistence; using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.Validators; using Umbraco.Core.PropertyEditors.Validators;
@@ -380,6 +381,8 @@ namespace Umbraco.Core.Runtime
builder.Services.AddUnique<MediaPermissions>(); builder.Services.AddUnique<MediaPermissions>();
builder.Services.AddUnique<IImageDimensionExtractor, ImageDimensionExtractor>(); builder.Services.AddUnique<IImageDimensionExtractor, ImageDimensionExtractor>();
builder.Services.AddUnique<PackageDataInstallation>();
} }
} }
} }

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -387,6 +386,16 @@ namespace Umbraco.Core.Services.Implement
} }
} }
/// <summary>
///
/// </summary>
/// <param name="contents"></param>
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns></returns>
Attempt<OperationResult> IContentServiceBase<IContent>.Save(IEnumerable<IContent> contents, int userId,
bool raiseEvents) => Attempt.Succeed(Save(contents, userId, raiseEvents));
/// <summary> /// <summary>
/// Gets <see cref="IContent"/> objects by Ids /// Gets <see cref="IContent"/> objects by Ids
/// </summary> /// </summary>

View File

@@ -4,8 +4,6 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Xml.Linq; using System.Xml.Linq;
using Newtonsoft.Json;
using Umbraco.Core.Composing;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Serialization; using Umbraco.Core.Serialization;
@@ -120,6 +118,7 @@ namespace Umbraco.Core.Services.Implement
//xml.Add(new XAttribute("creatorID", media.CreatorId)); //xml.Add(new XAttribute("creatorID", media.CreatorId));
xml.Add(new XAttribute("writerName", media.GetWriterProfile(_userService)?.Name ?? string.Empty)); xml.Add(new XAttribute("writerName", media.GetWriterProfile(_userService)?.Name ?? string.Empty));
xml.Add(new XAttribute("writerID", media.WriterId)); xml.Add(new XAttribute("writerID", media.WriterId));
xml.Add(new XAttribute("udi", media.GetUdi()));
//xml.Add(new XAttribute("template", 0)); // no template for media //xml.Add(new XAttribute("template", 0)); // no template for media
@@ -335,6 +334,7 @@ namespace Umbraco.Core.Services.Implement
return xml; return xml;
} }
public XElement Serialize(IMediaType mediaType) public XElement Serialize(IMediaType mediaType)
{ {
var info = new XElement("Info", var info = new XElement("Info",
@@ -375,7 +375,7 @@ namespace Umbraco.Core.Services.Implement
new XElement("Validation", propertyType.ValidationRegExp), new XElement("Validation", propertyType.ValidationRegExp),
new XElement("ValidationRegExpMessage", propertyType.ValidationRegExpMessage), new XElement("ValidationRegExpMessage", propertyType.ValidationRegExpMessage),
new XElement("LabelOnTop", propertyType.LabelOnTop), new XElement("LabelOnTop", propertyType.LabelOnTop),
new XElement("Description", new XCData(propertyType.Description))); new XElement("Description", new XCData(propertyType.Description ?? string.Empty)));
genericProperties.Add(genericProperty); genericProperties.Add(genericProperty);
} }
@@ -498,7 +498,7 @@ namespace Umbraco.Core.Services.Implement
new XElement("Alias", propertyType.Alias), new XElement("Alias", propertyType.Alias),
new XElement("Key", propertyType.Key), new XElement("Key", propertyType.Key),
new XElement("Type", propertyType.PropertyEditorAlias), new XElement("Type", propertyType.PropertyEditorAlias),
new XElement("Definition", definition.Key), new XElement("Definition", definition.Key),
new XElement("Tab", propertyGroup == null ? "" : propertyGroup.Name), new XElement("Tab", propertyGroup == null ? "" : propertyGroup.Name),
new XElement("SortOrder", propertyType.SortOrder), new XElement("SortOrder", propertyType.SortOrder),
new XElement("Mandatory", propertyType.Mandatory.ToString()), new XElement("Mandatory", propertyType.Mandatory.ToString()),

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -8,7 +7,6 @@ using Microsoft.Extensions.Logging;
using Umbraco.Core.Events; using Umbraco.Core.Events;
using Umbraco.Core.IO; using Umbraco.Core.IO;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Scoping; using Umbraco.Core.Scoping;
@@ -360,6 +358,8 @@ namespace Umbraco.Core.Services.Implement
} }
} }
/// <summary> /// <summary>
/// Gets an <see cref="IMedia"/> object by Id /// Gets an <see cref="IMedia"/> object by Id
/// </summary> /// </summary>
@@ -643,6 +643,8 @@ namespace Umbraco.Core.Services.Implement
#region Save #region Save
/// <summary> /// <summary>
/// Saves a single <see cref="IMedia"/> object /// Saves a single <see cref="IMedia"/> object
/// </summary> /// </summary>

View File

@@ -45,6 +45,8 @@ namespace Umbraco.Tests.Integration.Umbraco.Core.Packaging
private IEntityXmlSerializer EntityXmlSerializer => GetRequiredService<IEntityXmlSerializer>(); private IEntityXmlSerializer EntityXmlSerializer => GetRequiredService<IEntityXmlSerializer>();
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>(); private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
private IUmbracoVersion UmbracoVersion => GetRequiredService<IUmbracoVersion>(); private IUmbracoVersion UmbracoVersion => GetRequiredService<IUmbracoVersion>();
private IMediaService MediaService => GetRequiredService<IMediaService>();
private IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
public ICreatedPackagesRepository PackageBuilder => new PackagesRepository( public ICreatedPackagesRepository PackageBuilder => new PackagesRepository(
ContentService, ContentTypeService, DataTypeService, ContentService, ContentTypeService, DataTypeService,
@@ -53,6 +55,8 @@ namespace Umbraco.Tests.Integration.Umbraco.Core.Packaging
EntityXmlSerializer, LoggerFactory, EntityXmlSerializer, LoggerFactory,
UmbracoVersion, UmbracoVersion,
Microsoft.Extensions.Options.Options.Create(new GlobalSettings()), Microsoft.Extensions.Options.Options.Create(new GlobalSettings()),
MediaService,
MediaTypeService,
"createdPackages.config", "createdPackages.config",
//temp paths //temp paths
tempFolderPath: "~/" + _testBaseFolder + "/temp", tempFolderPath: "~/" + _testBaseFolder + "/temp",
@@ -158,8 +162,8 @@ namespace Umbraco.Tests.Integration.Umbraco.Core.Packaging
{ {
var file1 = $"~/{_testBaseFolder}/App_Plugins/MyPlugin/package.manifest"; var file1 = $"~/{_testBaseFolder}/App_Plugins/MyPlugin/package.manifest";
var file2 = $"~/{_testBaseFolder}/App_Plugins/MyPlugin/styles.css"; var file2 = $"~/{_testBaseFolder}/App_Plugins/MyPlugin/styles.css";
var mappedFile1 = IOHelper.MapPath(file1); var mappedFile1 = HostingEnvironment.MapPathContentRoot(file1);
var mappedFile2 = IOHelper.MapPath(file2); var mappedFile2 = HostingEnvironment.MapPathContentRoot(file2);
Directory.CreateDirectory(Path.GetDirectoryName(mappedFile1)); Directory.CreateDirectory(Path.GetDirectoryName(mappedFile1));
Directory.CreateDirectory(Path.GetDirectoryName(mappedFile2)); Directory.CreateDirectory(Path.GetDirectoryName(mappedFile2));
File.WriteAllText(mappedFile1, "hello world"); File.WriteAllText(mappedFile1, "hello world");
@@ -183,7 +187,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Core.Packaging
def = PackageBuilder.GetById(def.Id); //re-get def = PackageBuilder.GetById(def.Id); //re-get
Assert.IsNotNull(def.PackagePath); Assert.IsNotNull(def.PackagePath);
using (var archive = ZipFile.OpenRead(IOHelper.MapPath(zip))) using (var archive = ZipFile.OpenRead(HostingEnvironment.MapPathWebRoot(zip)))
{ {
Assert.AreEqual(3, archive.Entries.Count); Assert.AreEqual(3, archive.Entries.Count);

View File

@@ -2,13 +2,11 @@
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using Umbraco.Core; using Umbraco.Core;
using Umbraco.Core.Composing; using Umbraco.Core.Composing;
using Umbraco.Core.Composing.CompositionExtensions;
using Umbraco.Core.Configuration.Models; using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.Models.Packaging; using Umbraco.Core.Models.Packaging;
@@ -18,7 +16,7 @@ using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Serialization; using Umbraco.Core.Serialization;
using Umbraco.Core.Services; using Umbraco.Core.Services;
using Umbraco.Core.Strings; using Umbraco.Core.Strings;
using Umbraco.Tests.Services; using Umbraco.Tests.Integration.Testing;
using Umbraco.Tests.Services.Importing; using Umbraco.Tests.Services.Importing;
using Umbraco.Tests.Testing; using Umbraco.Tests.Testing;
@@ -27,9 +25,12 @@ namespace Umbraco.Tests.Packaging
[TestFixture] [TestFixture]
[Category("Slow")] [Category("Slow")]
[Apartment(ApartmentState.STA)] [Apartment(ApartmentState.STA)]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true)]
public class PackageDataInstallationTests : TestWithSomeContentBase public class PackageDataInstallationTests : UmbracoIntegrationTestWithContent
{ {
private ILocalizationService LocalizationService => GetRequiredService<ILocalizationService>();
private IMacroService MacroService => GetRequiredService<IMacroService>();
[HideFromTypeFinder] [HideFromTypeFinder]
[DataEditor("7e062c13-7c41-4ad9-b389-41d88aeef87c", "Editor1", "editor1")] [DataEditor("7e062c13-7c41-4ad9-b389-41d88aeef87c", "Editor1", "editor1")]
public class Editor1 : DataEditor public class Editor1 : DataEditor
@@ -50,31 +51,36 @@ namespace Umbraco.Tests.Packaging
} }
} }
protected override void Compose() // protected override void Compose()
{ // {
base.Compose(); // base.Compose();
//
// // the packages that are used by these tests reference totally bogus property
// // editors that must exist - so they are defined here - and in order not to
// // pollute everything, they are ignored by the type finder and explicitely
// // added to the editors collection
//
// Builder.WithCollectionBuilder<DataEditorCollectionBuilder>()
// .Add<Editor1>()
// .Add<Editor2>();
// }
//
// protected override void ComposeApplication(bool withApplication)
// {
// base.ComposeApplication(withApplication);
//
// if (!withApplication) return;
//
// // re-register with actual media fs
// Builder.ComposeFileSystems();
// }
// the packages that are used by these tests reference totally bogus property private PackageDataInstallation PackageDataInstallation => GetRequiredService<PackageDataInstallation>();
// editors that must exist - so they are defined here - and in order not to private IContentService ContentService => GetRequiredService<IContentService>();
// pollute everything, they are ignored by the type finder and explicitely private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
// added to the editors collection
Builder.WithCollectionBuilder<DataEditorCollectionBuilder>() private IMediaService MediaService => GetRequiredService<IMediaService>();
.Add<Editor1>() private IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
.Add<Editor2>();
}
protected override void ComposeApplication(bool withApplication)
{
base.ComposeApplication(withApplication);
if (!withApplication) return;
// re-register with actual media fs
Builder.ComposeFileSystems();
}
private PackageDataInstallation PackageDataInstallation => Factory.GetRequiredService<PackageDataInstallation>();
[Test] [Test]
public void Can_Import_uBlogsy_ContentTypes_And_Verify_Structure() public void Can_Import_uBlogsy_ContentTypes_And_Verify_Structure()
@@ -195,12 +201,12 @@ namespace Umbraco.Tests.Packaging
var xml = XElement.Parse(strXml); var xml = XElement.Parse(strXml);
var element = xml.Descendants("Templates").First(); var element = xml.Descendants("Templates").First();
var init = ServiceContext.FileService.GetTemplates().Count(); var init = FileService.GetTemplates().Count();
// Act // Act
var templates = PackageDataInstallation.ImportTemplates(element.Elements("Template").ToList(), 0); var templates = PackageDataInstallation.ImportTemplates(element.Elements("Template").ToList(), 0);
var numberOfTemplates = (from doc in element.Elements("Template") select doc).Count(); var numberOfTemplates = (from doc in element.Elements("Template") select doc).Count();
var allTemplates = ServiceContext.FileService.GetTemplates(); var allTemplates = FileService.GetTemplates();
// Assert // Assert
Assert.That(templates, Is.Not.Null); Assert.That(templates, Is.Not.Null);
@@ -322,16 +328,16 @@ namespace Umbraco.Tests.Packaging
var dataTypeElement = xml.Descendants("DataTypes").First(); var dataTypeElement = xml.Descendants("DataTypes").First();
var docTypesElement = xml.Descendants("DocumentTypes").First(); var docTypesElement = xml.Descendants("DocumentTypes").First();
var element = xml.Descendants("DocumentSet").First(); var element = xml.Descendants("DocumentSet").First();
var packageDocument = CompiledPackageDocument.Create(element); var packageDocument = CompiledPackageContentBase.Create(element);
// Act // Act
var dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); var dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0);
var contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); var contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0);
var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x);
var contents = PackageDataInstallation.ImportContent(packageDocument, -1, importedContentTypes, 0); var contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService);
var numberOfDocs = (from doc in element.Descendants() var numberOfDocs = (from doc in element.Descendants()
where (string) doc.Attribute("isDoc") == "" where (string) doc.Attribute("isDoc") == ""
select doc).Count(); select doc).Count();
// Assert // Assert
Assert.That(contents, Is.Not.Null); Assert.That(contents, Is.Not.Null);
@@ -341,6 +347,32 @@ namespace Umbraco.Tests.Packaging
Assert.That(contents.Count(), Is.EqualTo(numberOfDocs)); Assert.That(contents.Count(), Is.EqualTo(numberOfDocs));
} }
[Test]
public void Can_Import_Media_Package_Xml()
{
// Arrange
Core.Services.Implement.MediaTypeService.ClearScopeEvents();
string strXml = ImportResources.MediaTypesAndMedia_Package_xml;
var xml = XElement.Parse(strXml);
var mediaTypesElement = xml.Descendants("MediaTypes").First();
var element = xml.Descendants("MediaSet").First();
var packageMedia = CompiledPackageContentBase.Create(element);
// Act
var mediaTypes = PackageDataInstallation.ImportMediaTypes(mediaTypesElement.Elements("MediaType"), 0);
var importedMediaTypes = mediaTypes.ToDictionary(x => x.Alias, x => x);
var medias = PackageDataInstallation.ImportContentBase(packageMedia.Yield(), importedMediaTypes, 0, MediaTypeService, MediaService);
var numberOfDocs = (from doc in element.Descendants()
where (string) doc.Attribute("isDoc") == ""
select doc).Count();
// Assert
Assert.That(medias, Is.Not.Null);
Assert.That(mediaTypes.Any(), Is.True);
Assert.That(medias.Any(), Is.True);
Assert.That(medias.Count(), Is.EqualTo(numberOfDocs));
}
[Test] [Test]
public void Can_Import_CheckboxList_Content_Package_Xml_With_Property_Editor_Aliases() public void Can_Import_CheckboxList_Content_Package_Xml_With_Property_Editor_Aliases()
{ {
@@ -356,13 +388,13 @@ namespace Umbraco.Tests.Packaging
var dataTypeElement = xml.Descendants("DataTypes").First(); var dataTypeElement = xml.Descendants("DataTypes").First();
var docTypesElement = xml.Descendants("DocumentTypes").First(); var docTypesElement = xml.Descendants("DocumentTypes").First();
var element = xml.Descendants("DocumentSet").First(); var element = xml.Descendants("DocumentSet").First();
var packageDocument = CompiledPackageDocument.Create(element); var packageDocument = CompiledPackageContentBase.Create(element);
// Act // Act
var dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0); var dataTypeDefinitions = PackageDataInstallation.ImportDataTypes(dataTypeElement.Elements("DataType").ToList(), 0);
var contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0); var contentTypes = PackageDataInstallation.ImportDocumentTypes(docTypesElement.Elements("DocumentType"), 0);
var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x); var importedContentTypes = contentTypes.ToDictionary(x => x.Alias, x => x);
var contents = PackageDataInstallation.ImportContent(packageDocument, -1, importedContentTypes, 0); var contents = PackageDataInstallation.ImportContentBase(packageDocument.Yield(), importedContentTypes, 0, ContentTypeService, ContentService);
var numberOfDocs = (from doc in element.Descendants() var numberOfDocs = (from doc in element.Descendants()
where (string)doc.Attribute("isDoc") == "" where (string)doc.Attribute("isDoc") == ""
select doc).Count(); select doc).Count();
@@ -427,7 +459,7 @@ namespace Umbraco.Tests.Packaging
string strXml = ImportResources.SingleDocType; string strXml = ImportResources.SingleDocType;
var docTypeElement = XElement.Parse(strXml); var docTypeElement = XElement.Parse(strXml);
var serializer = Factory.GetRequiredService<IEntityXmlSerializer>(); var serializer = GetRequiredService<IEntityXmlSerializer>();
// Act // Act
var contentTypes = PackageDataInstallation.ImportDocumentType(docTypeElement, 0); var contentTypes = PackageDataInstallation.ImportDocumentType(docTypeElement, 0);
@@ -476,7 +508,7 @@ namespace Umbraco.Tests.Packaging
var templateElement = newPackageXml.Descendants("Templates").First(); var templateElement = newPackageXml.Descendants("Templates").First();
var templateElementUpdated = updatedPackageXml.Descendants("Templates").First(); var templateElementUpdated = updatedPackageXml.Descendants("Templates").First();
var fileService = ServiceContext.FileService; var fileService = FileService;
// kill default test data // kill default test data
fileService.DeleteTemplate("Textpage"); fileService.DeleteTemplate("Textpage");
@@ -535,11 +567,11 @@ namespace Umbraco.Tests.Packaging
var dictionaryItems = PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0); var dictionaryItems = PackageDataInstallation.ImportDictionaryItems(dictionaryItemsElement.Elements("DictionaryItem"), 0);
// Assert // Assert
Assert.That(ServiceContext.LocalizationService.DictionaryItemExists(parentKey), "DictionaryItem parentKey does not exist"); Assert.That(LocalizationService.DictionaryItemExists(parentKey), "DictionaryItem parentKey does not exist");
Assert.That(ServiceContext.LocalizationService.DictionaryItemExists(childKey), "DictionaryItem childKey does not exist"); Assert.That(LocalizationService.DictionaryItemExists(childKey), "DictionaryItem childKey does not exist");
var parentDictionaryItem = ServiceContext.LocalizationService.GetDictionaryItemByKey(parentKey); var parentDictionaryItem = LocalizationService.GetDictionaryItemByKey(parentKey);
var childDictionaryItem = ServiceContext.LocalizationService.GetDictionaryItemByKey(childKey); var childDictionaryItem = LocalizationService.GetDictionaryItemByKey(childKey);
Assert.That(parentDictionaryItem.ParentId, Is.Not.EqualTo(childDictionaryItem.ParentId)); Assert.That(parentDictionaryItem.ParentId, Is.Not.EqualTo(childDictionaryItem.ParentId));
Assert.That(childDictionaryItem.ParentId, Is.EqualTo(parentDictionaryItem.Key)); Assert.That(childDictionaryItem.ParentId, Is.EqualTo(parentDictionaryItem.Key));
@@ -604,7 +636,7 @@ namespace Umbraco.Tests.Packaging
// Act // Act
var languages = PackageDataInstallation.ImportLanguages(LanguageItemsElement.Elements("Language"), 0); var languages = PackageDataInstallation.ImportLanguages(LanguageItemsElement.Elements("Language"), 0);
var allLanguages = ServiceContext.LocalizationService.GetAllLanguages(); var allLanguages = LocalizationService.GetAllLanguages();
// Assert // Assert
Assert.That(languages.Any(x => x.HasIdentity == false), Is.False); Assert.That(languages.Any(x => x.HasIdentity == false), Is.False);
@@ -629,7 +661,7 @@ namespace Umbraco.Tests.Packaging
// Assert // Assert
Assert.That(macros.Any(), Is.True); Assert.That(macros.Any(), Is.True);
var allMacros = ServiceContext.MacroService.GetAll().ToList(); var allMacros = MacroService.GetAll().ToList();
foreach (var macro in macros) foreach (var macro in macros)
{ {
Assert.That(allMacros.Any(x => x.Alias == macro.Alias), Is.True); Assert.That(allMacros.Any(x => x.Alias == macro.Alias), Is.True);
@@ -652,7 +684,7 @@ namespace Umbraco.Tests.Packaging
Assert.That(macros.Any(), Is.True); Assert.That(macros.Any(), Is.True);
Assert.That(macros.First().Properties.Values.Any(), Is.True); Assert.That(macros.First().Properties.Values.Any(), Is.True);
var allMacros = ServiceContext.MacroService.GetAll().ToList(); var allMacros = MacroService.GetAll().ToList();
foreach (var macro in macros) foreach (var macro in macros)
{ {
Assert.That(allMacros.Any(x => x.Alias == macro.Alias), Is.True); Assert.That(allMacros.Any(x => x.Alias == macro.Alias), Is.True);
@@ -718,14 +750,14 @@ namespace Umbraco.Tests.Packaging
var globalSettings = new GlobalSettings(); var globalSettings = new GlobalSettings();
var norwegian = new Core.Models.Language(globalSettings, "nb-NO"); var norwegian = new Core.Models.Language(globalSettings, "nb-NO");
var english = new Core.Models.Language(globalSettings, "en-GB"); var english = new Core.Models.Language(globalSettings, "en-GB");
ServiceContext.LocalizationService.Save(norwegian, 0); LocalizationService.Save(norwegian, 0);
ServiceContext.LocalizationService.Save(english, 0); LocalizationService.Save(english, 0);
} }
private void AssertDictionaryItem(string key, string expectedValue, string cultureCode) private void AssertDictionaryItem(string key, string expectedValue, string cultureCode)
{ {
Assert.That(ServiceContext.LocalizationService.DictionaryItemExists(key), "DictionaryItem key does not exist"); Assert.That(LocalizationService.DictionaryItemExists(key), "DictionaryItem key does not exist");
var dictionaryItem = ServiceContext.LocalizationService.GetDictionaryItemByKey(key); var dictionaryItem = LocalizationService.GetDictionaryItemByKey(key);
var translation = dictionaryItem.Translations.SingleOrDefault(i => i.Language.IsoCode == cultureCode); var translation = dictionaryItem.Translations.SingleOrDefault(i => i.Language.IsoCode == cultureCode);
Assert.IsNotNull(translation, "Translation to {0} was not added", cultureCode); Assert.IsNotNull(translation, "Translation to {0} was not added", cultureCode);
var value = translation.Value; var value = translation.Value;
@@ -734,9 +766,9 @@ namespace Umbraco.Tests.Packaging
private void AddExistingEnglishParentDictionaryItem(string expectedEnglishParentValue) private void AddExistingEnglishParentDictionaryItem(string expectedEnglishParentValue)
{ {
var languages = ServiceContext.LocalizationService.GetAllLanguages().ToList(); var languages = LocalizationService.GetAllLanguages().ToList();
var englishLanguage = languages.Single(l => l.IsoCode == "en-GB"); var englishLanguage = languages.Single(l => l.IsoCode == "en-GB");
ServiceContext.LocalizationService.Save( LocalizationService.Save(
new DictionaryItem("Parent") new DictionaryItem("Parent")
{ {
Translations = new List<IDictionaryTranslation> Translations = new List<IDictionaryTranslation>
@@ -749,10 +781,10 @@ namespace Umbraco.Tests.Packaging
private void AddExistingEnglishAndNorwegianParentDictionaryItem(string expectedEnglishParentValue, string expectedNorwegianParentValue) private void AddExistingEnglishAndNorwegianParentDictionaryItem(string expectedEnglishParentValue, string expectedNorwegianParentValue)
{ {
var languages = ServiceContext.LocalizationService.GetAllLanguages().ToList(); var languages = LocalizationService.GetAllLanguages().ToList();
var englishLanguage = languages.Single(l => l.IsoCode == "en-GB"); var englishLanguage = languages.Single(l => l.IsoCode == "en-GB");
var norwegianLanguage = languages.Single(l => l.IsoCode == "nb-NO"); var norwegianLanguage = languages.Single(l => l.IsoCode == "nb-NO");
ServiceContext.LocalizationService.Save( LocalizationService.Save(
new DictionaryItem("Parent") new DictionaryItem("Parent")
{ {
Translations = new List<IDictionaryTranslation> Translations = new List<IDictionaryTranslation>

View File

@@ -2,74 +2,21 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework; using NUnit.Framework;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Hosting; using Umbraco.Core.Hosting;
using Umbraco.Core.Models.Packaging; using Umbraco.Core.Models.Packaging;
using Umbraco.Core.Packaging; using Umbraco.Core.Packaging;
using Umbraco.Core.PropertyEditors; using Umbraco.Tests.Integration.Testing;
using Umbraco.Core.Scoping;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.Testing; using Umbraco.Tests.Testing;
namespace Umbraco.Tests.Packaging namespace Umbraco.Tests.Packaging
{ {
[TestFixture] [TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)]
public class PackageInstallationTest : TestWithDatabaseBase public class PackageInstallationTest : UmbracoIntegrationTest
{ {
private DirectoryInfo _testBaseFolder; private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
private IPackageInstallation PackageInstallation => GetRequiredService<IPackageInstallation>();
public override void SetUp()
{
base.SetUp();
var path = Path.Combine(TestHelper.WorkingDirectory, Guid.NewGuid().ToString());
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
_testBaseFolder = new DirectoryInfo(path);
}
public override void TearDown()
{
base.TearDown();
//clear out files/folders
if (_testBaseFolder.Exists)
_testBaseFolder.Delete(true);
}
private CompiledPackageXmlParser Parser => new CompiledPackageXmlParser(
new ConflictingPackageData(
ServiceContext.MacroService,
ServiceContext.FileService),
Microsoft.Extensions.Options.Options.Create(new GlobalSettings()));
private PackageDataInstallation PackageDataInstallation => new PackageDataInstallation(
NullLoggerFactory.Instance.CreateLogger<PackageDataInstallation>(), NullLoggerFactory.Instance, ServiceContext.FileService, ServiceContext.MacroService, ServiceContext.LocalizationService,
ServiceContext.DataTypeService, ServiceContext.EntityService,
ServiceContext.ContentTypeService, ServiceContext.ContentService,
Factory.GetRequiredService<PropertyEditorCollection>(),
Factory.GetRequiredService<IScopeProvider>(),
Factory.GetRequiredService<IShortStringHelper>(),
Microsoft.Extensions.Options.Options.Create(new GlobalSettings()),
Factory.GetRequiredService<ILocalizedTextService>(),
Factory.GetRequiredService<IConfigurationEditorJsonSerializer>(),
Factory.GetRequiredService<IJsonSerializer>()
);
private IPackageInstallation PackageInstallation => new PackageInstallation(
PackageDataInstallation,
new PackageFileInstallation(Parser, IOHelper, HostingEnvironment, ProfilingLogger),
Parser, Mock.Of<IPackageActionRunner>(),
//we don't want to extract package files to the real root, so extract to a test folder
Mock.Of<IHostingEnvironment>(x => x.ApplicationPhysicalPath == _testBaseFolder.FullName));
private const string DocumentTypePickerPackage = "Document_Type_Picker_1.1.umb"; private const string DocumentTypePickerPackage = "Document_Type_Picker_1.1.umb";
private const string HelloPackage = "Hello_1.0.0.zip"; private const string HelloPackage = "Hello_1.0.0.zip";
@@ -79,7 +26,7 @@ namespace Umbraco.Tests.Packaging
{ {
var package = PackageInstallation.ReadPackage( var package = PackageInstallation.ReadPackage(
//this is where our test zip file is //this is where our test zip file is
new FileInfo(Path.Combine(IOHelper.MapPath("~/Packaging/packages"), DocumentTypePickerPackage))); new FileInfo(Path.Combine(HostingEnvironment.MapPathContentRoot("~/TestData/Packages"), DocumentTypePickerPackage)));
Assert.IsNotNull(package); Assert.IsNotNull(package);
Assert.AreEqual(1, package.Files.Count); Assert.AreEqual(1, package.Files.Count);
Assert.AreEqual("095e064b-ba4d-442d-9006-3050983c13d8.dll", package.Files[0].UniqueFileName); Assert.AreEqual("095e064b-ba4d-442d-9006-3050983c13d8.dll", package.Files[0].UniqueFileName);
@@ -102,7 +49,7 @@ namespace Umbraco.Tests.Packaging
{ {
var package = PackageInstallation.ReadPackage( var package = PackageInstallation.ReadPackage(
//this is where our test zip file is //this is where our test zip file is
new FileInfo(Path.Combine(IOHelper.MapPath("~/Packaging/packages"), HelloPackage))); new FileInfo(Path.Combine(HostingEnvironment.MapPathContentRoot("~/TestData/Packages"), HelloPackage)));
Assert.IsNotNull(package); Assert.IsNotNull(package);
Assert.AreEqual(0, package.Files.Count); Assert.AreEqual(0, package.Files.Count);
Assert.AreEqual("Hello", package.Name); Assert.AreEqual("Hello", package.Name);
@@ -128,12 +75,12 @@ namespace Umbraco.Tests.Packaging
{ {
//copy a file to the same path that the package will install so we can detect file conflicts //copy a file to the same path that the package will install so we can detect file conflicts
var filePath = Path.Combine(_testBaseFolder.FullName, "bin", "Auros.DocumentTypePicker.dll"); var filePath = Path.Combine(HostingEnvironment.MapPathContentRoot("~/"), "bin", "Auros.DocumentTypePicker.dll");
Directory.CreateDirectory(Path.GetDirectoryName(filePath)); Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, "test"); File.WriteAllText(filePath, "test");
//this is where our test zip file is //this is where our test zip file is
var packageFile = Path.Combine(IOHelper.MapPath("~/Packaging/packages"), DocumentTypePickerPackage); var packageFile = Path.Combine(HostingEnvironment.MapPathContentRoot("~/TestData/Packages"), DocumentTypePickerPackage);
Console.WriteLine(packageFile); Console.WriteLine(packageFile);
var package = PackageInstallation.ReadPackage(new FileInfo(packageFile)); var package = PackageInstallation.ReadPackage(new FileInfo(packageFile));
@@ -141,7 +88,7 @@ namespace Umbraco.Tests.Packaging
Assert.IsNotNull(preInstallWarnings); Assert.IsNotNull(preInstallWarnings);
Assert.AreEqual(1, preInstallWarnings.FilesReplaced.Count()); Assert.AreEqual(1, preInstallWarnings.FilesReplaced.Count());
Assert.AreEqual("bin\\Auros.DocumentTypePicker.dll", preInstallWarnings.FilesReplaced.First()); Assert.AreEqual(Path.Combine("bin", "Auros.DocumentTypePicker.dll"), preInstallWarnings.FilesReplaced.First());
// TODO: More Asserts // TODO: More Asserts
} }
@@ -151,7 +98,7 @@ namespace Umbraco.Tests.Packaging
{ {
var package = PackageInstallation.ReadPackage( var package = PackageInstallation.ReadPackage(
//this is where our test zip file is //this is where our test zip file is
new FileInfo(Path.Combine(IOHelper.MapPath("~/Packaging/packages"), DocumentTypePickerPackage))); new FileInfo(Path.Combine(HostingEnvironment.MapPathContentRoot("~/TestData/Packages"), DocumentTypePickerPackage)));
var def = PackageDefinition.FromCompiledPackage(package); var def = PackageDefinition.FromCompiledPackage(package);
def.Id = 1; def.Id = 1;
@@ -161,8 +108,8 @@ namespace Umbraco.Tests.Packaging
var result = PackageInstallation.InstallPackageFiles(def, package, -1).ToList(); var result = PackageInstallation.InstallPackageFiles(def, package, -1).ToList();
Assert.AreEqual(1, result.Count); Assert.AreEqual(1, result.Count);
Assert.AreEqual("bin\\Auros.DocumentTypePicker.dll", result[0]); Assert.AreEqual(Path.Combine("bin", "Auros.DocumentTypePicker.dll"), result[0]);
Assert.IsTrue(File.Exists(Path.Combine(_testBaseFolder.FullName, result[0]))); Assert.IsTrue(File.Exists(Path.Combine(HostingEnvironment.MapPathContentRoot("~/"), result[0])));
//make sure the def is updated too //make sure the def is updated too
Assert.AreEqual(result.Count, def.Files.Count); Assert.AreEqual(result.Count, def.Files.Count);
@@ -173,7 +120,7 @@ namespace Umbraco.Tests.Packaging
{ {
var package = PackageInstallation.ReadPackage( var package = PackageInstallation.ReadPackage(
//this is where our test zip file is //this is where our test zip file is
new FileInfo(Path.Combine(IOHelper.MapPath("~/Packaging/packages"), DocumentTypePickerPackage))); new FileInfo(Path.Combine(HostingEnvironment.MapPathContentRoot("~/TestData/Packages"), DocumentTypePickerPackage)));
var def = PackageDefinition.FromCompiledPackage(package); var def = PackageDefinition.FromCompiledPackage(package);
def.Id = 1; def.Id = 1;
def.PackageId = Guid.NewGuid(); def.PackageId = Guid.NewGuid();
@@ -186,7 +133,5 @@ namespace Umbraco.Tests.Packaging
//make sure the def is updated too //make sure the def is updated too
Assert.AreEqual(summary.DataTypesInstalled.Count(), def.DataTypes.Count); Assert.AreEqual(summary.DataTypesInstalled.Count(), def.DataTypes.Count);
} }
} }
} }

View File

@@ -8,7 +8,7 @@ using Umbraco.Core.Services;
using Umbraco.Tests.Common.Builders; using Umbraco.Tests.Common.Builders;
using Umbraco.Tests.Common.Builders.Extensions; using Umbraco.Tests.Common.Builders.Extensions;
using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Integration.Testing;
using Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing; using Umbraco.Tests.Services.Importing;
using Umbraco.Tests.Testing; using Umbraco.Tests.Testing;
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services

View File

@@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing { namespace Umbraco.Tests.Services.Importing {
using System; using System;
@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing {
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ImportResources { internal class ImportResources {
@@ -61,6 +61,88 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing {
} }
} }
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;CheckboxListTest&lt;/name&gt;
/// &lt;version&gt;1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;1&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;1&lt;/name&gt;
/// &lt;website&gt;1&lt;/website&gt;
/// &lt;/author&gt;
/// &lt;r [rest of string was truncated]&quot;;.
/// </summary>
internal static string CheckboxList_Content_Package {
get {
return ResourceManager.GetString("CheckboxList_Content_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Compositions Packaged&lt;/name&gt;
/// &lt;version&gt;1.0&lt;/version&gt;
/// &lt;license url=&quot;http://opensource.org/licenses/MIT&quot;&gt;MIT License&lt;/license&gt;
/// &lt;url&gt;http://blog.sitereactor.dk&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// &lt;website&gt;h [rest of string was truncated]&quot;;.
/// </summary>
internal static string CompositionsTestPackage {
get {
return ResourceManager.GetString("CompositionsTestPackage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Composite Test&lt;/name&gt;
/// &lt;version&gt;dfsfd&lt;/version&gt;
/// &lt;license url=&quot;http://opensource.org/licenses/MIT&quot;&gt;MIT License&lt;/license&gt;
/// &lt;url&gt;ddsff&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;fsdfds&lt;/name&gt;
/// &lt;website&gt;sfdf&lt;/website&gt;
/// &lt;/author&gt;
/// &lt;rea [rest of string was truncated]&quot;;.
/// </summary>
internal static string CompositionsTestPackage_Random {
get {
return ResourceManager.GetString("CompositionsTestPackage_Random", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; /// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
///&lt;umbPackage&gt; ///&lt;umbPackage&gt;
@@ -86,5 +168,243 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services.Importing {
return ResourceManager.GetString("Dictionary_Package", resourceCulture); return ResourceManager.GetString("Dictionary_Package", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;bootstrap.min.js&lt;/guid&gt;
/// &lt;orgPath&gt;/js&lt;/orgPath&gt;
/// &lt;orgName&gt;bootstrap.min.js&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;jquery.min.js&lt;/guid&gt;
/// &lt;orgPath&gt;/js&lt;/orgPath&gt;
/// &lt;orgName&gt;jquery.min.js&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;top-image.jpg&lt;/guid&gt;
/// &lt;orgPath&gt;/Media/1001&lt;/orgPath&gt;
/// &lt;orgName&gt;top-image.jpg&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;top-im [rest of string was truncated]&quot;;.
/// </summary>
internal static string Fanoe_Package {
get {
return ResourceManager.GetString("Fanoe_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;DocTypeError&lt;/name&gt;
/// &lt;version&gt;1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;Personal license&lt;/license&gt;
/// &lt;url&gt;http://www.iseli-webconsulting.de&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Iseli Webconsulting&lt;/name&gt; [rest of string was truncated]&quot;;.
/// </summary>
internal static string InheritedDocTypes_Package {
get {
return ResourceManager.GetString("InheritedDocTypes_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Package With MediaTypes And Media + Folder&lt;/name&gt;
/// &lt;version&gt;1.0.0&lt;/version&gt;
/// &lt;iconUrl&gt;&lt;/iconUrl&gt;
/// &lt;license url=&quot;http://opensource.org/licenses/MIT&quot;&gt;MIT License&lt;/license&gt;
/// &lt;url&gt;http://www.umbraco.com&lt;/url&gt;
/// &lt;requirements type=&quot;Strict&quot;&gt;
/// &lt;major&gt;0&lt;/major&gt;
/// &lt;minor&gt;5&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name [rest of string was truncated]&quot;;.
/// </summary>
internal static string MediaTypesAndMedia_Package_xml {
get {
return ResourceManager.GetString("MediaTypesAndMedia_Package.xml", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
///&lt;DocumentType&gt;
/// &lt;Info&gt;
/// &lt;Name&gt;test&lt;/Name&gt;
/// &lt;Alias&gt;test&lt;/Alias&gt;
/// &lt;Icon&gt;folder.gif&lt;/Icon&gt;
/// &lt;Thumbnail&gt;folder.png&lt;/Thumbnail&gt;
/// &lt;Description&gt;
/// &lt;/Description&gt;
/// &lt;AllowAtRoot&gt;False&lt;/AllowAtRoot&gt;
/// &lt;AllowedTemplates&gt;
/// &lt;Template&gt;test&lt;/Template&gt;
/// &lt;/AllowedTemplates&gt;
/// &lt;DefaultTemplate&gt;test&lt;/DefaultTemplate&gt;
/// &lt;/Info&gt;
/// &lt;Structure&gt;
/// &lt;DocumentType&gt;test&lt;/DocumentType&gt;
/// &lt;/Structure&gt;
/// &lt;GenericProperties&gt;
/// &lt;GenericProperty&gt; [rest of string was truncated]&quot;;.
/// </summary>
internal static string SingleDocType {
get {
return ResourceManager.GetString("SingleDocType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;Map.cshtml&lt;/guid&gt;
/// &lt;orgPath&gt;/macroScripts&lt;/orgPath&gt;
/// &lt;orgName&gt;Map.cshtml&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;AccountController.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;AccountController.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;ContactController.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;ContactController.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string StandardMvc_Package {
get {
return ResourceManager.GetString("StandardMvc_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Template-Update&lt;/name&gt;
/// &lt;version&gt;0.1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;https://our.umbraco.com/projects&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string TemplateOnly_Package {
get {
return ResourceManager.GetString("TemplateOnly_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Template-Update&lt;/name&gt;
/// &lt;version&gt;0.1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;https://our.umbraco.com/projects&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string TemplateOnly_Updated_Package {
get {
return ResourceManager.GetString("TemplateOnly_Updated_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.BusinessLogic.dll&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.BusinessLogic.dll&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.BusinessLogic.pdb&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.BusinessLogic.pdb&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.Common.dll&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.Common.dll&lt;/orgNam [rest of string was truncated]&quot;;.
/// </summary>
internal static string uBlogsy_Package {
get {
return ResourceManager.GetString("uBlogsy_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;XSLTsearch.xslt&lt;/guid&gt;
/// &lt;orgPath&gt;/xslt&lt;/orgPath&gt;
/// &lt;orgName&gt;XSLTsearch.xslt&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;XSLTsearch.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;XSLTsearch.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;/files&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;XSLTsearch&lt;/name&gt;
/// &lt;version&gt;3.0.4&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-li [rest of string was truncated]&quot;;.
/// </summary>
internal static string XsltSearch_Package {
get {
return ResourceManager.GetString("XsltSearch_Package", resourceCulture);
}
}
} }
} }

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
@@ -118,7 +118,43 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="InheritedDocTypes_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>InheritedDocTypes-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="StandardMvc_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>StandardMvc-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="uBlogsy_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>uBlogsy-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="XsltSearch_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>XsltSearch-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="SingleDocType" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>SingleDocType.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="TemplateOnly_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>TemplateOnly-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="TemplateOnly_Updated_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>TemplateOnly-Updated-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="CheckboxList_Content_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>CheckboxList-Content-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="Dictionary_Package" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="Dictionary_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Dictionary-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>Dictionary-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="CompositionsTestPackage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>CompositionsTestPackage.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="CompositionsTestPackage_Random" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>CompositionsTestPackage-Random.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="Fanoe_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Fanoe-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="MediaTypesAndMedia_Package.xml" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>MediaTypesAndMedia-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root> </root>

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<umbPackage>
<files />
<info>
<package>
<name>Package With MediaTypes And Media + Folder</name>
<version>1.0.0</version>
<iconUrl></iconUrl>
<license url="http://opensource.org/licenses/MIT">MIT License</license>
<url>http://www.umbraco.com</url>
<requirements type="Strict">
<major>0</major>
<minor>5</minor>
<patch>0</patch>
</requirements>
</package>
<author>
<name>dteam</name>
<website>http://www.umbraco.com</website>
</author>
<contributors></contributors>
<readme><![CDATA[]]></readme>
</info>
<DocumentTypes />
<MediaTypes>
<MediaType>
<Info>
<Name>Folder</Name>
<Alias>Folder</Alias>
<Icon>icon-folder</Icon>
<Thumbnail>icon-folder</Thumbnail>
<Description />
<AllowAtRoot>True</AllowAtRoot>
</Info>
<Structure>
<MediaType>Folder</MediaType>
<MediaType>Image</MediaType>
<MediaType>File</MediaType>
</Structure>
<GenericProperties />
<Tabs />
</MediaType>
<MediaType>
<Info>
<Name>Image</Name>
<Alias>Image</Alias>
<Icon>icon-picture</Icon>
<Thumbnail>icon-picture</Thumbnail>
<Description />
<AllowAtRoot>True</AllowAtRoot>
</Info>
<Structure />
<GenericProperties>
<GenericProperty>
<Name>Upload image</Name>
<Alias>umbracoFile</Alias>
<Type>Umbraco.ImageCropper</Type>
<Definition>1df9f033-e6d4-451f-b8d2-e0cbc50a836f</Definition>
<Tab>Image</Tab>
<Mandatory>True</Mandatory>
<MandatoryMessage />
<Validation />
<ValidationRegExpMessage />
<LabelOnTop>false</LabelOnTop>
<Description><![CDATA[]]></Description>
</GenericProperty>
<GenericProperty>
<Name>Width</Name>
<Alias>umbracoWidth</Alias>
<Type>Umbraco.Label</Type>
<Definition>8e7f995c-bd81-4627-9932-c40e568ec788</Definition>
<Tab>Image</Tab>
<Mandatory>False</Mandatory>
<MandatoryMessage />
<Validation />
<ValidationRegExpMessage />
<LabelOnTop>false</LabelOnTop>
<Description><![CDATA[in pixels]]></Description>
</GenericProperty>
<GenericProperty>
<Name>Height</Name>
<Alias>umbracoHeight</Alias>
<Type>Umbraco.Label</Type>
<Definition>8e7f995c-bd81-4627-9932-c40e568ec788</Definition>
<Tab>Image</Tab>
<Mandatory>False</Mandatory>
<MandatoryMessage />
<Validation />
<ValidationRegExpMessage />
<LabelOnTop>false</LabelOnTop>
<Description><![CDATA[in pixels]]></Description>
</GenericProperty>
<GenericProperty>
<Name>Size</Name>
<Alias>umbracoBytes</Alias>
<Type>Umbraco.Label</Type>
<Definition>930861bf-e262-4ead-a704-f99453565708</Definition>
<Tab>Image</Tab>
<Mandatory>False</Mandatory>
<MandatoryMessage />
<Validation />
<ValidationRegExpMessage />
<LabelOnTop>false</LabelOnTop>
<Description><![CDATA[in bytes]]></Description>
</GenericProperty>
<GenericProperty>
<Name>Type</Name>
<Alias>umbracoExtension</Alias>
<Type>Umbraco.Label</Type>
<Definition>f0bc4bfb-b499-40d6-ba86-058885a5178c</Definition>
<Tab>Image</Tab>
<Mandatory>False</Mandatory>
<MandatoryMessage />
<Validation />
<ValidationRegExpMessage />
<LabelOnTop>false</LabelOnTop>
<Description><![CDATA[]]></Description>
</GenericProperty>
</GenericProperties>
<Tabs>
<Tab>
<Id>3</Id>
<Caption>Image</Caption>
<SortOrder>1</SortOrder>
</Tab>
</Tabs>
</MediaType>
</MediaTypes>
<Templates />
<Stylesheets />
<Macros />
<DictionaryItems />
<Languages />
<DataTypes />
<MediaItems>
<MediaSet>
<Image id="1145" key="cd4caf13-0705-4e31-9661-48d5a6ce2cc6" parentID="-1" level="1" creatorID="-1" sortOrder="0" createDate="2020-12-15T12:56:46" updateDate="2020-12-15T12:56:46" nodeName="Ledersidetegning Mandag 27 01 20 Rgb (1) (1)" urlName="ledersidetegning-mandag-27-01-20-rgb-1-1" path="-1,1145" isDoc="" nodeType="1032" nodeTypeAlias="Image" writerName="" writerID="0" udi="umb://media/cd4caf1307054e31966148d5a6ce2cc6">
<umbracoFile><![CDATA[{"src":"/media/cwxfztif/ledersidetegning-mandag-27-01-20-rgb-1.jpg","crops":null}]]></umbracoFile>
<umbracoWidth><![CDATA[940]]></umbracoWidth>
<umbracoHeight><![CDATA[564]]></umbracoHeight>
<umbracoBytes><![CDATA[20340]]></umbracoBytes>
<umbracoExtension><![CDATA[jpg]]></umbracoExtension>
</Image>
</MediaSet>
<MediaSet>
<Folder id="1146" key="aef56c09-de35-4d45-b91a-93096dac5e45" parentID="-1" level="1" creatorID="-1" sortOrder="1" createDate="2020-12-15T12:57:26" updateDate="2020-12-15T12:57:26" nodeName="asd" urlName="asd" path="-1,1146" isDoc="" nodeType="1031" nodeTypeAlias="Folder" writerName="" writerID="0" udi="umb://media/aef56c09de354d45b91a93096dac5e45">
<Image id="1147" key="4a3172d8-3c68-4c32-890f-051894e50c8e" parentID="1146" level="2" creatorID="-1" sortOrder="0" createDate="2020-12-15T12:58:00" updateDate="2020-12-15T12:58:00" nodeName="Rider" urlName="rider" path="-1,1146,1147" isDoc="" nodeType="1032" nodeTypeAlias="Image" writerName="" writerID="0" udi="umb://media/4a3172d83c684c32890f051894e50c8e">
<umbracoFile><![CDATA[{"src":"/media/1zzdcsti/rider.png","crops":null}]]></umbracoFile>
<umbracoWidth><![CDATA[839]]></umbracoWidth>
<umbracoHeight><![CDATA[551]]></umbracoHeight>
<umbracoBytes><![CDATA[37605]]></umbracoBytes>
<umbracoExtension><![CDATA[png]]></umbracoExtension>
</Image>
</Folder>
</MediaSet>
</MediaItems>
<Actions />
</umbPackage>

View File

@@ -19,6 +19,16 @@
<EmbeddedResource Remove="Views\**" /> <EmbeddedResource Remove="Views\**" />
<None Remove="Views\**" /> <None Remove="Views\**" />
<None Remove="create_slicing_filter_condition.sh" /> <None Remove="create_slicing_filter_condition.sh" />
<EmbeddedResource Update="Umbraco.Infrastructure\Services\Importing\ImportResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ImportResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Update="Umbraco.Infrastructure\Services\Importing\ImportResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ImportResources.resx</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -26,7 +36,22 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Umbraco.Infrastructure\Services\Importing\CheckboxList-Content-Package.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="Umbraco.Infrastructure\Services\Importing\CompositionsTestPackage-Random.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\CompositionsTestPackage.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\Dictionary-Package.xml" /> <Content Include="Umbraco.Infrastructure\Services\Importing\Dictionary-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\Fanoe-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\InheritedDocTypes-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\SingleDocType.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\StandardMvc-Package.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="Umbraco.Infrastructure\Services\Importing\TemplateOnly-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\TemplateOnly-Updated-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\uBlogsy-Package.xml" />
<Content Include="Umbraco.Infrastructure\Services\Importing\XsltSearch-Package.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -58,20 +83,4 @@
<Folder Include="Umbraco\logs" /> <Folder Include="Umbraco\logs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Umbraco.Infrastructure\Services\Importing\ImportResources.Designer.cs">
<DependentUpon>ImportResources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Umbraco.Infrastructure\Services\Importing\ImportResources.resx">
<SubType>Designer</SubType>
<LastGenOutput>ImportResources.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
</Project> </Project>

View File

@@ -92,6 +92,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Umbraco.PublishedCache
Assert.AreEqual("one", s1.Get(1)); Assert.AreEqual("one", s1.Get(1));
} }
[Retry(5)] // TODO make this test non-flaky.
[Test] [Test]
public async Task CollectValues() public async Task CollectValues()
{ {
@@ -218,6 +219,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Umbraco.PublishedCache
Assert.AreEqual(0, d.Count); Assert.AreEqual(0, d.Count);
} }
[Retry(5)] // TODO make this test non-flaky.
[Test] [Test]
public async Task CollectNulls() public async Task CollectNulls()
{ {
@@ -527,6 +529,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Umbraco.PublishedCache
Assert.AreEqual(1, d.Test.GetValues(1).Length); Assert.AreEqual(1, d.Test.GetValues(1).Length);
} }
[Retry(5)] // TODO make this test non-flaky.
[Test] [Test]
public async Task RandomTest1() public async Task RandomTest1()
{ {
@@ -573,6 +576,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Umbraco.PublishedCache
Assert.AreEqual(0, d.SnapCount); Assert.AreEqual(0, d.SnapCount);
} }
[Retry(5)] // TODO make this test non-flaky.
[Test] [Test]
public async Task RandomTest2() public async Task RandomTest2()
{ {

View File

@@ -4,11 +4,11 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Xml; using System.Xml;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NPoco; using NPoco;
using Umbraco.Core; using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting; using Umbraco.Core.Hosting;
using Umbraco.Core.IO; using Umbraco.Core.IO;
using Umbraco.Core.Models; using Umbraco.Core.Models;
@@ -28,7 +28,6 @@ using Umbraco.Web.Composing;
using Umbraco.Web.PublishedCache; using Umbraco.Web.PublishedCache;
using Umbraco.Web.Scheduling; using Umbraco.Web.Scheduling;
using File = System.IO.File; using File = System.IO.File;
using Task = System.Threading.Tasks.Task;
namespace Umbraco.Tests.LegacyXmlPublishedCache namespace Umbraco.Tests.LegacyXmlPublishedCache
{ {
@@ -761,7 +760,7 @@ AND (umbracoNode.id=@id)";
// The indenting resumes once the mixed content element is closed." - says MSDN // The indenting resumes once the mixed content element is closed." - says MSDN
// about XmlWriterSettings.Indent // about XmlWriterSettings.Indent
// so ImportContent must also make sure of ignoring whitespaces! // so ImportContentBase must also make sure of ignoring whitespaces!
var sb = new StringBuilder(); var sb = new StringBuilder();
using (var xmlWriter = XmlWriter.Create(sb, new XmlWriterSettings using (var xmlWriter = XmlWriter.Create(sb, new XmlWriterSettings

View File

@@ -1,383 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Tests.Services.Importing {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ImportResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ImportResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Tests.Services.Importing.ImportResources", typeof(ImportResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;CheckboxListTest&lt;/name&gt;
/// &lt;version&gt;1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;1&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;1&lt;/name&gt;
/// &lt;website&gt;1&lt;/website&gt;
/// &lt;/author&gt;
/// &lt;r [rest of string was truncated]&quot;;.
/// </summary>
internal static string CheckboxList_Content_Package {
get {
return ResourceManager.GetString("CheckboxList_Content_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Compositions Packaged&lt;/name&gt;
/// &lt;version&gt;1.0&lt;/version&gt;
/// &lt;license url=&quot;http://opensource.org/licenses/MIT&quot;&gt;MIT License&lt;/license&gt;
/// &lt;url&gt;http://blog.sitereactor.dk&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// &lt;website&gt;h [rest of string was truncated]&quot;;.
/// </summary>
internal static string CompositionsTestPackage {
get {
return ResourceManager.GetString("CompositionsTestPackage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Composite Test&lt;/name&gt;
/// &lt;version&gt;dfsfd&lt;/version&gt;
/// &lt;license url=&quot;http://opensource.org/licenses/MIT&quot;&gt;MIT License&lt;/license&gt;
/// &lt;url&gt;ddsff&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;fsdfds&lt;/name&gt;
/// &lt;website&gt;sfdf&lt;/website&gt;
/// &lt;/author&gt;
/// &lt;rea [rest of string was truncated]&quot;;.
/// </summary>
internal static string CompositionsTestPackage_Random {
get {
return ResourceManager.GetString("CompositionsTestPackage_Random", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Dictionary-Package&lt;/name&gt;
/// &lt;version&gt;1.0&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;http://not.available&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Test&lt;/name&gt;
/// &lt;website&gt;http://not.available&lt;/w [rest of string was truncated]&quot;;.
/// </summary>
internal static string Dictionary_Package {
get {
return ResourceManager.GetString("Dictionary_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;bootstrap.min.js&lt;/guid&gt;
/// &lt;orgPath&gt;/js&lt;/orgPath&gt;
/// &lt;orgName&gt;bootstrap.min.js&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;jquery.min.js&lt;/guid&gt;
/// &lt;orgPath&gt;/js&lt;/orgPath&gt;
/// &lt;orgName&gt;jquery.min.js&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;top-image.jpg&lt;/guid&gt;
/// &lt;orgPath&gt;/Media/1001&lt;/orgPath&gt;
/// &lt;orgName&gt;top-image.jpg&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;top-im [rest of string was truncated]&quot;;.
/// </summary>
internal static string Fanoe_Package {
get {
return ResourceManager.GetString("Fanoe_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;DocTypeError&lt;/name&gt;
/// &lt;version&gt;1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;Personal license&lt;/license&gt;
/// &lt;url&gt;http://www.iseli-webconsulting.de&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Iseli Webconsulting&lt;/name&gt; [rest of string was truncated]&quot;;.
/// </summary>
internal static string InheritedDocTypes_Package {
get {
return ResourceManager.GetString("InheritedDocTypes_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
///&lt;DocumentType&gt;
/// &lt;Info&gt;
/// &lt;Name&gt;test&lt;/Name&gt;
/// &lt;Alias&gt;test&lt;/Alias&gt;
/// &lt;Icon&gt;folder.gif&lt;/Icon&gt;
/// &lt;Thumbnail&gt;folder.png&lt;/Thumbnail&gt;
/// &lt;Description&gt;
/// &lt;/Description&gt;
/// &lt;AllowAtRoot&gt;False&lt;/AllowAtRoot&gt;
/// &lt;AllowedTemplates&gt;
/// &lt;Template&gt;test&lt;/Template&gt;
/// &lt;/AllowedTemplates&gt;
/// &lt;DefaultTemplate&gt;test&lt;/DefaultTemplate&gt;
/// &lt;/Info&gt;
/// &lt;Structure&gt;
/// &lt;DocumentType&gt;test&lt;/DocumentType&gt;
/// &lt;/Structure&gt;
/// &lt;GenericProperties&gt;
/// &lt;GenericProperty&gt; [rest of string was truncated]&quot;;.
/// </summary>
internal static string SingleDocType {
get {
return ResourceManager.GetString("SingleDocType", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;Map.cshtml&lt;/guid&gt;
/// &lt;orgPath&gt;/macroScripts&lt;/orgPath&gt;
/// &lt;orgName&gt;Map.cshtml&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;AccountController.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;AccountController.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;ContactController.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;ContactController.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string StandardMvc_Package {
get {
return ResourceManager.GetString("StandardMvc_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Template-Update&lt;/name&gt;
/// &lt;version&gt;0.1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;https://our.umbraco.com/projects&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string TemplateOnly_Package {
get {
return ResourceManager.GetString("TemplateOnly_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files /&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;Template-Update&lt;/name&gt;
/// &lt;version&gt;0.1&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-license.php&quot;&gt;MIT license&lt;/license&gt;
/// &lt;url&gt;https://our.umbraco.com/projects&lt;/url&gt;
/// &lt;requirements&gt;
/// &lt;major&gt;3&lt;/major&gt;
/// &lt;minor&gt;0&lt;/minor&gt;
/// &lt;patch&gt;0&lt;/patch&gt;
/// &lt;/requirements&gt;
/// &lt;/package&gt;
/// &lt;author&gt;
/// &lt;name&gt;Morten Christensen&lt;/name&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string TemplateOnly_Updated_Package {
get {
return ResourceManager.GetString("TemplateOnly_Updated_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.BusinessLogic.dll&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.BusinessLogic.dll&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.BusinessLogic.pdb&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.BusinessLogic.pdb&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;uBlogsy.Common.dll&lt;/guid&gt;
/// &lt;orgPath&gt;/bin&lt;/orgPath&gt;
/// &lt;orgName&gt;uBlogsy.Common.dll&lt;/orgNam [rest of string was truncated]&quot;;.
/// </summary>
internal static string uBlogsy_Package {
get {
return ResourceManager.GetString("uBlogsy_Package", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
///&lt;umbPackage&gt;
/// &lt;files&gt;
/// &lt;file&gt;
/// &lt;guid&gt;XSLTsearch.xslt&lt;/guid&gt;
/// &lt;orgPath&gt;/xslt&lt;/orgPath&gt;
/// &lt;orgName&gt;XSLTsearch.xslt&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;file&gt;
/// &lt;guid&gt;XSLTsearch.cs&lt;/guid&gt;
/// &lt;orgPath&gt;/App_Code&lt;/orgPath&gt;
/// &lt;orgName&gt;XSLTsearch.cs&lt;/orgName&gt;
/// &lt;/file&gt;
/// &lt;/files&gt;
/// &lt;info&gt;
/// &lt;package&gt;
/// &lt;name&gt;XSLTsearch&lt;/name&gt;
/// &lt;version&gt;3.0.4&lt;/version&gt;
/// &lt;license url=&quot;http://www.opensource.org/licenses/mit-li [rest of string was truncated]&quot;;.
/// </summary>
internal static string XsltSearch_Package {
get {
return ResourceManager.GetString("XsltSearch_Package", resourceCulture);
}
}
}
}

View File

@@ -1,157 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="InheritedDocTypes_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>inheriteddoctypes-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="StandardMvc_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>standardmvc-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="uBlogsy_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>ublogsy-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="XsltSearch_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>xsltsearch-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="SingleDocType" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>singledoctype.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="TemplateOnly_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>templateonly-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="TemplateOnly_Updated_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>templateonly-updated-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="CheckboxList_Content_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>checkboxlist-content-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="Dictionary_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>dictionary-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="CompositionsTestPackage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>compositionstestpackage.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="CompositionsTestPackage_Random" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>compositionstestpackage-random.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="Fanoe_Package" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>fanoe-package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>

View File

@@ -200,7 +200,6 @@
<Compile Include="PublishedContent\PublishedRouterTests.cs" /> <Compile Include="PublishedContent\PublishedRouterTests.cs" />
<Compile Include="PublishedContent\RootNodeTests.cs" /> <Compile Include="PublishedContent\RootNodeTests.cs" />
<Compile Include="Scheduling\BackgroundTaskRunnerTests.cs" /> <Compile Include="Scheduling\BackgroundTaskRunnerTests.cs" />
<Compile Include="Packaging\PackageInstallationTest.cs" />
<Compile Include="Cache\PublishedCache\PublishedMediaCacheTests.cs" /> <Compile Include="Cache\PublishedCache\PublishedMediaCacheTests.cs" />
<Compile Include="Models\MediaXmlTest.cs" /> <Compile Include="Models\MediaXmlTest.cs" />
<Compile Include="Persistence\FaultHandling\ConnectionRetryTest.cs" /> <Compile Include="Persistence\FaultHandling\ConnectionRetryTest.cs" />
@@ -217,12 +216,6 @@
<Compile Include="Routing\ContentFinderByAliasWithDomainsTests.cs" /> <Compile Include="Routing\ContentFinderByAliasWithDomainsTests.cs" />
<Compile Include="Routing\DomainsAndCulturesTests.cs" /> <Compile Include="Routing\DomainsAndCulturesTests.cs" />
<Compile Include="Routing\UrlsWithNestedDomains.cs" /> <Compile Include="Routing\UrlsWithNestedDomains.cs" />
<Compile Include="Packaging\PackageDataInstallationTests.cs" />
<Compile Include="Services\Importing\ImportResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ImportResources.resx</DependentUpon>
</Compile>
<Compile Include="Web\Controllers\PluginControllerAreaTests.cs" /> <Compile Include="Web\Controllers\PluginControllerAreaTests.cs" />
<Compile Include="TestHelpers\TestWithDatabaseBase.cs" /> <Compile Include="TestHelpers\TestWithDatabaseBase.cs" />
<Compile Include="Routing\ContentFinderByAliasTests.cs" /> <Compile Include="Routing\ContentFinderByAliasTests.cs" />
@@ -271,7 +264,6 @@
<None Include="App.config"> <None Include="App.config">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>
<None Include="Packaging\Packages\Document_Type_Picker_1.1.umb" />
<None Include="UmbracoExamine\TestFiles\umbraco-sort.config"> <None Include="UmbracoExamine\TestFiles\umbraco-sort.config">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>
@@ -311,11 +303,6 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Services\Importing\ImportResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ImportResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="UmbracoExamine\TestFiles.resx"> <EmbeddedResource Include="UmbracoExamine\TestFiles.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TestFiles.Designer.cs</LastGenOutput> <LastGenOutput>TestFiles.Designer.cs</LastGenOutput>
@@ -323,23 +310,8 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Services\Importing\CheckboxList-Content-Package.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="Services\Importing\CompositionsTestPackage-Random.xml" />
<Content Include="Services\Importing\CompositionsTestPackage.xml" />
<Content Include="Services\Importing\Dictionary-Package.xml" /> <Content Include="Services\Importing\Dictionary-Package.xml" />
<Content Include="Services\Importing\Fanoe-Package.xml" />
<Content Include="UmbracoExamine\TestFiles\media.xml" /> <Content Include="UmbracoExamine\TestFiles\media.xml" />
<Content Include="Services\Importing\InheritedDocTypes-Package.xml" />
<Content Include="Services\Importing\SingleDocType.xml" />
<Content Include="Services\Importing\StandardMvc-Package.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="Services\Importing\TemplateOnly-Package.xml" />
<Content Include="Services\Importing\TemplateOnly-Updated-Package.xml" />
<Content Include="Services\Importing\uBlogsy-Package.xml" />
<Content Include="Services\Importing\XsltSearch-Package.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />

View File

@@ -11,18 +11,14 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Core; using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Dictionary; using Umbraco.Core.Dictionary;
using Umbraco.Core.Hosting; using Umbraco.Core.Hosting;
using Umbraco.Core.Mapping; using Umbraco.Core.Mapping;
using Umbraco.Core.Models; using Umbraco.Core.Models;
using Umbraco.Core.Packaging; using Umbraco.Core.Packaging;
using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Security; using Umbraco.Core.Security;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services; using Umbraco.Core.Services;
using Umbraco.Core.Strings; using Umbraco.Core.Strings;
using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Attributes;
@@ -45,9 +41,7 @@ namespace Umbraco.Web.BackOffice.Controllers
// It would be possible to have something like a ContentTypeInfoController for the GetAllPropertyTypeAliases/GetCount/GetAllowedChildren/etc... actions // It would be possible to have something like a ContentTypeInfoController for the GetAllPropertyTypeAliases/GetCount/GetAllowedChildren/etc... actions
private readonly IEntityXmlSerializer _serializer; private readonly IEntityXmlSerializer _serializer;
private readonly GlobalSettings _globalSettings;
private readonly PropertyEditorCollection _propertyEditors; private readonly PropertyEditorCollection _propertyEditors;
private readonly IScopeProvider _scopeProvider;
private readonly IContentTypeService _contentTypeService; private readonly IContentTypeService _contentTypeService;
private readonly UmbracoMapper _umbracoMapper; private readonly UmbracoMapper _umbracoMapper;
private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor;
@@ -56,15 +50,10 @@ namespace Umbraco.Web.BackOffice.Controllers
private readonly ILocalizedTextService _localizedTextService; private readonly ILocalizedTextService _localizedTextService;
private readonly IFileService _fileService; private readonly IFileService _fileService;
private readonly ILogger<ContentTypeController> _logger; private readonly ILogger<ContentTypeController> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IContentService _contentService; private readonly IContentService _contentService;
private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
private readonly ILocalizationService _LocalizationService;
private readonly IMacroService _macroService;
private readonly IEntityService _entityService;
private readonly IHostingEnvironment _hostingEnvironment; private readonly IHostingEnvironment _hostingEnvironment;
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer; private readonly PackageDataInstallation _packageDataInstallation;
private readonly IJsonSerializer _jsonSerializer;
public ContentTypeController( public ContentTypeController(
ICultureDictionary cultureDictionary, ICultureDictionary cultureDictionary,
@@ -74,24 +63,17 @@ namespace Umbraco.Web.BackOffice.Controllers
UmbracoMapper umbracoMapper, UmbracoMapper umbracoMapper,
ILocalizedTextService localizedTextService, ILocalizedTextService localizedTextService,
IEntityXmlSerializer serializer, IEntityXmlSerializer serializer,
IOptions<GlobalSettings> globalSettings,
PropertyEditorCollection propertyEditors, PropertyEditorCollection propertyEditors,
IScopeProvider scopeProvider,
IBackOfficeSecurityAccessor backofficeSecurityAccessor, IBackOfficeSecurityAccessor backofficeSecurityAccessor,
IDataTypeService dataTypeService, IDataTypeService dataTypeService,
IShortStringHelper shortStringHelper, IShortStringHelper shortStringHelper,
IFileService fileService, IFileService fileService,
ILogger<ContentTypeController> logger, ILogger<ContentTypeController> logger,
ILoggerFactory loggerFactory,
IContentService contentService, IContentService contentService,
IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider,
ILocalizationService localizationService,
IMacroService macroService,
IEntityService entityService,
IHostingEnvironment hostingEnvironment, IHostingEnvironment hostingEnvironment,
EditorValidatorCollection editorValidatorCollection, EditorValidatorCollection editorValidatorCollection,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer, PackageDataInstallation packageDataInstallation)
IJsonSerializer jsonSerializer)
: base(cultureDictionary, : base(cultureDictionary,
editorValidatorCollection, editorValidatorCollection,
contentTypeService, contentTypeService,
@@ -101,9 +83,7 @@ namespace Umbraco.Web.BackOffice.Controllers
localizedTextService) localizedTextService)
{ {
_serializer = serializer; _serializer = serializer;
_globalSettings = globalSettings.Value;
_propertyEditors = propertyEditors; _propertyEditors = propertyEditors;
_scopeProvider = scopeProvider;
_contentTypeService = contentTypeService; _contentTypeService = contentTypeService;
_umbracoMapper = umbracoMapper; _umbracoMapper = umbracoMapper;
_backofficeSecurityAccessor = backofficeSecurityAccessor; _backofficeSecurityAccessor = backofficeSecurityAccessor;
@@ -112,15 +92,10 @@ namespace Umbraco.Web.BackOffice.Controllers
_localizedTextService = localizedTextService; _localizedTextService = localizedTextService;
_fileService = fileService; _fileService = fileService;
_logger = logger; _logger = logger;
_loggerFactory = loggerFactory;
_contentService = contentService; _contentService = contentService;
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
_LocalizationService = localizationService;
_macroService = macroService;
_entityService = entityService;
_hostingEnvironment = hostingEnvironment; _hostingEnvironment = hostingEnvironment;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer; _packageDataInstallation = packageDataInstallation;
_jsonSerializer = jsonSerializer;
} }
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)] [Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
@@ -640,30 +615,13 @@ namespace Umbraco.Web.BackOffice.Controllers
return NotFound(); return NotFound();
} }
var dataInstaller = new PackageDataInstallation(
_loggerFactory.CreateLogger<PackageDataInstallation>(),
_loggerFactory,
_fileService,
_macroService,
_LocalizationService,
_dataTypeService,
_entityService,
_contentTypeService,
_contentService,
_propertyEditors,
_scopeProvider,
_shortStringHelper,
Options.Create(_globalSettings),
_localizedTextService,
_configurationEditorJsonSerializer,
_jsonSerializer);
var xd = new XmlDocument {XmlResolver = null}; var xd = new XmlDocument {XmlResolver = null};
xd.Load(filePath); xd.Load(filePath);
var userId = _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0); var userId = _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0);
var element = XElement.Parse(xd.InnerXml); var element = XElement.Parse(xd.InnerXml);
dataInstaller.ImportDocumentType(element, userId); _packageDataInstallation.ImportDocumentType(element, userId);
// Try to clean up the temporary file. // Try to clean up the temporary file.
try try

View File

@@ -479,7 +479,7 @@ namespace Umbraco.Web.BackOffice.Controllers
{ {
// Authorize... // Authorize...
var requirement = new MediaPermissionsResourceRequirement(); var requirement = new MediaPermissionsResourceRequirement();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, _mediaService.GetById(move.Id), requirement); var authorizationResult = await _authorizationService.AuthorizeAsync(User, new MediaPermissionsResource(_mediaService.GetById(move.Id)), requirement);
if (!authorizationResult.Succeeded) if (!authorizationResult.Succeeded)
{ {
return Forbid(); return Forbid();

View File

@@ -13,11 +13,9 @@ using Umbraco.Core.Hosting;
using Umbraco.Core.Models.Packaging; using Umbraco.Core.Models.Packaging;
using Umbraco.Core.Security; using Umbraco.Core.Security;
using Umbraco.Core.Services; using Umbraco.Core.Services;
using Umbraco.Web.BackOffice.Filters;
using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Common.Authorization; using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Common.Exceptions;
using Umbraco.Web.Security;
namespace Umbraco.Web.BackOffice.Controllers namespace Umbraco.Web.BackOffice.Controllers
{ {
@@ -105,7 +103,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (package == null) if (package == null)
return NotFound(); return NotFound();
var fullPath = _hostingEnvironment.MapPathContentRoot(package.PackagePath); var fullPath = _hostingEnvironment.MapPathWebRoot(package.PackagePath);
if (!System.IO.File.Exists(fullPath)) if (!System.IO.File.Exists(fullPath))
throw HttpResponseException.CreateNotificationValidationErrorResponse("No file found for path " + package.PackagePath); throw HttpResponseException.CreateNotificationValidationErrorResponse("No file found for path " + package.PackagePath);

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Threading;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Umbraco.Net; using Umbraco.Net;
@@ -21,16 +20,6 @@ namespace Umbraco.Web.Common.AspNetCore
public void Restart() public void Restart()
{ {
IsRestarting = true; IsRestarting = true;
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext != null)
{
// unload app domain - we must null out all identities otherwise we get serialization errors
// http://www.zpqrtbnk.net/posts/custom-iidentity-serialization-issue
httpContext.User = null;
}
Thread.CurrentPrincipal = null;
_hostApplicationLifetime.StopApplication(); _hostApplicationLifetime.StopApplication();
} }

View File

@@ -16,6 +16,7 @@
vm.filesOpen = true; vm.filesOpen = true;
vm.actionsOpen = true; vm.actionsOpen = true;
vm.loading = true; vm.loading = true;
vm.mediaNodeDisplayModels = [];
vm.back = back; vm.back = back;
vm.createOrUpdatePackage = createOrUpdatePackage; vm.createOrUpdatePackage = createOrUpdatePackage;
vm.removeContentItem = removeContentItem; vm.removeContentItem = removeContentItem;
@@ -28,6 +29,7 @@
vm.contributorsEditor = null; vm.contributorsEditor = null;
vm.selectDocumentType = selectDocumentType; vm.selectDocumentType = selectDocumentType;
vm.selectMediaType = selectMediaType;
vm.selectTemplate = selectTemplate; vm.selectTemplate = selectTemplate;
vm.selectStyleSheet = selectStyleSheet; vm.selectStyleSheet = selectStyleSheet;
vm.selectMacro = selectMacro; vm.selectMacro = selectMacro;
@@ -35,6 +37,15 @@
vm.selectDictionaryItem = selectDictionaryItem; vm.selectDictionaryItem = selectDictionaryItem;
vm.selectDataType = selectDataType; vm.selectDataType = selectDataType;
vm.mediaPickerModel = {
hideLabel: true,
view: "mediapicker",
value: "",
config: {
multiPicker: true,
allowEdit:false
}
}
vm.labels = {}; vm.labels = {};
vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/; vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/;
@@ -76,6 +87,7 @@
}); });
} }
vm.mediaPickerModel.value = vm.package.mediaUdis.join(',');
}); });
@@ -88,20 +100,31 @@
function loadResources() { function loadResources() {
// Get all document types // Get all document types
entityResource.getAll("DocumentType").then(documentTypes => { entityResource.getAll("DocumentType").then(documentTypes => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
documentTypes.forEach(documentType => { documentTypes.forEach(documentType => {
documentType.id = documentType.id.toString(); documentType.id = documentType.id.toString();
documentType.selected = vm.package.documentTypes.indexOf(documentType.id) !== -1; documentType.selected = vm.package.documentTypes.indexOf(documentType.id) !== -1;
});
vm.documentTypes = documentTypes;
}); });
vm.documentTypes = documentTypes;
});
// Get all media types
entityResource.getAll("MediaType").then(mediaTypes => {
// a package stores the id as a string so we
// need to convert all ids to string for comparison
mediaTypes.forEach(mediaType => {
mediaType.id = mediaType.id.toString();
mediaType.selected = vm.package.mediaTypes.indexOf(mediaType.id) !== -1;
});
vm.mediaTypes = mediaTypes;
});
// Get all templates // Get all templates
entityResource.getAll("Template").then(templates => { entityResource.getAll("Template").then(templates => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
templates.forEach(template => { templates.forEach(template => {
template.id = template.id.toString(); template.id = template.id.toString();
@@ -120,7 +143,7 @@
// Get all macros // Get all macros
entityResource.getAll("Macro").then(macros => { entityResource.getAll("Macro").then(macros => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
macros.forEach(macro => { macros.forEach(macro => {
macro.id = macro.id.toString(); macro.id = macro.id.toString();
@@ -131,7 +154,7 @@
// Get all languages // Get all languages
entityResource.getAll("Language").then(languages => { entityResource.getAll("Language").then(languages => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
languages.forEach(language => { languages.forEach(language => {
language.id = language.id.toString(); language.id = language.id.toString();
@@ -142,7 +165,7 @@
// Get all dictionary items // Get all dictionary items
entityResource.getAll("DictionaryItem").then(dictionaryItems => { entityResource.getAll("DictionaryItem").then(dictionaryItems => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
dictionaryItems.forEach(dictionaryItem => { dictionaryItems.forEach(dictionaryItem => {
dictionaryItem.id = dictionaryItem.id.toString(); dictionaryItem.id = dictionaryItem.id.toString();
@@ -153,7 +176,7 @@
// Get all data types // Get all data types
entityResource.getAll("DataType").then(dataTypes => { entityResource.getAll("DataType").then(dataTypes => {
// a package stores the id as a string so we // a package stores the id as a string so we
// need to convert all ids to string for comparison // need to convert all ids to string for comparison
dataTypes.forEach(dataType => { dataTypes.forEach(dataType => {
dataType.id = dataType.id.toString(); dataType.id = dataType.id.toString();
@@ -181,10 +204,12 @@
function createOrUpdatePackage(editPackageForm) { function createOrUpdatePackage(editPackageForm) {
let contributors = vm.contributorsEditor.value.map(o => o.value); let contributors = vm.contributorsEditor.value.map(o => o.value)
vm.package.contributors = contributors; vm.package.contributors = contributors;
// Split by comma and remove empty entries
vm.package.mediaUdis = vm.mediaPickerModel.value.split(",").filter(i => i);
if (formHelper.submitForm({ formCtrl: editPackageForm, scope: $scope })) { if (formHelper.submitForm({ formCtrl: editPackageForm, scope: $scope })) {
vm.buttonState = "busy"; vm.buttonState = "busy";
@@ -215,23 +240,23 @@
vm.package.contentNodeId = null; vm.package.contentNodeId = null;
} }
function openContentPicker() { function openContentPicker() {
const contentPicker = { const contentPicker = {
submit: function (model) { submit: function (model) {
if (model.selection && model.selection.length > 0) { if (model.selection && model.selection.length > 0) {
vm.package.contentNodeId = model.selection[0].id.toString(); vm.package.contentNodeId = model.selection[0].id.toString();
vm.contentNodeDisplayModel = model.selection[0]; vm.contentNodeDisplayModel = model.selection[0];
} }
editorService.close(); editorService.close();
}, },
close: function () { close: function () {
editorService.close(); editorService.close();
} }
}; };
editorService.contentPicker(contentPicker); editorService.contentPicker(contentPicker);
} }
function openFilePicker() { function openFilePicker() {
let selection = Utilities.copy(vm.package.files); let selection = Utilities.copy(vm.package.files);
@@ -313,6 +338,18 @@
} }
} }
function selectMediaType(mediatype) {
// Check if the document type is already selected.
var index = vm.package.mediaTypes.indexOf(mediatype.id);
if (index === -1) {
vm.package.mediaTypes.push(mediatype.id);
} else {
vm.package.mediaTypes.splice(index, 1);
}
}
function selectTemplate(template) { function selectTemplate(template) {
// Check if the template is already selected. // Check if the template is already selected.

View File

@@ -137,6 +137,22 @@
</umb-control-group> </umb-control-group>
<umb-control-group label="@general_media">
<umb-property property="vm.mediaPickerModel" ng-if="vm.loading === false">
<umb-property-editor model="vm.mediaPickerModel" is-pre-value="true"></umb-property-editor>
</umb-property>
<umb-checkbox model="vm.package.mediaLoadChildNodes"
disabled="vm.mediaPickerModel.value.length === 0"
text="{{vm.labels.includeAllChildNodes}}">
</umb-checkbox>
</umb-control-group>
<umb-control-group label="@treeHeaders_documentTypes"> <umb-control-group label="@treeHeaders_documentTypes">
<div ng-repeat="doctype in ::vm.documentTypes | orderBy:'name'"> <div ng-repeat="doctype in ::vm.documentTypes | orderBy:'name'">
<umb-checkbox model="doctype.selected" <umb-checkbox model="doctype.selected"
@@ -146,11 +162,20 @@
</div> </div>
</umb-control-group> </umb-control-group>
<umb-control-group label="@treeHeaders_mediaTypes">
<div ng-repeat="mediatype in ::vm.mediaTypes | orderBy:'name'">
<umb-checkbox model="mediatype.selected"
on-change="vm.selectMediaType(mediatype)"
text="{{mediatype.name}}">
</umb-checkbox>
</div>
</umb-control-group>
<umb-control-group label="@treeHeaders_templates"> <umb-control-group label="@treeHeaders_templates">
<div ng-repeat="template in ::vm.templates | orderBy:'name'"> <div ng-repeat="template in ::vm.templates | orderBy:'name'">
<umb-checkbox model="template.selected" <umb-checkbox model="template.selected"
on-change="vm.selectTemplate(template)" on-change="vm.selectTemplate(template)"
text="{{template.name}}"> text="{{template.name}}">umb-expansion-panel__content
</umb-checkbox> </umb-checkbox>
</div> </div>
</umb-control-group> </umb-control-group>

View File

@@ -22,6 +22,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="App_Plugins" />
<Folder Include="scripts" /> <Folder Include="scripts" />
<Folder Include="umbraco\MediaCache\2\c\6\9\3\a\6\5" /> <Folder Include="umbraco\MediaCache\2\c\6\9\3\a\6\5" />
<Folder Include="umbraco\MediaCache\a\e\e\1\9\e\4\b" /> <Folder Include="umbraco\MediaCache\a\e\e\1\9\e\4\b" />

View File

@@ -730,6 +730,7 @@
<key alias="logout">Logout</key> <key alias="logout">Logout</key>
<key alias="macro">Macro</key> <key alias="macro">Macro</key>
<key alias="mandatory">Mandatory</key> <key alias="mandatory">Mandatory</key>
<key alias="media">Media</key>
<key alias="message">Message</key> <key alias="message">Message</key>
<key alias="move">Move</key> <key alias="move">Move</key>
<key alias="name">Name</key> <key alias="name">Name</key>