@@ -44,13 +44,14 @@ final class EagerLoadingExtension implements QueryCollectionExtensionInterface,
44
44
private $ serializerContextBuilder ;
45
45
private $ requestStack ;
46
46
47
- public function __construct (PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , PropertyMetadataFactoryInterface $ propertyMetadataFactory , ResourceMetadataFactoryInterface $ resourceMetadataFactory , int $ maxJoins = 30 , bool $ forceEager = true , RequestStack $ requestStack = null , SerializerContextBuilderInterface $ serializerContextBuilder = null )
47
+ public function __construct (PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , PropertyMetadataFactoryInterface $ propertyMetadataFactory , ResourceMetadataFactoryInterface $ resourceMetadataFactory , int $ maxJoins = 30 , bool $ forceEager = true , bool $ fetchPartial = false , RequestStack $ requestStack = null , SerializerContextBuilderInterface $ serializerContextBuilder = null )
48
48
{
49
49
$ this ->propertyNameCollectionFactory = $ propertyNameCollectionFactory ;
50
50
$ this ->propertyMetadataFactory = $ propertyMetadataFactory ;
51
51
$ this ->resourceMetadataFactory = $ resourceMetadataFactory ;
52
52
$ this ->maxJoins = $ maxJoins ;
53
53
$ this ->forceEager = $ forceEager ;
54
+ $ this ->fetchPartial = $ fetchPartial ;
54
55
$ this ->serializerContextBuilder = $ serializerContextBuilder ;
55
56
$ this ->requestStack = $ requestStack ;
56
57
}
@@ -67,10 +68,11 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
67
68
}
68
69
69
70
$ forceEager = $ this ->shouldOperationForceEager ($ resourceClass , $ options );
71
+ $ fetchPartial = $ this ->shouldOperationFetchPartial ($ resourceClass , $ options );
70
72
71
73
$ groups = $ this ->getSerializerGroups ($ resourceClass , $ options , 'normalization_context ' );
72
74
73
- $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ forceEager , $ queryBuilder ->getRootAliases ()[0 ], $ groups );
75
+ $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ forceEager , $ fetchPartial , $ queryBuilder ->getRootAliases ()[0 ], $ groups );
74
76
}
75
77
76
78
/**
@@ -86,6 +88,7 @@ public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterf
86
88
}
87
89
88
90
$ forceEager = $ this ->shouldOperationForceEager ($ resourceClass , $ options );
91
+ $ fetchPartial = $ this ->shouldOperationFetchPartial ($ resourceClass , $ options );
89
92
90
93
if (isset ($ context ['groups ' ])) {
91
94
$ groups = ['serializer_groups ' => $ context ['groups ' ]];
@@ -95,7 +98,7 @@ public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterf
95
98
$ groups = $ this ->getSerializerGroups ($ resourceClass , $ options , 'normalization_context ' );
96
99
}
97
100
98
- $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ forceEager , $ queryBuilder ->getRootAliases ()[0 ], $ groups );
101
+ $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ resourceClass , $ forceEager , $ fetchPartial , $ queryBuilder ->getRootAliases ()[0 ], $ groups );
99
102
}
100
103
101
104
/**
@@ -112,7 +115,7 @@ public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterf
112
115
*
113
116
* @throws RuntimeException when the max number of joins has been reached
114
117
*/
115
- private function joinRelations (QueryBuilder $ queryBuilder , QueryNameGeneratorInterface $ queryNameGenerator , string $ resourceClass , bool $ forceEager , string $ parentAlias , array $ propertyMetadataOptions = [], bool $ wasLeftJoin = false , int &$ joinCount = 0 )
118
+ private function joinRelations (QueryBuilder $ queryBuilder , QueryNameGeneratorInterface $ queryNameGenerator , string $ resourceClass , bool $ forceEager , bool $ fetchPartial , string $ parentAlias , array $ propertyMetadataOptions = [], bool $ wasLeftJoin = false , int &$ joinCount = 0 )
116
119
{
117
120
if ($ joinCount > $ this ->maxJoins ) {
118
121
throw new RuntimeException ('The total number of joined relations has exceeded the specified maximum. Raise the limit if necessary. ' );
@@ -152,18 +155,23 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt
152
155
$ queryBuilder ->{$ method }(sprintf ('%s.%s ' , $ parentAlias , $ association ), $ associationAlias );
153
156
++$ joinCount ;
154
157
155
- try {
156
- $ this ->addSelect ($ queryBuilder , $ mapping ['targetEntity ' ], $ associationAlias , $ propertyMetadataOptions );
157
- } catch (ResourceClassNotFoundException $ resourceClassNotFoundException ) {
158
- continue ;
158
+ if (true === $ fetchPartial ) {
159
+ try {
160
+ $ this ->addSelect ($ queryBuilder , $ mapping ['targetEntity ' ], $ associationAlias , $ propertyMetadataOptions );
161
+ } catch (ResourceClassNotFoundException $ resourceClassNotFoundException ) {
162
+ continue ;
163
+ }
164
+ } else {
165
+ $ queryBuilder ->addSelect ($ associationAlias );
159
166
}
160
167
168
+ // Avoid recursion
161
169
if ($ mapping ['targetEntity ' ] === $ resourceClass ) {
162
170
$ queryBuilder ->addSelect ($ associationAlias );
163
171
continue ;
164
172
}
165
173
166
- $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ mapping ['targetEntity ' ], $ forceEager , $ associationAlias , $ propertyMetadataOptions , $ method === 'leftJoin ' , $ joinCount );
174
+ $ this ->joinRelations ($ queryBuilder , $ queryNameGenerator , $ mapping ['targetEntity ' ], $ forceEager , $ fetchPartial , $ associationAlias , $ propertyMetadataOptions , $ method === 'leftJoin ' , $ joinCount );
167
175
}
168
176
}
169
177
@@ -184,7 +192,7 @@ private function addSelect(QueryBuilder $queryBuilder, string $entity, string $a
184
192
}
185
193
186
194
//the field test allows to add methods to a Resource which do not reflect real database fields
187
- if (true === $ targetClassMetadata ->hasField ($ property ) && true === $ propertyMetadata ->isReadable ()) {
195
+ if (true === $ targetClassMetadata ->hasField ($ property ) && ( true === $ propertyMetadata ->getAttribute ( ' fetchable ' ) || true === $ propertyMetadata -> isReadable () )) {
188
196
$ select [] = $ property ;
189
197
}
190
198
}
0 commit comments