mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-04-05 21:01:35 +08:00
Fixing field indexing with nullable or multiple values
This commit is contained in:
parent
66a4e03378
commit
690e7f60e1
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using JetBrains.Annotations;
|
||||
@ -91,7 +90,8 @@ namespace Orchard.Core.Common.Drivers {
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The text associated with the field."));
|
||||
.Member(null, typeof(string), T("Value"), T("The text associated with the field."))
|
||||
.Enumerate<TextField>(() => field => new[] { field.Value });
|
||||
}
|
||||
}
|
||||
}
|
@ -65,7 +65,9 @@ namespace Orchard.Fields.Drivers {
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(Boolean), T("Value"), T("The boolean value of the field."));
|
||||
.Member(null, typeof(Boolean), T("Value"), T("The boolean value of the field."))
|
||||
.Enumerate<BooleanField>(() => field => new [] { field.Value })
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using System.Xml;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Fields.Fields;
|
||||
using Orchard.Fields.Settings;
|
||||
using Orchard.Fields.ViewModels;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
@ -11,7 +12,7 @@ using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Fields.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class DateTimeFieldDriver : ContentFieldDriver<Fields.DateTimeField> {
|
||||
public class DateTimeFieldDriver : ContentFieldDriver<DateTimeField> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private const string TemplateName = "Fields/DateTime.Edit"; // EditorTemplates/Fields/DateTime.Edit.cshtml
|
||||
private readonly Lazy<CultureInfo> _cultureInfo;
|
||||
@ -33,7 +34,7 @@ namespace Orchard.Fields.Drivers {
|
||||
return field.Name;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(ContentPart part, Fields.DateTimeField field, string displayType, dynamic shapeHelper) {
|
||||
protected override DriverResult Display(ContentPart part, DateTimeField field, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_DateTime", // this is just a key in the Shape Table
|
||||
GetDifferentiator(field, part),
|
||||
() => {
|
||||
@ -57,7 +58,7 @@ namespace Orchard.Fields.Drivers {
|
||||
);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, Fields.DateTimeField field, dynamic shapeHelper) {
|
||||
protected override DriverResult Editor(ContentPart part, DateTimeField field, dynamic shapeHelper) {
|
||||
|
||||
var settings = field.PartFieldDefinition.Settings.GetModel<DateTimeFieldSettings>();
|
||||
var value = field.DateTime;
|
||||
@ -76,7 +77,7 @@ namespace Orchard.Fields.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: viewModel, Prefix: GetPrefix(field, part)));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, Fields.DateTimeField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
protected override DriverResult Editor(ContentPart part, DateTimeField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var viewModel = new DateTimeFieldViewModel();
|
||||
|
||||
if(updater.TryUpdateModel(viewModel, GetPrefix(field, part), null, null)) {
|
||||
@ -116,17 +117,20 @@ namespace Orchard.Fields.Drivers {
|
||||
return Editor(part, field, shapeHelper);
|
||||
}
|
||||
|
||||
protected override void Importing(ContentPart part, Fields.DateTimeField field, ImportContentContext context) {
|
||||
protected override void Importing(ContentPart part, DateTimeField field, ImportContentContext context) {
|
||||
context.ImportAttribute(GetPrefix(field, part), "Value", v => field.Storage.Set(null, XmlConvert.ToDateTime(v, XmlDateTimeSerializationMode.Utc)));
|
||||
}
|
||||
|
||||
protected override void Exporting(ContentPart part, Fields.DateTimeField field, ExportContentContext context) {
|
||||
protected override void Exporting(ContentPart part, DateTimeField field, ExportContentContext context) {
|
||||
context.Element(GetPrefix(field, part)).SetAttributeValue("Value", XmlConvert.ToString(field.Storage.Get<DateTime>(null), XmlDateTimeSerializationMode.Utc));
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(DateTime), T("Value"), T("The date time value of the field."));
|
||||
.Member(null, typeof(DateTime), T("Value"), T("The date time value of the field."))
|
||||
.Enumerate<DateTimeField>(() => field => new[] { field.DateTime })
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
using System;
|
||||
using Orchard;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Fields.Settings;
|
||||
using Orchard.Fields.Fields;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Fields.Drivers {
|
||||
public class EnumerationFieldDriver : ContentFieldDriver<Fields.EnumerationField> {
|
||||
public class EnumerationFieldDriver : ContentFieldDriver<EnumerationField> {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private const string TemplateName = "Fields/Enumeration.Edit";
|
||||
|
||||
@ -24,21 +21,21 @@ namespace Orchard.Fields.Drivers {
|
||||
return part.PartDefinition.Name + "." + field.Name;
|
||||
}
|
||||
|
||||
private static string GetDifferentiator(Fields.EnumerationField field, ContentPart part) {
|
||||
private static string GetDifferentiator(EnumerationField field, ContentPart part) {
|
||||
return field.Name;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(ContentPart part, Fields.EnumerationField field, string displayType, dynamic shapeHelper) {
|
||||
protected override DriverResult Display(ContentPart part, EnumerationField field, string displayType, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Enumeration", GetDifferentiator(field, part),
|
||||
() => shapeHelper.Fields_Enumeration());
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, Fields.EnumerationField field, dynamic shapeHelper) {
|
||||
protected override DriverResult Editor(ContentPart part, EnumerationField field, dynamic shapeHelper) {
|
||||
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field, part),
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part)));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContentPart part, Fields.EnumerationField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
protected override DriverResult Editor(ContentPart part, EnumerationField field, IUpdateModel updater, dynamic shapeHelper) {
|
||||
if (updater.TryUpdateModel(field, GetPrefix(field, part), null, null)) {
|
||||
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
|
||||
if (settings.Required && field.SelectedValues.Length == 0) {
|
||||
@ -59,7 +56,8 @@ namespace Orchard.Fields.Drivers {
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The selected values of the field."));
|
||||
.Member(null, typeof(string), T("Value"), T("The selected values of the field."))
|
||||
.Enumerate<EnumerationField>(() => field => field.SelectedValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ namespace Orchard.Fields.Drivers {
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member(null, typeof(string), T("Value"), T("The value of the field."));
|
||||
.Member(null, typeof(string), T("Value"), T("The value of the field."))
|
||||
.Enumerate<InputField>(() => field => new[] { field.Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ namespace Orchard.Fields.Drivers {
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context
|
||||
.Member("Text", typeof(string), T("Text"), T("The text of the link."))
|
||||
.Member(null, typeof(string), T("Url"), T("The url of the link."));
|
||||
.Member(null, typeof(string), T("Url"), T("The url of the link."))
|
||||
.Enumerate<LinkField>(() => field => new[] { field.Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,9 @@ namespace Orchard.Fields.Drivers {
|
||||
}
|
||||
|
||||
protected override void Describe(DescribeMembersContext context) {
|
||||
context.Member(null, typeof(decimal), T("Value"), T("The value of the field."));
|
||||
context
|
||||
.Member(null, typeof(decimal), T("Value"), T("The value of the field."))
|
||||
.Enumerate<NumericField> (() => field => new[] { field.Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ namespace Orchard.Indexing.Handlers {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// part fields
|
||||
foreach ( var part in infosetPart.ContentItem.Parts ) {
|
||||
foreach ( var field in part.PartDefinition.Fields ) {
|
||||
@ -43,29 +42,36 @@ namespace Orchard.Indexing.Handlers {
|
||||
|
||||
ContentPart localPart = part;
|
||||
ContentPartFieldDefinition localField = field;
|
||||
var membersContext = new DescribeMembersContext(
|
||||
(storageName, storageType, displayName, description) =>
|
||||
{
|
||||
var fieldStorage = _fieldStorageProvider.BindStorage(localPart, localField);
|
||||
var fieldStorage = _fieldStorageProvider.BindStorage(localPart, localField);
|
||||
var indexName = infosetPart.TypeDefinition.Name.ToLower() + "-" + field.Name.ToLower();
|
||||
|
||||
// fieldStorage.Get<T>(storageName)
|
||||
var getter = typeof(IFieldStorage).GetMethod("Get").MakeGenericMethod(storageType);
|
||||
var fieldValue = getter.Invoke(fieldStorage, new[] { storageName });
|
||||
var indexName = String.Format("{0}-{1}", infosetPart.TypeDefinition.Name.ToLower(), field.Name.ToLower());
|
||||
var membersContext = new DescribeMembersContext(fieldStorage, values => {
|
||||
|
||||
TypeCode typeCode = Type.GetTypeCode(storageType);
|
||||
foreach (var value in values) {
|
||||
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var t = value.GetType();
|
||||
|
||||
// the T is nullable, convert using underlying type
|
||||
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
|
||||
t = Nullable.GetUnderlyingType(t);
|
||||
}
|
||||
|
||||
switch (typeCode)
|
||||
{
|
||||
var typeCode = Type.GetTypeCode(t);
|
||||
|
||||
switch (typeCode) {
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.String:
|
||||
case TypeCode.Char:
|
||||
context.DocumentIndex.Add(indexName, Convert.ToString(fieldValue)).RemoveTags().Analyze();
|
||||
context.DocumentIndex.Add(indexName, Convert.ToString(value)).RemoveTags().Analyze();
|
||||
break;
|
||||
case TypeCode.Boolean:
|
||||
context.DocumentIndex.Add(indexName, Convert.ToBoolean(fieldValue));
|
||||
context.DocumentIndex.Add(indexName, Convert.ToBoolean(value));
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Int16:
|
||||
@ -74,19 +80,19 @@ namespace Orchard.Indexing.Handlers {
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
context.DocumentIndex.Add(indexName, Convert.ToInt32(fieldValue));
|
||||
context.DocumentIndex.Add(indexName, Convert.ToInt32(value));
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.Decimal:
|
||||
context.DocumentIndex.Add(indexName, Convert.ToDouble(fieldValue));
|
||||
context.DocumentIndex.Add(indexName, Convert.ToDouble(value));
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
context.DocumentIndex.Add(indexName, Convert.ToDateTime(fieldValue));
|
||||
context.DocumentIndex.Add(indexName, Convert.ToDateTime(value));
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var driver in drivers) {
|
||||
driver.Describe(membersContext);
|
||||
|
@ -1,7 +1,10 @@
|
||||
@model Orchard.Indexing.Settings.FieldIndexing
|
||||
|
||||
<fieldset>
|
||||
@Html.EditorFor(m=>m.Included)
|
||||
<label for="@Html.FieldIdFor(m => m.Included)" class="forcheckbox">@T("Include in the index")</label>
|
||||
@Html.ValidationMessageFor(m => m.Included)
|
||||
<div>
|
||||
@Html.EditorFor(m=>m.Included)
|
||||
<label for="@Html.FieldIdFor(m => m.Included)" class="forcheckbox">@T("Include in the index")</label>
|
||||
@Html.ValidationMessageFor(m => m.Included)
|
||||
<span class="hint">@T("Check to add content of this field in the selected indexes.")</span>
|
||||
</div>
|
||||
</fieldset>
|
@ -631,7 +631,7 @@ select {
|
||||
select:focus, textarea:focus, input.text:focus, input.text-box:focus, input.text-small:focus, input.textMedium:focus {
|
||||
border-color:#666d51;
|
||||
}
|
||||
input.check-box {
|
||||
input.check-box, input[type=checkbox] {
|
||||
margin-left:0;
|
||||
vertical-align:-.1em;
|
||||
}
|
||||
|
@ -1,12 +1,25 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Orchard.ContentManagement.FieldStorage;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.ContentManagement.Handlers {
|
||||
public class DescribeMembersContext {
|
||||
private readonly Action<string, Type, LocalizedString, LocalizedString> _processMember;
|
||||
private readonly IFieldStorage _storage;
|
||||
private readonly Action<IEnumerable> _apply;
|
||||
|
||||
public DescribeMembersContext(Action<string, Type, LocalizedString, LocalizedString> processMember) {
|
||||
public DescribeMembersContext(Action<string, Type, LocalizedString, LocalizedString> processMember) : this(processMember, null, null) {
|
||||
}
|
||||
|
||||
public DescribeMembersContext(IFieldStorage storage, Action<IEnumerable> apply)
|
||||
: this(null, storage, apply) {
|
||||
}
|
||||
|
||||
public DescribeMembersContext(Action<string, Type, LocalizedString, LocalizedString> processMember, IFieldStorage storage, Action<IEnumerable> apply) {
|
||||
_processMember = processMember;
|
||||
_storage = storage;
|
||||
_apply = apply;
|
||||
}
|
||||
|
||||
public DescribeMembersContext Member(string storageName, Type storageType) {
|
||||
@ -18,7 +31,21 @@ namespace Orchard.ContentManagement.Handlers {
|
||||
}
|
||||
|
||||
public DescribeMembersContext Member(string storageName, Type storageType, LocalizedString displayName, LocalizedString description) {
|
||||
_processMember(storageName, storageType, displayName, description);
|
||||
if (_processMember != null) {
|
||||
_processMember(storageName, storageType, displayName, description);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescribeMembersContext Enumerate<TField>(Func<Func<TField, IEnumerable>> enumerate) where TField : ContentField, new() {
|
||||
|
||||
if (enumerate != null) {
|
||||
var f = enumerate();
|
||||
var field = Activator.CreateInstance<TField>();
|
||||
field.Storage = _storage;
|
||||
_apply(f(field));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user