diff --git a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs index 1b77aaa7d6..6133d63377 100644 --- a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs +++ b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Components; using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Packaging; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; @@ -56,6 +57,12 @@ namespace Umbraco.Core.Composing.Composers factory.GetInstance>(), factory.GetInstance())); + composition.RegisterUnique(); + + composition.RegisterUnique(); + composition.RegisterUnique(); + + //TODO: These are replaced in the web project - we need to declare them so that // something is wired up, just not sure this is very nice but will work for now. composition.RegisterUnique(); diff --git a/src/Umbraco.Core/Composing/Current.cs b/src/Umbraco.Core/Composing/Current.cs index cf67409925..4bed76d86f 100644 --- a/src/Umbraco.Core/Composing/Current.cs +++ b/src/Umbraco.Core/Composing/Current.cs @@ -5,6 +5,7 @@ using Umbraco.Core.Dictionary; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Packaging; using Umbraco.Core.Persistence; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; @@ -161,6 +162,9 @@ namespace Umbraco.Core.Composing internal static PackageActionCollection PackageActions => Factory.GetInstance(); + internal static PackageActionRunner PackageActionRunner + => Factory.GetInstance(); + internal static PropertyValueConverterCollection PropertyValueConverters => Factory.GetInstance(); diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index 5e2d44c90d..8c27c23604 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -308,84 +308,45 @@ namespace Umbraco.Core /// Creates the full xml representation for the object and all of it's descendants /// /// to generate xml for - /// + /// /// Xml representation of the passed in - internal static XElement ToDeepXml(this IContent content, IPackagingService packagingService) + internal static XElement ToDeepXml(this IContent content, IEntityXmlSerializer serializer) { - return packagingService.Export(content, true, raiseEvents: false); - } - - - [Obsolete("Use the overload that declares the IPackagingService to use")] - public static XElement ToXml(this IContent content) - { - return Current.Services.PackagingService.Export(content, raiseEvents: false); + return serializer.Serialize(content, false, true); } /// /// Creates the xml representation for the object /// /// to generate xml for - /// + /// /// Xml representation of the passed in - public static XElement ToXml(this IContent content, IPackagingService packagingService) + public static XElement ToXml(this IContent content, IEntityXmlSerializer serializer) { - return packagingService.Export(content, raiseEvents: false); - } - - [Obsolete("Use the overload that declares the IPackagingService to use")] - public static XElement ToXml(this IMedia media) - { - return Current.Services.PackagingService.Export(media, raiseEvents: false); + return serializer.Serialize(content, false, false); } + /// /// Creates the xml representation for the object /// /// to generate xml for - /// + /// /// Xml representation of the passed in - public static XElement ToXml(this IMedia media, IPackagingService packagingService) + public static XElement ToXml(this IMedia media, IEntityXmlSerializer serializer) { - return packagingService.Export(media, raiseEvents: false); + return serializer.Serialize(media); } - /// - /// Creates the full xml representation for the object and all of it's descendants - /// - /// to generate xml for - /// - /// Xml representation of the passed in - internal static XElement ToDeepXml(this IMedia media, IPackagingService packagingService) - { - return packagingService.Export(media, true, raiseEvents: false); - } - - - /// - /// Creates the xml representation for the object - /// - /// to generate xml for - /// - /// Boolean indicating whether the xml should be generated for preview - /// Xml representation of the passed in - public static XElement ToXml(this IContent content, IPackagingService packagingService, bool isPreview) - { - //TODO Do a proper implementation of this - //If current IContent is published we should get latest unpublished version - return content.ToXml(packagingService); - } - - /// /// Creates the xml representation for the object /// /// to generate xml for - /// + /// /// Xml representation of the passed in - public static XElement ToXml(this IMember member, IPackagingService packagingService) + public static XElement ToXml(this IMember member, IEntityXmlSerializer serializer) { - return ((PackagingService)(packagingService)).Export(member); + return serializer.Serialize(member); } #endregion diff --git a/src/Umbraco.Core/Events/ExportEventArgs.cs b/src/Umbraco.Core/Events/ExportEventArgs.cs deleted file mode 100644 index f46cccf05c..0000000000 --- a/src/Umbraco.Core/Events/ExportEventArgs.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Xml.Linq; - -namespace Umbraco.Core.Events -{ - public class ExportEventArgs : CancellableObjectEventArgs>, IEquatable> - { - /// - /// Constructor accepting a single entity instance - /// - /// - /// - /// - public ExportEventArgs(TEntity eventObject, XElement xml, bool canCancel) - : base(new List { eventObject }, canCancel) - { - Xml = xml; - } - - /// - /// Constructor accepting a single entity instance - /// and cancellable by default - /// - /// - /// - public ExportEventArgs(TEntity eventObject, string elementName) : base(new List {eventObject}, true) - { - Xml = new XElement(elementName); - } - - protected ExportEventArgs(IEnumerable eventObject, bool canCancel) : base(eventObject, canCancel) - { - } - - protected ExportEventArgs(IEnumerable eventObject) : base(eventObject) - { - } - - /// - /// Returns all entities that were exported during the operation - /// - public IEnumerable ExportedEntities - { - get { return EventObject; } - } - - /// - /// Returns the xml relating to the export event - /// - public XElement Xml { get; private set; } - - public bool Equals(ExportEventArgs other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return base.Equals(other) && Equals(Xml, other.Xml); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((ExportEventArgs) obj); - } - - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ (Xml != null ? Xml.GetHashCode() : 0); - } - } - - public static bool operator ==(ExportEventArgs left, ExportEventArgs right) - { - return Equals(left, right); - } - - public static bool operator !=(ExportEventArgs left, ExportEventArgs right) - { - return !Equals(left, right); - } - } -} diff --git a/src/Umbraco.Core/Models/Packaging/ActionRunAt.cs b/src/Umbraco.Core/Models/Packaging/ActionRunAt.cs new file mode 100644 index 0000000000..0023d4dbed --- /dev/null +++ b/src/Umbraco.Core/Models/Packaging/ActionRunAt.cs @@ -0,0 +1,9 @@ +namespace Umbraco.Core.Models.Packaging +{ + public enum ActionRunAt + { + Undefined = 0, + Install, + Uninstall + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Packaging/InstallationSummary.cs b/src/Umbraco.Core/Models/Packaging/InstallationSummary.cs index 3eb397d728..39df529300 100644 --- a/src/Umbraco.Core/Models/Packaging/InstallationSummary.cs +++ b/src/Umbraco.Core/Models/Packaging/InstallationSummary.cs @@ -21,23 +21,4 @@ namespace Umbraco.Core.Models.Packaging public IEnumerable Actions { get; set; } public bool PackageInstalled { get; set; } } - - internal static class InstallationSummaryExtentions - { - public static InstallationSummary InitEmpty(this InstallationSummary summary) - { - summary.Actions = new List(); - summary.ContentInstalled = new List(); - summary.ContentTypesInstalled = new List(); - summary.DataTypesInstalled = new List(); - summary.DictionaryItemsInstalled = new List(); - summary.FilesInstalled = new List(); - summary.LanguagesInstalled = new List(); - summary.MacrosInstalled = new List(); - summary.MetaData = new MetaData(); - summary.TemplatesInstalled = new List(); - summary.PackageInstalled = false; - return summary; - } - } } diff --git a/src/Umbraco.Core/Models/Packaging/InstallationSummaryExtentions.cs b/src/Umbraco.Core/Models/Packaging/InstallationSummaryExtentions.cs new file mode 100644 index 0000000000..3b969d84dc --- /dev/null +++ b/src/Umbraco.Core/Models/Packaging/InstallationSummaryExtentions.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace Umbraco.Core.Models.Packaging +{ + internal static class InstallationSummaryExtentions + { + public static InstallationSummary InitEmpty(this InstallationSummary summary) + { + summary.Actions = new List(); + summary.ContentInstalled = new List(); + summary.ContentTypesInstalled = new List(); + summary.DataTypesInstalled = new List(); + summary.DictionaryItemsInstalled = new List(); + summary.FilesInstalled = new List(); + summary.LanguagesInstalled = new List(); + summary.MacrosInstalled = new List(); + summary.MetaData = new MetaData(); + summary.TemplatesInstalled = new List(); + summary.PackageInstalled = false; + return summary; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Packaging/PackageAction.cs b/src/Umbraco.Core/Models/Packaging/PackageAction.cs index e941c5729a..ab7b120eae 100644 --- a/src/Umbraco.Core/Models/Packaging/PackageAction.cs +++ b/src/Umbraco.Core/Models/Packaging/PackageAction.cs @@ -4,13 +4,9 @@ using System.Xml.Linq; namespace Umbraco.Core.Models.Packaging { - public enum ActionRunAt - { - Undefined = 0, - Install, - Uninstall - } - + /// + /// Defines a package action declared within a package manifest + /// [Serializable] [DataContract(IsReference = true)] public class PackageAction diff --git a/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs new file mode 100644 index 0000000000..783b11235f --- /dev/null +++ b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; + +namespace Umbraco.Core.Models.Packaging +{ + [DataContract(Name = "packageInstance")] + public class PackageDefinition + { + [DataMember(Name = "id")] + public int Id { get; set; } + + //TODO: I don't see why this is necessary + [DataMember(Name = "repositoryGuid")] + public string RepositoryGuid { get; set; } + + [DataMember(Name = "packageGuid")] + public string PackageGuid { get; set; } + + [DataMember(Name = "hasUpdate")] + public bool HasUpdate { get; set; } + + [DataMember(Name = "name")] + [Required] + public string Name { get; set; } = string.Empty; + + [DataMember(Name = "url")] + [Required] + [Url] + public string Url { get; set; } = string.Empty; + + [DataMember(Name = "folder")] + public string Folder { get; set; } = string.Empty; + + [DataMember(Name = "packagePath")] + public string PackagePath { get; set; } = string.Empty; + + [DataMember(Name = "version")] + [Required] + public string Version { get; set; } = string.Empty; + + /// + /// The minimum umbraco version that this package requires + /// + [DataMember(Name = "umbracoVersion")] + public Version UmbracoVersion { get; set; } + + [DataMember(Name = "author")] + [Required] + public string Author { get; set; } = string.Empty; + + [DataMember(Name = "authorUrl")] + [Required] + [Url] + public string AuthorUrl { get; set; } = string.Empty; + + [DataMember(Name = "license")] + public string License { get; set; } = "MIT License"; + + [DataMember(Name = "licenseUrl")] + public string LicenseUrl { get; set; } = "http://opensource.org/licenses/MIT"; + + [DataMember(Name = "readme")] + public string Readme { get; set; } = string.Empty; + + [DataMember(Name = "contentLoadChildNodes")] + public bool ContentLoadChildNodes { get; set; } = false; + + [DataMember(Name = "contentNodeId")] + public string ContentNodeId { get; set; } = string.Empty; + + [DataMember(Name = "macros")] + public List Macros { get; set; } = new List(); + + [DataMember(Name = "languages")] + public List Languages { get; set; } = new List(); + + [DataMember(Name = "dictionaryItems")] + public List DictionaryItems { get; set; } = new List(); + + [DataMember(Name = "templates")] + public List Templates { get; set; } = new List(); + + [DataMember(Name = "documentTypes")] + public List DocumentTypes { get; set; } = new List(); + + [DataMember(Name = "stylesheets")] + public List Stylesheets { get; set; } = new List(); + + [DataMember(Name = "files")] + public List Files { get; set; } = new List(); + + //TODO: Change this to angular view + [DataMember(Name = "loadControl")] + public string LoadControl { get; set; } = string.Empty; + + [DataMember(Name = "actions")] + public string Actions { get; set; } + + [DataMember(Name = "dataTypes")] + public List DataTypes { get; set; } = new List(); + + [DataMember(Name = "iconUrl")] + public string IconUrl { get; set; } = string.Empty; + + } +} diff --git a/src/Umbraco.Core/Packaging/Models/UninstallationSummary.cs b/src/Umbraco.Core/Models/Packaging/UninstallationSummary.cs similarity index 50% rename from src/Umbraco.Core/Packaging/Models/UninstallationSummary.cs rename to src/Umbraco.Core/Models/Packaging/UninstallationSummary.cs index 1c31283ee8..cfa454f91c 100644 --- a/src/Umbraco.Core/Packaging/Models/UninstallationSummary.cs +++ b/src/Umbraco.Core/Models/Packaging/UninstallationSummary.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Packaging; -namespace Umbraco.Core.Packaging.Models +namespace Umbraco.Core.Models.Packaging { [Serializable] [DataContract(IsReference = true)] @@ -22,22 +20,4 @@ namespace Umbraco.Core.Packaging.Models public IEnumerable ContentUninstalled { get; set; } public bool PackageUninstalled { get; set; } } - - internal static class UninstallationSummaryExtentions - { - public static UninstallationSummary InitEmpty(this UninstallationSummary summary) - { - summary.ContentUninstalled = new List(); - summary.ContentTypesUninstalled = new List(); - summary.DataTypesUninstalled = new List(); - summary.DictionaryItemsUninstalled = new List(); - summary.FilesUninstalled = new List(); - summary.LanguagesUninstalled = new List(); - summary.MacrosUninstalled = new List(); - summary.MetaData = new MetaData(); - summary.TemplatesUninstalled = new List(); - summary.PackageUninstalled = false; - return summary; - } - } } diff --git a/src/Umbraco.Core/Models/Packaging/UninstallationSummaryExtentions.cs b/src/Umbraco.Core/Models/Packaging/UninstallationSummaryExtentions.cs new file mode 100644 index 0000000000..688b78fa1f --- /dev/null +++ b/src/Umbraco.Core/Models/Packaging/UninstallationSummaryExtentions.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +namespace Umbraco.Core.Models.Packaging +{ + internal static class UninstallationSummaryExtentions + { + public static UninstallationSummary InitEmpty(this UninstallationSummary summary) + { + summary.ContentUninstalled = new List(); + summary.ContentTypesUninstalled = new List(); + summary.DataTypesUninstalled = new List(); + summary.DictionaryItemsUninstalled = new List(); + summary.FilesUninstalled = new List(); + summary.LanguagesUninstalled = new List(); + summary.MacrosUninstalled = new List(); + summary.MetaData = new MetaData(); + summary.TemplatesUninstalled = new List(); + summary.PackageUninstalled = false; + return summary; + } + } +} diff --git a/src/Umbraco.Core/Packaging/IPackageCreation.cs b/src/Umbraco.Core/Packaging/IPackageCreation.cs new file mode 100644 index 0000000000..35397299a7 --- /dev/null +++ b/src/Umbraco.Core/Packaging/IPackageCreation.cs @@ -0,0 +1,22 @@ +using Umbraco.Core.Models.Packaging; + +namespace Umbraco.Core.Packaging +{ + /// + /// Creates packages + /// + public interface IPackageCreation + { + /// + /// Persists a package definition to storage + /// + /// + void SavePackageDefinition(PackageDefinition definition); + + /// + /// Creates the package file and returns it's physical path + /// + /// + string ExportPackageDefinition(PackageDefinition definition); + } +} diff --git a/src/Umbraco.Core/Packaging/IPackageInstallation.cs b/src/Umbraco.Core/Packaging/IPackageInstallation.cs index 1d0d46355c..6dc4f0fd4e 100644 --- a/src/Umbraco.Core/Packaging/IPackageInstallation.cs +++ b/src/Umbraco.Core/Packaging/IPackageInstallation.cs @@ -5,6 +5,9 @@ namespace Umbraco.Core.Packaging { internal interface IPackageInstallation { + //fixme: The reason why this isn't used currently is because package installation needs to be done in phases since + // there are app domain reboots involved so a single method cannot be used. This needs to either be split into several + // methods or return an object with a callback to proceed to the next step. InstallationSummary InstallPackage(string packageFilePath, int userId); MetaData GetMetaData(string packageFilePath); PreInstallWarnings GetPreInstallWarnings(string packageFilePath); diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs b/src/Umbraco.Core/Packaging/PackageActionRunner.cs similarity index 58% rename from src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs rename to src/Umbraco.Core/Packaging/PackageActionRunner.cs index bfd1030d85..c7545bdae8 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs +++ b/src/Umbraco.Core/Packaging/PackageActionRunner.cs @@ -1,17 +1,24 @@ using System; using System.Xml; -using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core._Legacy.PackageActions; -namespace Umbraco.Web._Legacy.Packager.PackageInstance +namespace Umbraco.Core.Packaging { /// /// Package actions are executed on packge install / uninstall. /// - public class PackageAction + public sealed class PackageActionRunner { + private readonly ILogger _logger; + private readonly PackageActionCollection _packageActions; + + public PackageActionRunner(ILogger logger, PackageActionCollection packageActions) + { + _logger = logger; + _packageActions = packageActions; + } /// /// Runs the package action with the specified action alias. @@ -19,22 +26,19 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance /// Name of the package. /// The action alias. /// The action XML. - public static void RunPackageAction(string packageName, string actionAlias, XmlNode actionXml) + public void RunPackageAction(string packageName, string actionAlias, XmlNode actionXml) { - foreach (var ipa in Current.PackageActions) + foreach (var ipa in _packageActions) { try { if (ipa.Alias() == actionAlias) - { - ipa.Execute(packageName, actionXml); - } } catch (Exception ex) { - Current.Logger.Error(ex, "Error loading package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); + _logger.Error(ex, "Error loading package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); } } } @@ -45,22 +49,18 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance /// Name of the package. /// The action alias. /// The action XML. - public static void UndoPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml) + public void UndoPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml) { - - foreach (IPackageAction ipa in Current.PackageActions) + foreach (var ipa in _packageActions) { try { if (ipa.Alias() == actionAlias) - { - ipa.Undo(packageName, actionXml); - } } catch (Exception ex) { - Current.Logger.Error(ex, "Error undoing package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); + _logger.Error(ex, "Error undoing package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); } } } diff --git a/src/Umbraco.Core/Packaging/PackageCreation.cs b/src/Umbraco.Core/Packaging/PackageCreation.cs new file mode 100644 index 0000000000..615b844101 --- /dev/null +++ b/src/Umbraco.Core/Packaging/PackageCreation.cs @@ -0,0 +1,564 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Xml.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Services; +using File = System.IO.File; + +namespace Umbraco.Core.Packaging +{ + internal class PackageCreation : IPackageCreation + { + private readonly IContentService _contentService; + private readonly IContentTypeService _contentTypeService; + private readonly IDataTypeService _dataTypeService; + private readonly IFileService _fileService; + private readonly IMacroService _macroService; + private readonly ILocalizationService _languageService; + private readonly IEntityXmlSerializer _serializer; + private readonly ILogger _logger; + + public PackageCreation(IContentService contentService, IContentTypeService contentTypeService, + IDataTypeService dataTypeService, IFileService fileService, IMacroService macroService, + ILocalizationService languageService, + IEntityXmlSerializer serializer, ILogger logger) + { + _contentService = contentService; + _contentTypeService = contentTypeService; + _dataTypeService = dataTypeService; + _fileService = fileService; + _macroService = macroService; + _languageService = languageService; + _serializer = serializer; + _logger = logger; + } + + public static string CreatedPackagesFile => SystemDirectories.Packages + IOHelper.DirSepChar + "createdPackages.config"; + + public void SavePackageDefinition(PackageDefinition definition) + { + if (definition == null) throw new ArgumentNullException(nameof(definition)); + + var packagesXml = EnsureStorage(out var packagesFile); + + if (definition.Id == default) + { + //need to gen an id and persist + // Find max id + var maxId = packagesXml.Root.Elements("package").Max(x => x.AttributeValue("id")); + var newId = maxId + 1; + definition.Id = newId; + definition.PackageGuid = Guid.NewGuid().ToString(); + definition.Folder = Guid.NewGuid().ToString(); + var packageXml = PackageDefinitionToXml(definition); + packagesXml.Add(packageXml); + } + else + { + //existing + var packageXml = packagesXml.Root.Elements("package").FirstOrDefault(x => x.AttributeValue("id") == definition.Id); + if (packageXml == null) + throw new InvalidOperationException($"The package with id {definition.Id} was not found"); + + var updatedXml = PackageDefinitionToXml(definition); + packageXml.ReplaceWith(updatedXml); + } + + packagesXml.Save(packagesFile); + } + + public string ExportPackageDefinition(PackageDefinition definition) + { + if (definition.Id == default) throw new ArgumentException("The package definition does not have an ID, it must be saved before being exported"); + if (definition.PackageGuid.IsNullOrWhiteSpace()) throw new ArgumentException("the package definition does not have a GUID, it must be saved before being exported"); + + //Create a folder for building this package + var temporaryPath = IOHelper.MapPath(SystemDirectories.Data + "/TEMP/PackageFiles/" + definition.Folder); + if (Directory.Exists(temporaryPath) == false) + Directory.CreateDirectory(temporaryPath); + + try + { + //Init package file + var packageManifest = CreatePackageManifest(out var manifestRoot, out var filesXml); + + //Info section + packageManifest.Add(GetPackageInfoXml(definition)); + + PackageDocumentsAndTags(definition, manifestRoot); + PackageDocumentTypes(definition, manifestRoot); + PackageTemplates(definition, manifestRoot); + PackageStylesheets(definition, manifestRoot); + PackageMacros(definition, manifestRoot, filesXml, temporaryPath); + PackageDictionaryItems(definition, manifestRoot); + PackageLanguages(definition, manifestRoot); + PackageDataTypes(definition, manifestRoot); + + //Files + foreach (var fileName in definition.Files) + AppendFileToManifest(fileName, temporaryPath, filesXml); + + //Load control on install... + if (!string.IsNullOrEmpty(definition.LoadControl)) + { + var control = new XElement("control", definition.LoadControl); + AppendFileToManifest(definition.LoadControl, temporaryPath, filesXml); + manifestRoot.Add(control); + } + + //Actions + if (string.IsNullOrEmpty(definition.Actions) == false) + { + var actionsXml = new XElement("Actions"); + try + { + actionsXml.Add(XElement.Parse(definition.Actions)); + manifestRoot.Add(actionsXml); + } + catch (Exception e) + { + _logger.Warn(e, "Could not add package actions to the package manifest, the xml did not parse"); + } + } + + var manifestFileName = temporaryPath + "/package.xml"; + + if (File.Exists(manifestFileName)) + File.Delete(manifestFileName); + + packageManifest.Save(manifestFileName); + + // check if there's a packages directory below media + var packagesDirectory = SystemDirectories.Media + "/created-packages"; + if (Directory.Exists(IOHelper.MapPath(packagesDirectory)) == false) + Directory.CreateDirectory(IOHelper.MapPath(packagesDirectory)); + + var packPath = packagesDirectory + "/" + (definition.Name + "_" + definition.Version).Replace(' ', '_') + ".zip"; + ZipPackage(temporaryPath, IOHelper.MapPath(packPath)); + + return packPath; + } + finally + { + //Clean up + Directory.Delete(temporaryPath, true); + } + } + + private void PackageDataTypes(PackageDefinition definition, XContainer manifestRoot) + { + var dataTypes = new XElement("DataTypes"); + foreach (var dtId in definition.DataTypes) + { + if (!int.TryParse(dtId, out var outInt)) continue; + var dataType = _dataTypeService.GetDataType(outInt); + if (dataType == null) continue; + dataTypes.Add(_serializer.Serialize(dataType)); + } + manifestRoot.Add(dataTypes); + } + + private void PackageLanguages(PackageDefinition definition, XContainer manifestRoot) + { + var languages = new XElement("Languages"); + foreach (var langId in definition.Languages) + { + if (!int.TryParse(langId, out var outInt)) continue; + var lang = _languageService.GetLanguageById(outInt); + if (lang == null) continue; + languages.Add(_serializer.Serialize(lang)); + } + manifestRoot.Add(languages); + } + + private void PackageDictionaryItems(PackageDefinition definition, XContainer manifestRoot) + { + var dictionaryItems = new XElement("DictionaryItems"); + foreach (var dictionaryId in definition.DictionaryItems) + { + if (!int.TryParse(dictionaryId, out var outInt)) continue; + var di = _languageService.GetDictionaryItemById(outInt); + if (di == null) continue; + dictionaryItems.Add(_serializer.Serialize(di, false)); + } + manifestRoot.Add(dictionaryItems); + } + + private void PackageMacros(PackageDefinition definition, XContainer manifestRoot, XContainer filesXml, string temporaryPath) + { + var macros = new XElement("Macros"); + foreach (var macroId in definition.Macros) + { + if (!int.TryParse(macroId, out var outInt)) continue; + + var macroXml = GetMacroXml(outInt, out var macro); + if (macroXml == null) continue; + macros.Add(macroXml); + //if the macro has a file copy it to the manifest + if (!string.IsNullOrEmpty(macro.MacroSource)) + AppendFileToManifest(macro.MacroSource, temporaryPath, filesXml); + } + manifestRoot.Add(macros); + } + + private void PackageStylesheets(PackageDefinition definition, XContainer manifestRoot) + { + var stylesheetsXml = new XElement("Stylesheets"); + foreach (var stylesheetName in definition.Stylesheets) + { + if (stylesheetName.IsNullOrWhiteSpace()) continue; + var xml = GetStylesheetXml(stylesheetName, true); + if (xml != null) + stylesheetsXml.Add(xml); + } + manifestRoot.Add(stylesheetsXml); + } + + private void PackageTemplates(PackageDefinition definition, XContainer manifestRoot) + { + var templatesXml = new XElement("Templates"); + foreach (var templateId in definition.Templates) + { + if (!int.TryParse(templateId, out var outInt)) continue; + var template = _fileService.GetTemplate(outInt); + if (template == null) continue; + templatesXml.Add(_serializer.Serialize(template)); + } + manifestRoot.Add(templatesXml); + } + + private void PackageDocumentTypes(PackageDefinition definition, XContainer manifestRoot) + { + var contentTypes = new HashSet(); + var docTypesXml = new XElement("DocumentTypes"); + foreach (var dtId in definition.DocumentTypes) + { + if (!int.TryParse(dtId, out var outInt)) continue; + var contentType = _contentTypeService.Get(outInt); + if (contentType == null) continue; + AddDocumentType(contentType, contentTypes); + } + foreach (var contentType in contentTypes) + docTypesXml.Add(_serializer.Serialize(contentType)); + + manifestRoot.Add(docTypesXml); + } + + private void PackageDocumentsAndTags(PackageDefinition definition, XContainer manifestRoot) + { + //Documents and tags + if (string.IsNullOrEmpty(definition.ContentNodeId) == false && int.TryParse(definition.ContentNodeId, out var contentNodeId)) + { + if (contentNodeId > 0) + { + //load content from umbraco. + var content = _contentService.GetById(contentNodeId); + if (content != null) + { + var contentXml = definition.ContentLoadChildNodes ? content.ToDeepXml(_serializer) : content.ToXml(_serializer); + + //Create the Documents/DocumentSet node + + manifestRoot.Add( + new XElement("Documents", + new XElement("DocumentSet", + new XAttribute("importMode", "root"), + contentXml))); + + //TODO: I guess tags has been broken for a very long time for packaging, we should get this working again sometime + ////Create the TagProperties node - this is used to store a definition for all + //// document properties that are tags, this ensures that we can re-import tags properly + //XmlNode tagProps = new XElement("TagProperties"); + + ////before we try to populate this, we'll do a quick lookup to see if any of the documents + //// being exported contain published tags. + //var allExportedIds = documents.SelectNodes("//@id").Cast() + // .Select(x => x.Value.TryConvertTo()) + // .Where(x => x.Success) + // .Select(x => x.Result) + // .ToArray(); + //var allContentTags = new List(); + //foreach (var exportedId in allExportedIds) + //{ + // allContentTags.AddRange( + // Current.Services.TagService.GetTagsForEntity(exportedId)); + //} + + ////This is pretty round-about but it works. Essentially we need to get the properties that are tagged + //// but to do that we need to lookup by a tag (string) + //var allTaggedEntities = new List(); + //foreach (var group in allContentTags.Select(x => x.Group).Distinct()) + //{ + // allTaggedEntities.AddRange( + // Current.Services.TagService.GetTaggedContentByTagGroup(group)); + //} + + ////Now, we have all property Ids/Aliases and their referenced document Ids and tags + //var allExportedTaggedEntities = allTaggedEntities.Where(x => allExportedIds.Contains(x.EntityId)) + // .DistinctBy(x => x.EntityId) + // .OrderBy(x => x.EntityId); + + //foreach (var taggedEntity in allExportedTaggedEntities) + //{ + // foreach (var taggedProperty in taggedEntity.TaggedProperties.Where(x => x.Tags.Any())) + // { + // XmlNode tagProp = new XElement("TagProperty"); + // var docId = packageManifest.CreateAttribute("docId", ""); + // docId.Value = taggedEntity.EntityId.ToString(CultureInfo.InvariantCulture); + // tagProp.Attributes.Append(docId); + + // var propertyAlias = packageManifest.CreateAttribute("propertyAlias", ""); + // propertyAlias.Value = taggedProperty.PropertyTypeAlias; + // tagProp.Attributes.Append(propertyAlias); + + // var group = packageManifest.CreateAttribute("group", ""); + // group.Value = taggedProperty.Tags.First().Group; + // tagProp.Attributes.Append(group); + + // tagProp.AppendChild(packageManifest.CreateCDataSection( + // JsonConvert.SerializeObject(taggedProperty.Tags.Select(x => x.Text).ToArray()))); + + // tagProps.AppendChild(tagProp); + // } + //} + + //manifestRoot.Add(tagProps); + } + } + } + } + + /// + /// Zips the package. + /// + /// The path. + /// The save path. + private static void ZipPackage(string path, string savePath) + { + ZipFile.CreateFromDirectory(path, savePath); + } + + /// + /// Appends a file to package manifest and copies the file to the correct folder. + /// + /// The path. + /// The package directory. + /// The files xml node + private static void AppendFileToManifest(string path, string packageDirectory, XContainer filesXml) + { + if (!path.StartsWith("~/") && !path.StartsWith("/")) + path = "~/" + path; + + var serverPath = IOHelper.MapPath(path); + + if (File.Exists(serverPath)) + AppendFileXml(new FileInfo(serverPath), path, packageDirectory, filesXml); + else if (Directory.Exists(serverPath)) + ProcessDirectory(new DirectoryInfo(serverPath), path, packageDirectory, filesXml); + } + + //Process files in directory and add them to package + private static void ProcessDirectory(DirectoryInfo directory, string dirPath, string packageDirectory, XContainer filesXml) + { + if (directory == null) throw new ArgumentNullException(nameof(directory)); + if (string.IsNullOrWhiteSpace(packageDirectory)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(packageDirectory)); + if (string.IsNullOrWhiteSpace(dirPath)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(dirPath)); + if (!directory.Exists) return; + + foreach (var file in directory.GetFiles()) + AppendFileXml(new FileInfo(Path.Combine(directory.FullName, file.Name)), dirPath + "/" + file.Name, packageDirectory, filesXml); + + foreach (var dir in directory.GetDirectories()) + ProcessDirectory(dir, dirPath + "/" + dir.Name, packageDirectory, filesXml); + } + + private static void AppendFileXml(FileInfo file, string filePath, string packageDirectory, XContainer filesXml) + { + if (file == null) throw new ArgumentNullException(nameof(file)); + if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(filePath)); + if (string.IsNullOrWhiteSpace(packageDirectory)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(packageDirectory)); + + var orgPath = filePath.Substring(0, (filePath.LastIndexOf('/'))); + var orgName = filePath.Substring((filePath.LastIndexOf('/') + 1)); + var newFileName = orgName; + + if (File.Exists(packageDirectory.EnsureEndsWith('/') + orgName)) + newFileName = Guid.NewGuid() + "_" + newFileName; + + //Copy file to directory for zipping... + File.Copy(file.FullName, packageDirectory + "/" + newFileName, true); + + filesXml.Add(new XElement("file", + new XElement("guid", newFileName), + new XElement("orgPath", orgPath == "" ? "/" : orgPath), + new XElement("orgName", orgName))); + } + + private XElement GetMacroXml(int macroId, out IMacro macro) + { + macro = _macroService.GetById(macroId); + if (macro == null) return null; + var xml = _serializer.Serialize(macro); + return xml; + } + + /// + /// Converts a umbraco stylesheet to a package xml node + /// + /// The name of the stylesheet. + /// if set to true [incluce properties]. + /// + private XElement GetStylesheetXml(string name, bool includeProperties) + { + if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(name)); +; + var sts = _fileService.GetStylesheetByName(name); + if (sts == null) return null; + var stylesheetXml = new XElement("Stylesheet"); + stylesheetXml.Add(new XElement("Name", sts.Alias)); + stylesheetXml.Add(new XElement("FileName", sts.Name)); + stylesheetXml.Add(new XElement("Content", new XCData(sts.Content))); + + if (!includeProperties) return stylesheetXml; + + var properties = new XElement("Properties"); + foreach (var ssP in sts.Properties) + { + var property = new XElement("Property"); + property.Add(new XElement("Name", ssP.Name)); + property.Add(new XElement("Alias", ssP.Alias)); + property.Add(new XElement("Value", ssP.Value)); + } + stylesheetXml.Add(properties); + return stylesheetXml; + } + + private void AddDocumentType(IContentType dt, HashSet dtl) + { + if (dt.ParentId > 0) + { + var parent = _contentTypeService.Get(dt.ParentId); + if (parent != null) // could be a container + AddDocumentType(parent, dtl); + } + + if (!dtl.Contains(dt)) + dtl.Add(dt); + } + + private static XElement GetPackageInfoXml(PackageDefinition definition) + { + var info = new XElement("info"); + + //Package info + var package = new XElement("package"); + package.Add(new XElement("name", definition.Name)); + package.Add(new XElement("version", definition.Version)); + package.Add(new XElement("iconUrl", definition.IconUrl)); + + var license = new XElement("license", definition.License); + license.Add(new XAttribute("url", definition.LicenseUrl)); + package.Add(license); + + package.Add(new XElement("url", definition.Url)); + + var requirements = new XElement("requirements"); + + requirements.Add(new XElement("major", definition.UmbracoVersion == null ? UmbracoVersion.SemanticVersion.Major.ToInvariantString() : definition.UmbracoVersion.Major.ToInvariantString())); + requirements.Add(new XElement("minor", definition.UmbracoVersion == null ? UmbracoVersion.SemanticVersion.Minor.ToInvariantString() : definition.UmbracoVersion.Minor.ToInvariantString())); + requirements.Add(new XElement("patch", definition.UmbracoVersion == null ? UmbracoVersion.SemanticVersion.Patch.ToInvariantString() : definition.UmbracoVersion.Build.ToInvariantString())); + + if (definition.UmbracoVersion != null) + requirements.Add(new XAttribute("type", "strict")); + + package.Add(requirements); + info.Add(package); + + //Author + var author = new XElement("author", ""); + author.Add(new XElement("name", definition.Author)); + author.Add(new XElement("website", definition.AuthorUrl)); + info.Add(author); + + info.Add(new XElement("readme", new XCData(definition.Readme))); + + return info; + } + + private static XDocument CreatePackageManifest(out XElement root, out XElement files) + { + files = new XElement("files"); + root = new XElement("umbPackage", files); + var packageManifest = new XDocument(); + return packageManifest; + } + + private static XDocument EnsureStorage(out string packagesFile) + { + var packagesFolder = IOHelper.MapPath(SystemDirectories.Packages); + //ensure it exists + Directory.CreateDirectory(packagesFolder); + + packagesFile = IOHelper.MapPath(CreatedPackagesFile); + if (!File.Exists(packagesFile)) + { + var xml = new XDocument(new XElement("packages")); + xml.Save(packagesFile); + } + + var packagesXml = XDocument.Load(packagesFile); + return packagesXml; + } + + private static XElement PackageDefinitionToXml(PackageDefinition def) + { + var packageXml = new XElement("package", + new XAttribute("id", def.Id), + new XAttribute("version", def.Version), + new XAttribute("url", def.Url), + new XAttribute("name", def.Name), + new XAttribute("folder", def.Folder), //fixme: What is this? + new XAttribute("packagepath", def.PackagePath), + new XAttribute("repositoryGuid", def.RepositoryGuid), + new XAttribute("iconUrl", def.IconUrl), + new XAttribute("umbVersion", def.UmbracoVersion), + new XAttribute("packageGuid", def.PackageGuid), + new XAttribute("hasUpdate", def.HasUpdate), //fixme: What is this? + + new XElement("license", + new XCData(def.License), + new XAttribute("url", def.LicenseUrl)), + + new XElement("author", + new XCData(def.Author), + new XAttribute("url", def.AuthorUrl)), + + new XElement("readme", def.Readme), + new XElement("actions", def.Actions), + new XElement("datatypes", string.Join(",", def.DataTypes)), + + new XElement("content", + new XAttribute("nodeId", def.ContentNodeId), + new XAttribute("loadChildNodes", def.ContentLoadChildNodes)), + + new XElement("templates", string.Join(",", def.Templates)), + new XElement("stylesheets", string.Join(",", def.Stylesheets)), + new XElement("documentTypes", string.Join(",", def.DocumentTypes)), + new XElement("macros", string.Join(",", def.Macros)), + new XElement("files", string.Join(",", def.Files)), + new XElement("languages", string.Join(",", def.Languages)), + new XElement("dictionaryitems", string.Join(",", def.DictionaryItems)), + new XElement("loadcontrol", "")); //fixme: no more loadcontrol, needs to be an angular view + + return packageXml; + } + + } +} diff --git a/src/Umbraco.Core/Services/IEntityXmlSerializer.cs b/src/Umbraco.Core/Services/IEntityXmlSerializer.cs new file mode 100644 index 0000000000..405fc47c3a --- /dev/null +++ b/src/Umbraco.Core/Services/IEntityXmlSerializer.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Xml.Linq; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Services +{ + /// + /// Serializes entities to XML + /// + public interface IEntityXmlSerializer + { + /// + /// Exports an IContent item as an XElement. + /// + XElement Serialize(IContent content, + bool published, + bool withDescendants = false) //fixme take care of usage! only used for the packager + ; + + /// + /// Exports an IMedia item as an XElement. + /// + XElement Serialize( + IMedia media, + bool withDescendants = false); + + /// + /// Exports an IMember item as an XElement. + /// + XElement Serialize(IMember member); + + /// + /// Exports a list of Data Types + /// + /// List of data types to export + /// containing the xml representation of the IDataTypeDefinition objects + XElement Serialize(IEnumerable dataTypeDefinitions); + + XElement Serialize(IDataType dataType); + + /// + /// Exports a list of items to xml as an + /// + /// List of dictionary items to export + /// Optional boolean indicating whether or not to include children + /// containing the xml representation of the IDictionaryItem objects + XElement Serialize(IEnumerable dictionaryItem, bool includeChildren = true); + + /// + /// Exports a single item to xml as an + /// + /// Dictionary Item to export + /// Optional boolean indicating whether or not to include children + /// containing the xml representation of the IDictionaryItem object + XElement Serialize(IDictionaryItem dictionaryItem, bool includeChildren); + + XElement Serialize(Stylesheet stylesheet); + + /// + /// Exports a list of items to xml as an + /// + /// List of Languages to export + /// containing the xml representation of the ILanguage objects + XElement Serialize(IEnumerable languages); + + XElement Serialize(ILanguage language); + XElement Serialize(ITemplate template); + + /// + /// Exports a list of items to xml as an + /// + /// + /// + XElement Serialize(IEnumerable templates); + + XElement Serialize(IMediaType mediaType); + + /// + /// Exports a list of items to xml as an + /// + /// Macros to export + /// containing the xml representation of the IMacro objects + XElement Serialize(IEnumerable macros); + + XElement Serialize(IMacro macro); + XElement Serialize(IContentType contentType); + } +} diff --git a/src/Umbraco.Core/Services/IPackagingService.cs b/src/Umbraco.Core/Services/IPackagingService.cs index ceab6e94bf..585ea36aa9 100644 --- a/src/Umbraco.Core/Services/IPackagingService.cs +++ b/src/Umbraco.Core/Services/IPackagingService.cs @@ -2,11 +2,21 @@ using System.Collections.Generic; using System.Xml.Linq; using Umbraco.Core.Models; +using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Packaging; namespace Umbraco.Core.Services { public interface IPackagingService : IService { + #region Package Creation + /// + /// Persists a package definition to storage + /// + /// + void SavePackageDefinition(PackageDefinition definition); + #endregion + /// /// Imports and saves package xml as /// @@ -80,114 +90,6 @@ namespace Umbraco.Core.Services /// An enumrable list of generated Templates IEnumerable ImportTemplates(XElement element, int userId = 0, bool raiseEvents = true); - /// - /// Exports an to xml as an - /// - /// ContentType to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ContentType item - XElement Export(IContentType contentType, bool raiseEvents = true); - - /// - /// Exports an item to xml as an - /// - /// Content to export - /// Optional parameter indicating whether to include descendents - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Content object - XElement Export(IContent content, bool deep = false, bool raiseEvents = true); - - /// - /// Exports an item to xml as an - /// - /// Media to export - /// Optional parameter indicating whether to include descendents - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Media object - XElement Export(IMedia media, bool deep = false, bool raiseEvents = true); - - /// - /// Exports a list of items to xml as an - /// - /// List of Languages to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Language object - XElement Export(IEnumerable languages, bool raiseEvents = true); - - /// - /// Exports a single item to xml as an - /// - /// Language to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Language object - XElement Export(ILanguage language, bool raiseEvents = true); - - /// - /// Exports a list of items to xml as an - /// - /// List of dictionary items to export - /// Optional boolean indicating whether or not to include children - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDictionaryItem objects - XElement Export(IEnumerable dictionaryItem, bool includeChildren = true, bool raiseEvents = true); - - /// - /// Exports a single item to xml as an - /// - /// Dictionary Item to export - /// Optional boolean indicating whether or not to include children - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDictionaryItem object - XElement Export(IDictionaryItem dictionaryItem, bool includeChildren, bool raiseEvents = true); - - /// - /// Exports a list of Data Types - /// - /// List of data types to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDataTypeDefinition objects - XElement Export(IEnumerable dataTypeDefinitions, bool raiseEvents = true); - - /// - /// Exports a single Data Type - /// - /// Data type to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDataTypeDefinition object - XElement Export(IDataType dataType, bool raiseEvents = true); - - /// - /// Exports a list of items to xml as an - /// - /// List of Templates to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ITemplate objects - XElement Export(IEnumerable templates, bool raiseEvents = true); - - /// - /// Exports a single item to xml as an - /// - /// Template to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ITemplate object - XElement Export(ITemplate template, bool raiseEvents = true); - - /// - /// Exports a list of items to xml as an - /// - /// Macros to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IMacro objects - XElement Export(IEnumerable macros, bool raiseEvents = true); - - /// - /// Exports a single item to xml as an - /// - /// Macro to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IMacro object - XElement Export(IMacro macro, bool raiseEvents = true); - /// /// This will fetch an Umbraco package file from the package repository and return the relative file path to the downloaded package file /// diff --git a/src/Umbraco.Core/Services/Implement/EntityService.cs b/src/Umbraco.Core/Services/Implement/EntityService.cs index 4a3db29940..37b569b814 100644 --- a/src/Umbraco.Core/Services/Implement/EntityService.cs +++ b/src/Umbraco.Core/Services/Implement/EntityService.cs @@ -258,6 +258,9 @@ namespace Umbraco.Core.Services.Implement public virtual IEnumerable GetAll(UmbracoObjectTypes objectType, params int[] ids) { var entityType = objectType.GetClrType(); + if (entityType == null) + throw new NotSupportedException($"Type \"{objectType}\" is not supported here."); + GetGetters(entityType); using (ScopeProvider.CreateScope(autoComplete: true)) diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs similarity index 70% rename from src/Umbraco.Core/Services/EntityXmlSerializer.cs rename to src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs index 5b64584dc6..e90d894fcd 100644 --- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs @@ -7,49 +7,61 @@ using System.Xml.Linq; using Newtonsoft.Json; using Umbraco.Core.Composing; using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Strings; -namespace Umbraco.Core.Services +namespace Umbraco.Core.Services.Implement { - //TODO: Move the rest of the logic for the PackageService.Export methods to here! - /// - /// A helper class to serialize entities to XML + /// Serializes entities to XML /// - internal class EntityXmlSerializer + internal class EntityXmlSerializer : IEntityXmlSerializer { - /// - /// Exports an IContent item as an XElement. - /// - public static XElement Serialize( + private readonly IContentTypeService _contentTypeService; + private readonly IMediaService _mediaService; + private readonly IContentService _contentService; + private readonly IDataTypeService _dataTypeService; + private readonly IUserService _userService; + private readonly ILocalizationService _localizationService; + private readonly IEnumerable _urlSegmentProviders; + + public EntityXmlSerializer( IContentService contentService, + IMediaService mediaService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, - IEnumerable urlSegmentProviders, - IContent content, + IContentTypeService contentTypeService, + IEnumerable urlSegmentProviders) + { + _contentTypeService = contentTypeService; + _mediaService = mediaService; + _contentService = contentService; + _dataTypeService = dataTypeService; + _userService = userService; + _localizationService = localizationService; + _urlSegmentProviders = urlSegmentProviders; + } + + /// + /// Exports an IContent item as an XElement. + /// + public XElement Serialize(IContent content, bool published, bool withDescendants = false) //fixme take care of usage! only used for the packager { - if (contentService == null) throw new ArgumentNullException(nameof(contentService)); - if (dataTypeService == null) throw new ArgumentNullException(nameof(dataTypeService)); - if (userService == null) throw new ArgumentNullException(nameof(userService)); - if (localizationService == null) throw new ArgumentNullException(nameof(localizationService)); if (content == null) throw new ArgumentNullException(nameof(content)); - if (urlSegmentProviders == null) throw new ArgumentNullException(nameof(urlSegmentProviders)); // nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); var nodeName = content.ContentType.Alias.ToSafeAliasWithForcingCheck(); - var xml = SerializeContentBase(dataTypeService, localizationService, content, content.GetUrlSegment(urlSegmentProviders), nodeName, published); + var xml = SerializeContentBase(content, content.GetUrlSegment(_urlSegmentProviders), nodeName, published); xml.Add(new XAttribute("nodeType", content.ContentType.Id)); xml.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias)); - xml.Add(new XAttribute("creatorName", content.GetCreatorProfile(userService)?.Name ?? "??")); + xml.Add(new XAttribute("creatorName", content.GetCreatorProfile(_userService)?.Name ?? "??")); //xml.Add(new XAttribute("creatorID", content.CreatorId)); - xml.Add(new XAttribute("writerName", content.GetWriterProfile(userService)?.Name ?? "??")); + xml.Add(new XAttribute("writerName", content.GetWriterProfile(_userService)?.Name ?? "??")); xml.Add(new XAttribute("writerID", content.WriterId)); xml.Add(new XAttribute("template", content.Template?.Id.ToString(CultureInfo.InvariantCulture) ?? "0")); @@ -63,8 +75,8 @@ namespace Umbraco.Core.Services var total = long.MaxValue; while(page * pageSize < total) { - var children = contentService.GetPagedChildren(content.Id, page++, pageSize, out total); - SerializeChildren(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, children, xml, published); + var children = _contentService.GetPagedChildren(content.Id, page++, pageSize, out total); + SerializeChildren(children, xml, published); } } @@ -75,34 +87,29 @@ namespace Umbraco.Core.Services /// /// Exports an IMedia item as an XElement. /// - public static XElement Serialize( - IMediaService mediaService, - IDataTypeService dataTypeService, - IUserService userService, - ILocalizationService localizationService, - IEnumerable urlSegmentProviders, + public XElement Serialize( IMedia media, bool withDescendants = false) { - if (mediaService == null) throw new ArgumentNullException(nameof(mediaService)); - if (dataTypeService == null) throw new ArgumentNullException(nameof(dataTypeService)); - if (userService == null) throw new ArgumentNullException(nameof(userService)); - if (localizationService == null) throw new ArgumentNullException(nameof(localizationService)); + if (_mediaService == null) throw new ArgumentNullException(nameof(_mediaService)); + if (_dataTypeService == null) throw new ArgumentNullException(nameof(_dataTypeService)); + if (_userService == null) throw new ArgumentNullException(nameof(_userService)); + if (_localizationService == null) throw new ArgumentNullException(nameof(_localizationService)); if (media == null) throw new ArgumentNullException(nameof(media)); - if (urlSegmentProviders == null) throw new ArgumentNullException(nameof(urlSegmentProviders)); + if (_urlSegmentProviders == null) throw new ArgumentNullException(nameof(_urlSegmentProviders)); // nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); var nodeName = media.ContentType.Alias.ToSafeAliasWithForcingCheck(); const bool published = false; // always false for media - var xml = SerializeContentBase(dataTypeService, localizationService, media, media.GetUrlSegment(urlSegmentProviders), nodeName, published); + var xml = SerializeContentBase(media, media.GetUrlSegment(_urlSegmentProviders), nodeName, published); xml.Add(new XAttribute("nodeType", media.ContentType.Id)); xml.Add(new XAttribute("nodeTypeAlias", media.ContentType.Alias)); //xml.Add(new XAttribute("creatorName", media.GetCreatorProfile(userService).Name)); //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("template", 0)); // no template for media @@ -114,8 +121,8 @@ namespace Umbraco.Core.Services var total = long.MaxValue; while (page * pageSize < total) { - var children = mediaService.GetPagedChildren(media.Id, page++, pageSize, out total); - SerializeChildren(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, children, xml); + var children = _mediaService.GetPagedChildren(media.Id, page++, pageSize, out total); + SerializeChildren(children, xml); } } @@ -125,16 +132,13 @@ namespace Umbraco.Core.Services /// /// Exports an IMember item as an XElement. /// - public static XElement Serialize( - IDataTypeService dataTypeService, - ILocalizationService localizationService, - IMember member) + public XElement Serialize(IMember member) { // nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias); var nodeName = member.ContentType.Alias.ToSafeAliasWithForcingCheck(); const bool published = false; // always false for member - var xml = SerializeContentBase(dataTypeService, localizationService, member, "", nodeName, published); + var xml = SerializeContentBase(member, "", nodeName, published); xml.Add(new XAttribute("nodeType", member.ContentType.Id)); xml.Add(new XAttribute("nodeTypeAlias", member.ContentType.Alias)); @@ -148,7 +152,22 @@ namespace Umbraco.Core.Services return xml; } - public XElement Serialize(IDataTypeService dataTypeService, IDataType dataType) + /// + /// Exports a list of Data Types + /// + /// List of data types to export + /// containing the xml representation of the IDataTypeDefinition objects + public XElement Serialize(IEnumerable dataTypeDefinitions) + { + var container = new XElement("DataTypes"); + foreach (var dataTypeDefinition in dataTypeDefinitions) + { + container.Add(Serialize(dataTypeDefinition)); + } + return container; + } + + public XElement Serialize(IDataType dataType) { var xml = new XElement("DataType"); xml.Add(new XAttribute("Name", dataType.Name)); @@ -162,7 +181,7 @@ namespace Umbraco.Core.Services if (dataType.Level != 1) { //get url encoded folder names - var folders = dataTypeService.GetContainers(dataType) + var folders = _dataTypeService.GetContainers(dataType) .OrderBy(x => x.Level) .Select(x => HttpUtility.UrlEncode(x.Name)); @@ -175,7 +194,45 @@ namespace Umbraco.Core.Services return xml; } - public XElement Serialize(IDictionaryItem dictionaryItem) + /// + /// Exports a list of items to xml as an + /// + /// List of dictionary items to export + /// Optional boolean indicating whether or not to include children + /// containing the xml representation of the IDictionaryItem objects + public XElement Serialize(IEnumerable dictionaryItem, bool includeChildren = true) + { + var xml = new XElement("DictionaryItems"); + foreach (var item in dictionaryItem) + { + xml.Add(Serialize(item, includeChildren)); + } + return xml; + } + + /// + /// Exports a single item to xml as an + /// + /// Dictionary Item to export + /// Optional boolean indicating whether or not to include children + /// containing the xml representation of the IDictionaryItem object + public XElement Serialize(IDictionaryItem dictionaryItem, bool includeChildren) + { + var xml = Serialize(dictionaryItem); + + if (includeChildren) + { + var children = _localizationService.GetDictionaryItemChildren(dictionaryItem.Key); + foreach (var child in children) + { + xml.Add(Serialize(child, true)); + } + } + + return xml; + } + + private XElement Serialize(IDictionaryItem dictionaryItem) { var xml = new XElement("DictionaryItem", new XAttribute("Key", dictionaryItem.ItemKey)); foreach (var translation in dictionaryItem.Translations) @@ -210,6 +267,21 @@ namespace Umbraco.Core.Services return xml; } + /// + /// Exports a list of items to xml as an + /// + /// List of Languages to export + /// containing the xml representation of the ILanguage objects + public XElement Serialize(IEnumerable languages) + { + var xml = new XElement("Languages"); + foreach (var language in languages) + { + xml.Add(Serialize(language)); + } + return xml; + } + public XElement Serialize(ILanguage language) { var xml = new XElement("Language", @@ -240,7 +312,22 @@ namespace Umbraco.Core.Services return xml; } - public XElement Serialize(IDataTypeService dataTypeService, IMediaType mediaType) + /// + /// Exports a list of items to xml as an + /// + /// + /// + public XElement Serialize(IEnumerable templates) + { + var xml = new XElement("Templates"); + foreach (var item in templates) + { + xml.Add(Serialize(item)); + } + return xml; + } + + public XElement Serialize(IMediaType mediaType) { var info = new XElement("Info", new XElement("Name", mediaType.Name), @@ -263,7 +350,7 @@ namespace Umbraco.Core.Services var genericProperties = new XElement("GenericProperties"); // actually, all of them foreach (var propertyType in mediaType.PropertyTypes) { - var definition = dataTypeService.GetDataType(propertyType.DataTypeId); + var definition = _dataTypeService.GetDataType(propertyType.DataTypeId); var propertyGroup = propertyType.PropertyGroupId == null // true generic property ? null @@ -301,6 +388,21 @@ namespace Umbraco.Core.Services return xml; } + /// + /// Exports a list of items to xml as an + /// + /// Macros to export + /// containing the xml representation of the IMacro objects + public XElement Serialize(IEnumerable macros) + { + var xml = new XElement("Macros"); + foreach (var item in macros) + { + xml.Add(Serialize(item)); + } + return xml; + } + public XElement Serialize(IMacro macro) { var xml = new XElement("macro"); @@ -328,7 +430,7 @@ namespace Umbraco.Core.Services return xml; } - public XElement Serialize(IDataTypeService dataTypeService, IContentTypeService contentTypeService, IContentType contentType) + public XElement Serialize(IContentType contentType) { var info = new XElement("Info", new XElement("Name", contentType.Name), @@ -372,7 +474,7 @@ namespace Umbraco.Core.Services var genericProperties = new XElement("GenericProperties"); // actually, all of them foreach (var propertyType in contentType.PropertyTypes) { - var definition = dataTypeService.GetDataType(propertyType.DataTypeId); + var definition = _dataTypeService.GetDataType(propertyType.DataTypeId); var propertyGroup = propertyType.PropertyGroupId == null // true generic property ? null @@ -413,7 +515,7 @@ namespace Umbraco.Core.Services if (contentType.Level != 1 && masterContentType == null) { //get url encoded folder names - var folders = contentTypeService.GetContainers(contentType) + var folders = _contentTypeService.GetContainers(contentType) .OrderBy(x => x.Level) .Select(x => HttpUtility.UrlEncode(x.Name)); @@ -427,7 +529,7 @@ namespace Umbraco.Core.Services } // exports an IContentBase (IContent, IMedia or IMember) as an XElement. - private static XElement SerializeContentBase(IDataTypeService dataTypeService, ILocalizationService localizationService, IContentBase contentBase, string urlValue, string nodeName, bool published) + private XElement SerializeContentBase(IContentBase contentBase, string urlValue, string nodeName, bool published) { var xml = new XElement(nodeName, new XAttribute("id", contentBase.Id), @@ -444,13 +546,13 @@ namespace Umbraco.Core.Services new XAttribute("isDoc", "")); foreach (var property in contentBase.Properties) - xml.Add(SerializeProperty(dataTypeService, localizationService, property, published)); + xml.Add(SerializeProperty(property, published)); return xml; } // exports a property as XElements. - private static IEnumerable SerializeProperty(IDataTypeService dataTypeService, ILocalizationService localizationService, Property property, bool published) + private IEnumerable SerializeProperty(Property property, bool published) { var propertyType = property.PropertyType; @@ -458,16 +560,16 @@ namespace Umbraco.Core.Services var propertyEditor = Current.PropertyEditors[propertyType.PropertyEditorAlias]; return propertyEditor == null ? Array.Empty() - : propertyEditor.GetValueEditor().ConvertDbToXml(property, dataTypeService, localizationService, published); + : propertyEditor.GetValueEditor().ConvertDbToXml(property, _dataTypeService, _localizationService, published); } // exports an IContent item descendants. - private static void SerializeChildren(IContentService contentService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable urlSegmentProviders, IEnumerable children, XElement xml, bool published) + private void SerializeChildren(IEnumerable children, XElement xml, bool published) { foreach (var child in children) { // add the child xml - var childXml = Serialize(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, child, published); + var childXml = Serialize(child, published); xml.Add(childXml); const int pageSize = 500; @@ -475,20 +577,20 @@ namespace Umbraco.Core.Services var total = long.MaxValue; while(page * pageSize < total) { - var grandChildren = contentService.GetPagedChildren(child.Id, page++, pageSize, out total); + var grandChildren = _contentService.GetPagedChildren(child.Id, page++, pageSize, out total); // recurse - SerializeChildren(contentService, dataTypeService, userService, localizationService, urlSegmentProviders, grandChildren, childXml, published); + SerializeChildren(grandChildren, childXml, published); } } } // exports an IMedia item descendants. - private static void SerializeChildren(IMediaService mediaService, IDataTypeService dataTypeService, IUserService userService, ILocalizationService localizationService, IEnumerable urlSegmentProviders, IEnumerable children, XElement xml) + private void SerializeChildren(IEnumerable children, XElement xml) { foreach (var child in children) { // add the child xml - var childXml = Serialize(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, child); + var childXml = Serialize(child); xml.Add(childXml); const int pageSize = 500; @@ -496,9 +598,9 @@ namespace Umbraco.Core.Services var total = long.MaxValue; while (page * pageSize < total) { - var grandChildren = mediaService.GetPagedChildren(child.Id, page++, pageSize, out total); + var grandChildren = _mediaService.GetPagedChildren(child.Id, page++, pageSize, out total); // recurse - SerializeChildren(mediaService, dataTypeService, userService, localizationService, urlSegmentProviders, grandChildren, childXml); + SerializeChildren(grandChildren, childXml); } } } diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index 106d2b9f12..203a2cb2e8 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; @@ -8,8 +7,6 @@ using System.Text.RegularExpressions; using System.Web; using System.Xml.Linq; using Umbraco.Core.Collections; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; using Umbraco.Core.IO; @@ -18,8 +15,6 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Packaging; using Umbraco.Core.Packaging; -using Umbraco.Core.Packaging.Models; -using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.PropertyEditors; @@ -35,56 +30,53 @@ namespace Umbraco.Core.Services.Implement /// public class PackagingService : IPackagingService { + //fixme: inject when ready to use this + private IPackageInstallation _packageInstallation; + private readonly ILogger _logger; private readonly IContentService _contentService; private readonly IContentTypeService _contentTypeService; - private readonly IMediaService _mediaService; private readonly IMacroService _macroService; private readonly IDataTypeService _dataTypeService; private readonly IFileService _fileService; private readonly ILocalizationService _localizationService; private readonly IEntityService _entityService; private readonly IScopeProvider _scopeProvider; - private readonly IEnumerable _urlSegmentProviders; private Dictionary _importedContentTypes; - private IPackageInstallation _packageInstallation; - private readonly IUserService _userService; private readonly IAuditRepository _auditRepository; private readonly IContentTypeRepository _contentTypeRepository; private readonly PropertyEditorCollection _propertyEditors; + private readonly IPackageCreation _packageCreation; private static HttpClient _httpClient; public PackagingService( ILogger logger, IContentService contentService, IContentTypeService contentTypeService, - IMediaService mediaService, IMacroService macroService, IDataTypeService dataTypeService, IFileService fileService, ILocalizationService localizationService, IEntityService entityService, - IUserService userService, IScopeProvider scopeProvider, - UrlSegmentProviderCollection urlSegmentProviders, - IAuditRepository auditRepository, IContentTypeRepository contentTypeRepository, - PropertyEditorCollection propertyEditors) + IAuditRepository auditRepository, + IContentTypeRepository contentTypeRepository, + PropertyEditorCollection propertyEditors, + IPackageCreation packageCreation) { _logger = logger; _contentService = contentService; _contentTypeService = contentTypeService; - _mediaService = mediaService; _macroService = macroService; _dataTypeService = dataTypeService; _fileService = fileService; _localizationService = localizationService; _entityService = entityService; _scopeProvider = scopeProvider; - _urlSegmentProviders = urlSegmentProviders; _auditRepository = auditRepository; _contentTypeRepository = contentTypeRepository; _propertyEditors = propertyEditors; - _userService = userService; + _packageCreation = packageCreation; _importedContentTypes = new Dictionary(); } @@ -92,31 +84,7 @@ namespace Umbraco.Core.Services.Implement #region Content - /// - /// Exports an item to xml as an - /// - /// Content to export - /// Optional parameter indicating whether to include descendents - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Content object - public XElement Export(IContent content, bool deep = false, bool raiseEvents = true) - { - var nodeName = content.ContentType.Alias.ToSafeAliasWithForcingCheck(); - - if (raiseEvents) - { - if (ExportingContent.IsRaisedEventCancelled(new ExportEventArgs(content, nodeName), this)) - return new XElement(nodeName); - } - - const bool published = false; // fixme - what shall we export? - var xml = EntityXmlSerializer.Serialize(_contentService, _dataTypeService, _userService, _localizationService, _urlSegmentProviders, content, published, deep); - - if (raiseEvents) - ExportedContent.RaiseEvent(new ExportEventArgs(content, xml, false), this); - - return xml; - } + @@ -308,28 +276,7 @@ namespace Umbraco.Core.Services.Implement #region ContentTypes - /// - /// Exports an to xml as an - /// - /// ContentType to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ContentType item. - public XElement Export(IContentType contentType, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingContentType.IsRaisedEventCancelled(new ExportEventArgs(contentType, "DocumentType"), this)) - return new XElement("DocumentType"); - } - - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(_dataTypeService, _contentTypeService, contentType); - - if (raiseEvents) - ExportedContentType.RaiseEvent(new ExportEventArgs(contentType, xml, false), this); - - return xml; - } + /// /// Imports and saves package xml as @@ -804,44 +751,9 @@ namespace Umbraco.Core.Services.Implement #region DataTypes - /// - /// Exports a list of Data Types - /// - /// List of data types to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDataTypeDefinition objects - public XElement Export(IEnumerable dataTypeDefinitions, bool raiseEvents = true) - { - var container = new XElement("DataTypes"); - foreach (var dataTypeDefinition in dataTypeDefinitions) - { - container.Add(Export(dataTypeDefinition, raiseEvents)); - } - return container; - } + - /// - /// Exports a single Data Type - /// - /// Data type to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDataTypeDefinition object - public XElement Export(IDataType dataType, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingDataType.IsRaisedEventCancelled(new ExportEventArgs(dataType, "DataType"), this)) - return new XElement("DataType"); - } - - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(_dataTypeService, dataType); - - if (raiseEvents) - ExportedDataType.RaiseEvent(new ExportEventArgs(dataType, xml, false), this); - - return xml; - } + /// /// Imports and saves package xml as @@ -993,55 +905,9 @@ namespace Umbraco.Core.Services.Implement #region Dictionary Items - /// - /// Exports a list of items to xml as an - /// - /// List of dictionary items to export - /// Optional boolean indicating whether or not to include children - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDictionaryItem objects - public XElement Export(IEnumerable dictionaryItem, bool includeChildren = true, bool raiseEvents = true) - { - var xml = new XElement("DictionaryItems"); - foreach (var item in dictionaryItem) - { - xml.Add(Export(item, includeChildren, raiseEvents)); - } - return xml; - } + - /// - /// Exports a single item to xml as an - /// - /// Dictionary Item to export - /// Optional boolean indicating whether or not to include children - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IDictionaryItem object - public XElement Export(IDictionaryItem dictionaryItem, bool includeChildren, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingDictionaryItem.IsRaisedEventCancelled(new ExportEventArgs(dictionaryItem, "DictionaryItem"), this)) - return new XElement("DictionaryItem"); - } - - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(dictionaryItem); - - if (includeChildren) - { - var children = _localizationService.GetDictionaryItemChildren(dictionaryItem.Key); - foreach (var child in children) - { - xml.Add(Export(child, true)); - } - } - - if (raiseEvents) - ExportedDictionaryItem.RaiseEvent(new ExportEventArgs(dictionaryItem, xml, false), this); - - return xml; - } + /// /// Imports and saves the 'DictionaryItems' part of the package xml as a list of @@ -1138,44 +1004,9 @@ namespace Umbraco.Core.Services.Implement #region Languages - /// - /// Exports a list of items to xml as an - /// - /// List of Languages to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ILanguage objects - public XElement Export(IEnumerable languages, bool raiseEvents = true) - { - var xml = new XElement("Languages"); - foreach (var language in languages) - { - xml.Add(Export(language, raiseEvents)); - } - return xml; - } + - /// - /// Exports a single item to xml as an - /// - /// Language to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ILanguage object - public XElement Export(ILanguage language, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingLanguage.IsRaisedEventCancelled(new ExportEventArgs(language, "Language"), this)) - return new XElement("Language"); - } - - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(language); - - if (raiseEvents) - ExportedLanguage.RaiseEvent(new ExportEventArgs(language, xml, false), this); - - return xml; - } + /// /// Imports and saves the 'Languages' part of a package xml as a list of @@ -1326,109 +1157,10 @@ namespace Umbraco.Core.Services.Implement return macro; } - /// - /// Exports a list of items to xml as an - /// - /// Macros to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IMacro objects - public XElement Export(IEnumerable macros, bool raiseEvents = true) - { - var xml = new XElement("Macros"); - foreach (var item in macros) - { - xml.Add(Export(item, raiseEvents)); - } - return xml; - } + - /// - /// Exports a single item to xml as an - /// - /// Macro to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the IMacro object - public XElement Export(IMacro macro, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingMacro.IsRaisedEventCancelled(new ExportEventArgs(macro, "macro"), this)) - return new XElement("macro"); - } + - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(macro); - - if (raiseEvents) - ExportedMacro.RaiseEvent(new ExportEventArgs(macro, xml, false), this); - - return xml; - } - - #endregion - - #region Members - - /// - /// Exports an item to xml as an - /// - /// Member to export - /// containing the xml representation of the Member object - public XElement Export(IMember member) - { - return EntityXmlSerializer.Serialize(_dataTypeService, _localizationService, member); - } - - #endregion - - #region Media - - /// - /// Exports an item to xml as an - /// - /// Media to export - /// Optional parameter indicating whether to include descendents - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the Media object - public XElement Export(IMedia media, bool deep = false, bool raiseEvents = true) - { - var nodeName = media.ContentType.Alias.ToSafeAliasWithForcingCheck(); - - if (raiseEvents) - { - if (ExportingMedia.IsRaisedEventCancelled(new ExportEventArgs(media, nodeName), this)) - return new XElement(nodeName); - } - - var xml = EntityXmlSerializer.Serialize(_mediaService, _dataTypeService, _userService, _localizationService, _urlSegmentProviders, media, deep); - - if (raiseEvents) - ExportedMedia.RaiseEvent(new ExportEventArgs(media, xml, false), this); - - return xml; - } - - - #endregion - - #region MediaTypes - - /// - /// Exports an to xml as an - /// - /// MediaType to export - /// containing the xml representation of the MediaType item. - internal XElement Export(IMediaType mediaType) - { - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(_dataTypeService, mediaType); - - return xml; - } - - #endregion - - #region Package Manifest #endregion #region Package Files @@ -1579,6 +1311,26 @@ namespace Umbraco.Core.Services.Implement } + private bool IsMasterPageSyntax(string code) + { + return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || + code.InvariantContains(" ImportStylesheets(XElement element, int userId = 0, bool raiseEvents = true) { @@ -1601,69 +1353,12 @@ namespace Umbraco.Core.Services.Implement } - - private bool IsMasterPageSyntax(string code) - { - return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || - code.InvariantContains(" - /// Exports a list of items to xml as an - /// - /// List of Templates to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ITemplate objects - public XElement Export(IEnumerable templates, bool raiseEvents = true) - { - var xml = new XElement("Templates"); - foreach (var item in templates) - { - xml.Add(Export(item, raiseEvents)); - } - return xml; - } - - /// - /// Exports a single item to xml as an - /// - /// Template to export - /// Optional parameter indicating whether or not to raise events - /// containing the xml representation of the ITemplate object - public XElement Export(ITemplate template, bool raiseEvents = true) - { - if (raiseEvents) - { - if (ExportingTemplate.IsRaisedEventCancelled(new ExportEventArgs(template, "Template"), this)) - return new XElement("Template"); - } - - var exporter = new EntityXmlSerializer(); - var xml = exporter.Serialize(template); - - if (raiseEvents) - ExportedTemplate.RaiseEvent(new ExportEventArgs(template, xml, false), this); - - return xml; - } - - #endregion - - #region Stylesheets #endregion #region Installation + //fixme: None of these methods are actually used! They have unit tests for them though, but we don't actively use this yet but we should! + internal IPackageInstallation PackageInstallation { private get { return _packageInstallation ?? new PackageInstallation(this, _macroService, _fileService, new PackageExtraction()); } @@ -1706,6 +1401,9 @@ namespace Umbraco.Core.Services.Implement #endregion #region Package Building + + public void SavePackageDefinition(PackageDefinition definition) => _packageCreation.SavePackageDefinition(definition); + #endregion /// @@ -1737,24 +1435,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedContent; - - public static event TypedEventHandler> ExportingContent; - - /// - /// Occurs after Content is Exported to Xml - /// - public static event TypedEventHandler> ExportedContent; - - /// - /// Occurs before Exporting Media - /// - public static event TypedEventHandler> ExportingMedia; - - /// - /// Occurs after Media is Exported to Xml - /// - public static event TypedEventHandler> ExportedMedia; - /// /// Occurs before Importing ContentType /// @@ -1765,16 +1445,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedContentType; - /// - /// Occurs before Exporting ContentType - /// - public static event TypedEventHandler> ExportingContentType; - - /// - /// Occurs after ContentType is Exported to Xml - /// - public static event TypedEventHandler> ExportedContentType; - /// /// Occurs before Importing DataType /// @@ -1785,16 +1455,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedDataType; - /// - /// Occurs before Exporting DataType - /// - public static event TypedEventHandler> ExportingDataType; - - /// - /// Occurs after DataType is Exported to Xml - /// - public static event TypedEventHandler> ExportedDataType; - /// /// Occurs before Importing DictionaryItem /// @@ -1805,16 +1465,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedDictionaryItem; - /// - /// Occurs before Exporting DictionaryItem - /// - public static event TypedEventHandler> ExportingDictionaryItem; - - /// - /// Occurs after DictionaryItem is Exported to Xml - /// - public static event TypedEventHandler> ExportedDictionaryItem; - /// /// Occurs before Importing Macro /// @@ -1825,16 +1475,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedMacro; - /// - /// Occurs before Exporting Macro - /// - public static event TypedEventHandler> ExportingMacro; - - /// - /// Occurs after Macro is Exported to Xml - /// - public static event TypedEventHandler> ExportedMacro; - /// /// Occurs before Importing Language /// @@ -1845,16 +1485,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedLanguage; - /// - /// Occurs before Exporting Language - /// - public static event TypedEventHandler> ExportingLanguage; - - /// - /// Occurs after Language is Exported to Xml - /// - public static event TypedEventHandler> ExportedLanguage; - /// /// Occurs before Importing Template /// @@ -1870,16 +1500,6 @@ namespace Umbraco.Core.Services.Implement /// public static event TypedEventHandler> ImportedTemplate; - /// - /// Occurs before Exporting Template - /// - public static event TypedEventHandler> ExportingTemplate; - - /// - /// Occurs after Template is Exported to Xml - /// - public static event TypedEventHandler> ExportedTemplate; - /// /// Occurs before Importing umbraco package /// @@ -1896,5 +1516,7 @@ namespace Umbraco.Core.Services.Implement public static event TypedEventHandler> UninstalledPackage; #endregion + + } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index a01bbf1746..58ba136cc4 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -429,6 +429,9 @@ + + + @@ -440,6 +443,10 @@ + + + + @@ -554,7 +561,6 @@ - @@ -883,7 +889,7 @@ - + @@ -1351,6 +1357,7 @@ + @@ -1370,7 +1377,7 @@ - + @@ -1525,6 +1532,7 @@ + \ No newline at end of file diff --git a/src/Umbraco.Core/_Legacy/PackageActions/PackageActionCollection.cs b/src/Umbraco.Core/_Legacy/PackageActions/PackageActionCollection.cs index 46ea3c1e39..a38c8cea56 100644 --- a/src/Umbraco.Core/_Legacy/PackageActions/PackageActionCollection.cs +++ b/src/Umbraco.Core/_Legacy/PackageActions/PackageActionCollection.cs @@ -3,7 +3,7 @@ using Umbraco.Core.Composing; namespace Umbraco.Core._Legacy.PackageActions { - internal class PackageActionCollection : BuilderCollectionBase + public sealed class PackageActionCollection : BuilderCollectionBase { public PackageActionCollection(IEnumerable items) : base(items) diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 28e753cadc..12ea87087d 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; using Umbraco.Tests.Testing.Objects.Accessors; @@ -66,7 +67,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var domainCache = new DomainCache(ServiceContext.DomainService, DefaultCultureAccessor); var publishedShapshot = new Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedSnapshot( new PublishedContentCache(xmlStore, domainCache, cacheProvider, globalSettings, new SiteDomainHelper(), ContentTypesCache, null, null), - new PublishedMediaCache(xmlStore, ServiceContext.MediaService, ServiceContext.UserService, cacheProvider, ContentTypesCache), + new PublishedMediaCache(xmlStore, ServiceContext.MediaService, ServiceContext.UserService, cacheProvider, ContentTypesCache, Factory.GetInstance()), new PublishedMemberCache(null, cacheProvider, Current.Services.MemberService, ContentTypesCache), domainCache); var publishedSnapshotService = new Mock(); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index 5237b92ab8..acf76ca8d7 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -15,6 +15,7 @@ using Umbraco.Tests.Testing; using Current = Umbraco.Web.Composing.Current; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; namespace Umbraco.Tests.Cache.PublishedCache @@ -74,7 +75,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild2 = MakeNewMedia("Child2", mType, user, mRoot2.Id); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var roots = cache.GetAtRoot(); Assert.AreEqual(2, roots.Count()); Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id})); @@ -92,7 +93,7 @@ namespace Umbraco.Tests.Cache.PublishedCache //var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); var umbracoContext = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var publishedMedia = cache.GetById(mRoot.Id); Assert.IsNotNull(publishedMedia); @@ -203,7 +204,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var result = new SearchResult("1234", 1, 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); - var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); + var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); DoAssert(doc, 1234, key, 0, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); @@ -219,7 +220,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var xmlDoc = GetMediaXml(); ((XmlElement)xmlDoc.DocumentElement.FirstChild).SetAttribute("key", key.ToString()); var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator(); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true)); DoAssert(doc, 2000, key, 0, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); diff --git a/src/Umbraco.Tests/Models/ContentXmlTest.cs b/src/Umbraco.Tests/Models/ContentXmlTest.cs index ab318ec1cb..3779993d22 100644 --- a/src/Umbraco.Tests/Models/ContentXmlTest.cs +++ b/src/Umbraco.Tests/Models/ContentXmlTest.cs @@ -2,7 +2,9 @@ using System.Xml.Linq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; @@ -29,7 +31,7 @@ namespace Umbraco.Tests.Models var urlName = content.GetUrlSegment(new[]{new DefaultUrlSegmentProvider() }); // Act - XElement element = content.ToXml(); + XElement element = content.ToXml(Factory.GetInstance()); // Assert Assert.That(element, Is.Not.Null); diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index 1a56fac4eb..d0d00c64a6 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -50,7 +51,7 @@ namespace Umbraco.Tests.Models var urlName = media.GetUrlSegment(new[] { new DefaultUrlSegmentProvider() }); // Act - XElement element = media.ToXml(); + XElement element = media.ToXml(Factory.GetInstance()); // Assert Assert.That(element, Is.Not.Null); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 3ba0ef64ce..ef37a822c1 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -152,7 +152,8 @@ namespace Umbraco.Tests.PublishedContent new TestDefaultCultureAccessor(), dataSource, globalSettings, - new SiteDomainHelper()); + new SiteDomainHelper(), + Mock.Of()); // get a snapshot, get a published content var snapshot = snapshotService.CreatePublishedSnapshot(previewToken: null); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 88b211d0ee..4f55b4fd71 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -22,6 +22,7 @@ using Umbraco.Tests.Testing; using Umbraco.Core.Composing; using Umbraco.Core.Models.Membership; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Tests.PublishedContent { @@ -66,7 +67,9 @@ namespace Umbraco.Tests.PublishedContent /// internal IPublishedContent GetNode(int id, UmbracoContext umbracoContext) { - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), + ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, + Factory.GetInstance()); var doc = cache.GetById(id); Assert.IsNotNull(doc); return doc; @@ -123,7 +126,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -153,7 +156,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //ensure it is found var publishedMedia = cache.GetById(3113); @@ -200,7 +203,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -228,7 +231,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -256,7 +259,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -285,7 +288,7 @@ namespace Umbraco.Tests.PublishedContent var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(3113); @@ -311,7 +314,7 @@ namespace Umbraco.Tests.PublishedContent var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, indexer, new StaticCacheProvider(), ContentTypesCache); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(3113); @@ -479,7 +482,7 @@ namespace Umbraco.Tests.PublishedContent "); var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var nav = node.CreateNavigator(); @@ -499,7 +502,7 @@ namespace Umbraco.Tests.PublishedContent var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234)); var nav = errorXml.CreateNavigator(); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache, Factory.GetInstance()); var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234); Assert.IsNull(converted); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index b273ee9526..e8f3463ca7 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -95,7 +95,8 @@ namespace Umbraco.Tests.Scoping documentRepository, mediaRepository, memberRepository, DefaultCultureAccessor, new DatabaseDataSource(), - Factory.GetInstance(), new SiteDomainHelper()); + Factory.GetInstance(), new SiteDomainHelper(), + Factory.GetInstance()); } protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable urlProviders = null) diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs index 94d2126bd2..d0c0b93b48 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs @@ -67,7 +67,8 @@ namespace Umbraco.Tests.Services documentRepository, mediaRepository, memberRepository, DefaultCultureAccessor, new DatabaseDataSource(), - Factory.GetInstance(), new SiteDomainHelper()); + Factory.GetInstance(), new SiteDomainHelper(), + Factory.GetInstance()); } public class LocalServerMessenger : ServerMessengerBase diff --git a/src/Umbraco.Tests/Services/EntityXmlSerializerTests.cs b/src/Umbraco.Tests/Services/EntityXmlSerializerTests.cs new file mode 100644 index 0000000000..28c69344b7 --- /dev/null +++ b/src/Umbraco.Tests/Services/EntityXmlSerializerTests.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Xml.Linq; +using NUnit.Framework; +using Umbraco.Core.Composing; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Tests.Services.Importing; +using Umbraco.Tests.Testing; + +namespace Umbraco.Tests.Services +{ + [TestFixture] + [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] + public class EntityXmlSerializerTests : TestWithSomeContentBase + { + private IEntityXmlSerializer Serializer => Factory.GetInstance(); + + [Test] + public void Can_Export_Macro() + { + // Arrange + var macro = new Macro("test1", "Test", "~/views/macropartials/test.cshtml", MacroTypes.PartialView); + ServiceContext.MacroService.Save(macro); + + // Act + var element = Serializer.Serialize(macro); + + // Assert + Assert.That(element, Is.Not.Null); + Assert.That(element.Element("name").Value, Is.EqualTo("Test")); + Assert.That(element.Element("alias").Value, Is.EqualTo("test1")); + Debug.Print(element.ToString()); + } + + [Test] + public void Can_Export_DictionaryItems() + { + // Arrange + CreateDictionaryData(); + var dictionaryItem = ServiceContext.LocalizationService.GetDictionaryItemByKey("Parent"); + + var newPackageXml = XElement.Parse(ImportResources.Dictionary_Package); + var dictionaryItemsElement = newPackageXml.Elements("DictionaryItems").First(); + + // Act + var xml = Serializer.Serialize(new[] { dictionaryItem }); + + // Assert + Assert.That(xml.ToString(), Is.EqualTo(dictionaryItemsElement.ToString())); + } + + [Test] + public void Can_Export_Languages() + { + // Arrange + var languageNbNo = new Language("nb-NO") { CultureName = "Norwegian" }; + ServiceContext.LocalizationService.Save(languageNbNo); + + var languageEnGb = new Language("en-GB") { CultureName = "English (United Kingdom)" }; + ServiceContext.LocalizationService.Save(languageEnGb); + + var newPackageXml = XElement.Parse(ImportResources.Dictionary_Package); + var languageItemsElement = newPackageXml.Elements("Languages").First(); + + // Act + var xml = Serializer.Serialize(new[] { languageNbNo, languageEnGb }); + + // Assert + Assert.That(xml.ToString(), Is.EqualTo(languageItemsElement.ToString())); + } + + private void CreateDictionaryData() + { + var languageNbNo = new Language("nb-NO") { CultureName = "nb-NO" }; + ServiceContext.LocalizationService.Save(languageNbNo); + + var languageEnGb = new Language("en-GB") { CultureName = "en-GB" }; + ServiceContext.LocalizationService.Save(languageEnGb); + + var parentItem = new DictionaryItem("Parent"); + var parentTranslations = new List + { + new DictionaryTranslation(languageNbNo, "ForelderVerdi"), + new DictionaryTranslation(languageEnGb, "ParentValue") + }; + parentItem.Translations = parentTranslations; + ServiceContext.LocalizationService.Save(parentItem); + + var childItem = new DictionaryItem(parentItem.Key, "Child"); + var childTranslations = new List + { + new DictionaryTranslation(languageNbNo, "BarnVerdi"), + new DictionaryTranslation(languageEnGb, "ChildValue") + }; + childItem.Translations = childTranslations; + ServiceContext.LocalizationService.Save(childItem); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs index 8e67aa4e1f..84eb75a4f7 100644 --- a/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs +++ b/src/Umbraco.Tests/Services/Importing/PackageImportTests.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Composing.Composers; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Tests.Testing; namespace Umbraco.Tests.Services.Importing @@ -416,11 +417,12 @@ namespace Umbraco.Tests.Services.Importing string strXml = ImportResources.SingleDocType; var docTypeElement = XElement.Parse(strXml); var packagingService = ServiceContext.PackagingService; + var serializer = Factory.GetInstance(); // Act var contentTypes = packagingService.ImportContentTypes(docTypeElement); var contentType = contentTypes.FirstOrDefault(); - var element = packagingService.Export(contentType); + var element = serializer.Serialize(contentType); // Assert Assert.That(element, Is.Not.Null); diff --git a/src/Umbraco.Tests/Services/PackagingServiceTests.cs b/src/Umbraco.Tests/Services/PackagingServiceTests.cs index 87225c1288..a87e7907b5 100644 --- a/src/Umbraco.Tests/Services/PackagingServiceTests.cs +++ b/src/Umbraco.Tests/Services/PackagingServiceTests.cs @@ -1,16 +1,9 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using System.Linq; -using System.Xml.Linq; using NUnit.Framework; using Umbraco.Core.IO; -using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; -using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; -using Umbraco.Tests.Services.Importing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; @@ -20,59 +13,7 @@ namespace Umbraco.Tests.Services [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] public class PackagingServiceTests : TestWithSomeContentBase { - [Test] - public void PackagingService_Can_Export_Macro() - { - // Arrange - var macro = new Macro("test1", "Test", "~/views/macropartials/test.cshtml", MacroTypes.PartialView); - ServiceContext.MacroService.Save(macro); - - // Act - var element = ServiceContext.PackagingService.Export(macro); - - // Assert - Assert.That(element, Is.Not.Null); - Assert.That(element.Element("name").Value, Is.EqualTo("Test")); - Assert.That(element.Element("alias").Value, Is.EqualTo("test1")); - Debug.Print(element.ToString()); - } - - [Test] - public void PackagingService_Can_Export_DictionaryItems() - { - // Arrange - CreateDictionaryData(); - var dictionaryItem = ServiceContext.LocalizationService.GetDictionaryItemByKey("Parent"); - - var newPackageXml = XElement.Parse(ImportResources.Dictionary_Package); - var dictionaryItemsElement = newPackageXml.Elements("DictionaryItems").First(); - - // Act - var xml = ServiceContext.PackagingService.Export(new []{dictionaryItem}); - - // Assert - Assert.That(xml.ToString(), Is.EqualTo(dictionaryItemsElement.ToString())); - } - - [Test] - public void PackagingService_Can_Export_Languages() - { - // Arrange - var languageNbNo = new Language("nb-NO") { CultureName = "Norwegian" }; - ServiceContext.LocalizationService.Save(languageNbNo); - - var languageEnGb = new Language("en-GB") { CultureName = "English (United Kingdom)" }; - ServiceContext.LocalizationService.Save(languageEnGb); - - var newPackageXml = XElement.Parse(ImportResources.Dictionary_Package); - var languageItemsElement = newPackageXml.Elements("Languages").First(); - - // Act - var xml = ServiceContext.PackagingService.Export(new[] { languageNbNo, languageEnGb }); - - // Assert - Assert.That(xml.ToString(), Is.EqualTo(languageItemsElement.ToString())); - } + private static string GetTestPackagePath(string packageName) { @@ -123,31 +64,6 @@ namespace Umbraco.Tests.Services Assert.IsNotNull(preInstallWarnings); } - private void CreateDictionaryData() - { - var languageNbNo = new Language("nb-NO") { CultureName = "nb-NO" }; - ServiceContext.LocalizationService.Save(languageNbNo); - - var languageEnGb = new Language("en-GB") { CultureName = "en-GB" }; - ServiceContext.LocalizationService.Save(languageEnGb); - - var parentItem = new DictionaryItem("Parent"); - var parentTranslations = new List - { - new DictionaryTranslation(languageNbNo, "ForelderVerdi"), - new DictionaryTranslation(languageEnGb, "ParentValue") - }; - parentItem.Translations = parentTranslations; - ServiceContext.LocalizationService.Save(parentItem); - - var childItem = new DictionaryItem(parentItem.Key, "Child"); - var childTranslations = new List - { - new DictionaryTranslation(languageNbNo, "BarnVerdi"), - new DictionaryTranslation(languageEnGb, "ChildValue") - }; - childItem.Translations = childTranslations; - ServiceContext.LocalizationService.Save(childItem); - } + } } diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index cb36e6ca5f..120b0bcabb 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -12,6 +12,7 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Core.Packaging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.Repositories; @@ -167,7 +168,10 @@ namespace Umbraco.Tests.TestHelpers GetRepo(c))); var macroService = GetLazyService(factory, c => new MacroService(scopeProvider, logger, eventMessagesFactory, GetRepo(c), GetRepo(c))); - var packagingService = GetLazyService(factory, c => new PackagingService(logger, contentService.Value, contentTypeService.Value, mediaService.Value, macroService.Value, dataTypeService.Value, fileService.Value, localizationService.Value, entityService.Value, userService.Value, scopeProvider, urlSegmentProviders, GetRepo(c), GetRepo(c), new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())))); + var packagingService = GetLazyService(factory, c => new PackagingService( + logger, contentService.Value, contentTypeService.Value, macroService.Value, dataTypeService.Value, fileService.Value, localizationService.Value, entityService.Value, scopeProvider, GetRepo(c), GetRepo(c), new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())), + new PackageCreation(contentService.Value, contentTypeService.Value, dataTypeService.Value, fileService.Value, macroService.Value, localizationService.Value, + new EntityXmlSerializer(contentService.Value, mediaService.Value, dataTypeService.Value, userService.Value, localizationService.Value, contentTypeService.Value, urlSegmentProviders), logger))); var relationService = GetLazyService(factory, c => new RelationService(scopeProvider, logger, eventMessagesFactory, entityService.Value, GetRepo(c), GetRepo(c))); var treeService = GetLazyService(factory, c => new ApplicationTreeService(logger, cache, typeLoader)); var tagService = GetLazyService(factory, c => new TagService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index a2a0c35c56..0729aa0b6e 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -268,6 +268,7 @@ namespace Umbraco.Tests.TestHelpers DefaultCultureAccessor, Logger, Factory.GetInstance(), new SiteDomainHelper(), + Factory.GetInstance(), ContentTypesCache, null, true, Options.PublishedRepositoryEvents); diff --git a/src/Umbraco.Tests/UI/LegacyDialogTests.cs b/src/Umbraco.Tests/UI/LegacyDialogTests.cs index be9b0d4d7e..5c8a621e10 100644 --- a/src/Umbraco.Tests/UI/LegacyDialogTests.cs +++ b/src/Umbraco.Tests/UI/LegacyDialogTests.cs @@ -24,7 +24,6 @@ namespace Umbraco.Tests.UI } [TestCase(typeof(macroTasks), Constants.Applications.Settings)] - [TestCase(typeof(CreatedPackageTasks), Constants.Applications.Packages)] public void Check_Assigned_Apps_For_Tasks(Type taskType, string app) { var task = (LegacyDialogTask)Activator.CreateInstance(taskType); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 661ccb6ab8..12b830407e 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -139,6 +139,7 @@ + diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 0ad3bff109..192b0975d1 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -419,11 +419,13 @@ namespace Umbraco.Tests.Web.Mvc //var provider = new ScopeUnitOfWorkProvider(databaseFactory, new RepositoryFactory(Mock.Of())); var scopeProvider = TestObjects.GetScopeProvider(Mock.Of()); var factory = Mock.Of(); - _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, Enumerable.Empty(), + _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, null, null, null, null, null, new TestDefaultCultureAccessor(), - Current.Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), null, true, false); // no events + Current.Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), + Factory.GetInstance(), + null, true, false); // no events var http = GetHttpContextFactory(url, routeData).HttpContext; diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index ffe07393e6..3e7c14147b 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Packaging; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Scoping; using Umbraco.Core.Services; @@ -215,6 +216,8 @@ namespace Umbraco.Web.Composing internal static ManifestValueValidatorCollection ManifestValidators => CoreCurrent.ManifestValidators; + internal static PackageActionRunner PackageActionRunner => CoreCurrent.PackageActionRunner; + internal static PackageActionCollection PackageActions => CoreCurrent.PackageActions; internal static PropertyValueConverterCollection PropertyValueConverters => CoreCurrent.PropertyValueConverters; diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 397f6b3e9d..0d56b34617 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -11,10 +11,15 @@ using System.Web.Http; using System.Xml; using System.Xml.Linq; using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; +using Umbraco.Core.Dictionary; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Persistence; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Web.Composing; using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; @@ -40,6 +45,13 @@ namespace Umbraco.Web.Editors [EnableOverrideAuthorization] public class ContentTypeController : ContentTypeControllerBase { + private readonly IEntityXmlSerializer _serializer; + + public ContentTypeController(IEntityXmlSerializer serializer, ICultureDictionaryFactory cultureDictionaryFactory, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, IProfilingLogger logger, IRuntimeState runtimeState) : base(cultureDictionaryFactory, globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + _serializer = serializer; + } + public int GetCount() { return Services.ContentTypeService.Count(); @@ -444,11 +456,7 @@ namespace Umbraco.Web.Editors var contentType = Services.ContentTypeService.Get(id); if (contentType == null) throw new NullReferenceException("No content type found with id " + id); - var serializer = new EntityXmlSerializer(); - var xml = serializer.Serialize( - Services.DataTypeService, - Services.ContentTypeService, - contentType); + var xml = _serializer.Serialize(contentType); var response = new HttpResponseMessage { @@ -559,5 +567,7 @@ namespace Umbraco.Web.Editors return model; } + + } } diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 2572bed816..898208319a 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -7,9 +7,13 @@ using System.Text; using System.Web.Http; using AutoMapper; using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; using Umbraco.Core.Exceptions; +using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Persistence; using Umbraco.Core.Services; using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; @@ -26,8 +30,16 @@ namespace Umbraco.Web.Editors public abstract class ContentTypeControllerBase : UmbracoAuthorizedJsonController where TContentType : class, IContentTypeComposition { + private readonly ICultureDictionaryFactory _cultureDictionaryFactory; private ICultureDictionary _cultureDictionary; + protected ContentTypeControllerBase(ICultureDictionaryFactory cultureDictionaryFactory, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, IProfilingLogger logger, IRuntimeState runtimeState) : base(globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + _cultureDictionaryFactory = cultureDictionaryFactory; + } + + + /// /// Returns the available composite content types for a given content type /// @@ -536,6 +548,6 @@ namespace Umbraco.Web.Editors } private ICultureDictionary CultureDictionary - => _cultureDictionary ?? (_cultureDictionary = Current.CultureDictionaryFactory.CreateDictionary()); + => _cultureDictionary ?? (_cultureDictionary = _cultureDictionaryFactory.CreateDictionary()); } } diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index f8455fc01d..f2b8fd3dda 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -15,6 +15,11 @@ using System; using System.ComponentModel; using System.Web.Http.Controllers; using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; +using Umbraco.Core.Dictionary; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; using Umbraco.Web.Composing; namespace Umbraco.Web.Editors @@ -32,6 +37,10 @@ namespace Umbraco.Web.Editors [MediaTypeControllerControllerConfiguration] public class MediaTypeController : ContentTypeControllerBase { + public MediaTypeController(ICultureDictionaryFactory cultureDictionaryFactory, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, IProfilingLogger logger, IRuntimeState runtimeState) : base(cultureDictionaryFactory, globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + } + /// /// Configures this controller with a custom action selector /// @@ -302,5 +311,7 @@ namespace Umbraco.Web.Editors getContentType: i => Services.MediaTypeService.Get(i), doCopy: (type, i) => Services.MediaTypeService.Copy(type, i)); } + + } } diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs index 77ff974aaa..3abc0035d3 100644 --- a/src/Umbraco.Web/Editors/MemberTypeController.cs +++ b/src/Umbraco.Web/Editors/MemberTypeController.cs @@ -6,7 +6,13 @@ using System.Net.Http; using System.Web.Http; using System.Web.Security; using AutoMapper; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; +using Umbraco.Core.Dictionary; +using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Persistence; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; @@ -24,6 +30,10 @@ namespace Umbraco.Web.Editors [UmbracoTreeAuthorize(new string[] { Constants.Trees.MemberTypes, Constants.Trees.Members})] public class MemberTypeController : ContentTypeControllerBase { + public MemberTypeController(ICultureDictionaryFactory cultureDictionaryFactory, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, IProfilingLogger logger, IRuntimeState runtimeState) : base(cultureDictionaryFactory, globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + } + private readonly MembershipProvider _provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); [UmbracoTreeAuthorize(Constants.Trees.MemberTypes)] @@ -166,5 +176,7 @@ namespace Umbraco.Web.Editors return display; } + + } } diff --git a/src/Umbraco.Web/Editors/PackageController.cs b/src/Umbraco.Web/Editors/PackageController.cs index 8b9e15f9d1..dfb8823a39 100644 --- a/src/Umbraco.Web/Editors/PackageController.cs +++ b/src/Umbraco.Web/Editors/PackageController.cs @@ -4,10 +4,12 @@ using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Web.Http; -using umbraco.cms.businesslogic.packager; +using Umbraco.Core.Models.Packaging; +using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; +using Umbraco.Web._Legacy.Packager.PackageInstance; namespace Umbraco.Web.Editors { @@ -21,14 +23,12 @@ namespace Umbraco.Web.Editors [UmbracoApplicationAuthorize(Core.Constants.Applications.Packages)] public class PackageController : UmbracoAuthorizedJsonController { - [HttpGet] - public List GetCreatedPackages() + public List GetCreatedPackages() { return CreatedPackage.GetAllCreatedPackages().Select(x => x.Data).ToList(); } - [HttpGet] - public PackageInstance GetCreatedPackageById(int id) + public PackageDefinition GetCreatedPackageById(int id) { var package = CreatedPackage.GetById(id); if (package == null) @@ -37,44 +37,46 @@ namespace Umbraco.Web.Editors return package.Data; } - [HttpPost] - public PackageInstance PostCreatePackage(PackageInstance model) + public PackageDefinition PostUpdatePackage(PackageDefinition model) { + var package = CreatedPackage.GetById(model.Id); + if (package == null) + throw new HttpResponseException(HttpStatusCode.NotFound); + if (ModelState.IsValid == false) { //Throw/bubble up errors - throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); + throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - - var package = new CreatedPackage - { - Data = model - }; - //If ID is 0 & PackageGuid is null - its brand new - if(model.Id == 0 && model.PackageGuid == null) - { - //Brand new - package = CreatedPackage.MakeNew(model.Name); - - var packageId = package.Data.Id; - var packageGuid = package.Data.PackageGuid; - - //Need to reset the package ID - as the posted model the package ID is always 0 - //MakeNew will init create the XML & update the file and give us an ID to use - package.Data = model; - package.Data.Id = packageId; - package.Data.PackageGuid = packageGuid; - } - - //Save then publish - package.Save(); - package.Publish(); + package.Data = model; //We should have packagepath populated now return package.Data; } + public PackageDefinition PostCreatePackage(PackageDefinition model) + { + //creating requires an empty model/package id + if (model.Id != 0 || model.PackageGuid != null) + throw new HttpResponseException(HttpStatusCode.NotFound); + + if (ModelState.IsValid == false) + { + //Throw/bubble up errors + throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); + } + + //save it + Services.PackagingService.SavePackageDefinition(model); + + //then publish to get the file + //package.Publish(); + //TODO: We need a link to the downloadable zip file, in packagepath ? + + return model; + } + /// /// Deletes a created package /// diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index 4898c54616..b58ed05bde 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -9,12 +9,15 @@ using System.Threading.Tasks; using System.Web.Http; using System.Xml; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Packaging.Models; +using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Packaging; +using Umbraco.Core.Persistence; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Web.Composing; @@ -40,6 +43,16 @@ namespace Umbraco.Web.Editors [UmbracoApplicationAuthorize(Core.Constants.Applications.Packages)] public class PackageInstallController : UmbracoAuthorizedJsonController { + private readonly PackageActionRunner _packageActionRunner; + + public PackageInstallController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, + ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, + IProfilingLogger logger, IRuntimeState runtimeState, PackageActionRunner packageActionRunner) + : base(globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + _packageActionRunner = packageActionRunner; + } + /// /// This checks if this package & version is alraedy installed /// @@ -128,14 +141,14 @@ namespace Umbraco.Web.Editors //Remove Document Types var contentTypes = new List(); var contentTypeService = Services.ContentTypeService; - foreach (var item in pack.Data.Documenttypes.ToArray()) + foreach (var item in pack.Data.DocumentTypes.ToArray()) { int nId; if (int.TryParse(item, out nId) == false) continue; var contentType = contentTypeService.Get(nId); if (contentType == null) continue; contentTypes.Add(contentType); - pack.Data.Documenttypes.Remove(nId.ToString(CultureInfo.InvariantCulture)); + pack.Data.DocumentTypes.Remove(nId.ToString(CultureInfo.InvariantCulture)); } //Order the DocumentTypes before removing them @@ -195,8 +208,7 @@ namespace Umbraco.Web.Editors { try { - global::Umbraco.Web._Legacy.Packager.PackageInstance.PackageAction - .UndoPackageAction(pack.Data.Name, n.Attributes["alias"].Value, n); + _packageActionRunner.UndoPackageAction(pack.Data.Name, n.Attributes["alias"].Value, n); } catch (Exception ex) { diff --git a/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs b/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs index 2b1fce884d..3baa5e85ff 100644 --- a/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs +++ b/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs @@ -1,4 +1,10 @@ -using Umbraco.Web.WebApi; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; +using Umbraco.Core.Services; +using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web.Editors @@ -13,5 +19,26 @@ namespace Umbraco.Web.Editors [ValidateAngularAntiForgeryToken] [AngularJsonOnlyConfiguration] public abstract class UmbracoAuthorizedJsonController : UmbracoAuthorizedApiController - { } + { + /// + /// Initializes a new instance of the with auto dependencies. + /// + protected UmbracoAuthorizedJsonController() + { + } + + /// + /// Initializes a new instance of the class with all its dependencies. + /// + /// + /// + /// + /// + /// + /// + /// + protected UmbracoAuthorizedJsonController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, CacheHelper applicationCache, IProfilingLogger logger, IRuntimeState runtimeState) : base(globalSettings, umbracoContextAccessor, sqlContext, services, applicationCache, logger, runtimeState) + { + } + } } diff --git a/src/Umbraco.Web/Models/ContentEditing/UmbracoEntityTypes.cs b/src/Umbraco.Web/Models/ContentEditing/UmbracoEntityTypes.cs index 74e82ecfe9..04d06845d9 100644 --- a/src/Umbraco.Web/Models/ContentEditing/UmbracoEntityTypes.cs +++ b/src/Umbraco.Web/Models/ContentEditing/UmbracoEntityTypes.cs @@ -87,5 +87,7 @@ namespace Umbraco.Web.Models.ContentEditing /// Property Group /// PropertyGroup + + //TODO: Dictionary? } } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs index ce8b5835e2..f2392c9c3d 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs @@ -8,30 +8,29 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Security; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Core.Xml.XPath; using Umbraco.Web.PublishedCache.NuCache.Navigable; namespace Umbraco.Web.PublishedCache.NuCache { - class MemberCache : IPublishedMemberCache, INavigableData + internal class MemberCache : IPublishedMemberCache, INavigableData { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; public readonly IVariationContextAccessor VariationContextAccessor; + private readonly IEntityXmlSerializer _entitySerializer; private readonly ICacheProvider _snapshotCache; private readonly IMemberService _memberService; - private readonly IDataTypeService _dataTypeService; - private readonly ILocalizationService _localizationService; private readonly PublishedContentTypeCache _contentTypeCache; private readonly bool _previewDefault; - public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, IDataTypeService dataTypeService, ILocalizationService localizationService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) + public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IEntityXmlSerializer entitySerializer) { _snapshotCache = snapshotCache; _publishedSnapshotAccessor = publishedSnapshotAccessor; VariationContextAccessor = variationContextAccessor; + _entitySerializer = entitySerializer; _memberService = memberService; - _dataTypeService = dataTypeService; - _localizationService = localizationService; _previewDefault = previewDefault; _contentTypeCache = contentTypeCache; } @@ -141,7 +140,7 @@ namespace Umbraco.Web.PublishedCache.NuCache var result = _memberService.GetById(id); if (result == null) return null; - var s = EntityXmlSerializer.Serialize(_dataTypeService, _localizationService, result); + var s = _entitySerializer.Serialize(result); var n = s.GetXmlNode(); return n.CreateNavigator(); } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 3aa33f0e2f..4ebddee6dc 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -43,6 +43,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IMemberRepository _memberRepository; private readonly IGlobalSettings _globalSettings; private readonly ISiteDomainHelper _siteDomainHelper; + private readonly IEntityXmlSerializer _entitySerializer; private readonly IDefaultCultureAccessor _defaultCultureAccessor; // volatile because we read it with no lock @@ -85,7 +86,8 @@ namespace Umbraco.Web.PublishedCache.NuCache ILogger logger, IScopeProvider scopeProvider, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, - IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper) + IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, + IEntityXmlSerializer entitySerializer) : base(publishedSnapshotAccessor, variationContextAccessor) { //if (Interlocked.Increment(ref _singletonCheck) > 1) @@ -102,6 +104,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _defaultCultureAccessor = defaultCultureAccessor; _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; + _entitySerializer = entitySerializer; // we always want to handle repository events, configured or not // assuming no repository event will trigger before the whole db is ready @@ -1011,7 +1014,7 @@ namespace Umbraco.Web.PublishedCache.NuCache { ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainHelper, _globalSettings, _serviceContext.LocalizationService), MediaCache = new MediaCache(previewDefault, mediaSnap, snapshotCache, elementsCache), - MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, _serviceContext.DataTypeService, _serviceContext.LocalizationService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor), + MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _entitySerializer), DomainCache = domainCache, SnapshotCache = snapshotCache, ElementsCache = elementsCache diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs index 229a981510..7ec935139e 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Xml; using Umbraco.Examine; using Umbraco.Core.Cache; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Web.Composing; namespace Umbraco.Web.PublishedCache.XmlPublishedCache @@ -37,14 +38,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache // method GetExamineManagerSafe(). // private readonly ISearcher _searchProvider; - private readonly IIndex _indexProvider; private readonly XmlStore _xmlStore; private readonly PublishedContentTypeCache _contentTypeCache; + private readonly IEntityXmlSerializer _entitySerializer; // must be specified by the ctor private readonly ICacheProvider _cacheProvider; - public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, IUserService userService, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache) + public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, IUserService userService, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache, IEntityXmlSerializer entitySerializer) : base(false) { _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); @@ -53,6 +54,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _cacheProvider = cacheProvider; _xmlStore = xmlStore; _contentTypeCache = contentTypeCache; + _entitySerializer = entitySerializer; } /// @@ -61,18 +63,18 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache /// /// /// - /// /// /// - internal PublishedMediaCache(IMediaService mediaService, IUserService userService, ISearcher searchProvider, BaseIndexProvider indexProvider, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache) + /// + internal PublishedMediaCache(IMediaService mediaService, IUserService userService, ISearcher searchProvider, ICacheProvider cacheProvider, PublishedContentTypeCache contentTypeCache, IEntityXmlSerializer entitySerializer) : base(false) { _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); _userService = userService ?? throw new ArgumentNullException(nameof(userService)); _searchProvider = searchProvider ?? throw new ArgumentNullException(nameof(searchProvider)); - _indexProvider = indexProvider ?? throw new ArgumentNullException(nameof(indexProvider)); _cacheProvider = cacheProvider; _contentTypeCache = contentTypeCache; + _entitySerializer = entitySerializer; } static PublishedMediaCache() @@ -555,14 +557,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache return Enumerable.Empty(); } - var serialized = EntityXmlSerializer.Serialize( - Current.Services.MediaService, - Current.Services.DataTypeService, - Current.Services.UserService, - Current.Services.LocalizationService, - Current.UrlSegmentProviders, - media, - true); + var serialized = _entitySerializer.Serialize(media, true); var mediaIterator = serialized.CreateNavigator().Select("/"); diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs index 78585ba2e2..e286e9d95c 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs @@ -34,6 +34,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly IGlobalSettings _globalSettings; private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly ISiteDomainHelper _siteDomainHelper; + private readonly IEntityXmlSerializer _entitySerializer; #region Constructors @@ -42,20 +43,20 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IPublishedContentTypeFactory publishedContentTypeFactory, IScopeProvider scopeProvider, ICacheProvider requestCache, - IEnumerable segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, + IEntityXmlSerializer entitySerializer, MainDom mainDom, bool testing = false, bool enableRepositoryEvents = true) - : this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, segmentProviders, + : this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, publishedSnapshotAccessor, variationContextAccessor, documentRepository, mediaRepository, memberRepository, defaultCultureAccessor, - logger, globalSettings, siteDomainHelper, null, mainDom, testing, enableRepositoryEvents) + logger, globalSettings, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents) { } // used in some tests @@ -69,27 +70,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, - PublishedContentTypeCache contentTypeCache, - MainDom mainDom, - bool testing, bool enableRepositoryEvents) - : this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, Enumerable.Empty(), - publishedSnapshotAccessor, variationContextAccessor, - documentRepository, mediaRepository, memberRepository, - defaultCultureAccessor, - logger, globalSettings, siteDomainHelper, contentTypeCache, mainDom, testing, enableRepositoryEvents) - { } - - private PublishedSnapshotService(ServiceContext serviceContext, - IPublishedContentTypeFactory publishedContentTypeFactory, - IScopeProvider scopeProvider, - ICacheProvider requestCache, - IEnumerable segmentProviders, - IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, - IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, - IDefaultCultureAccessor defaultCultureAccessor, - ILogger logger, - IGlobalSettings globalSettings, - ISiteDomainHelper siteDomainHelper, + IEntityXmlSerializer entitySerializer, PublishedContentTypeCache contentTypeCache, MainDom mainDom, bool testing, bool enableRepositoryEvents) @@ -100,9 +81,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _contentTypeCache = contentTypeCache ?? new PublishedContentTypeCache(serviceContext.ContentTypeService, serviceContext.MediaTypeService, serviceContext.MemberTypeService, publishedContentTypeFactory, logger); - _xmlStore = new XmlStore(serviceContext, scopeProvider, _routesCache, - _contentTypeCache, segmentProviders, publishedSnapshotAccessor, mainDom, testing, enableRepositoryEvents, - documentRepository, mediaRepository, memberRepository, globalSettings); + _xmlStore = new XmlStore(serviceContext.ContentTypeService, serviceContext.ContentService, scopeProvider, _routesCache, + _contentTypeCache, publishedSnapshotAccessor, mainDom, testing, enableRepositoryEvents, + documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer); _domainService = serviceContext.DomainService; _memberService = serviceContext.MemberService; @@ -113,6 +94,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _requestCache = requestCache; _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; + _entitySerializer = entitySerializer; } public override void Dispose() @@ -157,7 +139,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache return new PublishedSnapshot( new PublishedContentCache(_xmlStore, domainCache, _requestCache, _globalSettings, _siteDomainHelper, _contentTypeCache, _routesCache, previewToken), - new PublishedMediaCache(_xmlStore, _mediaService, _userService, _requestCache, _contentTypeCache), + new PublishedMediaCache(_xmlStore, _mediaService, _userService, _requestCache, _contentTypeCache, _entitySerializer), new PublishedMemberCache(_xmlStore, _requestCache, _memberService, _contentTypeCache), domainCache); } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs index fef5039579..614515e433 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs @@ -44,15 +44,16 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly IMediaRepository _mediaRepository; private readonly IMemberRepository _memberRepository; private readonly IGlobalSettings _globalSettings; + private readonly IEntityXmlSerializer _entitySerializer; private XmlStoreFilePersister _persisterTask; private volatile bool _released; private bool _withRepositoryEvents; private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly PublishedContentTypeCache _contentTypeCache; - private readonly IEnumerable _segmentProviders; private readonly RoutesCache _routesCache; - private readonly ServiceContext _serviceContext; // fixme WHY + private readonly IContentTypeService _contentTypeService; + private readonly IContentService _contentService; private readonly IScopeProvider _scopeProvider; #region Constructors @@ -61,22 +62,23 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache /// Initializes a new instance of the class. /// /// The default constructor will boot the cache, load data from file or database, /// wire events in order to manage changes, etc. - public XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, - IEnumerable segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings) - : this(serviceContext, scopeProvider, routesCache, contentTypeCache, segmentProviders, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, globalSettings) + public XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, + IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer) + : this(contentTypeService, contentService, scopeProvider, routesCache, contentTypeCache, publishedSnapshotAccessor, mainDom, false, false, documentRepository, mediaRepository, memberRepository, globalSettings, entitySerializer) { } // internal for unit tests // no file nor db, no config check // fixme - er, we DO have a DB? - internal XmlStore(ServiceContext serviceContext, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, - IEnumerable segmentProviders, IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, - bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings) + internal XmlStore(IContentTypeService contentTypeService, IContentService contentService, IScopeProvider scopeProvider, RoutesCache routesCache, PublishedContentTypeCache contentTypeCache, + IPublishedSnapshotAccessor publishedSnapshotAccessor, MainDom mainDom, + bool testing, bool enableRepositoryEvents, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IGlobalSettings globalSettings, IEntityXmlSerializer entitySerializer) { if (testing == false) EnsureConfigurationIsValid(); - _serviceContext = serviceContext; + _contentTypeService = contentTypeService; + _contentService = contentService; _scopeProvider = scopeProvider; _routesCache = routesCache; _contentTypeCache = contentTypeCache; @@ -85,8 +87,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _mediaRepository = mediaRepository; _memberRepository = memberRepository; _globalSettings = globalSettings; + _entitySerializer = entitySerializer; _xmlFileName = IOHelper.MapPath(SystemFiles.GetContentCacheXml(_globalSettings)); - _segmentProviders = segmentProviders; if (testing) { @@ -399,7 +401,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache try { var dtdInner = new StringBuilder(); - var contentTypes = _serviceContext.ContentTypeService.GetAll(); + var contentTypes = _contentTypeService.GetAll(); // though aliases should be safe and non null already? var aliases = contentTypes.Select(x => x.Alias.ToSafeAlias()).WhereNotNull(); foreach (var alias in aliases) @@ -556,7 +558,7 @@ AND (umbracoNode.id=@id)"; public XmlDocument GetPreviewXml(int contentId, bool includeSubs) { - var content = _serviceContext.ContentService.GetById(contentId); + var content = _contentService.GetById(contentId); var doc = (XmlDocument)Xml.Clone(); if (content == null) return doc; @@ -1065,7 +1067,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; continue; } - var content = _serviceContext.ContentService.GetById(payload.Id); + var content = _contentService.GetById(payload.Id); var current = safeXml.Xml.GetElementById(payload.Id.ToInvariantString()); if (content == null || content.Published == false || content.Trashed) @@ -1536,7 +1538,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; var entity = args.Entity; // serialize edit values for preview - var editXml = EntityXmlSerializer.Serialize(_serviceContext.ContentService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, entity, false).ToDataString(); + var editXml = _entitySerializer.Serialize(entity, false).ToDataString(); // change below to write only one row - not one per version var dto1 = new PreviewXmlDto @@ -1565,7 +1567,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; return; // serialize published values for content cache - var publishedXml = EntityXmlSerializer.Serialize(_serviceContext.ContentService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, entity, true).ToDataString(); + var publishedXml = _entitySerializer.Serialize(entity, true).ToDataString(); var dto2 = new ContentXmlDto { NodeId = entity.Id, Xml = publishedXml }; OnRepositoryRefreshed(db, dto2); @@ -1581,7 +1583,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; if (entity.Trashed) db.Execute("DELETE FROM cmsContentXml WHERE nodeId=@id", new { id = entity.Id }); - var xml = EntityXmlSerializer.Serialize(_serviceContext.MediaService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, entity).ToDataString(); + var xml = _entitySerializer.Serialize(entity).ToDataString(); var dto1 = new ContentXmlDto { NodeId = entity.Id, Xml = xml }; OnRepositoryRefreshed(db, dto1); @@ -1592,7 +1594,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; var db = args.Scope.Database; var entity = args.Entity; - var xml = EntityXmlSerializer.Serialize(_serviceContext.DataTypeService, _serviceContext.LocalizationService, entity).ToDataString(); + var xml = _entitySerializer.Serialize(entity).ToDataString(); var dto1 = new ContentXmlDto { NodeId = entity.Id, Xml = xml }; OnRepositoryRefreshed(db, dto1); @@ -1749,7 +1751,7 @@ WHERE cmsContentXml.nodeId IN ( var descendants = _documentRepository.GetPage(query, pageIndex++, groupSize, out total, null, Ordering.By("Path")); const bool published = true; // contentXml contains published content! var items = descendants.Select(c => new ContentXmlDto { NodeId = c.Id, Xml = - EntityXmlSerializer.Serialize(_serviceContext.ContentService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, c, published).ToDataString() }).ToArray(); + _entitySerializer.Serialize(c, published).ToDataString() }).ToArray(); db.BulkInsertRecords(items); processed += items.Length; } while (processed < total); @@ -1824,7 +1826,7 @@ WHERE cmsPreviewXml.nodeId IN ( var items = descendants.Select(c => new PreviewXmlDto { NodeId = c.Id, - Xml = EntityXmlSerializer.Serialize(_serviceContext.ContentService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, c, published).ToDataString() + Xml = _entitySerializer.Serialize(c, published).ToDataString() }).ToArray(); db.BulkInsertRecords(items); processed += items.Length; @@ -1894,7 +1896,7 @@ WHERE cmsContentXml.nodeId IN ( { var descendants = _mediaRepository.GetPage(query, pageIndex++, groupSize, out total, null, Ordering.By("Path")); var items = descendants.Select(m => new ContentXmlDto { NodeId = m.Id, Xml = - EntityXmlSerializer.Serialize(_serviceContext.MediaService, _serviceContext.DataTypeService, _serviceContext.UserService, _serviceContext.LocalizationService, _segmentProviders, m).ToDataString() }).ToArray(); + _entitySerializer.Serialize(m).ToDataString() }).ToArray(); db.BulkInsertRecords(items); processed += items.Length; } while (processed < total); @@ -1962,7 +1964,7 @@ WHERE cmsContentXml.nodeId IN ( do { var descendants = _memberRepository.GetPage(query, pageIndex++, groupSize, out total, null, Ordering.By("Path")); - var items = descendants.Select(m => new ContentXmlDto { NodeId = m.Id, Xml = EntityXmlSerializer.Serialize(_serviceContext.DataTypeService, _serviceContext.LocalizationService, m).ToDataString() }).ToArray(); + var items = descendants.Select(m => new ContentXmlDto { NodeId = m.Id, Xml = _entitySerializer.Serialize(m).ToDataString() }).ToArray(); db.BulkInsertRecords(items); processed += items.Length; } while (processed < total); diff --git a/src/Umbraco.Web/Services/SectionService.cs b/src/Umbraco.Web/Services/SectionService.cs index 5d013d7e79..6337db67f9 100644 --- a/src/Umbraco.Web/Services/SectionService.cs +++ b/src/Umbraco.Web/Services/SectionService.cs @@ -298,7 +298,7 @@ namespace Umbraco.Web.Services //we need to interrogate the attributes for the data. Would be better to have a base class that contains //metadata populated by the attribute. Oh well i guess. var attrs = types.Select(x => x.GetCustomAttributes(false).Single()); - return Enumerable.ToArray
(attrs.Select(x => new Section(x.Name, x.Alias, x.SortOrder))); + return attrs.Select(x => new Section(x.Name, x.Alias, x.SortOrder)).ToArray(); }); } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 36f0a835b1..fdf7f48201 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1144,9 +1144,6 @@ - - - @@ -1231,7 +1228,6 @@ Code - FeedProxy.aspx diff --git a/src/Umbraco.Web/_Legacy/Packager/Installer.cs b/src/Umbraco.Web/_Legacy/Packager/Installer.cs index 15ea222bda..9d7fe77e7b 100644 --- a/src/Umbraco.Web/_Legacy/Packager/Installer.cs +++ b/src/Umbraco.Web/_Legacy/Packager/Installer.cs @@ -14,18 +14,18 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; +using Umbraco.Core.Packaging; using Umbraco.Core.Services.Implement; using Umbraco.Core.Xml; using Umbraco.Web._Legacy.Packager.PackageInstance; using File = System.IO.File; -using PackageAction = Umbraco.Web._Legacy.Packager.PackageInstance.PackageAction; namespace Umbraco.Web._Legacy.Packager { /// /// The packager is a component which enables sharing of both data and functionality components between different umbraco installations. /// - /// The output is a .umb (a zip compressed file) which contains the exported documents/medias/macroes/documenttypes (etc.) + /// The output is a .umb (a zip compressed file) which contains the exported documents/medias/macroes/documentTypes (etc.) /// in a Xml document, along with the physical files used (images/usercontrols/xsl documents etc.) /// /// Partly implemented, import of packages is done, the export is *under construction*. @@ -420,7 +420,7 @@ namespace Umbraco.Web._Legacy.Packager var contentTypes = packagingService.ImportContentTypes(docTypeElement, currentUser.Id); foreach (var contentType in contentTypes) { - insPack.Data.Documenttypes.Add(contentType.Id.ToString(CultureInfo.InvariantCulture)); + insPack.Data.DocumentTypes.Add(contentType.Id.ToString(CultureInfo.InvariantCulture)); //saveNeeded = true; } } @@ -510,7 +510,7 @@ namespace Umbraco.Web._Legacy.Packager if (alias.IsNullOrWhiteSpace() == false) { - PackageAction.RunPackageAction(insPack.Data.Name, alias, n); + Current.PackageActionRunner.RunPackageAction(insPack.Data.Name, alias, n); } } } diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/CreatedPackage.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/CreatedPackage.cs index 3bfcdd3f86..deff3b2ffd 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/CreatedPackage.cs +++ b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/CreatedPackage.cs @@ -7,11 +7,13 @@ using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using File = System.IO.File; namespace Umbraco.Web._Legacy.Packager.PackageInstance { + //TODO: Fix this class , service + model + internal? public class CreatedPackage { @@ -22,14 +24,13 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance return pack; } - public static CreatedPackage MakeNew(string name) + public static CreatedPackage MakeNew(string name, Core.Models.Packaging.PackageDefinition packageData = null) { var pack = new CreatedPackage { - Data = data.MakeNew(name, IOHelper.MapPath(Settings.CreatedPackagesSettings)) + Data = packageData ?? data.MakeNew(name, IOHelper.MapPath(Settings.CreatedPackagesSettings)) }; - return pack; } @@ -43,7 +44,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance data.Delete(this.Data.Id, IOHelper.MapPath(Settings.CreatedPackagesSettings)); } - public PackageInstance Data { get; set; } + public Core.Models.Packaging.PackageDefinition Data { get; set; } public static List GetAllCreatedPackages() { @@ -81,7 +82,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance } - public void Publish() + public void Publish(IEntityXmlSerializer serializer) { var package = this; @@ -118,7 +119,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance //var umbDocument = new Document(contentNodeId); //var x = umbDocument.ToXml(_packageManifest, pack.ContentLoadChildNodes); var udoc = Current.Services.ContentService.GetById(contentNodeId); - var xe = pack.ContentLoadChildNodes ? udoc.ToDeepXml(Current.Services.PackagingService) : udoc.ToXml(Current.Services.PackagingService); + var xe = pack.ContentLoadChildNodes ? udoc.ToDeepXml(serializer) : udoc.ToXml(serializer); var x = xe.GetXmlNode(_packageManifest); documentSet.AppendChild(x); @@ -188,7 +189,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance //Document types.. var dtl = new List(); var docTypes = _packageManifest.CreateElement("DocumentTypes"); - foreach (var dtId in pack.Documenttypes) + foreach (var dtId in pack.DocumentTypes) { if (int.TryParse(dtId, out outInt)) { @@ -200,11 +201,9 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance } } - var exporter = new EntityXmlSerializer(); - foreach (var d in dtl) { - var xml = exporter.Serialize(Current.Services.DataTypeService, Current.Services.ContentTypeService, d); + var xml = serializer.Serialize(d); var xNode = xml.GetXmlNode(); var n = (XmlElement) _packageManifest.ImportNode(xNode, true); docTypes.AppendChild(n); @@ -220,7 +219,6 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance { var t = Current.Services.FileService.GetTemplate(outInt); - var serializer = new EntityXmlSerializer(); var serialized = serializer.Serialize(t); var n = serialized.GetXmlNode(_packageManifest); @@ -241,16 +239,16 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance } AppendElement(stylesheets); - //Macros - var macros = _packageManifest.CreateElement("Macros"); - foreach (var macroId in pack.Macros) - { - if (int.TryParse(macroId, out outInt)) - { - macros.AppendChild(PackagerUtility.Macro(int.Parse(macroId), true, localPath, _packageManifest)); - } - } - AppendElement(macros); + ////Macros + //var macros = _packageManifest.CreateElement("Macros"); + //foreach (var macroId in pack.Macros) + //{ + // if (int.TryParse(macroId, out outInt)) + // { + // macros.AppendChild(PackagerUtility.Macro(int.Parse(macroId), true, localPath, _packageManifest)); + // } + //} + //AppendElement(macros); //Dictionary Items var dictionaryItems = _packageManifest.CreateElement("DictionaryItems"); @@ -259,8 +257,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance if (int.TryParse(dictionaryId, out outInt)) { var di = Current.Services.LocalizationService.GetDictionaryItemById(outInt); - var entitySerializer = new EntityXmlSerializer(); - var xmlNode = entitySerializer.Serialize(di).GetXmlNode(_packageManifest); + var xmlNode = serializer.Serialize(di, false).GetXmlNode(_packageManifest); dictionaryItems.AppendChild(xmlNode); } } @@ -274,7 +271,6 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance { var lang = Current.Services.LocalizationService.GetLanguageById(outInt); - var serializer = new EntityXmlSerializer(); var xml = serializer.Serialize(lang); var n = xml.GetXmlNode(_packageManifest); @@ -328,7 +324,10 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance AppendElement(actions); } } - catch { } + catch + { + //TODO: Log!? + } } var manifestFileName = localPath + "/package.xml"; diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/IPackageInstance.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/IPackageInstance.cs deleted file mode 100644 index b920c85a9f..0000000000 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/IPackageInstance.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Umbraco.Web._Legacy.Packager.PackageInstance{ - public interface IPackageInstance { - string Actions { get; set; } - string Author { get; set; } - string AuthorUrl { get; set; } - bool ContentLoadChildNodes { get; set; } - string ContentNodeId { get; set; } - System.Collections.Generic.List Documenttypes { get; set; } - System.Collections.Generic.List Files { get; set; } - string Folder { get; set; } - bool HasUpdate { get; set; } - int Id { get; set; } - string License { get; set; } - string LicenseUrl { get; set; } - string LoadControl { get; set; } - System.Collections.Generic.List Macros { get; set; } - string Name { get; set; } - string PackageGuid { get; set; } - string PackagePath { get; set; } - string Readme { get; set; } - string RepositoryGuid { get; set; } - System.Collections.Generic.List Stylesheets { get; set; } - System.Collections.Generic.List Templates { get; set; } - string Url { get; set; } - string Version { get; set; } - } -} diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs index 5842a456e5..8c106f142d 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs +++ b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs @@ -53,7 +53,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance List val = new List(); - foreach (PackageInstance pack in data.GetAllPackages(IOHelper.MapPath(Settings.InstalledPackagesSettings))) + foreach (Core.Models.Packaging.PackageDefinition pack in data.GetAllPackages(IOHelper.MapPath(Settings.InstalledPackagesSettings))) { InstalledPackage insPackage = new InstalledPackage(); insPackage.Data = pack; @@ -63,8 +63,8 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance return val; } - private PackageInstance m_data; - public PackageInstance Data + private Core.Models.Packaging.PackageDefinition m_data; + public Core.Models.Packaging.PackageDefinition Data { get { return m_data; } set { m_data = value; } @@ -156,7 +156,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance { var macros = TryGetIntegerIds(Data.Macros).Select(macroService.GetById).ToList(); var templates = TryGetIntegerIds(Data.Templates).Select(fileService.GetTemplate).ToList(); - var contentTypes = TryGetIntegerIds(Data.Documenttypes).Select(contentTypeService.Get).ToList(); // fixme - media types? + var contentTypes = TryGetIntegerIds(Data.DocumentTypes).Select(contentTypeService.Get).ToList(); // fixme - media types? var dataTypes = TryGetIntegerIds(Data.DataTypes).Select(dataTypeService.GetDataType).ToList(); var dictionaryItems = TryGetIntegerIds(Data.DictionaryItems).Select(localizationService.GetDictionaryItemById).ToList(); var languages = TryGetIntegerIds(Data.Languages).Select(localizationService.GetLanguageById).ToList(); diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageInstance.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageInstance.cs deleted file mode 100644 index 8ec3c21bdb..0000000000 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageInstance.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; - -namespace Umbraco.Web._Legacy.Packager.PackageInstance -{ - [DataContract(Name = "packageInstance")] - public class PackageInstance - { - [DataMember(Name = "id")] - public int Id { get; set; } - - [DataMember(Name = "repositoryGuid")] - public string RepositoryGuid { get; set; } - - [DataMember(Name = "packageGuid")] - public string PackageGuid { get; set; } - - [DataMember(Name = "hasUpdate")] - public bool HasUpdate { get; set; } - - [DataMember(Name = "name")] - [Required] - public string Name { get; set; } - - [DataMember(Name = "url")] - [Required] - [Url] - public string Url { get; set; } - - [DataMember(Name = "folder")] - public string Folder { get; set; } - - [DataMember(Name = "packagePath")] - public string PackagePath { get; set; } - - [DataMember(Name = "version")] - [Required] - public string Version { get; set; } - - /// - /// The minimum umbraco version that this package requires - /// - [DataMember(Name = "umbracoVersion")] - public Version UmbracoVersion { get; set; } - - [DataMember(Name = "author")] - [Required] - public string Author { get; set; } - - [DataMember(Name = "authorUrl")] - [Required] - [Url] - public string AuthorUrl { get; set; } - - [DataMember(Name = "license")] - public string License { get; set; } - - [DataMember(Name = "licenseUrl")] - public string LicenseUrl { get; set; } - - [DataMember(Name = "readme")] - public string Readme { get; set; } - - [DataMember(Name = "contentLoadChildNodes")] - public bool ContentLoadChildNodes { get; set; } - - [DataMember(Name = "contentNodeId")] - public string ContentNodeId { get; set; } - - [DataMember(Name = "macros")] - public List Macros { get; set; } - - [DataMember(Name = "languages")] - public List Languages { get; set; } - - [DataMember(Name = "dictionaryItems")] - public List DictionaryItems { get; set; } - - [DataMember(Name = "templates")] - public List Templates { get; set; } - - [DataMember(Name = "documenttypes")] - public List Documenttypes { get; set; } - - [DataMember(Name = "stylesheets")] - public List Stylesheets { get; set; } - - [DataMember(Name = "files")] - public List Files { get; set; } - - [DataMember(Name = "loadControl")] - public string LoadControl { get; set; } - - [DataMember(Name = "actions")] - public string Actions { get; set; } - - [DataMember(Name = "dataTypes")] - public List DataTypes { get; set; } - - [DataMember(Name = "iconUrl")] - public string IconUrl { get; set; } - - public PackageInstance() - { - Name = string.Empty; - Url = string.Empty; - Folder = string.Empty; - PackagePath = string.Empty; - Version = string.Empty; - UmbracoVersion = null; - Author = string.Empty; - AuthorUrl = string.Empty; - License = string.Empty; - LicenseUrl = string.Empty; - Readme = string.Empty; - ContentNodeId = string.Empty; - IconUrl = string.Empty; - Macros = new List(); - Languages = new List(); - DictionaryItems = new List(); - Templates = new List(); - Documenttypes = new List(); - Stylesheets = new List(); - Files = new List(); - LoadControl = string.Empty; - DataTypes = new List(); - ContentLoadChildNodes = false; - } - } -} diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackagerUtility.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackagerUtility.cs index d972977bad..af32e8c80a 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackagerUtility.cs +++ b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackagerUtility.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; namespace Umbraco.Web._Legacy.Packager.PackageInstance { @@ -22,7 +23,7 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance /// The packinstance. /// The xml document. /// - public static XmlNode PackageInfo(PackageInstance pack, XmlDocument doc) + public static XmlNode PackageInfo(Core.Models.Packaging.PackageDefinition pack, XmlDocument doc) { XmlNode info = doc.CreateElement("info"); @@ -60,31 +61,6 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance return info; } - - /// - /// Converts an umbraco template to a package xml node - /// - /// The template id. - /// The xml doc. - /// - public static XmlNode Template(int templateId, XmlDocument doc) - { - var tmpl = Current.Services.FileService.GetTemplate(templateId); - //Template tmpl = new Template(templateId); - - XmlNode template = doc.CreateElement("Template"); - template.AppendChild(CreateNode("Name", tmpl.Name, doc)); - template.AppendChild(CreateNode("Alias", tmpl.Alias, doc)); - - //if (tmpl.MasterTemplate != 0) - if (string.IsNullOrWhiteSpace(tmpl.MasterTemplateAlias) == false) - template.AppendChild(CreateNode("Master", tmpl.MasterTemplateAlias, doc)); - - template.AppendChild(CreateNode("Design", "", doc)); - - return template; - } - /// /// Converts a umbraco stylesheet to a package xml node /// @@ -118,29 +94,6 @@ namespace Umbraco.Web._Legacy.Packager.PackageInstance return stylesheet; } - /// - /// Converts a macro to a package xml node - /// - /// The macro id. - /// if set to true [append file]. - /// The package directory. - /// The doc. - /// - public static XmlNode Macro(int macroId, bool appendFile, string packageDirectory, XmlDocument doc) - { - var mcr = Current.Services.MacroService.GetById(macroId); - - if (appendFile) - { - if (!string.IsNullOrEmpty(mcr.MacroSource)) - AppendFileToManifest(mcr.MacroSource, packageDirectory, doc); - } - - var serializer = new EntityXmlSerializer(); - var xml = serializer.Serialize(mcr); - return xml.GetXmlNode(doc); - } - /// /// Appends a file to package manifest and copies the file to the correct folder. diff --git a/src/Umbraco.Web/_Legacy/Packager/Settings.cs b/src/Umbraco.Web/_Legacy/Packager/Settings.cs index 57ab4b9ea4..92b0ae030a 100644 --- a/src/Umbraco.Web/_Legacy/Packager/Settings.cs +++ b/src/Umbraco.Web/_Legacy/Packager/Settings.cs @@ -6,69 +6,11 @@ namespace Umbraco.Web._Legacy.Packager { public class Settings { + public static string InstalledPackagesSettings => SystemDirectories.Packages + IOHelper.DirSepChar + "installedPackages.config"; - public static string PackagerRoot - { - get { return SystemDirectories.Packages; } - } - - public static string PackagesStorage - { - get { return SystemDirectories.Packages + IOHelper.DirSepChar + "created"; } - } - - public static string InstalledPackagesStorage - { - get { return SystemDirectories.Packages + IOHelper.DirSepChar + "installed"; } - } - - public static string InstalledPackagesSettings - { - get { return SystemDirectories.Packages + IOHelper.DirSepChar + "installed" + IOHelper.DirSepChar + "installedPackages.config"; } - } - - public static string CreatedPackagesSettings - { - get { return SystemDirectories.Packages + IOHelper.DirSepChar + "created" + IOHelper.DirSepChar + "createdPackages.config"; } - } - - public static string PackageFileExtension - { - get { return "zip"; } - } - - public static bool HasFileAccess(ref Exception exp) - { - bool hasAccess = false; - StreamWriter sw1 = null; - StreamWriter sw2 = null; - try - { - sw1 = System.IO.File.AppendText(IOHelper.MapPath(InstalledPackagesSettings)); - sw1.Close(); - - sw2 = System.IO.File.AppendText(IOHelper.MapPath(CreatedPackagesSettings)); - sw1.Close(); - - System.IO.Directory.CreateDirectory(IOHelper.MapPath(PackagesStorage) + IOHelper.DirSepChar + "__testFolder__"); - System.IO.Directory.CreateDirectory(IOHelper.MapPath(InstalledPackagesStorage) + IOHelper.DirSepChar + "__testFolder__"); - - System.IO.Directory.Delete(IOHelper.MapPath(PackagesStorage) + IOHelper.DirSepChar + "__testFolder__", true); - System.IO.Directory.Delete(IOHelper.MapPath(InstalledPackagesStorage) + IOHelper.DirSepChar + "__testFolder__", true); - - hasAccess = true; - } - finally - { - if (sw1 != null) - sw1.Close(); - if (sw2 != null) - sw2.Close(); - } - - return hasAccess; - } + public static string CreatedPackagesSettings => SystemDirectories.Packages + IOHelper.DirSepChar + "createdPackages.config"; + public static string PackageFileExtension => "zip"; } diff --git a/src/Umbraco.Web/_Legacy/Packager/data.cs b/src/Umbraco.Web/_Legacy/Packager/data.cs index 962b7d5ed4..1882c151d2 100644 --- a/src/Umbraco.Web/_Legacy/Packager/data.cs +++ b/src/Umbraco.Web/_Legacy/Packager/data.cs @@ -23,20 +23,12 @@ namespace Umbraco.Web._Legacy.Packager //do some error checking and create the folders/files if they don't exist if (!File.Exists(dataSource)) { - if (!Directory.Exists(IOHelper.MapPath(Settings.PackagerRoot))) + if (!Directory.Exists(IOHelper.MapPath(SystemDirectories.Packages))) { - Directory.CreateDirectory(IOHelper.MapPath(Settings.PackagerRoot)); - } - if (!Directory.Exists(IOHelper.MapPath(Settings.PackagesStorage))) - { - Directory.CreateDirectory(IOHelper.MapPath(Settings.PackagesStorage)); - } - if (!Directory.Exists(IOHelper.MapPath(Settings.InstalledPackagesStorage))) - { - Directory.CreateDirectory(IOHelper.MapPath(Settings.InstalledPackagesStorage)); + Directory.CreateDirectory(IOHelper.MapPath(SystemDirectories.Packages)); } - using (StreamWriter sw = File.CreateText(dataSource)) + using (var sw = File.CreateText(dataSource)) { sw.Write($@"{Environment.NewLine}{Environment.NewLine}"); sw.Flush(); @@ -85,7 +77,7 @@ namespace Umbraco.Web._Legacy.Packager return Source.SelectSingleNode("/packages/package [@packageGuid = '" + guid + "']"); } - public static PackageInstance.PackageInstance MakeNew(string Name, string dataSource) + public static Core.Models.Packaging.PackageDefinition MakeNew(string name, string dataSource) { Reload(dataSource); @@ -101,7 +93,7 @@ namespace Umbraco.Web._Legacy.Packager instance.Attributes.Append(XmlHelper.AddAttribute(Source, "id", maxId.ToString())); instance.Attributes.Append(XmlHelper.AddAttribute(Source, "version", "")); instance.Attributes.Append(XmlHelper.AddAttribute(Source, "url", "")); - instance.Attributes.Append(XmlHelper.AddAttribute(Source, "name", Name)); + instance.Attributes.Append(XmlHelper.AddAttribute(Source, "name", name)); instance.Attributes.Append(XmlHelper.AddAttribute(Source, "folder", Guid.NewGuid().ToString())); instance.Attributes.Append(XmlHelper.AddAttribute(Source, "packagepath", "")); instance.Attributes.Append(XmlHelper.AddAttribute(Source, "repositoryGuid", "")); @@ -137,7 +129,7 @@ namespace Umbraco.Web._Legacy.Packager instance.AppendChild(XmlHelper.AddTextNode(Source, "templates", "")); instance.AppendChild(XmlHelper.AddTextNode(Source, "stylesheets", "")); - instance.AppendChild(XmlHelper.AddTextNode(Source, "documenttypes", "")); + instance.AppendChild(XmlHelper.AddTextNode(Source, "documentTypes", "")); instance.AppendChild(XmlHelper.AddTextNode(Source, "macros", "")); instance.AppendChild(XmlHelper.AddTextNode(Source, "files", "")); instance.AppendChild(XmlHelper.AddTextNode(Source, "languages", "")); @@ -151,26 +143,26 @@ namespace Umbraco.Web._Legacy.Packager return retVal; } - public static PackageInstance.PackageInstance Package(int id, string datasource) + public static Core.Models.Packaging.PackageDefinition Package(int id, string datasource) { return ConvertXmlToPackage(GetFromId(id, datasource, true)); } - public static PackageInstance.PackageInstance Package(string guid, string datasource) + public static Core.Models.Packaging.PackageDefinition Package(string guid, string datasource) { XmlNode node = GetFromGuid(guid, datasource, true); if (node != null) return ConvertXmlToPackage(node); else - return new PackageInstance.PackageInstance(); + return new Core.Models.Packaging.PackageDefinition(); } - public static List GetAllPackages(string dataSource) + public static List GetAllPackages(string dataSource) { Reload(dataSource); XmlNodeList nList = data.Source.SelectNodes("packages/package"); - List retVal = new List(); + List retVal = new List(); for (int i = 0; i < nList.Count; i++) { @@ -187,9 +179,9 @@ namespace Umbraco.Web._Legacy.Packager return retVal; } - private static PackageInstance.PackageInstance ConvertXmlToPackage(XmlNode n) + private static Core.Models.Packaging.PackageDefinition ConvertXmlToPackage(XmlNode n) { - PackageInstance.PackageInstance retVal = new PackageInstance.PackageInstance(); + Core.Models.Packaging.PackageDefinition retVal = new Core.Models.Packaging.PackageDefinition(); if (n != null) { @@ -227,7 +219,7 @@ namespace Umbraco.Web._Legacy.Packager retVal.Macros = new List(SafeNodeValue(n.SelectSingleNode("macros")).Trim(',').Split(',')); retVal.Templates = new List(SafeNodeValue(n.SelectSingleNode("templates")).Trim(',').Split(',')); retVal.Stylesheets = new List(SafeNodeValue(n.SelectSingleNode("stylesheets")).Trim(',').Split(',')); - retVal.Documenttypes = new List(SafeNodeValue(n.SelectSingleNode("documenttypes")).Trim(',').Split(',')); + retVal.DocumentTypes = new List(SafeNodeValue(n.SelectSingleNode("documentTypes")).Trim(',').Split(',')); retVal.Languages = new List(SafeNodeValue(n.SelectSingleNode("languages")).Trim(',').Split(',')); retVal.DictionaryItems = new List(SafeNodeValue(n.SelectSingleNode("dictionaryitems")).Trim(',').Split(',')); retVal.DataTypes = new List(SafeNodeValue(n.SelectSingleNode("datatypes")).Trim(',').Split(',')); @@ -263,7 +255,7 @@ namespace Umbraco.Web._Legacy.Packager } - public static void Save(PackageInstance.PackageInstance package, string dataSource) + public static void Save(Core.Models.Packaging.PackageDefinition package, string dataSource) { Reload(dataSource); var xmlDef = GetFromId(package.Id, dataSource, false); @@ -311,7 +303,7 @@ namespace Umbraco.Web._Legacy.Packager XmlHelper.SetTextNode(Source, xmlDef, "macros", JoinList(package.Macros, ',')); XmlHelper.SetTextNode(Source, xmlDef, "templates", JoinList(package.Templates, ',')); XmlHelper.SetTextNode(Source, xmlDef, "stylesheets", JoinList(package.Stylesheets, ',')); - XmlHelper.SetTextNode(Source, xmlDef, "documenttypes", JoinList(package.Documenttypes, ',')); + XmlHelper.SetTextNode(Source, xmlDef, "documentTypes", JoinList(package.DocumentTypes, ',')); XmlHelper.SetTextNode(Source, xmlDef, "languages", JoinList(package.Languages, ',')); XmlHelper.SetTextNode(Source, xmlDef, "dictionaryitems", JoinList(package.DictionaryItems, ',')); XmlHelper.SetTextNode(Source, xmlDef, "datatypes", JoinList(package.DataTypes, ',')); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/CreatedPackageTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/CreatedPackageTasks.cs deleted file mode 100644 index 47980f2808..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/CreatedPackageTasks.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Umbraco.Core.Logging; -using Umbraco.Web.UI; -using Umbraco.Core; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web._Legacy.Packager.PackageInstance; -using Umbraco.Web._Legacy.UI; - -namespace Umbraco.Web -{ - public class CreatedPackageTasks : LegacyDialogTask - { - - public override bool PerformSave() - { - Current.Logger.Info("Xml save started"); - int id = CreatedPackage.MakeNew(Alias).Data.Id; - _returnUrl = string.Format("developer/packages/editPackage.aspx?id={0}", id); - return true; - } - - public override bool PerformDelete() - { - // we need to grab the id from the alias as the new tree needs to prefix the NodeID with "package_" - if (ParentID == 0) - { - ParentID = int.Parse(Alias.Substring("package_".Length)); - } - CreatedPackage.GetById(ParentID).Delete(); - return true; - } - - private string _returnUrl = ""; - - public override string ReturnUrl - { - get { return _returnUrl; } - } - - public override string AssignedApp - { - get { return Constants.Applications.Packages.ToString(); } - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs index 645aa088f2..3b863895a4 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs @@ -10,6 +10,8 @@ using System.Xml; using umbraco.controls; using Umbraco.Core; using Umbraco.Core.IO; +using Umbraco.Core.Models.Packaging; +using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.UI; using Umbraco.Web.UI.Pages; using Umbraco.Web._Legacy.Packager.PackageInstance; @@ -32,7 +34,7 @@ namespace umbraco.presentation.developer.packages public Umbraco.Web._Legacy.Controls.TabPage packageActions; protected ContentPicker cp; - private PackageInstance pack; + private PackageDefinition pack; private CreatedPackage createdPackage; protected void Page_Load(object sender, EventArgs e) @@ -102,7 +104,7 @@ namespace umbraco.presentation.developer.packages foreach (var dc in nContentTypes) { ListItem li = new ListItem(dc.Name, dc.Id.ToString()); - if (pack.Documenttypes.Contains(dc.Id.ToString())) + if (pack.DocumentTypes.Contains(dc.Id.ToString())) li.Selected = true; documentTypes.Items.Add(li); @@ -223,41 +225,41 @@ namespace umbraco.presentation.developer.packages e.IsValid = true; } - protected void saveOrPublish(object sender, CommandEventArgs e) - { + //protected void saveOrPublish(object sender, CommandEventArgs e) + //{ - if (!Page.IsValid) - { - this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Error, "Saved failed.", "Some fields have not been filled-out correctly"); - } - else - { - if (e.CommandName == "save") - SavePackage(true); + // if (!Page.IsValid) + // { + // this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Error, "Saved failed.", "Some fields have not been filled-out correctly"); + // } + // else + // { + // if (e.CommandName == "save") + // SavePackage(true); - if (e.CommandName == "publish") - { - SavePackage(false); - int packageID = int.Parse(Request.QueryString["id"]); - //string packFileName = cms.businesslogic.packager. Publish.publishPackage(packageID); + // if (e.CommandName == "publish") + // { + // SavePackage(false); + // int packageID = int.Parse(Request.QueryString["id"]); + // //string packFileName = cms.businesslogic.packager. Publish.publishPackage(packageID); - createdPackage.Publish(); + // createdPackage.Publish(); - if (!string.IsNullOrEmpty(pack.PackagePath)) - { + // if (!string.IsNullOrEmpty(pack.PackagePath)) + // { - packageUmbFile.Text = "   Download"; + // packageUmbFile.Text = "   Download"; - this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Success, "Package saved and published", ""); - } - else - { - this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Error, "Save failed", "check your umbraco log."); - } - } - } - } + // this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Success, "Package saved and published", ""); + // } + // else + // { + // this.ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Error, "Save failed", "check your umbraco log."); + // } + // } + // } + //} private void SavePackage(bool showNotification) @@ -300,7 +302,7 @@ namespace umbraco.presentation.developer.packages if (li.Selected) tmpDoctypes += li.Value + ","; } - pack.Documenttypes = new List(tmpDoctypes.Trim(',').Split(',')); + pack.DocumentTypes = new List(tmpDoctypes.Trim(',').Split(',')); string tmpMacros = ""; @@ -361,7 +363,7 @@ namespace umbraco.presentation.developer.packages if (newPath.Trim() != "") { CreatedPackage createdPackage = CreatedPackage.GetById(int.Parse(Request.QueryString["id"])); - PackageInstance pack = createdPackage.Data; + PackageDefinition pack = createdPackage.Data; pack.Files.Add(newPath); @@ -388,7 +390,7 @@ namespace umbraco.presentation.developer.packages } CreatedPackage createdPackage = CreatedPackage.GetById(int.Parse(Request.QueryString["id"])); - PackageInstance pack = createdPackage.Data; + PackageDefinition pack = createdPackage.Data; pack.Files = new List(tmpFilePathString.Trim('�').Split('�')); pack.Files.TrimExcess();