diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js
new file mode 100644
index 0000000000..c1d95861eb
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js
@@ -0,0 +1,105 @@
+/**
+ * @ngdoc service
+ * @name umbraco.resources.packageInstallResource
+ * @description handles data for package installations
+ **/
+function packageResource($q, $http, umbDataFormatter, umbRequestHelper) {
+
+ return {
+
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.packageInstallResource#fetchPackage
+ * @methodOf umbraco.resources.packageInstallResource
+ *
+ * @description
+ * Downloads a package file from our.umbraco.org to the website server.
+ *
+ * ##usage
+ *
+ * packageResource.download("guid-guid-guid-guid")
+ * .then(function(path) {
+ * alert('downloaded');
+ * });
+ *
+ *
+ * @param {String} the unique package ID
+ * @returns {String} path to the downloaded zip file.
+ *
+ */
+ fetch: function (id) {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "packageInstallApiBaseUrl",
+ "Fetch",
+ [{ packageGuid: id }])),
+ 'Failed to download package with guid ' + id);
+ },
+
+ /**
+ * @ngdoc method
+ * @name umbraco.resources.packageInstallResource#createmanifest
+ * @methodOf umbraco.resources.packageInstallResource
+ *
+ * @description
+ * Creates a package manifest for a given folder of files.
+ * This manifest keeps track of all installed files and data items
+ * so a package can be uninstalled at a later time.
+ * After creating a manifest, you can use the ID to install files and data.
+ *
+ * ##usage
+ *
+ * packageResource.createManifest("packages/id-of-install-file")
+ * .then(function(summary) {
+ * alert('unzipped');
+ * });
+ *
+ *
+ * @param {String} folder the path to the temporary folder containing files
+ * @returns {Int} the ID assigned to the saved package manifest
+ *
+ */
+ import: function (package) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "packageInstallApiBaseUrl",
+ "Import"), package),
+ 'Failed to create package manifest for zip file ');
+ },
+
+ installFiles: function (package) {
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "packageInstallApiBaseUrl",
+ "InstallFiles"), package),
+ 'Failed to create package manifest for zip file ');
+ },
+
+ installData: function (package) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "packageInstallApiBaseUrl",
+ "InstallData"), package),
+ 'Failed to create package manifest for zip file ');
+ },
+
+ cleanUp: function (package) {
+
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "packageInstallApiBaseUrl",
+ "CleanUp"), package),
+ 'Failed to create package manifest for zip file ');
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('packageResource', packageResource);
diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js
index be10ebae9e..092f3cbf0f 100644
--- a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js
@@ -16,6 +16,44 @@ function startUpVideosDashboardController($scope, xmlhelper, $log, $http) {
}
angular.module("umbraco").controller("Umbraco.Dashboard.StartupVideosController", startUpVideosDashboardController);
+
+
+function FormsController($scope, $route, packageResource) {
+ $scope.installForms = function(){
+ $scope.state = "Installng package";
+ packageResource
+ .fetch("6DA629D5-177A-4ACE-875B-A06B13CCEC48")
+ .then(function(pack){
+ $scope.state = "importing";
+ return packageResource.import(pack);
+ }, $scope.error)
+ .then(function(pack){
+ $scope.state = "Installing";
+ return packageResource.installFiles(pack);
+ }, $scope.error)
+ .then(function(pack){
+ $scope.state = "Restarting, please hold...";
+ return packageResource.installData(pack);
+ }, $scope.error)
+ .then(function(pack){
+ $scope.state = "All done, your browser will now refresh";
+ return packageResource.cleanUp(pack);
+ }, $scope.error)
+ .then($scope.complete, $scope.error);
+ };
+
+ $scope.complete = function(result){
+ $route.reload();
+ };
+
+ $scope.error = function(err){
+ $scope.state = undefined;
+ $scope.error = err;
+ };
+}
+
+angular.module("umbraco").controller("Umbraco.Dashboard.FormsDashboardController", FormsController);
+
function startupLatestEditsController($scope) {
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html
new file mode 100644
index 0000000000..8ba5746a80
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html
@@ -0,0 +1,34 @@
+
+
Build flawless forms without a single line of code
+
Contour makes creating contact forms, entry forms and questionnaires just as easy as using Word. You won't need to write a single line of code.
+
Instead, you can create, edit and administer your forms via a user interface that is a fully integrated part of Umbraco.
+
+
Download a free trial now
+
+
+
+
+ {{error}}
+
+
+
+
Some of the great features
+
+
+
+
Feature
+
+
+
Feature
+
+
+
Feature
+
+
+
Feature
+
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/config/Dashboard.Release.config b/src/Umbraco.Web.UI/config/Dashboard.Release.config
index c76ee4c62c..14fd92ada0 100644
--- a/src/Umbraco.Web.UI/config/Dashboard.Release.config
+++ b/src/Umbraco.Web.UI/config/Dashboard.Release.config
@@ -12,6 +12,17 @@
+
+
+ forms
+
+
+
+ views/dashboard/forms/formsdashboardintro.html
+
+
+
+
developer
diff --git a/src/Umbraco.Web.UI/config/applications.Release.config b/src/Umbraco.Web.UI/config/applications.Release.config
index 062500e1fc..c35a68e941 100644
--- a/src/Umbraco.Web.UI/config/applications.Release.config
+++ b/src/Umbraco.Web.UI/config/applications.Release.config
@@ -6,5 +6,6 @@
-
+
+
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs
index 6343d614b4..8ef7753c6f 100644
--- a/src/Umbraco.Web/Editors/BackOfficeController.cs
+++ b/src/Umbraco.Web/Editors/BackOfficeController.cs
@@ -178,6 +178,10 @@ namespace Umbraco.Web.Editors
"memberApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl(
controller => controller.GetByKey(Guid.Empty))
},
+ {
+ "packageInstallApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl(
+ controller => controller.Fetch(string.Empty))
+ },
{
"rteApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl(
controller => controller.GetConfiguration())
@@ -186,6 +190,7 @@ namespace Umbraco.Web.Editors
"stylesheetApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl(
controller => controller.GetAll())
},
+
{
"templateApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl(
controller => controller.GetById(0))
diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs
new file mode 100644
index 0000000000..346a5153d1
--- /dev/null
+++ b/src/Umbraco.Web/Editors/PackageInstallController.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.IO.Compression;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Http;
+using System.Xml;
+using System.Xml.Linq;
+using umbraco.cms.businesslogic.packager.repositories;
+using Umbraco.Core.IO;
+using Umbraco.Core.Packaging.Models;
+using Umbraco.Core.Services;
+using Umbraco.Web.Models;
+using Umbraco.Web.Mvc;
+using Umbraco.Web.WebApi.Filters;
+
+namespace Umbraco.Web.Editors
+{
+ [PluginController("UmbracoApi")]
+ [UmbracoApplicationAuthorize(Core.Constants.Applications.Developer)]
+ public class PackageInstallController : UmbracoAuthorizedJsonController
+ {
+
+ [HttpGet]
+ public PackageInstallModel Fetch(string packageGuid)
+ {
+ //Default path
+ string path = Path.Combine("packages", packageGuid + ".umb");
+ if (!File.Exists(IOHelper.MapPath(Path.Combine(SystemDirectories.Data, path))))
+ {
+ //our repo guid
+ var our = Repository.getByGuid("65194810-1f85-11dd-bd0b-0800200c9a66");
+ path = our.fetch(packageGuid);
+ }
+
+ PackageInstallModel p = new PackageInstallModel();
+ p.PackageGuid = Guid.Parse(packageGuid);
+ p.RepositoryGuid = Guid.Parse("65194810-1f85-11dd-bd0b-0800200c9a66");
+ //p.ZipFilePath = path;
+ p.ZipFilePath = Path.Combine("temp", "package.umb");
+ return p;
+ }
+
+ [HttpPost]
+ public PackageInstallModel Import(PackageInstallModel model)
+ {
+ global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer();
+ model.TemporaryDirectoryPath = Path.Combine(SystemDirectories.Data, ins.Import(model.ZipFilePath));
+ model.Id = ins.CreateManifest( IOHelper.MapPath(model.TemporaryDirectoryPath), model.PackageGuid.ToString(), model.RepositoryGuid.ToString());
+ return model;
+ }
+
+ [HttpPost]
+ public PackageInstallModel InstallFiles(PackageInstallModel model)
+ {
+ global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer();
+ ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath));
+ ins.InstallFiles(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath));
+ return model;
+ }
+
+
+ [HttpPost]
+ public PackageInstallModel InstallData(PackageInstallModel model)
+ {
+ global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer();
+ ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath));
+ ins.InstallBusinessLogic(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath));
+ return model;
+ }
+
+
+ [HttpPost]
+ public PackageInstallModel CleanUp(PackageInstallModel model)
+ {
+ global::umbraco.cms.businesslogic.packager.Installer ins = new global::umbraco.cms.businesslogic.packager.Installer();
+ ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath));
+ ins.InstallCleanUp(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath));
+ return model;
+ }
+
+
+ }
+}
diff --git a/src/Umbraco.Web/Models/PackageInstallModel.cs b/src/Umbraco.Web/Models/PackageInstallModel.cs
new file mode 100644
index 0000000000..34b28843b6
--- /dev/null
+++ b/src/Umbraco.Web/Models/PackageInstallModel.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Umbraco.Web.Models
+{
+ [DataContract(Name = "packageInstallModel")]
+ public class PackageInstallModel
+ {
+ [DataMember(Name="id")]
+ public int Id { get; set; }
+
+ [DataMember(Name = "packageGuid")]
+ public Guid PackageGuid { get; set; }
+
+ [DataMember(Name = "repositoryGuid")]
+ public Guid RepositoryGuid { get; set; }
+
+ [DataMember(Name = "temporaryDirectoryPath")]
+ public string TemporaryDirectoryPath { get; set; }
+
+ [DataMember(Name = "zipFilePath")]
+ public string ZipFilePath { get; set; }
+ }
+}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index c4a3f20a17..4a3859e926 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -160,6 +160,7 @@
System.Drawing
+
False
False
@@ -303,9 +304,11 @@
+
+