#19224: Implementing import/export hooks for forms data

Work Item: 19224

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros 2013-07-12 10:45:13 -07:00
parent 181780cb6d
commit 769afd3083
8 changed files with 240 additions and 58 deletions

View File

@ -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

View File

@ -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"));

View File

@ -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);
}
}

View File

@ -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; }
}
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
}
}
}