Gets package uninstall working, fixes other UI issues with packages
This commit is contained in:
@@ -149,37 +149,50 @@ namespace Umbraco.Core.Packaging
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the package actions stored in the package definition
|
||||
/// </summary>
|
||||
/// <param name="actionsElement"></param>
|
||||
/// <param name="packageName"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<PackageAction> GetPackageActions(XElement actionsElement, string packageName)
|
||||
{
|
||||
if (actionsElement == null) { return new PackageAction[0]; }
|
||||
if (actionsElement == null) return Enumerable.Empty<PackageAction>();
|
||||
|
||||
if (string.Equals("Actions", actionsElement.Name.LocalName) == false)
|
||||
throw new ArgumentException($"Must be \"Actions\" as root", nameof(actionsElement));
|
||||
//invariant check ... because people can realy enter anything :/
|
||||
if (!string.Equals("actions", actionsElement.Name.LocalName, StringComparison.InvariantCultureIgnoreCase))
|
||||
throw new FormatException("Must be \"<actions>\" as root");
|
||||
|
||||
return actionsElement.Elements("Action")
|
||||
.Select(elemet =>
|
||||
if (!actionsElement.HasElements) return Enumerable.Empty<PackageAction>();
|
||||
|
||||
var actionElementName = actionsElement.Elements().First().Name.LocalName;
|
||||
|
||||
//invariant check ... because people can realy enter anything :/
|
||||
if (!string.Equals("action", actionElementName, StringComparison.InvariantCultureIgnoreCase))
|
||||
throw new FormatException("Must be \"<action\" as element");
|
||||
|
||||
return actionsElement.Elements(actionElementName)
|
||||
.Select(e =>
|
||||
{
|
||||
var aliasAttr = elemet.Attribute("Alias");
|
||||
var aliasAttr = e.Attribute("alias") ?? e.Attribute("Alias"); //allow both ... because people can really enter anything :/
|
||||
if (aliasAttr == null)
|
||||
throw new ArgumentException("missing \"Alias\" atribute in alias element", nameof(actionsElement));
|
||||
throw new ArgumentException("missing \"alias\" atribute in alias element", nameof(actionsElement));
|
||||
|
||||
var packageAction = new PackageAction
|
||||
{
|
||||
XmlData = elemet,
|
||||
XmlData = e,
|
||||
Alias = aliasAttr.Value,
|
||||
PackageName = packageName,
|
||||
};
|
||||
|
||||
|
||||
var attr = elemet.Attribute("runat");
|
||||
var attr = e.Attribute("runat") ?? e.Attribute("Runat"); //allow both ... because people can really enter anything :/
|
||||
|
||||
if (attr != null && Enum.TryParse(attr.Value, true, out ActionRunAt runAt)) { packageAction.RunAt = runAt; }
|
||||
|
||||
attr = elemet.Attribute("undo");
|
||||
attr = e.Attribute("undo") ?? e.Attribute("Undo"); //allow both ... because people can really enter anything :/
|
||||
|
||||
if (attr != null && bool.TryParse(attr.Value, out var undo)) { packageAction.Undo = undo; }
|
||||
|
||||
|
||||
return packageAction;
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
@@ -105,5 +105,7 @@ namespace Umbraco.Core.Packaging
|
||||
|
||||
return packageXml;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace Umbraco.Core.Packaging
|
||||
{
|
||||
//running this will update the PackageDefinition with the items being removed
|
||||
var summary = _packageDataInstallation.UninstallPackageData(package, userId);
|
||||
|
||||
summary.Actions = _parser.GetPackageActions(XElement.Parse(package.Actions), package.Name);
|
||||
|
||||
//run actions before files are removed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesOverviewController($scope, $route, $location, navigationService, $timeout, localStorageService) {
|
||||
function PackagesOverviewController($scope, $location, localStorageService) {
|
||||
|
||||
//Hack!
|
||||
// if there is a cookie value for packageInstallUri then we need to redirect there,
|
||||
@@ -9,12 +9,13 @@
|
||||
// because it will double load it.
|
||||
// we will refresh and then navigate there.
|
||||
|
||||
var installPackageUri = localStorageService.get("packageInstallUri");
|
||||
const packageUri = $location.search().subview;
|
||||
let installPackageUri = localStorageService.get("packageInstallUri");
|
||||
let packageUri = $location.search().subview;
|
||||
|
||||
if (installPackageUri) {
|
||||
localStorageService.remove("packageInstallUri");
|
||||
}
|
||||
|
||||
if (installPackageUri && installPackageUri !== "installed") {
|
||||
//navigate to the custom installer screen, if it is just "installed", then we'll
|
||||
//show the installed view
|
||||
@@ -23,6 +24,8 @@
|
||||
else {
|
||||
var vm = this;
|
||||
|
||||
packageUri = installPackageUri ? installPackageUri : packageUri; //use the path stored in storage over the one in the current path
|
||||
|
||||
vm.page = {};
|
||||
vm.page.name = "Packages";
|
||||
vm.page.navigation = [
|
||||
@@ -30,7 +33,7 @@
|
||||
"name": "Packages",
|
||||
"icon": "icon-cloud",
|
||||
"view": "views/packages/views/repo.html",
|
||||
"active": !packageUri || installPackageUri === "navigation" || packageUri === "navigation",
|
||||
"active": !packageUri || packageUri === "navigation",
|
||||
"alias": "umbPackages",
|
||||
"action": function() {
|
||||
$location.search("subview", "navigation");
|
||||
@@ -40,7 +43,7 @@
|
||||
"name": "Installed",
|
||||
"icon": "icon-box",
|
||||
"view": "views/packages/views/installed.html",
|
||||
"active": installPackageUri === "installed" || packageUri === "installed",
|
||||
"active": packageUri === "installed",
|
||||
"alias": "umbInstalled",
|
||||
"action": function() {
|
||||
$location.search("subview", "installed");
|
||||
@@ -50,7 +53,7 @@
|
||||
"name": "Install local",
|
||||
"icon": "icon-add",
|
||||
"view": "views/packages/views/install-local.html",
|
||||
"active": installPackageUri === "local" || packageUri === "local",
|
||||
"active": packageUri === "local",
|
||||
"alias": "umbInstallLocal",
|
||||
"action": function() {
|
||||
$location.search("subview", "local");
|
||||
|
||||
@@ -1,28 +1,24 @@
|
||||
<div data-element="editor-packages" ng-controller="Umbraco.Editors.Packages.OverviewController as vm" class="clearfix">
|
||||
|
||||
<form name="packagesForm" ng-submit="save()" novalidate val-form-manager>
|
||||
<umb-editor-view footer="false">
|
||||
|
||||
<umb-editor-view footer="false">
|
||||
<umb-editor-header
|
||||
name="vm.page.name"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
navigation="vm.page.navigation"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-header
|
||||
name="vm.page.name"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
navigation="vm.page.navigation"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
<umb-editor-container>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-editor-sub-views
|
||||
sub-views="vm.page.navigation" model="vm.page">
|
||||
</umb-editor-sub-views>
|
||||
|
||||
<umb-editor-sub-views
|
||||
sub-views="vm.page.navigation" model="vm.page">
|
||||
</umb-editor-sub-views>
|
||||
</umb-editor-container>
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</form>
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function PackagesInstallLocalController($scope, $route, $location, Upload, umbRequestHelper, packageResource, localStorageService, $timeout, $window, localizationService, $q) {
|
||||
function PackagesInstallLocalController($scope, Upload, umbRequestHelper, packageResource, localStorageService, $timeout, $window, localizationService, $q) {
|
||||
|
||||
var vm = this;
|
||||
vm.state = "upload";
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
};
|
||||
vm.package = {};
|
||||
|
||||
var labels = {};
|
||||
|
||||
function init() {
|
||||
packageResource.getInstalled()
|
||||
.then(function (packs) {
|
||||
@@ -20,6 +22,16 @@
|
||||
});
|
||||
vm.installState.status = "";
|
||||
vm.state = "list";
|
||||
|
||||
var labelKeys = [
|
||||
"packager_installStateUninstalling",
|
||||
"packager_installStateComplete",
|
||||
];
|
||||
|
||||
localizationService.localizeMany(labelKeys).then(function (values) {
|
||||
labels.installStateUninstalling = values[0];
|
||||
labels.installStateComplete = values[1];
|
||||
});
|
||||
}
|
||||
|
||||
function confirmUninstall(pck) {
|
||||
@@ -28,14 +40,14 @@
|
||||
}
|
||||
|
||||
function uninstallPackage(installedPackage) {
|
||||
vm.installState.status = localizationService.localize("packager_installStateUninstalling");
|
||||
vm.installState.status = labels.installStateUninstalling;
|
||||
vm.installState.progress = "0";
|
||||
|
||||
packageResource.uninstall(installedPackage.id)
|
||||
.then(function () {
|
||||
|
||||
if (installedPackage.files.length > 0) {
|
||||
vm.installState.status = localizationService.localize("packager_installStateComplete");
|
||||
vm.installState.status = labels.installStateComplete;
|
||||
vm.installState.progress = "100";
|
||||
|
||||
//set this flag so that on refresh it shows the installed packages list
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
//using System;
|
||||
//using System.Linq;
|
||||
//using System.Net;
|
||||
//using System.Net.Http;
|
||||
//using System.Text;
|
||||
//using System.Threading.Tasks;
|
||||
//using System.Web;
|
||||
//using System.Web.Http;
|
||||
//using Newtonsoft.Json.Linq;
|
||||
//using umbraco;
|
||||
//using Umbraco.Core;
|
||||
//using Umbraco.Web.Cache;
|
||||
//using Umbraco.Core.Configuration;
|
||||
//using Umbraco.Core.Models.Packaging;
|
||||
//using Umbraco.Core.Services;
|
||||
//using Umbraco.Web.Composing;
|
||||
//using Umbraco.Web.Install.Models;
|
||||
//using Umbraco.Web.WebApi;
|
||||
|
||||
//namespace Umbraco.Web.Install.Controllers
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// A controller for the installation process regarding packages
|
||||
// /// </summary>
|
||||
// /// <remarks>
|
||||
// /// Currently this is used for web services however we should/could eventually migrate the whole installer to MVC as it
|
||||
// /// is a bit of a mess currently.
|
||||
// /// </remarks>
|
||||
// [HttpInstallAuthorize]
|
||||
// [AngularJsonOnlyConfiguration]
|
||||
// [Obsolete("This is only used for the legacy way of installing starter kits in the back office")]
|
||||
// //fixme: Is this used anymore??
|
||||
// public class InstallPackageController : ApiController
|
||||
// {
|
||||
// private readonly IPackagingService _packagingService;
|
||||
// private readonly UmbracoContext _umbracoContext;
|
||||
|
||||
// public InstallPackageController(IPackagingService packagingService, UmbracoContext umbracoContext)
|
||||
// {
|
||||
// _packagingService = packagingService;
|
||||
// _umbracoContext = umbracoContext;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Empty action, useful for retrieving the base url for this controller
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpGet]
|
||||
// public HttpResponseMessage Index()
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Connects to the repo, downloads the package and creates the definition
|
||||
// /// </summary>
|
||||
// /// <param name="model"></param>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public async Task<HttpResponseMessage> DownloadPackageFiles(InstallPackageModel model)
|
||||
// {
|
||||
// var packageFile = await _packagingService.FetchPackageFileAsync(
|
||||
// model.KitGuid,
|
||||
// UmbracoVersion.Current,
|
||||
// UmbracoContext.Current.Security.CurrentUser.Id);
|
||||
|
||||
|
||||
// var packageInfo = _packagingService.GetCompiledPackageInfo(packageFile);
|
||||
// if (packageInfo == null) throw new InvalidOperationException("Could not read package file " + packageFile);
|
||||
|
||||
// //save to the installedPackages.config
|
||||
// var packageDefinition = PackageDefinition.FromCompiledPackage(packageInfo);
|
||||
// _packagingService.SaveInstalledPackage(packageDefinition);
|
||||
|
||||
// return Json(new
|
||||
// {
|
||||
// success = true,
|
||||
// packageId = packageDefinition.Id,
|
||||
// packageFile = packageInfo.PackageFileName,
|
||||
// percentage = 10,
|
||||
// message = "Downloading starter kit files..."
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Installs the files in the package
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public HttpResponseMessage InstallPackageFiles(InstallPackageModel model)
|
||||
// {
|
||||
// model.PackageFile = HttpUtility.UrlDecode(model.PackageFile);
|
||||
|
||||
// var definition = _packagingService.GetInstalledPackageById(model.PackageId);
|
||||
// if (definition == null) throw new InvalidOperationException("Not package definition found with id " + model.PackageId);
|
||||
|
||||
// _packagingService.InstallCompiledPackageFiles(definition, model.PackageFile, _umbracoContext.Security.GetUserId().ResultOr(0));
|
||||
|
||||
// return Json(new
|
||||
// {
|
||||
// success = true,
|
||||
// ManifestId = model.PackageId,
|
||||
// model.PackageFile,
|
||||
// percentage = 20,
|
||||
// message = "Installing starter kit files"
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Ensures the app pool is restarted
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public HttpResponseMessage RestartAppPool()
|
||||
// {
|
||||
// Current.RestartAppPool(Request.TryGetHttpContext().Result);
|
||||
// return Json(new
|
||||
// {
|
||||
// success = true,
|
||||
// percentage = 25,
|
||||
// message = "Installing starter kit files"
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Checks if the app pool has completed restarted
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public HttpResponseMessage CheckAppPoolRestart()
|
||||
// {
|
||||
// if (Request.TryGetHttpContext().Result.Application.AllKeys.Contains("AppPoolRestarting"))
|
||||
// {
|
||||
// return Request.CreateResponse(HttpStatusCode.BadRequest);
|
||||
// }
|
||||
|
||||
// return Json(new
|
||||
// {
|
||||
// percentage = 30,
|
||||
// success = true,
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Installs the business logic portion of the package after app restart
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public HttpResponseMessage InstallBusinessLogic(InstallPackageModel model)
|
||||
// {
|
||||
// model.PackageFile = HttpUtility.UrlDecode(model.PackageFile);
|
||||
|
||||
// var definition = _packagingService.GetInstalledPackageById(model.PackageId);
|
||||
// if (definition == null) throw new InvalidOperationException("Not package definition found with id " + model.PackageId);
|
||||
|
||||
// _packagingService.InstallCompiledPackageData(definition, model.PackageFile, _umbracoContext.Security.GetUserId().ResultOr(0));
|
||||
|
||||
// return Json(new
|
||||
// {
|
||||
// success = true,
|
||||
// ManifestId = model.PackageId,
|
||||
// model.PackageFile,
|
||||
// percentage = 70,
|
||||
// message = "Installing starter kit files"
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Cleans up the package installation
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [HttpPost]
|
||||
// public HttpResponseMessage CleanupInstallation(InstallPackageModel model)
|
||||
// {
|
||||
// model.PackageFile = HttpUtility.UrlDecode(model.PackageFile);
|
||||
|
||||
// return Json(new
|
||||
// {
|
||||
// success = true,
|
||||
// ManifestId = model.PackageId,
|
||||
// model.PackageFile,
|
||||
// percentage = 100,
|
||||
// message = "Starter kit has been installed"
|
||||
// }, HttpStatusCode.OK);
|
||||
// }
|
||||
|
||||
// private HttpResponseMessage Json(object jsonObject, HttpStatusCode status)
|
||||
// {
|
||||
// var response = Request.CreateResponse(status);
|
||||
// var json = JObject.FromObject(jsonObject);
|
||||
// response.Content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
|
||||
// return response;
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
@@ -32,14 +32,6 @@ namespace Umbraco.Web.Install
|
||||
new { controller = "Install", action = "Index", id = UrlParameter.Optional },
|
||||
new[] { typeof(InstallController).Namespace });
|
||||
|
||||
//TODO: We can remove this when we re-build the back office package installer
|
||||
//Create the install routes
|
||||
context.MapHttpRoute(
|
||||
"Umbraco_install_packages",
|
||||
"Install/PackageInstaller/{action}/{id}",
|
||||
new { controller = "InstallPackage", action = "Index", id = UrlParameter.Optional },
|
||||
new[] { typeof(InstallPackageController).Namespace });
|
||||
|
||||
context.MapHttpRoute(
|
||||
"umbraco-install-api",
|
||||
"install/api/{action}/{id}",
|
||||
|
||||
Reference in New Issue
Block a user