mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-31 19:06:34 +08:00
#19224: Implementing import/export hooks for forms data
Work Item: 19224 --HG-- branch : 1.x
This commit is contained in:
parent
181780cb6d
commit
769afd3083
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Logging;
|
||||
|
||||
@ -48,6 +49,41 @@ namespace Orchard.Forms.Services {
|
||||
return formShape;
|
||||
}
|
||||
|
||||
public string Export(string formName, string state, ExportContentContext exportContext) {
|
||||
var describeContext = new DescribeContext();
|
||||
foreach (var provider in _formProviders) {
|
||||
provider.Describe(describeContext);
|
||||
}
|
||||
|
||||
var descriptor = describeContext.Describe().FirstOrDefault(x => x.Name == formName);
|
||||
|
||||
if (descriptor == null || descriptor.Export == null) {
|
||||
return state;
|
||||
}
|
||||
|
||||
var dynamicState = FormParametersHelper.ToDynamic(state);
|
||||
descriptor.Export(dynamicState, exportContext);
|
||||
|
||||
return FormParametersHelper.ToString(dynamicState);
|
||||
}
|
||||
|
||||
public string Import(string formName, string state, ImportContentContext importContext) {
|
||||
var describeContext = new DescribeContext();
|
||||
foreach (var provider in _formProviders) {
|
||||
provider.Describe(describeContext);
|
||||
}
|
||||
|
||||
var descriptor = describeContext.Describe().FirstOrDefault(x => x.Name == formName);
|
||||
|
||||
if (descriptor == null || descriptor.Import == null) {
|
||||
return state;
|
||||
}
|
||||
|
||||
var dynamicState = FormParametersHelper.ToDynamic(state);
|
||||
descriptor.Import(dynamicState, importContext);
|
||||
|
||||
return FormParametersHelper.ToString(dynamicState);
|
||||
}
|
||||
|
||||
private static void BindValue(dynamic shape, IValueProvider valueProvider, string prefix) {
|
||||
// if the shape has a Name property, look for a value in
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
@ -8,6 +9,15 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Orchard.Forms.Services {
|
||||
public static class FormParametersHelper {
|
||||
public static string ToString(dynamic state) {
|
||||
var json = JsonConvert.SerializeObject(state);
|
||||
var doc = (XmlDocument)JsonConvert.DeserializeXmlNode("{ 'Form': " + json + "}");
|
||||
using (var sw = new StringWriter()) {
|
||||
doc.Save(sw);
|
||||
return sw.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToString(IDictionary<string, string> parameters) {
|
||||
var doc = new XDocument();
|
||||
doc.Add(new XElement("Form"));
|
||||
|
@ -1,9 +1,13 @@
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Forms.Services {
|
||||
public interface IFormManager : IDependency {
|
||||
dynamic Build(string formName, string prefix = "");
|
||||
dynamic Bind(dynamic formShape, IValueProvider state, string prefix = "");
|
||||
void Validate(ValidatingContext context);
|
||||
|
||||
string Export(string formName, string state, ExportContentContext exportContext);
|
||||
string Import(string formName, string state, ImportContentContext exportContext);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Events;
|
||||
|
||||
@ -20,10 +21,24 @@ namespace Orchard.Forms.Services {
|
||||
_descriptors[name] = new FormDescriptor { Name = name, Shape = shape };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescribeContext Form(string name, Func<IShapeFactory, dynamic> shape, Action<dynamic, ImportContentContext> importing, Action<dynamic, ExportContentContext> exporting) {
|
||||
_descriptors[name] = new FormDescriptor { Name = name, Shape = shape, Import = importing, Export = exporting};
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class FormDescriptor {
|
||||
public string Name { get; set; }
|
||||
public Func<IShapeFactory, dynamic> Shape { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the logic to be executed when the state is imported, like adapting content identities
|
||||
/// </summary>
|
||||
public Action<dynamic, ImportContentContext> Import { get; set; }
|
||||
/// <summary>
|
||||
/// Contains the logic to be executed when the state is imported, like adapting content identities
|
||||
/// </summary>
|
||||
public Action<dynamic, ExportContentContext> Export { get; set; }
|
||||
}
|
||||
}
|
@ -4,11 +4,21 @@ using System.Xml.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Forms.Services;
|
||||
using Orchard.Projections.Models;
|
||||
using Orchard.Projections.Services;
|
||||
|
||||
namespace Orchard.Projections.Drivers {
|
||||
|
||||
public class QueryPartDriver : ContentPartDriver<QueryPart> {
|
||||
private readonly IProjectionManager _projectionManager;
|
||||
private readonly IFormManager _formManager;
|
||||
|
||||
public QueryPartDriver(IProjectionManager projectionManager, IFormManager formManager) {
|
||||
_projectionManager = projectionManager;
|
||||
_formManager = formManager;
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(QueryPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
if(updater == null) {
|
||||
return null;
|
||||
@ -23,49 +33,68 @@ namespace Orchard.Projections.Drivers {
|
||||
|
||||
element.Add(
|
||||
new XElement("FilterGroups",
|
||||
part.FilterGroups.Select( filterGroup =>
|
||||
part.FilterGroups.Select(filterGroup =>
|
||||
new XElement("FilterGroup",
|
||||
filterGroup.Filters.Select( filter =>
|
||||
new XElement("Filter",
|
||||
new XAttribute("Category", filter.Category ?? ""),
|
||||
new XAttribute("Description", filter.Description ?? ""),
|
||||
new XAttribute("Position", filter.Position),
|
||||
new XAttribute("State", filter.State ?? ""),
|
||||
new XAttribute("Type", filter.Type ?? "")
|
||||
)
|
||||
)
|
||||
filterGroup.Filters.Select(filter => {
|
||||
|
||||
var descriptor = _projectionManager.GetFilter(filter.Category, filter.Type);
|
||||
|
||||
if (descriptor != null) {
|
||||
filter.State = _formManager.Export(descriptor.Form, filter.State, context);
|
||||
}
|
||||
|
||||
return new XElement("Filter",
|
||||
new XAttribute("Category", filter.Category ?? ""),
|
||||
new XAttribute("Description", filter.Description ?? ""),
|
||||
new XAttribute("Position", filter.Position),
|
||||
new XAttribute("State", filter.State ?? ""),
|
||||
new XAttribute("Type", filter.Type ?? "")
|
||||
);
|
||||
})
|
||||
)
|
||||
)
|
||||
),
|
||||
new XElement("SortCriteria",
|
||||
part.SortCriteria.Select( sortCriterion =>
|
||||
new XElement("SortCriterion",
|
||||
new XAttribute("Category", sortCriterion.Category ?? ""),
|
||||
new XAttribute("Description", sortCriterion.Description ?? ""),
|
||||
new XAttribute("Position", sortCriterion.Position),
|
||||
new XAttribute("State", sortCriterion.State ?? ""),
|
||||
new XAttribute("Type", sortCriterion.Type ?? "")
|
||||
)
|
||||
)
|
||||
part.SortCriteria.Select(sortCriterion => {
|
||||
var descriptor = _projectionManager.GetFilter(sortCriterion.Category, sortCriterion.Type);
|
||||
|
||||
if (descriptor != null) {
|
||||
sortCriterion.State = _formManager.Export(descriptor.Form, sortCriterion.State, context);
|
||||
}
|
||||
|
||||
return new XElement("SortCriterion",
|
||||
new XAttribute("Category", sortCriterion.Category ?? ""),
|
||||
new XAttribute("Description", sortCriterion.Description ?? ""),
|
||||
new XAttribute("Position", sortCriterion.Position),
|
||||
new XAttribute("State", sortCriterion.State ?? ""),
|
||||
new XAttribute("Type", sortCriterion.Type ?? "")
|
||||
);
|
||||
})
|
||||
),
|
||||
new XElement("Layouts",
|
||||
part.Layouts.Select( layout =>
|
||||
new XElement("Layout",
|
||||
// Attributes
|
||||
new XAttribute("Category", layout.Category ?? ""),
|
||||
new XAttribute("Description", layout.Description ?? ""),
|
||||
new XAttribute("State", layout.State),
|
||||
new XAttribute("Display", layout.Display),
|
||||
new XAttribute("DisplayType", layout.DisplayType ?? ""),
|
||||
new XAttribute("Type", layout.Type ?? ""),
|
||||
|
||||
// Properties
|
||||
new XElement("Properties", layout.Properties.Select(GetPropertyXml)),
|
||||
part.Layouts.Select(layout => {
|
||||
var descriptor = _projectionManager.GetFilter(layout.Category, layout.Type);
|
||||
|
||||
// Group
|
||||
new XElement("Group", GetPropertyXml(layout.GroupProperty))
|
||||
)
|
||||
)
|
||||
if (descriptor != null) {
|
||||
layout.State = _formManager.Export(descriptor.Form, layout.State, context);
|
||||
}
|
||||
|
||||
return new XElement("Layout",
|
||||
// Attributes
|
||||
new XAttribute("Category", layout.Category ?? ""),
|
||||
new XAttribute("Description", layout.Description ?? ""),
|
||||
new XAttribute("State", layout.State),
|
||||
new XAttribute("Display", layout.Display),
|
||||
new XAttribute("DisplayType", layout.DisplayType ?? ""),
|
||||
new XAttribute("Type", layout.Type ?? ""),
|
||||
|
||||
// Properties
|
||||
new XElement("Properties", layout.Properties.Select(GetPropertyXml)),
|
||||
|
||||
// Group
|
||||
new XElement("Group", GetPropertyXml(layout.GroupProperty))
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -74,49 +103,79 @@ namespace Orchard.Projections.Drivers {
|
||||
var queryElement = context.Data.Element(part.PartDefinition.Name);
|
||||
|
||||
part.Record.FilterGroups.Clear();
|
||||
foreach(var item in queryElement.Element("FilterGroups").Elements("FilterGroup").Select(filterGroup =>
|
||||
foreach (var item in queryElement.Element("FilterGroups").Elements("FilterGroup").Select(filterGroup =>
|
||||
new FilterGroupRecord {
|
||||
Filters = filterGroup.Elements("Filter").Select( filter =>
|
||||
new FilterRecord {
|
||||
Category = filter.Attribute("Category").Value,
|
||||
Filters = filterGroup.Elements("Filter").Select(filter => {
|
||||
|
||||
var category = filter.Attribute("Category").Value;
|
||||
var type = filter.Attribute("Type").Value;
|
||||
var state = filter.Attribute("State").Value;
|
||||
|
||||
var descriptor = _projectionManager.GetFilter(category, type);
|
||||
if (descriptor != null) {
|
||||
state = _formManager.Import(descriptor.Form, state, context);
|
||||
}
|
||||
|
||||
return new FilterRecord {
|
||||
Category = category,
|
||||
Description = filter.Attribute("Description").Value,
|
||||
Position = Convert.ToInt32(filter.Attribute("Position").Value),
|
||||
State = filter.Attribute("State").Value,
|
||||
Type = filter.Attribute("Type").Value
|
||||
}).ToList()
|
||||
State = state,
|
||||
Type = type
|
||||
};
|
||||
}).ToList()
|
||||
})) {
|
||||
part.Record.FilterGroups.Add(item);
|
||||
}
|
||||
|
||||
part.Record.SortCriteria.Clear();
|
||||
foreach(var item in queryElement.Element("SortCriteria").Elements("SortCriterion").Select(sortCriterion =>
|
||||
new SortCriterionRecord {
|
||||
Category = sortCriterion.Attribute("Category").Value,
|
||||
foreach (var item in queryElement.Element("SortCriteria").Elements("SortCriterion").Select(sortCriterion => {
|
||||
var category = sortCriterion.Attribute("Category").Value;
|
||||
var type = sortCriterion.Attribute("Type").Value;
|
||||
var state = sortCriterion.Attribute("State").Value;
|
||||
|
||||
var descriptor = _projectionManager.GetFilter(category, type);
|
||||
if (descriptor != null) {
|
||||
state = _formManager.Import(descriptor.Form, state, context);
|
||||
}
|
||||
|
||||
return new SortCriterionRecord {
|
||||
Category = category,
|
||||
Description = sortCriterion.Attribute("Description").Value,
|
||||
Position = Convert.ToInt32(sortCriterion.Attribute("Position").Value),
|
||||
State = sortCriterion.Attribute("State").Value,
|
||||
Type = sortCriterion.Attribute("Type").Value
|
||||
State = state,
|
||||
Type = type
|
||||
|
||||
})) {
|
||||
};
|
||||
})) {
|
||||
part.Record.SortCriteria.Add(item);
|
||||
}
|
||||
|
||||
part.Record.Layouts.Clear();
|
||||
foreach(var item in queryElement.Element("Layouts").Elements("Layout").Select(layout =>
|
||||
new LayoutRecord {
|
||||
|
||||
Category = layout.Attribute("Category").Value,
|
||||
foreach (var item in queryElement.Element("Layouts").Elements("Layout").Select(layout => {
|
||||
var category = layout.Attribute("Category").Value;
|
||||
var type = layout.Attribute("Type").Value;
|
||||
var state = layout.Attribute("State").Value;
|
||||
|
||||
var descriptor = _projectionManager.GetFilter(category, type);
|
||||
if (descriptor != null) {
|
||||
state = _formManager.Import(descriptor.Form, state, context);
|
||||
}
|
||||
|
||||
return new LayoutRecord {
|
||||
|
||||
Category = category,
|
||||
Description = layout.Attribute("Description").Value,
|
||||
Display = int.Parse(layout.Attribute("Display").Value),
|
||||
DisplayType = layout.Attribute("DisplayType").Value,
|
||||
State = layout.Attribute("State").Value,
|
||||
Type = layout.Attribute("Type").Value,
|
||||
State = state,
|
||||
Type = type,
|
||||
Properties = layout.Element("Properties").Elements("Property").Select(GetProperty).ToList(),
|
||||
GroupProperty = GetProperty(layout.Element("Group").Element("Property"))
|
||||
})) {
|
||||
};
|
||||
})) {
|
||||
part.Record.Layouts.Add(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private XElement GetPropertyXml(PropertyRecord property) {
|
||||
|
@ -13,6 +13,11 @@ namespace Orchard.Projections.Services {
|
||||
IEnumerable<TypeDescriptor<LayoutDescriptor>> DescribeLayouts();
|
||||
IEnumerable<TypeDescriptor<PropertyDescriptor>> DescribeProperties();
|
||||
|
||||
FilterDescriptor GetFilter(string category, string type);
|
||||
SortCriterionDescriptor GetSortCriterion(string category, string type);
|
||||
LayoutDescriptor GetLayout(string category, string type);
|
||||
PropertyDescriptor GetProperty(string category, string type);
|
||||
|
||||
IEnumerable<ContentItem> GetContentItems(int queryId, int skip = 0, int count = 0);
|
||||
int GetCount(int queryId);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data;
|
||||
using Orchard.Forms.Services;
|
||||
using Orchard.Projections.Descriptors;
|
||||
@ -80,6 +79,30 @@ namespace Orchard.Projections.Services {
|
||||
return context.Describe();
|
||||
}
|
||||
|
||||
public FilterDescriptor GetFilter(string category, string type) {
|
||||
return DescribeFilters()
|
||||
.SelectMany(x => x.Descriptors)
|
||||
.FirstOrDefault(x => x.Category == category && x.Type == type);
|
||||
}
|
||||
|
||||
public SortCriterionDescriptor GetSortCriterion(string category, string type) {
|
||||
return DescribeSortCriteria()
|
||||
.SelectMany(x => x.Descriptors)
|
||||
.FirstOrDefault(x => x.Category == category && x.Type == type);
|
||||
}
|
||||
|
||||
public LayoutDescriptor GetLayout(string category, string type) {
|
||||
return DescribeLayouts()
|
||||
.SelectMany(x => x.Descriptors)
|
||||
.FirstOrDefault(x => x.Category == category && x.Type == type);
|
||||
}
|
||||
|
||||
public PropertyDescriptor GetProperty(string category, string type) {
|
||||
return DescribeProperties()
|
||||
.SelectMany(x => x.Descriptors)
|
||||
.FirstOrDefault(x => x.Category == category && x.Type == type);
|
||||
}
|
||||
|
||||
public int GetCount(int queryId) {
|
||||
|
||||
var queryRecord = _queryRepository.Get(queryId);
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Taxonomies.Helpers;
|
||||
using Orchard.Taxonomies.Services;
|
||||
using Orchard.DisplayManagement;
|
||||
@ -65,7 +67,35 @@ namespace Orchard.Taxonomies.Projections {
|
||||
return f;
|
||||
};
|
||||
|
||||
context.Form("SelectTerms", form);
|
||||
context.Form("SelectTerms",
|
||||
form,
|
||||
(Action<dynamic, ImportContentContext>) Import,
|
||||
(Action<dynamic, ExportContentContext>) Export
|
||||
);
|
||||
}
|
||||
|
||||
public void Export(dynamic state, ExportContentContext context) {
|
||||
string termIds = Convert.ToString(state.TermIds);
|
||||
|
||||
if (!String.IsNullOrEmpty(termIds)) {
|
||||
var ids = termIds.Split(new[] {','}).Select(Int32.Parse).ToArray();
|
||||
var terms = ids.Select(_taxonomyService.GetTerm).ToList();
|
||||
var identities = terms.Select(context.ContentManager.GetItemMetadata).Select(x => x.Identity.ToString()).ToArray();
|
||||
|
||||
state.TermIds = String.Join(",", identities);
|
||||
}
|
||||
}
|
||||
|
||||
public void Import(dynamic state, ImportContentContext context) {
|
||||
string termIdentities = Convert.ToString(state.TermIds);
|
||||
|
||||
if (!String.IsNullOrEmpty(termIdentities)) {
|
||||
var identities = termIdentities.Split(new[] { ',' }).ToArray();
|
||||
var terms = identities.Select(context.GetItemFromSession).ToList();
|
||||
var ids = terms.Select(x => x.Id).Select(x => x.ToString()).ToArray();
|
||||
|
||||
state.TermIds = String.Join(",", ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user