Moved recipe builder and execution API into Framework and simplified step names.

This enables other modules to implement custom steps without taking a dependency on Orchard.Recipes, which would cause circular dependencies in certain cases (e.g. Orchard.Themes).
This commit is contained in:
Sipke Schoorstra
2015-07-15 14:13:36 +01:00
parent 901c11a1ea
commit 03e6948055
32 changed files with 154 additions and 91 deletions

View File

@@ -100,7 +100,7 @@ namespace Orchard.ImportExport.Commands {
var recipeBuilderSteps = new List<IRecipeBuilderStep>();
if (Metadata || Data) {
var dataStep = _orchardServices.WorkContext.Resolve<ContentRecipeBuilderStep>();
var dataStep = _orchardServices.WorkContext.Resolve<ContentStep>();
if(Data)
dataStep.DataContentTypes = exportTypes;
@@ -113,12 +113,12 @@ namespace Orchard.ImportExport.Commands {
}
if (SiteSettings) {
var siteSettingsStep = _orchardServices.WorkContext.Resolve<SettingsBuilderStep>();
var siteSettingsStep = _orchardServices.WorkContext.Resolve<SettingsStep>();
recipeBuilderSteps.Add(siteSettingsStep);
}
if (enteredSteps.Any()) {
var customStepsStep = _orchardServices.WorkContext.Resolve<CustomStepsRecipeBuilderStep>();
var customStepsStep = _orchardServices.WorkContext.Resolve<CustomStepsStep>();
recipeBuilderSteps.Add(customStepsStep);
}

View File

@@ -71,7 +71,7 @@
<Compile Include="Models\ExportOptions.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecipeBuilderSteps\CustomStepsRecipeBuilderStep.cs" />
<Compile Include="RecipeBuilderSteps\CustomStepsStep.cs" />
<Compile Include="Services\ExportContext.cs" />
<Compile Include="ViewModels\CustomStepEntry.cs" />
<Compile Include="Services\ICustomExportStep.cs" />

View File

@@ -8,11 +8,11 @@ using Orchard.Localization;
using Orchard.Recipes.Services;
namespace Orchard.ImportExport.RecipeBuilderSteps {
public class CustomStepsRecipeBuilderStep : RecipeBuilderStep {
public class CustomStepsStep : RecipeBuilderStep {
private readonly IEnumerable<IExportEventHandler> _exportEventHandlers;
private readonly ICustomExportStep _customExportStep;
public CustomStepsRecipeBuilderStep(IEnumerable<IExportEventHandler> exportEventHandlers, ICustomExportStep customExportStep) {
public CustomStepsStep(IEnumerable<IExportEventHandler> exportEventHandlers, ICustomExportStep customExportStep) {
_exportEventHandlers = exportEventHandlers;
_customExportStep = customExportStep;
CustomSteps = new List<string>();

View File

@@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Orchard.Environment.Features;
using Orchard.Events;
namespace Orchard.Modules.ImportExport {
public interface IExportEventHandler : IEventHandler {
void Exporting(dynamic context);
void Exported(dynamic context);
}
public class FeaturesExportHandler : IExportEventHandler {
private readonly IFeatureManager _featureManager;
public FeaturesExportHandler(IFeatureManager featureManager) {
_featureManager = featureManager;
}
public void Exporting(dynamic context) {
if (!((IEnumerable<string>)context.ExportOptions.CustomSteps).Contains("EnabledFeatures")) {
return;
}
var enabledFeatures = _featureManager.GetEnabledFeatures();
var root = new XElement("Feature", new XAttribute("enable", String.Join(", ", enabledFeatures.Select(x => x.Id).OrderBy(x => x))));
context.Document.Element("Orchard").Add(root);
// Add the Migration element to force migrations run immediately after the features have been synced.
context.Document.Element("Orchard").Add(new XElement("Migration", new XAttribute("features", "*")));
}
public void Exported(dynamic context) {
}
}
}

View File

@@ -1,14 +0,0 @@
using System.Collections.Generic;
using Orchard.Events;
namespace Orchard.Modules.ImportExport {
public interface ICustomExportStep : IEventHandler {
void Register(IList<string> steps);
}
public class FeaturesStep : ICustomExportStep {
public void Register(IList<string> steps) {
steps.Add("EnabledFeatures");
}
}
}

View File

@@ -72,8 +72,9 @@
<Compile Include="AdminMenu.cs" />
<Compile Include="Data\Migration\DataMigrationNotificationProvider.cs" />
<Compile Include="Events\IExtensionDisplayEventHandler.cs" />
<Compile Include="ImportExport\FeaturesStep.cs" />
<Compile Include="ImportExport\FeaturesExportHandler.cs" />
<Compile Include="RecipeBuilderSteps\FeatureStep.cs" />
<Compile Include="RecipeExecutionSteps\FeatureStep.cs" />
<Compile Include="ViewModels\FeatureStepViewModel.cs" />
<Compile Include="ResourceManifest.cs" />
<Compile Include="Commands\FeatureCommands.cs" />
<Compile Include="Controllers\AdminController.cs" />
@@ -140,6 +141,10 @@
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="Views\EditorTemplates\ExportSteps\Feature.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -0,0 +1,68 @@
using System;
using System.Linq;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.Environment.Features;
using Orchard.Localization;
using Orchard.Modules.ViewModels;
using Orchard.Recipes.Services;
namespace Orchard.Modules.RecipeBuilderSteps {
public class FeatureStep : RecipeBuilderStep {
private readonly IFeatureManager _featureManager;
public FeatureStep(IFeatureManager featureManager) {
_featureManager = featureManager;
}
public override string Name {
get { return "Feature"; }
}
public override LocalizedString DisplayName {
get { return T("Features"); }
}
public override LocalizedString Description {
get { return T("Exports enabled and disabled features."); }
}
public override int Priority { get { return 0; } }
public bool ExportEnabledFeatures { get; set; }
public bool ExportDisabledFeatures { get; set; }
public override dynamic BuildEditor(dynamic shapeFactory) {
return UpdateEditor(shapeFactory, null);
}
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
var viewModel = new FeatureStepViewModel();
if (updater != null && updater.TryUpdateModel(viewModel, Prefix, null, null)) {
ExportEnabledFeatures = viewModel.ExportEnabledFeatures;
ExportDisabledFeatures = viewModel.ExportDisabledFeatures;
}
return shapeFactory.EditorTemplate(TemplateName: "ExportSteps/Feature", Model: viewModel, Prefix: Prefix);
}
public override void Build(BuildContext context) {
if (!ExportEnabledFeatures && !ExportDisabledFeatures)
return;
var enabledFeatures = _featureManager.GetEnabledFeatures();
var disabledFeatures = _featureManager.GetDisabledFeatures();
var orchardElement = context.RecipeDocument.Element("Orchard");
var root = new XElement("Feature");
if(ExportEnabledFeatures)
root.Add(new XAttribute("enable", String.Join(", ", enabledFeatures.Select(x => x.Id).OrderBy(x => x))));
if (ExportDisabledFeatures)
root.Add(new XAttribute("disable", String.Join(", ", disabledFeatures.Select(x => x.Id).OrderBy(x => x))));
orchardElement.Add(root);
}
}
}

View File

@@ -5,7 +5,7 @@ using Orchard.Environment.Features;
using Orchard.Logging;
using Orchard.Recipes.Services;
namespace Orchard.Recipes.RecipeExecutionSteps {
namespace Orchard.Modules.RecipeExecutionSteps {
public class FeatureStep : RecipeExecutionStep {
private readonly IFeatureManager _featureManager;

View File

@@ -0,0 +1,6 @@
namespace Orchard.Modules.ViewModels {
public class FeatureStepViewModel {
public bool ExportEnabledFeatures { get; set; }
public bool ExportDisabledFeatures { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
@model Orchard.Modules.ViewModels.FeatureStepViewModel
<div>
@Html.CheckBoxFor(m => m.ExportEnabledFeatures)
@Html.LabelFor(m => m.ExportEnabledFeatures, T("Enabled Features").ToString(), new {@class = "forcheckbox"})
@Html.Hint(T("Check this option to export the set of enabled features."))
</div>
<div>
@Html.CheckBoxFor(m => m.ExportDisabledFeatures)
@Html.LabelFor(m => m.ExportDisabledFeatures, T("Disabled Features").ToString(), new { @class = "forcheckbox" })
@Html.Hint(T("Check this option to export the set of disabled features."))
</div>

View File

@@ -82,12 +82,11 @@
<Compile Include="Models\RecipeStepResultRecord.cs" />
<Compile Include="Models\VersionHistoryOptions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecipeBuilders\ContentRecipeBuilderStep.cs" />
<Compile Include="RecipeBuilders\RecipeMetadataBuilderStep.cs" />
<Compile Include="RecipeBuilders\SettingsBuilderStep.cs" />
<Compile Include="RecipeBuilders\ContentStep.cs" />
<Compile Include="RecipeBuilders\RecipeMetadataStep.cs" />
<Compile Include="RecipeBuilders\SettingsStep.cs" />
<Compile Include="RecipeExecutionSteps\CommandStep.cs" />
<Compile Include="RecipeExecutionSteps\ContentStep.cs" />
<Compile Include="RecipeExecutionSteps\FeatureStep.cs" />
<Compile Include="RecipeExecutionSteps\ContentSchemaStep.cs" />
<Compile Include="RecipeExecutionSteps\MigrationStep.cs" />
<Compile Include="RecipeExecutionSteps\ModuleStep.cs" />
@@ -95,16 +94,6 @@
<Compile Include="RecipeExecutionSteps\ThemeStep.cs" />
<Compile Include="RecipeHandlers\RecipeExecutionStepHandler.cs" />
<Compile Include="Routes.cs" />
<Compile Include="Services\BuildContext.cs" />
<Compile Include="Services\IRecipeExecutionStep.cs" />
<Compile Include="Services\IRecipeExecutor.cs" />
<Compile Include="Services\RecipeExecutionContext.cs" />
<Compile Include="Services\RecipeExecutionStep.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" />

View File

@@ -10,12 +10,12 @@ using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.Recipes.RecipeBuilders {
public class ContentRecipeBuilderStep : RecipeBuilderStep {
public class ContentStep : RecipeBuilderStep {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IOrchardServices _orchardServices;
private readonly IContentDefinitionWriter _contentDefinitionWriter;
public ContentRecipeBuilderStep(
public ContentStep(
IContentDefinitionManager contentDefinitionManager,
IOrchardServices orchardServices,
IContentDefinitionWriter contentDefinitionWriter) {

View File

@@ -4,9 +4,9 @@ using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.Recipes.RecipeBuilders {
public class RecipeMetadataBuilderStep : RecipeBuilderStep {
public class RecipeMetadataStep : RecipeBuilderStep {
private readonly IOrchardServices _orchardServices;
public RecipeMetadataBuilderStep(IOrchardServices orchardServices) {
public RecipeMetadataStep(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
}

View File

@@ -7,10 +7,10 @@ using Orchard.Recipes.Services;
using Orchard.Recipes.ViewModels;
namespace Orchard.Recipes.RecipeBuilders {
public class SettingsBuilderStep : RecipeBuilderStep {
public class SettingsStep : RecipeBuilderStep {
private readonly IOrchardServices _orchardServices;
public SettingsBuilderStep(IOrchardServices orchardServices) {
public SettingsStep(IOrchardServices orchardServices) {
_orchardServices = orchardServices;
}

View File

@@ -35,7 +35,7 @@ namespace Orchard.Roles.ImportExport {
var root = new XElement("Roles");
context.Document.Element("Orchard").Add(root);
foreach (var role in roles.OrderBy(x => x)) {
foreach (var role in roles.OrderBy(x => x.Name)) {
root.Add(new XElement("Role",
new XAttribute("Name", role.Name),
new XAttribute("Permissions", string.Join(",", role.RolesPermissions.Select(rolePermission => rolePermission.Permission.Name)))));

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions.Models;
namespace Orchard.Environment.Extensions.Helpers {
public static class ExtensionManagerExtensions {
public static IEnumerable<FeatureDescriptor> EnabledFeatures(this IExtensionManager extensionManager, ShellDescriptor descriptor) {
return extensionManager.AvailableFeatures().Where(fd => descriptor.Features.Any(sf => sf.Name == fd.Id));
}
public static IEnumerable<FeatureDescriptor> DisabledFeatures(this IExtensionManager extensionManager, ShellDescriptor descriptor) {
return extensionManager.AvailableFeatures().Where(fd => descriptor.Features.All(sf => sf.Name != fd.Id));
}
}
}

View File

@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions.Models;
namespace Orchard.Environment.Extensions {
@@ -12,10 +10,4 @@ namespace Orchard.Environment.Extensions {
IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> featureDescriptors);
}
public static class ExtensionManagerExtensions {
public static IEnumerable<FeatureDescriptor> EnabledFeatures(this IExtensionManager extensionManager, ShellDescriptor descriptor) {
return extensionManager.AvailableFeatures().Where(fd => descriptor.Features.Any(sf => sf.Name == fd.Id));
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Linq;
using Orchard.Environment.Descriptor;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Helpers;
using Orchard.Environment.Extensions.Models;
using Orchard.Localization;
using Orchard.Logging;
@@ -48,6 +49,15 @@ namespace Orchard.Environment.Features {
return _extensionManager.EnabledFeatures(currentShellDescriptor);
}
/// <summary>
/// Retrieves the disabled features.
/// </summary>
/// <returns>An enumeration of feature descriptors for the disabled features.</returns>
public IEnumerable<FeatureDescriptor> GetDisabledFeatures() {
var currentShellDescriptor = _shellDescriptorManager.GetShellDescriptor();
return _extensionManager.DisabledFeatures(currentShellDescriptor);
}
/// <summary>
/// Enables a list of features.
/// </summary>

View File

@@ -19,6 +19,12 @@ namespace Orchard.Environment.Features {
/// <returns>An enumeration of feature descriptors for the enabled features.</returns>
IEnumerable<FeatureDescriptor> GetEnabledFeatures();
/// <summary>
/// Retrieves the disabled features.
/// </summary>
/// <returns>An enumeration of feature descriptors for the disabled features.</returns>
IEnumerable<FeatureDescriptor> GetDisabledFeatures();
/// <summary>
/// Enables a list of features.
/// </summary>

View File

@@ -10,6 +10,7 @@ using Orchard.ContentManagement.Records;
using Orchard.Environment.Configuration;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Helpers;
using Orchard.Environment.Extensions.Models;
using Orchard.Environment.ShellBuilders.Models;
using Orchard.Logging;

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Web.Mvc;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Helpers;
using Orchard.Environment.Extensions.Models;
using Orchard.Logging;

View File

@@ -149,9 +149,20 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="Environment\Extensions\Helpers\ExtensionManagerExtensions.cs" />
<Compile Include="Recipes\Models\RecipeResult.cs" />
<Compile Include="Recipes\Models\RecipeStepResult.cs" />
<Compile Include="Recipes\Models\BuildContext.cs" />
<Compile Include="Recipes\Services\IRecipeBuilder.cs" />
<Compile Include="Recipes\Services\IRecipeBuilderStep.cs" />
<Compile Include="Recipes\Services\IRecipeExecutionStep.cs" />
<Compile Include="Recipes\Services\IRecipeExecutor.cs" />
<Compile Include="Recipes\Services\IRecipeResultAccessor.cs" />
<Compile Include="Recipes\Services\RecipeBuilder.cs" />
<Compile Include="Recipes\Services\RecipeBuilderStep.cs" />
<Compile Include="Recipes\Models\RecipeExecutionContext.cs" />
<Compile Include="Recipes\Services\RecipeExecutionStep.cs" />
<Compile Include="Recipes\Services\RecipeExecutor.cs" />
<Compile Include="Reports\Report.cs" />
<Compile Include="Reports\ReportEntry.cs" />
<Compile Include="Reports\ReportExtentions.cs" />