Skip to content

Commit ea865ce

Browse files
authored
Fixes errors when filtering by content fields in GraphQL (OrchardCMS#17378)
1 parent 17b0073 commit ea865ce

File tree

18 files changed

+448
-96
lines changed

18 files changed

+448
-96
lines changed

src/OrchardCore.Modules/OrchardCore.ContentFields/GraphQL/Fields/ContentFieldsProvider.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Frozen;
2+
using GraphQL;
23
using GraphQL.Resolvers;
34
using GraphQL.Types;
45
using Microsoft.Extensions.Localization;
@@ -25,7 +26,7 @@ public class ContentFieldsProvider : IContentFieldProvider
2526
UnderlyingType = typeof(BooleanField),
2627
FieldAccessor = field => ((BooleanField)field).Value,
2728
IndexType = typeof(BooleanFieldIndex),
28-
Index = nameof(BooleanFieldIndex.Boolean),
29+
IndexProperty = nameof(BooleanFieldIndex.Boolean),
2930
}
3031
},
3132
{
@@ -38,7 +39,7 @@ public class ContentFieldsProvider : IContentFieldProvider
3839
UnderlyingType = typeof(DateField),
3940
FieldAccessor = field => ((DateField)field).Value,
4041
IndexType = typeof(DateFieldIndex),
41-
Index = nameof(DateFieldIndex.Date),
42+
IndexProperty = nameof(DateFieldIndex.Date),
4243
}
4344
},
4445
{
@@ -51,7 +52,7 @@ public class ContentFieldsProvider : IContentFieldProvider
5152
UnderlyingType = typeof(DateTimeField),
5253
FieldAccessor = field => ((DateTimeField)field).Value,
5354
IndexType = typeof(DateTimeFieldIndex),
54-
Index = nameof(DateTimeFieldIndex.DateTime),
55+
IndexProperty = nameof(DateTimeFieldIndex.DateTime),
5556
}
5657
},
5758
{
@@ -64,7 +65,7 @@ public class ContentFieldsProvider : IContentFieldProvider
6465
UnderlyingType = typeof(NumericField),
6566
FieldAccessor = field => ((NumericField)field).Value,
6667
IndexType = typeof(NumericFieldIndex),
67-
Index = nameof(NumericFieldIndex.Numeric)
68+
IndexProperty = nameof(NumericFieldIndex.Numeric)
6869
}
6970
},
7071
{
@@ -77,7 +78,7 @@ public class ContentFieldsProvider : IContentFieldProvider
7778
UnderlyingType = typeof(TextField),
7879
FieldAccessor = field => ((TextField)field).Text,
7980
IndexType = typeof(TextFieldIndex),
80-
Index = nameof(TextFieldIndex.Text)
81+
IndexProperty = nameof(TextFieldIndex.Text)
8182
}
8283
},
8384
{
@@ -90,7 +91,7 @@ public class ContentFieldsProvider : IContentFieldProvider
9091
UnderlyingType = typeof(TimeField),
9192
FieldAccessor = field => ((TimeField)field).Value,
9293
IndexType = typeof(TimeFieldIndex),
93-
Index = nameof(TimeFieldIndex.Time)
94+
IndexProperty = nameof(TimeFieldIndex.Time)
9495
}
9596
},
9697
{
@@ -157,15 +158,16 @@ public FieldTypeIndexDescriptor GetFieldIndex(ContentPartFieldDefinition field)
157158

158159
return new FieldTypeIndexDescriptor
159160
{
160-
Index = fieldDescriptor.Index,
161-
IndexType = fieldDescriptor.IndexType,
161+
AliasName = $"{field.PartDefinition.Name.ToFieldName()}:{field.Name.ToCamelCase()}:{fieldDescriptor.IndexProperty}",
162+
Index = fieldDescriptor.IndexType.Name,
163+
IndexType = fieldDescriptor.IndexType
162164
};
163165
}
164166

165167
public bool HasFieldIndex(ContentPartFieldDefinition field)
166168
=> _contentFieldTypeMappings.TryGetValue(field.FieldDefinition.Name, out var fieldTypeDescriptor) &&
167169
fieldTypeDescriptor.IndexType != null &&
168-
!string.IsNullOrWhiteSpace(fieldTypeDescriptor.Index);
170+
!string.IsNullOrWhiteSpace(fieldTypeDescriptor.IndexProperty);
169171

170172
private sealed class FieldTypeDescriptor
171173
{
@@ -179,7 +181,7 @@ private sealed class FieldTypeDescriptor
179181

180182
public Func<ContentElement, object> FieldAccessor { get; set; }
181183

182-
public string Index { get; set; }
184+
public string IndexProperty { get; set; }
183185

184186
public Type IndexType { get; set; }
185187
}

src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Extensions/GraphQLTypeExtensions.cs renamed to src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Extensions/GraphQLTypeExtensions.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using GraphQL.Types;
22

3-
namespace OrchardCore.ContentManagement.GraphQL;
3+
namespace OrchardCore.Apis.GraphQL;
44

55
public static class GraphQLTypeExtensions
66
{
@@ -10,6 +10,15 @@ public static FieldType WithPartCollapsedMetaData(this FieldType fieldType, bool
1010
public static FieldType WithPartNameMetaData(this FieldType fieldType, string partName)
1111
=> fieldType.WithMetaData("PartName", partName);
1212

13+
public static FieldType WithAliasNameMetaData(this FieldType fieldType, string aliasName)
14+
=> fieldType.WithMetaData("AliasName", aliasName);
15+
16+
public static FieldType WithContentPartMetaData(this FieldType fieldType, string contentPart)
17+
=> fieldType.WithMetaData("ContentPart", contentPart);
18+
19+
public static FieldType WithContentFieldMetaData(this FieldType fieldType, string contentField)
20+
=> fieldType.WithMetaData("ContentField", contentField);
21+
1322
/// <summary>
1423
/// Checks if the field exists in the GraphQL type in a case-insensitive way.
1524
/// </summary>
@@ -27,10 +36,13 @@ public static bool HasFieldIgnoreCase(this IComplexGraphType graphType, string f
2736

2837
private static FieldType WithMetaData(this FieldType fieldType, string name, object value)
2938
{
30-
// TODO: Understand if locking is the best solution to https://github.com/OrchardCMS/OrchardCore/issues/15308
31-
lock (fieldType.Metadata)
39+
if (value != null)
3240
{
33-
fieldType.Metadata.TryAdd(name, value);
41+
// TODO: Understand if locking is the best solution to https://github.com/OrchardCMS/OrchardCore/issues/15308
42+
lock (fieldType.Metadata)
43+
{
44+
fieldType.Metadata.TryAdd(name, value);
45+
}
3446
}
3547

3648
return fieldType;
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
using GraphQL.Types;
1+
using GraphQL.Types;
22

33
namespace OrchardCore.Apis.GraphQL.Queries;
44

55
public interface IFilterInputObjectGraphType : IInputObjectGraphType
66
{
77
void AddScalarFilterFields<TGraphType>(string fieldName, string description);
88

9+
void AddScalarFilterFields<TGraphType>(string fieldName, string description, string aliasName, string contentPart, string contentField)
10+
=> AddScalarFilterFields<TGraphType>(fieldName, description);
11+
912
void AddScalarFilterFields(Type graphType, string fieldName, string description);
13+
14+
void AddScalarFilterFields(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
15+
=> AddScalarFilterFields(graphType, fieldName, description);
1016
}

src/OrchardCore/OrchardCore.Apis.GraphQL.Abstractions/Queries/WhereInputObjectGraphType.cs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,31 @@ public override object ParseDictionary(IDictionary<string, object> value)
6262
{ "_not_ends_with", (S, description) => S["{0} does not end with the string", description] },
6363
};
6464

65-
public virtual void AddScalarFilterFields<TGraphType>(string fieldName, string description)
65+
public void AddScalarFilterFields<TGraphType>(string fieldName, string description)
66+
=> AddScalarFilterFields<TGraphType>(fieldName, description, null, null, null);
67+
68+
public virtual void AddScalarFilterFields<TGraphType>(string fieldName, string description, string aliasName, string contentPart, string contentField)
6669
{
67-
AddScalarFilterFields(typeof(TGraphType), fieldName, description);
70+
AddScalarFilterFields(typeof(TGraphType), fieldName, description, aliasName, contentPart, contentField);
6871
}
6972

70-
public virtual void AddScalarFilterFields(Type graphType, string fieldName, string description)
73+
public void AddScalarFilterFields(Type graphType, string fieldName, string description)
74+
=> AddScalarFilterFields(graphType, fieldName, description, null, null, null);
75+
76+
public virtual void AddScalarFilterFields(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
7177
{
7278
if (!typeof(ScalarGraphType).IsAssignableFrom(graphType) &&
7379
!typeof(IInputObjectGraphType).IsAssignableFrom(graphType))
7480
{
7581
return;
7682
}
7783

78-
AddEqualityFilters(graphType, fieldName, description);
84+
AddEqualityFilters(graphType, fieldName, description, aliasName, contentPart, contentField);
7985

8086
if (graphType == typeof(StringGraphType))
8187
{
82-
AddMultiValueFilters(graphType, fieldName, description);
83-
AddStringFilters(graphType, fieldName, description);
88+
AddMultiValueFilters(graphType, fieldName, description, aliasName, contentPart, contentField);
89+
AddStringFilters(graphType, fieldName, description, aliasName, contentPart, contentField);
8490
}
8591
else if (graphType == typeof(DateTimeGraphType) ||
8692
graphType == typeof(DateGraphType) ||
@@ -92,36 +98,39 @@ public virtual void AddScalarFilterFields(Type graphType, string fieldName, stri
9298
graphType == typeof(FloatGraphType) ||
9399
graphType == typeof(BigIntGraphType))
94100
{
95-
AddMultiValueFilters(graphType, fieldName, description);
96-
AddNonStringFilters(graphType, fieldName, description);
101+
AddMultiValueFilters(graphType, fieldName, description, aliasName, contentPart, contentField);
102+
AddNonStringFilters(graphType, fieldName, description, aliasName, contentPart, contentField);
97103
}
98104
}
99105

100-
private void AddEqualityFilters(Type graphType, string fieldName, string description)
106+
private void AddEqualityFilters(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
101107
{
102-
AddFilterFields(graphType, EqualityOperators, fieldName, description);
108+
AddFilterFields(graphType, EqualityOperators, fieldName, description, aliasName, contentPart, contentField);
103109
}
104110

105-
private void AddStringFilters(Type graphType, string fieldName, string description)
111+
private void AddStringFilters(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
106112
{
107-
AddFilterFields(graphType, StringComparisonOperators, fieldName, description);
113+
AddFilterFields(graphType, StringComparisonOperators, fieldName, description, aliasName, contentPart, contentField);
108114
}
109115

110-
private void AddNonStringFilters(Type graphType, string fieldName, string description)
116+
private void AddNonStringFilters(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
111117
{
112-
AddFilterFields(graphType, NonStringValueComparisonOperators, fieldName, description);
118+
AddFilterFields(graphType, NonStringValueComparisonOperators, fieldName, description, aliasName, contentPart, contentField);
113119
}
114120

115-
private void AddMultiValueFilters(Type graphType, string fieldName, string description)
121+
private void AddMultiValueFilters(Type graphType, string fieldName, string description, string aliasName, string contentPart, string contentField)
116122
{
117-
AddFilterFields(graphType, MultiValueComparisonOperators, fieldName, description);
123+
AddFilterFields(graphType, MultiValueComparisonOperators, fieldName, description, aliasName, contentPart, contentField);
118124
}
119125

120126
private void AddFilterFields(
121127
Type graphType,
122128
IDictionary<string, Func<IStringLocalizer, string, string>> filters,
123129
string fieldName,
124-
string description)
130+
string description,
131+
string aliasName,
132+
string contentPart,
133+
string contentField)
125134
{
126135
foreach (var filter in filters)
127136
{
@@ -130,7 +139,9 @@ private void AddFilterFields(
130139
Name = fieldName + filter.Key,
131140
Description = filter.Value(S, description),
132141
Type = graphType,
133-
});
142+
}.WithAliasNameMetaData(aliasName)
143+
.WithContentPartMetaData(contentPart)
144+
.WithContentFieldMetaData(contentField));
134145
}
135146
}
136147
}

0 commit comments

Comments
 (0)