diff --git a/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs
index 16934dc4c4..67d0c2970f 100644
--- a/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs
+++ b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
@@ -29,6 +30,7 @@ namespace Umbraco.Core.Models.Packaging
[DataMember(Name = "folder")]
public Guid FolderId { get; set; }
+ [ReadOnly(true)]
[DataMember(Name = "packagePath")]
public string PackagePath { get; set; } = string.Empty;
diff --git a/src/Umbraco.Core/Packaging/PackageBuilder.cs b/src/Umbraco.Core/Packaging/PackageBuilder.cs
index cc77f9bc78..6b26b09cbe 100644
--- a/src/Umbraco.Core/Packaging/PackageBuilder.cs
+++ b/src/Umbraco.Core/Packaging/PackageBuilder.cs
@@ -162,7 +162,9 @@ namespace Umbraco.Core.Packaging
var actionsXml = new XElement("Actions");
try
{
- actionsXml.Add(XElement.Parse(definition.Actions));
+ //this will be formatted like a full xml block like ... and we want the child nodes
+ var parsed = XElement.Parse(definition.Actions);
+ actionsXml.Add(parsed.Elements());
manifestRoot.Add(actionsXml);
}
catch (Exception e)
@@ -596,7 +598,7 @@ namespace Umbraco.Core.Packaging
Author = xml.Element("author")?.Value ?? string.Empty,
AuthorUrl = xml.Element("author")?.AttributeValue("url") ?? string.Empty,
Readme = xml.Element("readme")?.Value ?? string.Empty,
- Actions = xml.Element("actions")?.ToString() ?? string.Empty,
+ Actions = xml.Element("actions")?.ToString(SaveOptions.None) ?? string.Empty, //take the entire outer xml value
ContentNodeId = xml.Element("content")?.AttributeValue("nodeId") ?? string.Empty,
ContentLoadChildNodes = xml.Element("content")?.AttributeValue("loadChildNodes") ?? false,
Macros = xml.Element("macros")?.Value.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(),
@@ -613,8 +615,18 @@ namespace Umbraco.Core.Packaging
return retVal;
}
- private static XElement PackageDefinitionToXml(PackageDefinition def)
+ private XElement PackageDefinitionToXml(PackageDefinition def)
{
+ var actionsXml = new XElement("actions");
+ try
+ {
+ actionsXml = XElement.Parse(def.Actions);
+ }
+ catch (Exception e)
+ {
+ _logger.Warn(e, "Could not add package actions to the package xml definition, the xml did not parse");
+ }
+
var packageXml = new XElement("package",
new XAttribute("id", def.Id),
new XAttribute("version", def.Version ?? string.Empty),
@@ -634,8 +646,8 @@ namespace Umbraco.Core.Packaging
new XCData(def.Author ?? string.Empty),
new XAttribute("url", def.AuthorUrl ?? string.Empty)),
- new XElement("readme", def.Readme ?? string.Empty),
- new XElement("actions", def.Actions ?? string.Empty),
+ new XElement("readme", new XCData(def.Readme ?? string.Empty)),
+ actionsXml,
new XElement("datatypes", string.Join(",", def.DataTypes ?? Array.Empty())),
new XElement("content",
diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js
index 5f3832f79b..f351456609 100644
--- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js
@@ -1,7 +1,7 @@
(function () {
"use strict";
- function EditController($scope, $location, $routeParams, entityResource, stylesheetResource, languageResource, packageResource, dictionaryResource, editorService, formHelper) {
+ function EditController($scope, $location, $routeParams, umbRequestHelper, entityResource, stylesheetResource, languageResource, packageResource, dictionaryResource, editorService, formHelper) {
const vm = this;
@@ -21,6 +21,7 @@
vm.removeFile = removeFile;
vm.openControlPicker = openControlPicker;
vm.removeControl = removeControl;
+ vm.downloadFile = downloadFile;
const packageId = $routeParams.id;
const create = $routeParams.create;
@@ -76,8 +77,14 @@
vm.stylesheets = stylesheets;
});
- // TODO: implement macros
- vm.macros = [];
+ entityResource.getAll("Macro").then(macros => {
+ // a package stores the id as a string so we
+ // need to convert all ids to string for comparison
+ macros.forEach(macro => {
+ macro.id = macro.id.toString();
+ });
+ vm.macros = macros;
+ });
// get all languages
languageResource.getAll().then(languages => {
@@ -111,6 +118,17 @@
}
+ function downloadFile(id) {
+ var url = umbRequestHelper.getApiUrl(
+ "packageApiBaseUrl",
+ "DownloadCreatedPackage",
+ { id: id });
+
+ umbRequestHelper.downloadFile(url).then(function () {
+
+ });
+ }
+
function back() {
$location.path("packages/packages/overview").search('create', null);;
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html
index b1a417fd6f..20bc4277f8 100644
--- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html
@@ -48,9 +48,10 @@
+
@@ -170,7 +171,15 @@
- NOT IMPLEMENTED IN V8 YET
+
+
+
+
@@ -301,6 +310,14 @@
+
+
+
+
+
diff --git a/src/Umbraco.Web/Editors/PackageController.cs b/src/Umbraco.Web/Editors/PackageController.cs
index 66a0349417..0369e3eb24 100644
--- a/src/Umbraco.Web/Editors/PackageController.cs
+++ b/src/Umbraco.Web/Editors/PackageController.cs
@@ -1,9 +1,12 @@
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
+using System.Net.Http.Headers;
using System.Web.Http;
+using Umbraco.Core.IO;
using Umbraco.Core.Models.Packaging;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
@@ -33,7 +36,7 @@ namespace Umbraco.Web.Editors
var package = Services.PackagingService.GetById(id);
if (package == null)
throw new HttpResponseException(HttpStatusCode.NotFound);
-
+
return package;
}
@@ -75,6 +78,40 @@ namespace Umbraco.Web.Editors
return Ok();
}
-
+
+ [HttpGet]
+ public HttpResponseMessage DownloadCreatedPackage(int id)
+ {
+ var package = Services.PackagingService.GetById(id);
+ if (package == null)
+ return Request.CreateResponse(HttpStatusCode.NotFound);
+
+ var fullPath = IOHelper.MapPath(package.PackagePath);
+ if (!File.Exists(fullPath))
+ return Request.CreateNotificationValidationErrorResponse("No file found for path " + package.PackagePath);
+
+ var fileName = Path.GetFileName(package.PackagePath);
+
+ var response = new HttpResponseMessage
+ {
+ Content = new StreamContent(File.OpenRead(fullPath))
+ {
+ Headers =
+ {
+ ContentDisposition = new ContentDispositionHeaderValue("attachment")
+ {
+ FileName = fileName
+ },
+ ContentType = new MediaTypeHeaderValue( "application/octet-stream")
+ }
+ }
+ };
+
+ // Set custom header so umbRequestHelper.downloadFile can save the correct filename
+ response.Headers.Add("x-filename", fileName);
+
+ return response;
+ }
+
}
}