From f8f0707c79dfcb971cab7d8163445850eb633e0d Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Fri, 22 Jun 2012 12:56:45 -0700 Subject: [PATCH] Making Import/Export extensible --HG-- branch : 1.x --- .../Controllers/AdminController.cs | 33 ++++++++-- .../Models/ExportOptions.cs | 5 +- .../Orchard.ImportExport.csproj | 2 + .../Services/ICustomExportStep.cs | 8 +++ .../Services/IExportEventHandler.cs | 17 +++++ .../Services/ImportExportService.cs | 15 ++++- .../ViewModels/ExportViewModel.cs | 6 ++ .../Views/Admin/Export.cshtml | 66 ++++++++++++------- 8 files changed, 122 insertions(+), 30 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Services/ICustomExportStep.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportEventHandler.cs diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs index 9853fb416..ad28a6194 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs @@ -14,10 +14,17 @@ namespace Orchard.ImportExport.Controllers { public class AdminController : Controller { private readonly IImportExportService _importExportService; private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly ICustomExportStep _customExportStep; - public AdminController(IOrchardServices services, IImportExportService importExportService, IContentDefinitionManager contentDefinitionManager) { + public AdminController( + IOrchardServices services, + IImportExportService importExportService, + IContentDefinitionManager contentDefinitionManager, + ICustomExportStep customExportStep + ) { _importExportService = importExportService; _contentDefinitionManager = contentDefinitionManager; + _customExportStep = customExportStep; Services = services; T = NullLocalizer.Instance; } @@ -50,10 +57,18 @@ namespace Orchard.ImportExport.Controllers { } public ActionResult Export() { - var viewModel = new ExportViewModel { ContentTypes = new List() }; + var customSteps = new List(); + _customExportStep.Register(customSteps); + + var viewModel = new ExportViewModel { + ContentTypes = new List(), + CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x }).ToList() + }; + foreach (var contentType in _contentDefinitionManager.ListTypeDefinitions().OrderBy(c => c.Name)) { viewModel.ContentTypes.Add(new ContentTypeEntry { ContentTypeName = contentType.Name }); } + return View(viewModel); } @@ -62,11 +77,21 @@ namespace Orchard.ImportExport.Controllers { if (!Services.Authorizer.Authorize(Permissions.Export, T("Not allowed to export."))) return new HttpUnauthorizedResult(); - var viewModel = new ExportViewModel { ContentTypes = new List() }; + var viewModel = new ExportViewModel { + ContentTypes = new List(), + CustomSteps = new List() + }; UpdateModel(viewModel); var contentTypesToExport = viewModel.ContentTypes.Where(c => c.IsChecked).Select(c => c.ContentTypeName); - var exportOptions = new ExportOptions { ExportMetadata = viewModel.Metadata, ExportSiteSettings = viewModel.SiteSettings }; + var customSteps = viewModel.CustomSteps.Where(c => c.IsChecked).Select(c => c.CustomStep); + + var exportOptions = new ExportOptions { + ExportMetadata = viewModel.Metadata, + ExportSiteSettings = viewModel.SiteSettings, + CustomSteps = customSteps + }; + if (viewModel.Data) { exportOptions.ExportData = true; exportOptions.VersionHistoryOptions = (VersionHistoryOptions)Enum.Parse(typeof(VersionHistoryOptions), viewModel.DataImportChoice, true); diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Models/ExportOptions.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Models/ExportOptions.cs index b5f0f3637..8a1aa71fe 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Models/ExportOptions.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Models/ExportOptions.cs @@ -1,9 +1,12 @@ -namespace Orchard.ImportExport.Models { +using System.Collections.Generic; + +namespace Orchard.ImportExport.Models { public class ExportOptions { public bool ExportMetadata { get; set; } public bool ExportData { get; set; } public VersionHistoryOptions VersionHistoryOptions { get; set; } public bool ExportSiteSettings { get; set; } + public IEnumerable CustomSteps { get; set; } } public enum VersionHistoryOptions { diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj b/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj index 0d8435f92..687beddf5 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj @@ -53,6 +53,8 @@ + + diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ICustomExportStep.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ICustomExportStep.cs new file mode 100644 index 000000000..0a822a5cd --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ICustomExportStep.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using Orchard.Events; + +namespace Orchard.ImportExport.Services { + public interface ICustomExportStep : IEventHandler { + void Register(IList steps); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportEventHandler.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportEventHandler.cs new file mode 100644 index 000000000..856ffb20c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportEventHandler.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Xml.Linq; +using Orchard.Events; +using Orchard.ImportExport.Models; + +namespace Orchard.ImportExport.Services { + public class ExportContext { + public XDocument Document { get; set; } + public IEnumerable ContentTypes { get; set; } + public ExportOptions ExportOptions { get; set; } + } + + public interface IExportEventHandler : IEventHandler { + void Exporting(ExportContext context); + void Exported(ExportContext context); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ImportExportService.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ImportExportService.cs index 43ec5dc8e..c90b2e466 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ImportExportService.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ImportExportService.cs @@ -23,6 +23,7 @@ namespace Orchard.ImportExport.Services { private readonly IRecipeParser _recipeParser; private readonly IRecipeManager _recipeManager; private readonly IShellDescriptorManager _shellDescriptorManager; + private readonly IEnumerable _exportEventHandlers; private const string ExportsDirectory = "Exports"; public ImportExportService( @@ -32,7 +33,8 @@ namespace Orchard.ImportExport.Services { IAppDataFolder appDataFolder, IRecipeParser recipeParser, IRecipeManager recipeManager, - IShellDescriptorManager shellDescriptorManager) { + IShellDescriptorManager shellDescriptorManager, + IEnumerable exportEventHandlers) { _orchardServices = orchardServices; _contentDefinitionManager = contentDefinitionManager; _contentDefinitionWriter = contentDefinitionWriter; @@ -40,6 +42,7 @@ namespace Orchard.ImportExport.Services { _recipeParser = recipeParser; _recipeManager = recipeManager; _shellDescriptorManager = shellDescriptorManager; + _exportEventHandlers = exportEventHandlers; Logger = NullLogger.Instance; T = NullLocalizer.Instance; } @@ -56,6 +59,14 @@ namespace Orchard.ImportExport.Services { public string Export(IEnumerable contentTypes, ExportOptions exportOptions) { var exportDocument = CreateExportRoot(); + var context = new ExportContext { + Document = exportDocument, + ContentTypes = contentTypes, + ExportOptions = exportOptions + }; + + _exportEventHandlers.Invoke(x => x.Exporting(context), Logger); + if (exportOptions.ExportMetadata) { exportDocument.Element("Orchard").Add(ExportMetadata(contentTypes)); } @@ -68,6 +79,8 @@ namespace Orchard.ImportExport.Services { exportDocument.Element("Orchard").Add(ExportData(contentTypes, exportOptions.VersionHistoryOptions)); } + _exportEventHandlers.Invoke(x => x.Exported(context), Logger); + return WriteExportFile(exportDocument.ToString()); } diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs index 684a7e910..7ae152b3c 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs @@ -3,6 +3,7 @@ namespace Orchard.ImportExport.ViewModels { public class ExportViewModel { public IList ContentTypes { get; set; } + public IList CustomSteps { get; set; } public virtual bool Metadata { get; set; } public virtual bool Data { get; set; } public virtual string DataImportChoice { get; set; } @@ -13,4 +14,9 @@ namespace Orchard.ImportExport.ViewModels { public string ContentTypeName { get; set; } public bool IsChecked { get; set; } } + + public class CustomStepEntry { + public string CustomStep { get; set; } + public bool IsChecked { get; set; } + } } diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml b/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml index c7585a746..9c5a5dd8f 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml @@ -3,7 +3,7 @@ @{ Layout.Title = T("Export").ToString(); } -@using(Html.BeginFormAntiForgeryPost()) { +@using (Html.BeginFormAntiForgeryPost()) { Html.ValidationSummary();
@T("Choose the types to include in the export file:") @@ -15,36 +15,54 @@ - contentTypeIndex = contentTypeIndex + 1; - } + contentTypeIndex = contentTypeIndex + 1; + }

- @T("Choose what to save for these types:") -
- @Html.EditorFor(m => m.Metadata) - - @T("Metadata is the definition of your content types: what parts and fields they have, with what settings.") -
-
- @Html.EditorFor(m => m.Data) - - @T("Data is the actual content of your site.") -
-
-

@T("Version History")

+ @T("Choose what to save for these types:") +
+ @Html.EditorFor(m => m.Metadata) + + @T("Metadata is the definition of your content types: what parts and fields they have, with what settings.") +
+
+ @Html.EditorFor(m => m.Data) + + @T("Data is the actual content of your site.") +
+
+

@T("Version History")

@Html.RadioButtonFor(m => m.DataImportChoice, "Published", new { id = "Published", Checked = "Checked" }) -
+
@Html.RadioButtonFor(m => m.DataImportChoice, "Draft", new { id = "Draft" })
-
- @Html.EditorFor(m => m.SiteSettings) -
- @T("Please verify that you are not exporting confidential information, such as passwords or application keys.") -
-
- +
+ @Html.EditorFor(m => m.SiteSettings) +
+ @T("Please verify that you are not exporting confidential information, such as passwords or application keys.") +
+ + + if (Model.CustomSteps.Any()) { +
+ @T("Choose the custom steps to execute in the export file:") +
    + @{ var customStepIndex = 0; } + @foreach (var customStepEntry in Model.CustomSteps) { +
  1. + + + +
  2. + customStepIndex = customStepIndex + 1; + } +
+
+ } + + }