Incremental refactoring of ImportExport and Recipes.

This commit is contained in:
Sipke Schoorstra
2015-07-15 00:01:23 +01:00
parent 18469ad462
commit 19126126d6
44 changed files with 371 additions and 238 deletions

View File

@@ -4,9 +4,11 @@ using System.IO;
using System.Linq;
using Orchard.Commands;
using Orchard.ContentManagement.MetaData;
using Orchard.ImportExport.Models;
using Orchard.ImportExport.Providers;
using Orchard.ImportExport.RecipeBuilderSteps;
using Orchard.ImportExport.Services;
using Orchard.Recipes.Models;
using Orchard.Recipes.RecipeBuilders;
using Orchard.Recipes.Services;
using Orchard.Security;
using Orchard.Settings;
@@ -95,13 +97,10 @@ namespace Orchard.ImportExport.Commands {
.ToList();
var enteredSteps = (Steps ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var exportSteps = new List<IExportStepProvider>();
var exportOptions = new ExportOptions {
CustomSteps = enteredSteps
};
var recipeBuilderSteps = new List<IRecipeBuilderStep>();
if (Metadata || Data) {
var dataStep = _orchardServices.WorkContext.Resolve<DataExportStep>();
var dataStep = _orchardServices.WorkContext.Resolve<DataRecipeBuilderStep>();
if(Data)
dataStep.DataContentTypes = exportTypes;
@@ -110,17 +109,22 @@ namespace Orchard.ImportExport.Commands {
dataStep.SchemaContentTypes = exportTypes;
dataStep.VersionHistoryOptions = versionOption;
exportSteps.Add(dataStep);
recipeBuilderSteps.Add(dataStep);
}
if (SiteSettings) {
var siteSettingsStep = _orchardServices.WorkContext.Resolve<SiteSettingsExportStep>();
exportSteps.Add(siteSettingsStep);
var siteSettingsStep = _orchardServices.WorkContext.Resolve<SiteSettingsBuilderStep>();
recipeBuilderSteps.Add(siteSettingsStep);
}
if (enteredSteps.Any()) {
var customStepsStep = _orchardServices.WorkContext.Resolve<CustomStepsRecipeBuilderStep>();
recipeBuilderSteps.Add(customStepsStep);
}
Context.Output.WriteLine(T("Export starting..."));
var exportFilePath = _importExportService.Export(exportSteps, exportOptions);
var exportFilePath = _importExportService.Export(recipeBuilderSteps);
Context.Output.WriteLine(T("Export completed at {0}", exportFilePath));
}

View File

@@ -4,8 +4,6 @@ using System.IO;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ImportExport.Models;
using Orchard.ImportExport.Services;
using Orchard.ImportExport.ViewModels;
using Orchard.Localization;
@@ -15,22 +13,16 @@ using Orchard.UI.Notify;
namespace Orchard.ImportExport.Controllers {
public class AdminController : Controller, IUpdateModel {
private readonly IImportExportService _importExportService;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ICustomExportStep _customExportStep;
private readonly IRecipeResultAccessor _recipeResultAccessor;
private readonly IEnumerable<IExportStepProvider> _exportStepProviders;
private readonly IEnumerable<IRecipeBuilderStep> _exportStepProviders;
public AdminController(
IOrchardServices services,
IImportExportService importExportService,
IContentDefinitionManager contentDefinitionManager,
ICustomExportStep customExportStep,
IRecipeResultAccessor recipeResultAccessor,
IEnumerable<IExportStepProvider> exportStepProviders) {
IEnumerable<IRecipeBuilderStep> exportStepProviders) {
_importExportService = importExportService;
_contentDefinitionManager = contentDefinitionManager;
_customExportStep = customExportStep;
_recipeResultAccessor = recipeResultAccessor;
_exportStepProviders = exportStepProviders;
Services = services;
@@ -75,10 +67,7 @@ namespace Orchard.ImportExport.Controllers {
}
public ActionResult Export() {
var customSteps = new List<string>();
_customExportStep.Register(customSteps);
var exportSteps = _exportStepProviders.OrderBy(x => x.Position).Select(x => new ExportStepViewModel {
var exportSteps = _exportStepProviders.OrderBy(x => x.Priority).Select(x => new ExportStepViewModel {
Name = x.Name,
DisplayName = x.DisplayName,
Description = x.Description,
@@ -86,7 +75,6 @@ namespace Orchard.ImportExport.Controllers {
}).Where(x => x != null);
var viewModel = new ExportViewModel {
CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x }).ToList(),
ExportSteps = exportSteps.ToList()
};
@@ -94,33 +82,22 @@ namespace Orchard.ImportExport.Controllers {
}
[HttpPost, ActionName("Export")]
public ActionResult ExportPOST() {
public ActionResult ExportPOST(ExportViewModel viewModel) {
if (!Services.Authorizer.Authorize(Permissions.Export, T("Not allowed to export.")))
return new HttpUnauthorizedResult();
var viewModel = new ExportViewModel {
CustomSteps = new List<CustomStepEntry>(),
ExportSteps = new List<ExportStepViewModel>()
};
UpdateModel(viewModel);
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();
var customSteps = viewModel.CustomSteps.Where(c => c.IsChecked).Select(c => c.CustomStep);
var exportOptions = new ExportOptions {
CustomSteps = customSteps
};
foreach (var exportStep in exportSteps) {
exportStep.UpdateEditor(Services.New, this);
}
var exportFilePath = _importExportService.Export(exportSteps, exportOptions);
var exportFilePath = _importExportService.Export(exportSteps);
var exportFileName = "export.xml";
return File(exportFilePath, "text/xml", exportFileName);

View File

@@ -4,10 +4,4 @@ namespace Orchard.ImportExport.Models {
public class ExportOptions {
public IEnumerable<string> CustomSteps { get; set; }
}
public enum VersionHistoryOptions {
Published,
Draft,
Latest
}
}

View File

@@ -8,4 +8,4 @@ OrchardVersion: 1.9
Description: Provides content item data import and export capability.
FeatureDescription: Imports and exports content item data
Category: Content
Dependencies: Orchard.jQuery
Dependencies: Orchard.jQuery, Orchard.Recipes

View File

@@ -71,23 +71,15 @@
<Compile Include="Models\ExportOptions.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\SetupRecipeExportStep.cs" />
<Compile Include="Providers\SiteSettingsExportStep.cs" />
<Compile Include="Providers\DataExportStep.cs" />
<Compile Include="ViewModels\ContentTypeEntry.cs" />
<Compile Include="RecipeBuilderSteps\CustomStepsRecipeBuilderStep.cs" />
<Compile Include="Services\ExportContext.cs" />
<Compile Include="ViewModels\CustomStepEntry.cs" />
<Compile Include="ViewModels\ExportStepViewModel.cs" />
<Compile Include="ViewModels\SetupRecipeStepViewModel.cs" />
<Compile Include="ViewModels\SiteSettingsStepViewModel.cs" />
<Compile Include="ViewModels\DataExportStepViewModel.cs" />
<Compile Include="Services\ICustomExportStep.cs" />
<Compile Include="Services\IExportEventHandler.cs" />
<Compile Include="Services\IImportExportService.cs" />
<Compile Include="Services\IImportStepProvider.cs" />
<Compile Include="Services\ImportExportService.cs" />
<Compile Include="Services\IExportStepProvider.cs" />
<Compile Include="Services\ImportStepProvider.cs" />
<Compile Include="Services\ExportStepProvider.cs" />
<Compile Include="ViewModels\CustomStepsViewModel.cs" />
<Compile Include="ViewModels\ExportStepViewModel.cs" />
<Compile Include="ViewModels\ExportViewModel.cs" />
<Compile Include="ViewModels\ImportResultViewModel.cs" />
<Compile Include="ViewModels\ImportViewModel.cs" />
@@ -106,9 +98,12 @@
<Name>Orchard.Core</Name>
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\Orchard.Recipes\Orchard.Recipes.csproj">
<Project>{fc1d74e8-7a4d-48f4-83de-95c6173780c4}</Project>
<Name>Orchard.Recipes</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\exportstep-data.js" />
<Content Include="Styles\images\menu.importexport.png" />
<Content Include="Styles\exportstep-data.css" />
<Content Include="Styles\menu.importexport-admin.css" />
@@ -128,19 +123,9 @@
<ItemGroup>
<Content Include="Views\Admin\ImportResult.cshtml" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\Data.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\SiteSettings.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\SetupRecipe.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Views\EditorTemplates\ExportSteps\CustomSteps.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>

View File

@@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ImportExport.Models;
using Orchard.ImportExport.Services;
using Orchard.ImportExport.ViewModels;
using Orchard.Localization;
using Orchard.Recipes.Services;
namespace Orchard.ImportExport.RecipeBuilderSteps {
public class CustomStepsRecipeBuilderStep : RecipeBuilderStep {
private readonly IEnumerable<IExportEventHandler> _exportEventHandlers;
private readonly ICustomExportStep _customExportStep;
public CustomStepsRecipeBuilderStep(IEnumerable<IExportEventHandler> exportEventHandlers, ICustomExportStep customExportStep) {
_exportEventHandlers = exportEventHandlers;
_customExportStep = customExportStep;
CustomSteps = new List<string>();
}
public override string Name {
get { return "CustomSteps"; }
}
public override LocalizedString DisplayName {
get { return T("Additional Export Steps"); }
}
public override LocalizedString Description {
get { return T("Exports additional items."); }
}
public override int Priority { get { return 60; } }
public IList<string> CustomSteps { get; set; }
public override dynamic BuildEditor(dynamic shapeFactory) {
return UpdateEditor(shapeFactory, null);
}
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
var customSteps = new List<string>();
_customExportStep.Register(customSteps);
var viewModel = new CustomStepsViewModel {
CustomSteps = customSteps.Select(x => new CustomStepEntry { CustomStep = x}).ToList()
};
if (updater != null && updater.TryUpdateModel(viewModel, Prefix, null, null)) {
CustomSteps = viewModel.CustomSteps.Where(x => x.IsChecked).Select(x => x.CustomStep).ToList();
}
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/CustomSteps", Model: viewModel, Prefix: Prefix);
}
public override void Build(BuildContext context) {
var exportContext = new ExportContext {
Document = context.RecipeDocument,
ExportOptions = new ExportOptions {
CustomSteps = CustomSteps
}
};
_exportEventHandlers.Invoke(x => x.Exporting(exportContext), Logger);
_exportEventHandlers.Invoke(x => x.Exported(exportContext), Logger);
}
}
}

View File

@@ -0,0 +1,9 @@
using System.Xml.Linq;
using Orchard.ImportExport.Models;
namespace Orchard.ImportExport.Services {
public class ExportContext {
public XDocument Document { get; set; }
public ExportOptions ExportOptions { get; set; }
}
}

View File

@@ -1,13 +1,6 @@
using System.Xml.Linq;
using Orchard.Events;
using Orchard.ImportExport.Models;
using Orchard.Events;
namespace Orchard.ImportExport.Services {
public class ExportContext {
public XDocument Document { get; set; }
public ExportOptions ExportOptions { get; set; }
}
public interface IExportEventHandler : IEventHandler {
void Exporting(ExportContext context);
void Exported(ExportContext context);

View File

@@ -1,12 +1,9 @@
using System.Collections.Generic;
using Orchard.ImportExport.Models;
using Orchard.Recipes.Services;
namespace Orchard.ImportExport.Services {
public interface IImportExportService : IDependency {
string Import(string recipeText);
string Export(IEnumerable<IExportStepProvider> steps, ExportOptions exportOptions);
string Export(IEnumerable<IRecipeBuilderStep> steps);
}
}

View File

@@ -1,11 +0,0 @@
using Orchard.ContentManagement;
using Orchard.Localization;
namespace Orchard.ImportExport.Services {
public interface IImportStepProvider : IDependency {
string Name { get; }
LocalizedString DisplayName { get; }
dynamic BuildEditor(dynamic shapeFactory);
dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater);
}
}

View File

@@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.Environment.Descriptor;
using Orchard.FileSystems.AppData;
using Orchard.ImportExport.Models;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Recipes.Services;
@@ -15,29 +10,23 @@ namespace Orchard.ImportExport.Services {
public class ImportExportService : IImportExportService {
private readonly IOrchardServices _orchardServices;
private readonly IAppDataFolder _appDataFolder;
private readonly IRecipeParser _recipeParser;
private readonly IRecipeManager _recipeManager;
private readonly IShellDescriptorManager _shellDescriptorManager;
private readonly IRecipeBuilder _recipeBuilder;
private readonly IRecipeExecutor _recipeExecutor;
private readonly IClock _clock;
private readonly IEnumerable<IExportEventHandler> _exportEventHandlers;
private const string ExportsDirectory = "Exports";
public ImportExportService(
IOrchardServices orchardServices,
IAppDataFolder appDataFolder,
IRecipeParser recipeParser,
IRecipeManager recipeManager,
IShellDescriptorManager shellDescriptorManager,
IClock clock,
IEnumerable<IExportEventHandler> exportEventHandlers) {
IRecipeBuilder recipeBuilder,
IRecipeExecutor recipeExecutor,
IClock clock) {
_orchardServices = orchardServices;
_appDataFolder = appDataFolder;
_recipeParser = recipeParser;
_recipeManager = recipeManager;
_shellDescriptorManager = shellDescriptorManager;
_recipeBuilder = recipeBuilder;
_recipeExecutor = recipeExecutor;
_clock = clock;
_exportEventHandlers = exportEventHandlers;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
@@ -46,46 +35,16 @@ namespace Orchard.ImportExport.Services {
public ILogger Logger { get; set; }
public string Import(string recipeText) {
var recipe = _recipeParser.ParseRecipe(recipeText);
var executionId = _recipeManager.Execute(recipe);
UpdateShell();
return executionId;
return _recipeExecutor.Execute(recipeText);
}
public string Export(IEnumerable<IExportStepProvider> steps, ExportOptions exportOptions) {
var exportDocument = CreateExportRoot();
var context = new ExportContext {
Document = exportDocument,
ExportOptions = exportOptions
};
_exportEventHandlers.Invoke(x => x.Exporting(context), Logger);
foreach (var step in steps) {
step.Export(context);
}
_exportEventHandlers.Invoke(x => x.Exported(context), Logger);
return WriteExportFile(exportDocument.ToString());
}
private XDocument CreateExportRoot() {
var exportRoot = new XDocument(
new XDeclaration("1.0", "", "yes"),
new XComment("Exported from Orchard"),
new XElement("Orchard",
new XElement("Recipe",
new XElement("ExportUtc", XmlConvert.ToString(_clock.UtcNow, XmlDateTimeSerializationMode.Utc))
)
)
);
return exportRoot;
public string Export(IEnumerable<IRecipeBuilderStep> steps) {
var recipe = _recipeBuilder.Build(steps);
return WriteExportFile(recipe);
}
private string WriteExportFile(string exportDocument) {
var exportFile = String.Format("Export-{0}-{1}.xml", _orchardServices.WorkContext.CurrentUser.UserName, DateTime.UtcNow.Ticks);
var exportFile = String.Format("Export-{0}-{1}.xml", _orchardServices.WorkContext.CurrentUser.UserName, _clock.UtcNow.Ticks);
if (!_appDataFolder.DirectoryExists(ExportsDirectory)) {
_appDataFolder.CreateDirectory(ExportsDirectory);
}
@@ -95,10 +54,5 @@ namespace Orchard.ImportExport.Services {
return _appDataFolder.MapPath(path);
}
private void UpdateShell() {
var descriptor = _shellDescriptorManager.GetShellDescriptor();
_shellDescriptorManager.UpdateShellDescriptor(descriptor.SerialNumber, descriptor.Features, descriptor.Parameters);
}
}
}

View File

@@ -1,21 +0,0 @@
using Orchard.ContentManagement;
using Orchard.Localization;
namespace Orchard.ImportExport.Services {
public abstract class ImportStepProvider : Component, IImportStepProvider {
public abstract string Name { get; }
public abstract LocalizedString DisplayName { 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;
}
}
}

View File

@@ -0,0 +1,7 @@
using System.Collections.Generic;
namespace Orchard.ImportExport.ViewModels {
public class CustomStepsViewModel {
public IList<CustomStepEntry> CustomSteps { get; set; }
}
}

View File

@@ -2,7 +2,6 @@
namespace Orchard.ImportExport.ViewModels {
public class ExportViewModel {
public IList<CustomStepEntry> CustomSteps { get; set; }
public IList<ExportStepViewModel> ExportSteps { get; set; }
}
}

View File

@@ -1,5 +1,5 @@
@using Orchard.Utility.Extensions
@model Orchard.ImportExport.ViewModels.ExportViewModel
@model Orchard.ImportExport.ViewModels.CustomStepsViewModel
@{ Layout.Title = T("Export").ToString(); }
@using (Html.BeginFormAntiForgeryPost()) {
Html.ValidationSummary();
@@ -25,20 +25,5 @@
}
}
if (Model.CustomSteps.Any()) {
<fieldset>
<legend>@T("Choose the custom steps to execute in the export file:")</legend>
<ol>
@for (var customStepIndex = 0; customStepIndex < Model.CustomSteps.Count; customStepIndex++) {
<li>
<input type="hidden" value="@Model.CustomSteps[customStepIndex].CustomStep" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].CustomStep)" />
<input type="checkbox" value="true" name="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" id="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)" />
<label class="forcheckbox" for="@Html.NameOf(m => m.CustomSteps[customStepIndex].IsChecked)">@Model.CustomSteps[customStepIndex].CustomStep.CamelFriendly()</label>
</li>
}
</ol>
</fieldset>
}
<button type="submit" class="primaryAction">@T("Export")</button>
}

View File

@@ -0,0 +1,17 @@
@using Orchard.Utility.Extensions
@model Orchard.ImportExport.ViewModels.CustomStepsViewModel
@if (Model.CustomSteps.Any()) {
<fieldset>
<legend>@T("Choose the custom steps to execute in the export file:")</legend>
<ol>
@for (var customStepIndex = 0; customStepIndex < Model.CustomSteps.Count; customStepIndex++) {
var closureIndex = customStepIndex;
<li>
<input type="hidden" value="@Model.CustomSteps[customStepIndex].CustomStep" name="@Html.NameOf(m => m.CustomSteps[closureIndex].CustomStep)" />
<input type="checkbox" value="true" name="@Html.NameOf(m => m.CustomSteps[closureIndex].IsChecked)" id="@Html.NameOf(m => m.CustomSteps[closureIndex].IsChecked)" />
<label class="forcheckbox" for="@Html.NameOf(m => m.CustomSteps[closureIndex].IsChecked)">@Model.CustomSteps[closureIndex].CustomStep.CamelFriendly()</label>
</li>
}
</ol>
</fieldset>
}

View File

@@ -0,0 +1,7 @@
namespace Orchard.Recipes.Models {
public enum VersionHistoryOptions {
Published,
Draft,
Latest
}
}

View File

@@ -51,6 +51,7 @@
<Reference Include="Autofac">
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.ApplicationServices" />
@@ -68,6 +69,10 @@
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Scripts\exportstep-data.js" />
<Content Include="Styles\exportstep-data.css" />
<Content Include="Styles\images\menu.importexport.png" />
<Content Include="Styles\menu.importexport-admin.css" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
@@ -75,7 +80,11 @@
<Compile Include="Migrations.cs" />
<Compile Include="Models\RecipeResultRecord.cs" />
<Compile Include="Models\RecipeStepResultRecord.cs" />
<Compile Include="Models\VersionHistoryOptions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecipeBuilders\DataRecipeBuilderStep.cs" />
<Compile Include="RecipeBuilders\SetupRecipeBuilderStep.cs" />
<Compile Include="RecipeBuilders\SiteSettingsBuilderStep.cs" />
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
<Compile Include="RecipeHandlers\DataRecipeHandler.cs" />
<Compile Include="RecipeHandlers\FeatureRecipeHandler.cs" />
@@ -85,6 +94,13 @@
<Compile Include="RecipeHandlers\SettingsRecipeHandler.cs" />
<Compile Include="RecipeHandlers\ThemeRecipeHandler.cs" />
<Compile Include="Routes.cs" />
<Compile Include="Services\BuildContext.cs" />
<Compile Include="Services\IRecipeExecutor.cs" />
<Compile Include="Services\RecipeExecutor.cs" />
<Compile Include="Services\IRecipeBuilder.cs" />
<Compile Include="Services\RecipeBuilder.cs" />
<Compile Include="Services\IRecipeBuilderStep.cs" />
<Compile Include="Services\RecipeBuilderStep.cs" />
<Compile Include="Services\RecipeHarvester.cs" />
<Compile Include="Services\RecipeManager.cs" />
<Compile Include="Services\RecipeParser.cs" />
@@ -92,6 +108,13 @@
<Compile Include="Services\RecipeScheduler.cs" />
<Compile Include="Services\RecipeStepExecutor.cs" />
<Compile Include="Services\RecipeStepQueue.cs" />
<Compile Include="ViewModels\ContentTypeEntry.cs" />
<Compile Include="ViewModels\CustomStepEntry.cs" />
<Compile Include="ViewModels\DataExportStepViewModel.cs" />
<Compile Include="ViewModels\ImportResultViewModel.cs" />
<Compile Include="ViewModels\ImportViewModel.cs" />
<Compile Include="ViewModels\SetupRecipeStepViewModel.cs" />
<Compile Include="ViewModels\SiteSettingsStepViewModel.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
@@ -112,7 +135,25 @@
<Name>Orchard.Themes</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="Scripts\Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Styles\Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\Data.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\SetupRecipe.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\SiteSettings.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -4,18 +4,18 @@ using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ImportExport.Models;
using Orchard.ImportExport.Services;
using Orchard.ImportExport.ViewModels;
using Orchard.Localization;
using Orchard.Recipes.Models;
using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.ImportExport.Providers {
public class DataExportStep : ExportStepProvider {
namespace Orchard.Recipes.RecipeBuilders {
public class DataRecipeBuilderStep : RecipeBuilderStep {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IOrchardServices _orchardServices;
private readonly IContentDefinitionWriter _contentDefinitionWriter;
public DataExportStep(
public DataRecipeBuilderStep(
IContentDefinitionManager contentDefinitionManager,
IOrchardServices orchardServices,
IContentDefinitionWriter contentDefinitionWriter) {
@@ -37,7 +37,7 @@ namespace Orchard.ImportExport.Providers {
get { return T("Exports content items and content item definitions."); }
}
public override int Position { get { return 10; } }
public override int Priority { get { return 10; } }
public IList<string> SchemaContentTypes { get; set; }
public IList<string> DataContentTypes { get; set; }
@@ -67,7 +67,7 @@ namespace Orchard.ImportExport.Providers {
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/Data", Model: viewModel, Prefix: Prefix);
}
public override void Export(ExportContext context) {
public override void Build(BuildContext context) {
var dataContentTypes = DataContentTypes;
var schemaContentTypes = SchemaContentTypes;
var exportVersionOptions = GetContentExportVersionOptions(VersionHistoryOptions);
@@ -76,10 +76,10 @@ namespace Orchard.ImportExport.Providers {
: Enumerable.Empty<ContentItem>();
if(schemaContentTypes.Any())
context.Document.Element("Orchard").Add(ExportMetadata(schemaContentTypes));
context.RecipeDocument.Element("Orchard").Add(ExportMetadata(schemaContentTypes));
if(contentItems.Any())
context.Document.Element("Orchard").Add(ExportData(dataContentTypes, contentItems, ImportBatchSize));
context.RecipeDocument.Element("Orchard").Add(ExportData(dataContentTypes, contentItems, ImportBatchSize));
}
private XElement ExportMetadata(IEnumerable<string> contentTypes) {

View File

@@ -1,12 +1,12 @@
using Orchard.ContentManagement;
using Orchard.ImportExport.Services;
using Orchard.ImportExport.ViewModels;
using Orchard.Localization;
using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.ImportExport.Providers {
public class SetupRecipeExportStep : ExportStepProvider {
namespace Orchard.Recipes.RecipeBuilders {
public class SetupRecipeBuilderStep : RecipeBuilderStep {
private readonly IOrchardServices _orchardServices;
public SetupRecipeExportStep(IOrchardServices orchardServices) {
public SetupRecipeBuilderStep(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
}
@@ -22,7 +22,7 @@ namespace Orchard.ImportExport.Providers {
get { return T("Turns the export file into a Setup recipe."); }
}
public override int Position { get { return -10; } }
public override int Priority { get { return -10; } }
public string RecipeName { get; set; }
public string RecipeDescription { get; set; }
@@ -54,8 +54,8 @@ namespace Orchard.ImportExport.Providers {
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/SetupRecipe", Model: viewModel, Prefix: Prefix);
}
public override void Export(ExportContext context) {
var recipeElement = context.Document.Element("Orchard").Element("Recipe");
public override void Build(BuildContext context) {
var recipeElement = context.RecipeDocument.Element("Orchard").Element("Recipe");
recipeElement.SetElementValue("Name", RecipeName);
recipeElement.SetElementValue("Description", RecipeDescription);

View File

@@ -2,15 +2,15 @@
using System.Linq;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.ImportExport.Services;
using Orchard.ImportExport.ViewModels;
using Orchard.Localization;
using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.ImportExport.Providers {
public class SiteSettingsExportStep : ExportStepProvider {
namespace Orchard.Recipes.RecipeBuilders {
public class SiteSettingsBuilderStep : RecipeBuilderStep {
private readonly IOrchardServices _orchardServices;
public SiteSettingsExportStep(IOrchardServices orchardServices) {
public SiteSettingsBuilderStep(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
}
@@ -26,7 +26,7 @@ namespace Orchard.ImportExport.Providers {
get { return T("Exports site settings."); }
}
public override int Position { get { return 20; } }
public override int Priority { get { return 20; } }
public override dynamic BuildEditor(dynamic shapeFactory) {
return UpdateEditor(shapeFactory, null);
@@ -37,8 +37,8 @@ namespace Orchard.ImportExport.Providers {
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/SiteSettings", Model: viewModel, Prefix: Prefix);
}
public override void Export(ExportContext context) {
context.Document.Element("Orchard").Add(ExportSiteSettings());
public override void Build(BuildContext context) {
context.RecipeDocument.Element("Orchard").Add(ExportSiteSettings());
}
private XElement ExportSiteSettings() {

View File

@@ -0,0 +1,7 @@
using System.Xml.Linq;
namespace Orchard.Recipes.Services {
public class BuildContext {
public XDocument RecipeDocument { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
using System.Collections.Generic;
namespace Orchard.Recipes.Services {
public interface IRecipeBuilder : IDependency {
string Build(IEnumerable<IRecipeBuilderStep> steps);
}
}

View File

@@ -1,14 +1,14 @@
using Orchard.ContentManagement;
using Orchard.Localization;
namespace Orchard.ImportExport.Services {
public interface IExportStepProvider : IDependency {
namespace Orchard.Recipes.Services {
public interface IRecipeBuilderStep : IDependency {
string Name { get; }
LocalizedString DisplayName { get; }
LocalizedString Description { get; }
int Position { get; }
int Priority { get; }
dynamic BuildEditor(dynamic shapeFactory);
dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater);
void Export(ExportContext context);
void Build(BuildContext context);
}
}

View File

@@ -0,0 +1,5 @@
namespace Orchard.Recipes.Services {
public interface IRecipeExecutor : IDependency {
string Execute(string recipeText);
}
}

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Xml.Linq;
namespace Orchard.Recipes.Services {
public class RecipeBuilder : Component, IRecipeBuilder {
public string Build(IEnumerable<IRecipeBuilderStep> steps) {
var exportDocument = CreateRecipeRoot();
var context = new BuildContext {
RecipeDocument = CreateRecipeRoot()
};
foreach (var step in steps) {
step.Build(context);
}
return exportDocument.ToString();
}
private XDocument CreateRecipeRoot() {
var recipeRoot = new XDocument(
new XDeclaration("1.0", "", "yes"),
new XComment("Exported from Orchard"),
new XElement("Orchard",
new XElement("Recipe")
)
);
return recipeRoot;
}
}
}

View File

@@ -1,12 +1,12 @@
using Orchard.ContentManagement;
using Orchard.Localization;
namespace Orchard.ImportExport.Services {
public abstract class ExportStepProvider : Component, IExportStepProvider {
namespace Orchard.Recipes.Services {
public abstract class RecipeBuilderStep : Component, IRecipeBuilderStep {
public abstract string Name { get; }
public abstract LocalizedString DisplayName { get; }
public abstract LocalizedString Description { get; }
public virtual int Position { get { return 0; } }
public virtual int Priority { get { return 0; } }
protected virtual string Prefix {
get { return GetType().Name; }
@@ -20,6 +20,6 @@ namespace Orchard.ImportExport.Services {
return null;
}
public virtual void Export(ExportContext context) {}
public virtual void Build(BuildContext context) {}
}
}

View File

@@ -0,0 +1,31 @@
using Orchard.Environment.Descriptor;
namespace Orchard.Recipes.Services {
public class RecipeExecutor : Component, IRecipeExecutor {
private readonly IRecipeParser _recipeParser;
private readonly IRecipeManager _recipeManager;
private readonly IShellDescriptorManager _shellDescriptorManager;
public RecipeExecutor(
IRecipeParser recipeParser,
IRecipeManager recipeManager,
IShellDescriptorManager shellDescriptorManager) {
_recipeParser = recipeParser;
_recipeManager = recipeManager;
_shellDescriptorManager = shellDescriptorManager;
}
public string Execute(string recipeText) {
var recipe = _recipeParser.ParseRecipe(recipeText);
var executionId = _recipeManager.Execute(recipe);
UpdateShell();
return executionId;
}
private void UpdateShell() {
var descriptor = _shellDescriptorManager.GetShellDescriptor();
_shellDescriptorManager.UpdateShellDescriptor(descriptor.SerialNumber, descriptor.Features, descriptor.Parameters);
}
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>
<handlers accessPolicy="Script,Read">
<!--
iis7 - for any request to a file exists on disk, return it via native http module.
accessPolicy 'Script' is to allow for a managed 404 page.
-->
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
</handlers>
</system.webServer>
</configuration>

View File

@@ -0,0 +1,9 @@
fieldset.export-step-data table.items {
width: 500px;
margin: 0;
}
fieldset.export-step-data table.items td,
fieldset.export-step-data table.items thead tr.sub th {
padding: 0 12px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,6 @@
.navicon-import-export {
background-image:url(images/menu.importexport.png) !important;
}
.navicon-import-export:hover {
background-position:0 -30px !important;
}

View File

@@ -1,4 +1,4 @@
namespace Orchard.ImportExport.ViewModels {
namespace Orchard.Recipes.ViewModels {
public class ContentTypeEntry {
public string Name { get; set; }
public string DisplayName { get; set; }

View File

@@ -0,0 +1,6 @@
namespace Orchard.Recipes.ViewModels {
public class CustomStepEntry {
public string CustomStep { get; set; }
public bool IsChecked { get; set; }
}
}

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Orchard.ImportExport.Models;
using Orchard.Recipes.Models;
namespace Orchard.ImportExport.ViewModels {
namespace Orchard.Recipes.ViewModels {
public class DataExportStepViewModel {
public DataExportStepViewModel() {
ContentTypes = new List<ContentTypeEntry>();

View File

@@ -0,0 +1,7 @@
using Orchard.Recipes.Models;
namespace Orchard.Recipes.ViewModels {
public class ImportResultViewModel {
public RecipeResult Result { get; set; }
}
}

View File

@@ -0,0 +1,4 @@
namespace Orchard.Recipes.ViewModels {
public class ImportViewModel {
}
}

View File

@@ -1,4 +1,4 @@
namespace Orchard.ImportExport.ViewModels {
namespace Orchard.Recipes.ViewModels {
public class SetupRecipeStepViewModel {
public string RecipeName { get; set; }
public string RecipeDescription { get; set; }

View File

@@ -1,3 +1,3 @@
namespace Orchard.ImportExport.ViewModels {
namespace Orchard.Recipes.ViewModels {
public class SiteSettingsStepViewModel {}
}

View File

@@ -1,4 +1,4 @@
@model Orchard.ImportExport.ViewModels.DataExportStepViewModel
@model Orchard.Recipes.ViewModels.DataExportStepViewModel
@{
Style.Include("exportstep-data.css");
Script.Require("jQuery");

View File

@@ -1,4 +1,4 @@
@model Orchard.ImportExport.ViewModels.SetupRecipeStepViewModel
@model Orchard.Recipes.ViewModels.SetupRecipeStepViewModel
<div>
@Html.LabelFor(m => m.RecipeName, T("Name"))
@Html.TextBoxFor(m => m.RecipeName, new { @class = "text medium" })

View File

@@ -1,2 +1,2 @@
@model Orchard.ImportExport.ViewModels.SiteSettingsStepViewModel
@model Orchard.Recipes.ViewModels.SiteSettingsStepViewModel
@Html.Hint(T("Please verify that you are not exporting confidential information, such as passwords or application keys."))