Merge pull request #6138 from neTp9c/issue/6137

Import and Export of element blueprints don't invoke events for their base elements.
This commit is contained in:
Sipke Schoorstra
2016-02-19 13:43:37 +01:00
4 changed files with 102 additions and 22 deletions

View File

@@ -0,0 +1,19 @@
using Orchard.ContentManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Orchard.Layouts.Framework.Drivers {
public class ImportContentSessionWrapper : IContentImportSession {
private readonly ImportContentSession _session;
public ImportContentSessionWrapper(ImportContentSession session) {
_session = session;
}
public ContentItem GetItemFromSession(string id) {
return _session.Get(id);
}
}
}

View File

@@ -336,6 +336,7 @@
<Compile Include="Elements\Projection.cs" />
<Compile Include="Filters\ControllerAccessorFilter.cs" />
<Compile Include="Framework\Display\ElementCreatingDisplayShapeContext.cs" />
<Compile Include="Framework\Drivers\ImportContentSessionWrapper.cs" />
<Compile Include="Framework\Drivers\ImportElementContext.cs" />
<Compile Include="Framework\Drivers\ImportLayoutContext.cs" />
<Compile Include="Framework\Elements\IElement.cs" />

View File

@@ -4,14 +4,19 @@ using Orchard.Data;
using Orchard.Layouts.Models;
using Orchard.Localization;
using Orchard.Recipes.Services;
using Orchard.Layouts.Services;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Framework.Drivers;
namespace Orchard.Layouts.Recipes.Builders {
public class CustomElementsStep : RecipeBuilderStep {
private readonly IRepository<ElementBlueprint> _repository;
private readonly IElementManager _elementManager;
public CustomElementsStep(IRepository<ElementBlueprint> repository) {
public CustomElementsStep(IRepository<ElementBlueprint> repository, IElementManager elementManager) {
_repository = repository;
_elementManager = elementManager;
}
public override string Name {
@@ -26,24 +31,41 @@ namespace Orchard.Layouts.Recipes.Builders {
get { return T("Exports custom defined elements."); }
}
public override void Build(BuildContext context) {
var elements = _repository.Table.OrderBy(x => x.ElementTypeName).ToList();
public override void Build(BuildContext context)
{
var blueprints = _repository.Table.OrderBy(x => x.ElementTypeName).ToList();
if (!elements.Any()) {
if (!blueprints.Any())
return;
}
var blueprintEntries = blueprints.Select(blueprint => {
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
var baseElement = _elementManager.ActivateElement(descriptor);
baseElement.Data = ElementDataHelper.Deserialize(blueprint.BaseElementState);
return new { Blueprint = blueprint, BaseElement = baseElement };
}).ToList();
var baseElements = blueprintEntries.Select(e => e.BaseElement).ToList();
var exportLayoutContext = new ExportLayoutContext();
_elementManager.Exporting(baseElements, exportLayoutContext);
_elementManager.Exported(baseElements, exportLayoutContext);
var root = new XElement("CustomElements");
context.RecipeDocument.Element("Orchard").Add(root);
foreach (var element in elements) {
foreach (var bluprintEntry in blueprintEntries) {
root.Add(new XElement("Element",
new XAttribute("ElementTypeName", element.ElementTypeName),
new XAttribute("BaseElementTypeName", element.BaseElementTypeName),
new XAttribute("ElementDisplayName", element.ElementDisplayName),
new XAttribute("ElementDescription", element.ElementDescription),
new XAttribute("ElementCategory", element.ElementCategory),
new XElement("BaseElementState", new XCData(element.BaseElementState))));
new XAttribute("ElementTypeName", bluprintEntry.Blueprint.ElementTypeName),
new XAttribute("BaseElementTypeName", bluprintEntry.Blueprint.BaseElementTypeName),
new XAttribute("ElementDisplayName", bluprintEntry.Blueprint.ElementDisplayName),
new XAttribute("ElementDescription", bluprintEntry.Blueprint.ElementDescription ?? ""),
new XAttribute("ElementCategory", bluprintEntry.Blueprint.ElementCategory ?? ""),
new XAttribute("BaseExportableData", bluprintEntry.BaseElement.ExportableData.Serialize()),
new XElement("BaseElementState", new XCData(bluprintEntry.Blueprint.BaseElementState))));
}
}
}

View File

@@ -1,20 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Data;
using Orchard.Layouts.Models;
using Orchard.Logging;
using Orchard.Recipes.Models;
using Orchard.Recipes.Services;
using Orchard.Layouts.Services;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
using Orchard.ContentManagement;
using Orchard.Layouts.Framework.Drivers;
namespace Orchard.Layouts.Recipes.Executors {
public class CustomElementsStep : RecipeExecutionStep {
private readonly IRepository<ElementBlueprint> _repository;
private readonly IElementManager _elementManager;
private readonly IOrchardServices _orchardServices;
public CustomElementsStep(
IRepository<ElementBlueprint> repository,
IElementManager elementManager,
IOrchardServices orchardServices,
RecipeExecutionLogger logger) : base(logger) {
_repository = repository;
_elementManager = elementManager;
_orchardServices = orchardServices;
}
public override string Name {
@@ -25,24 +37,50 @@ namespace Orchard.Layouts.Recipes.Executors {
get { return new[] { Name, "LayoutElements" }; }
}
public override void Execute(RecipeExecutionContext context) {
foreach (var elementElement in context.RecipeStep.Step.Elements()) {
var typeName = elementElement.Attribute("ElementTypeName").Value;
public override void Execute(RecipeExecutionContext context)
{
var blueprintEntries = context.RecipeStep.Step.Elements().Select(xmlBlueprint => {
var typeName = xmlBlueprint.Attribute("ElementTypeName").Value;
Logger.Information("Importing custom element '{0}'.", typeName);
try {
var element = GetOrCreateElement(typeName);
element.BaseElementTypeName = elementElement.Attribute("BaseElementTypeName").Value;
element.ElementDisplayName = elementElement.Attribute("ElementDisplayName").Value;
element.ElementDescription = elementElement.Attribute("ElementDescription").Value;
element.ElementCategory = elementElement.Attribute("ElementCategory").Value;
element.BaseElementState = elementElement.Element("BaseElementState").Value;
var blueprint = GetOrCreateElement(typeName);
blueprint.BaseElementTypeName = xmlBlueprint.Attribute("BaseElementTypeName").Value;
blueprint.ElementDisplayName = xmlBlueprint.Attribute("ElementDisplayName").Value;
blueprint.ElementDescription = xmlBlueprint.Attribute("ElementDescription").Value;
blueprint.ElementCategory = xmlBlueprint.Attribute("ElementCategory").Value;
blueprint.BaseElementState = xmlBlueprint.Element("BaseElementState").Value;
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
var baseElement = _elementManager.ActivateElement(descriptor);
baseElement.Data = ElementDataHelper.Deserialize(blueprint.BaseElementState);
baseElement.ExportableData = ElementDataHelper.Deserialize(xmlBlueprint.Attribute("BaseExportableData").Value);
return new { Blueprint = blueprint, BaseElement = baseElement };
}
catch (Exception ex) {
Logger.Error(ex, "Error while importing custom element '{0}'.", typeName);
throw;
}
}
}).ToList();
var baseElements = blueprintEntries.Select(e => e.BaseElement).ToList();
var importContentSession = new ImportContentSession(_orchardServices.ContentManager);
var importLayoutContext = new ImportLayoutContext {
Session = new ImportContentSessionWrapper(importContentSession)
};
_elementManager.Importing(baseElements, importLayoutContext);
_elementManager.Imported(baseElements, importLayoutContext);
_elementManager.ImportCompleted(baseElements, importLayoutContext);
foreach (var blueprintEntry in blueprintEntries)
blueprintEntry.Blueprint.BaseElementState = blueprintEntry.BaseElement.Data.Serialize();
}
private ElementBlueprint GetOrCreateElement(string typeName) {