From edd6db2331ad1d4e7175bd75657bc15059efc634 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 15 Jul 2015 17:03:48 +0100 Subject: [PATCH] Created ExportAction abstraction and RecipeBuilder implementation. --- .../Controllers/AdminController.cs | 53 ++++-------- .../Orchard.ImportExport.csproj | 13 ++- .../Providers/ExportActions/RecipeBuilder.cs | 86 +++++++++++++++++++ .../Services/ExportAction.cs | 22 +++++ .../Services/ExportActionContext.cs | 7 ++ .../Services/IExportAction.cs | 12 +++ .../ViewModels/ExportActionViewModel.cs | 5 ++ .../ViewModels/ExportViewModel.cs | 2 +- .../ViewModels/RecipeBuilderViewModel.cs | 7 ++ .../Views/Admin/Export.cshtml | 26 ++---- .../ExportActions/RecipeBuilder.cshtml | 25 ++++++ 11 files changed, 201 insertions(+), 57 deletions(-) create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Providers/ExportActions/RecipeBuilder.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportAction.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportActionContext.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportAction.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportActionViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/RecipeBuilderViewModel.cs create mode 100644 src/Orchard.Web/Modules/Orchard.ImportExport/Views/EditorTemplates/ExportActions/RecipeBuilder.cshtml diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs index 0182479be..2dc619707 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Controllers/AdminController.cs @@ -7,28 +7,26 @@ using Orchard.ContentManagement; using Orchard.ImportExport.Services; using Orchard.ImportExport.ViewModels; using Orchard.Localization; -using Orchard.Recipes.Models; using Orchard.Recipes.Services; using Orchard.UI.Notify; -using Orchard.Utility.Extensions; namespace Orchard.ImportExport.Controllers { public class AdminController : Controller, IUpdateModel { private readonly IImportExportService _importExportService; private readonly IRecipeResultAccessor _recipeResultAccessor; - private readonly IEnumerable _exportStepProviders; + private readonly IEnumerable _exportActions; private readonly IRecipeParser _recipeParser; public AdminController( IOrchardServices services, IImportExportService importExportService, IRecipeResultAccessor recipeResultAccessor, - IEnumerable exportStepProviders, + IEnumerable exportActions, IRecipeParser recipeParser) { _importExportService = importExportService; _recipeResultAccessor = recipeResultAccessor; - _exportStepProviders = exportStepProviders; + _exportActions = exportActions; _recipeParser = recipeParser; Services = services; T = NullLocalizer.Instance; @@ -72,15 +70,12 @@ namespace Orchard.ImportExport.Controllers { } public ActionResult Export() { - var exportSteps = _exportStepProviders.OrderBy(x => x.Priority).Select(x => new ExportStepViewModel { - Name = x.Name, - DisplayName = x.DisplayName, - Description = x.Description, + var actions = _exportActions.OrderBy(x => x.Priority).Select(x => new ExportActionViewModel { Editor = x.BuildEditor(Services.New) - }).Where(x => x != null); + }).Where(x => x != null).ToList(); var viewModel = new ExportViewModel { - ExportSteps = exportSteps.ToList() + Actions = actions }; return View(viewModel); @@ -90,32 +85,22 @@ namespace Orchard.ImportExport.Controllers { public ActionResult ExportPOST(ExportViewModel viewModel) { if (!Services.Authorizer.Authorize(Permissions.Export, T("Not allowed to export."))) return new HttpUnauthorizedResult(); - - var exportStepNames = viewModel.ExportSteps.Where(x => x.IsSelected).Select(x => x.Name); - var exportStepsQuery = from name in exportStepNames - let provider = _exportStepProviders.SingleOrDefault(x => x.Name == name) - where provider != null - select provider; - var exportSteps = exportStepsQuery.ToArray(); - - foreach (var exportStep in exportSteps) { - exportStep.UpdateEditor(Services.New, this); + + var actions = _exportActions.OrderBy(x => x.Priority).ToList(); + + foreach (var action in actions) { + action.UpdateEditor(Services.New, this); } - var recipeDocument = _importExportService.ExportXml(exportSteps); - var recipe = _recipeParser.ParseRecipe(recipeDocument); - var exportFileName = GetExportFileName(recipe); - var exportFilePath = _importExportService.WriteExportFile(recipeDocument); + var exportActionContext = new ExportActionContext { + ActionResult = RedirectToAction("Export") + }; - return File(exportFilePath, "text/xml", exportFileName); - } - - private string GetExportFileName(Recipe recipe) { - return String.IsNullOrWhiteSpace(recipe.Name) - ? "export.xml" - : String.Format(recipe.IsSetupRecipe - ? "{0}.recipe.xml" - : "{0}.export.xml", recipe.Name.HtmlClassify()); + foreach (var action in actions) { + action.Execute(exportActionContext); + } + + return exportActionContext.ActionResult; } bool IUpdateModel.TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) { diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj b/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj index c74d94799..810442b6c 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Orchard.ImportExport.csproj @@ -71,18 +71,24 @@ + + + + + + @@ -123,10 +129,15 @@ - + + + + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Providers/ExportActions/RecipeBuilder.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Providers/ExportActions/RecipeBuilder.cs new file mode 100644 index 000000000..0b9fac155 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Providers/ExportActions/RecipeBuilder.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Mvc; +using Orchard.ContentManagement; +using Orchard.ImportExport.Services; +using Orchard.ImportExport.ViewModels; +using Orchard.Mvc; +using Orchard.Recipes.Models; +using Orchard.Recipes.Services; +using Orchard.Utility.Extensions; + +namespace Orchard.ImportExport.Providers.ExportActions { + public class RecipeBuilder : ExportAction { + private readonly IEnumerable _recipeBuilderSteps; + private readonly IImportExportService _importExportService; + private readonly IRecipeParser _recipeParser; + + public RecipeBuilder(IEnumerable recipeBuilderSteps, IImportExportService importExportService, IRecipeParser recipeParser) { + _recipeBuilderSteps = recipeBuilderSteps; + _importExportService = importExportService; + _recipeParser = recipeParser; + + RecipeBuilderSteps = new List(); + } + + public override string Name { get { return "RecipeBuilder"; } } + + public IList RecipeBuilderSteps { get; set; } + + public override dynamic BuildEditor(dynamic shapeFactory) { + return UpdateEditor(shapeFactory, null); + } + + public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) { + var builderSteps = _recipeBuilderSteps.OrderBy(x => x.Priority).Select(x => new ExportStepViewModel { + Name = x.Name, + DisplayName = x.DisplayName, + Description = x.Description, + Editor = x.BuildEditor(shapeFactory) + }).Where(x => x != null); + + var viewModel = new RecipeBuilderViewModel { + Steps = builderSteps.ToList() + }; + + if (updater != null) { + if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { + var exportStepNames = viewModel.Steps.Where(x => x.IsSelected).Select(x => x.Name); + var stepsQuery = from name in exportStepNames + let provider = _recipeBuilderSteps.SingleOrDefault(x => x.Name == name) + where provider != null + select provider; + var steps = stepsQuery.ToArray(); + var stepUpdater = new Updater(updater, secondHalf => String.Format("{0}.{1}", Prefix, secondHalf)); + foreach (var exportStep in steps) { + exportStep.UpdateEditor(shapeFactory, stepUpdater); + } + + RecipeBuilderSteps = steps; + } + } + + return shapeFactory.EditorTemplate(TemplateName: "ExportActions/RecipeBuilder", Model: viewModel, Prefix: Prefix); + } + + public override void Execute(ExportActionContext context) { + var recipeDocument = _importExportService.ExportXml(RecipeBuilderSteps); + var recipe = _recipeParser.ParseRecipe(recipeDocument); + var exportFileName = GetExportFileName(recipe); + var exportFilePath = _importExportService.WriteExportFile(recipeDocument); + var actionResult = new FilePathResult(exportFilePath, "text/xml"); + + actionResult.FileDownloadName = exportFileName; + context.ActionResult = actionResult; + } + + private string GetExportFileName(Recipe recipe) { + return String.IsNullOrWhiteSpace(recipe.Name) + ? "export.xml" + : String.Format(recipe.IsSetupRecipe + ? "{0}.recipe.xml" + : "{0}.export.xml", recipe.Name.HtmlClassify()); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportAction.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportAction.cs new file mode 100644 index 000000000..a4fe2b27e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportAction.cs @@ -0,0 +1,22 @@ +using Orchard.ContentManagement; + +namespace Orchard.ImportExport.Services { + public abstract class ExportAction : IExportAction { + public virtual int Priority { get { return 0; } } + public abstract string Name { get; } + + protected virtual string Prefix { + get { return GetType().Name; } + } + + public virtual dynamic BuildEditor(dynamic shapeFactory) { + return null; + } + + public virtual dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) { + return null; + } + + public abstract void Execute(ExportActionContext exportActionContext); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportActionContext.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportActionContext.cs new file mode 100644 index 000000000..7e4509824 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/ExportActionContext.cs @@ -0,0 +1,7 @@ +using System.Web.Mvc; + +namespace Orchard.ImportExport.Services { + public class ExportActionContext { + public ActionResult ActionResult { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportAction.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportAction.cs new file mode 100644 index 000000000..6bb6415fe --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Services/IExportAction.cs @@ -0,0 +1,12 @@ +using Orchard.ContentManagement; + +namespace Orchard.ImportExport.Services { + public interface IExportAction : IDependency { + int Priority { get; } + string Name { get; } + + dynamic BuildEditor(dynamic shapeFactory); + dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater); + void Execute(ExportActionContext exportActionContext); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportActionViewModel.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportActionViewModel.cs new file mode 100644 index 000000000..a6b0d815f --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportActionViewModel.cs @@ -0,0 +1,5 @@ +namespace Orchard.ImportExport.ViewModels { + public class ExportActionViewModel { + public dynamic Editor { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs index 45667d538..6a1d9f8c3 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/ExportViewModel.cs @@ -2,6 +2,6 @@ namespace Orchard.ImportExport.ViewModels { public class ExportViewModel { - public IList ExportSteps { get; set; } + public IList Actions { get; set; } } } diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/RecipeBuilderViewModel.cs b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/RecipeBuilderViewModel.cs new file mode 100644 index 000000000..cfa2b1d9d --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/ViewModels/RecipeBuilderViewModel.cs @@ -0,0 +1,7 @@ +using System.Collections.Generic; + +namespace Orchard.ImportExport.ViewModels { + public class RecipeBuilderViewModel { + public IList Steps { get; set; } + } +} \ No newline at end of file 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 4c5e7513b..222b02d83 100644 --- a/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Views/Admin/Export.cshtml @@ -1,28 +1,12 @@ -@using Orchard.Utility.Extensions -@model Orchard.ImportExport.ViewModels.ExportViewModel +@model Orchard.ImportExport.ViewModels.ExportViewModel @{ Layout.Title = T("Export").ToString(); } @using (Html.BeginFormAntiForgeryPost()) { Html.ValidationSummary(); - var exportStepIndex = 0; - foreach (var exportStep in Model.ExportSteps) { - var stepName = Html.NameFor(m => m.ExportSteps[exportStepIndex].IsSelected).ToString(); - var stepId = stepName.HtmlClassify(); -
- - - - - - @Html.Hint(@exportStep.Description) -
- @Display(exportStep.Editor) -
-
- exportStepIndex++; - if (exportStepIndex < Model.ExportSteps.Count) { -
- } + foreach(var action in Model.Actions) { +
+ @Display(action.Editor) +
} diff --git a/src/Orchard.Web/Modules/Orchard.ImportExport/Views/EditorTemplates/ExportActions/RecipeBuilder.cshtml b/src/Orchard.Web/Modules/Orchard.ImportExport/Views/EditorTemplates/ExportActions/RecipeBuilder.cshtml new file mode 100644 index 000000000..ecbe53c5e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ImportExport/Views/EditorTemplates/ExportActions/RecipeBuilder.cshtml @@ -0,0 +1,25 @@ +@using Orchard.Utility.Extensions +@model Orchard.ImportExport.ViewModels.RecipeBuilderViewModel +@{ + var exportStepIndex = 0; + foreach (var exportStep in Model.Steps) { + var stepName = Html.NameFor(m => m.Steps[exportStepIndex].IsSelected).ToString(); + var stepId = stepName.HtmlClassify(); + +
+ + + + + + @Html.Hint(@exportStep.Description) +
+ @Display(exportStep.Editor) +
+
+ exportStepIndex++; + if (exportStepIndex < Model.Steps.Count) { +
+ } + } +}